Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
8cea2e95
Commit
8cea2e95
authored
Aug 12, 2015
by
4ast
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #127 from iovisor/bblanco_dev
Changes to support map entry read/write in fuse
parents
f04003e1
2582ecfc
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
182 additions
and
131 deletions
+182
-131
src/cc/bpf_common.cc
src/cc/bpf_common.cc
+18
-13
src/cc/bpf_common.h
src/cc/bpf_common.h
+3
-4
src/cc/bpf_module.cc
src/cc/bpf_module.cc
+96
-96
src/cc/bpf_module.h
src/cc/bpf_module.h
+3
-2
src/cc/table_desc.h
src/cc/table_desc.h
+4
-4
src/python/bpf/__init__.py
src/python/bpf/__init__.py
+54
-10
tests/cc/test_clang.py
tests/cc/test_clang.py
+4
-2
No files found.
src/cc/bpf_common.cc
View file @
8cea2e95
...
@@ -104,6 +104,12 @@ size_t bpf_num_tables(void *program) {
...
@@ -104,6 +104,12 @@ size_t bpf_num_tables(void *program) {
return
mod
->
num_tables
();
return
mod
->
num_tables
();
}
}
size_t
bpf_table_id
(
void
*
program
,
const
char
*
table_name
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
~
0ull
;
return
mod
->
table_id
(
table_name
);
}
int
bpf_table_fd
(
void
*
program
,
const
char
*
table_name
)
{
int
bpf_table_fd
(
void
*
program
,
const
char
*
table_name
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
-
1
;
if
(
!
mod
)
return
-
1
;
...
@@ -170,27 +176,26 @@ size_t bpf_table_leaf_size_id(void *program, size_t id) {
...
@@ -170,27 +176,26 @@ size_t bpf_table_leaf_size_id(void *program, size_t id) {
return
mod
->
table_leaf_size
(
id
);
return
mod
->
table_leaf_size
(
id
);
}
}
int
bpf_table_
update
(
void
*
program
,
const
char
*
table_name
,
const
char
*
key
,
const
char
*
leaf
)
{
int
bpf_table_
key_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
return
mod
->
table_
update
(
table_name
,
key
,
leaf
);
return
mod
->
table_
key_printf
(
id
,
buf
,
buflen
,
key
);
}
}
int
bpf_table_leaf_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
)
{
int
bpf_table_update_id
(
void
*
program
,
size_t
id
,
const
char
*
key
,
const
char
*
leaf
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
return
mod
->
table_
update
(
id
,
key
,
leaf
);
return
mod
->
table_
leaf_printf
(
id
,
buf
,
buflen
,
leaf
);
}
}
int
bpf_table_key_s
nprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
)
{
int
bpf_table_key_s
scanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
key
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
return
mod
->
table_key_
printf
(
id
,
buf
,
buflen
,
key
);
return
mod
->
table_key_
scanf
(
id
,
buf
,
key
);
}
}
int
bpf_table_leaf_s
nprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
)
{
int
bpf_table_leaf_s
scanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
leaf
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
return
mod
->
table_
key_printf
(
id
,
buf
,
buflen
,
leaf
);
return
mod
->
table_
leaf_scanf
(
id
,
buf
,
leaf
);
}
}
}
}
src/cc/bpf_common.h
View file @
8cea2e95
...
@@ -37,6 +37,7 @@ void * bpf_function_start(void *program, const char *name);
...
@@ -37,6 +37,7 @@ void * bpf_function_start(void *program, const char *name);
size_t
bpf_function_size_id
(
void
*
program
,
size_t
id
);
size_t
bpf_function_size_id
(
void
*
program
,
size_t
id
);
size_t
bpf_function_size
(
void
*
program
,
const
char
*
name
);
size_t
bpf_function_size
(
void
*
program
,
const
char
*
name
);
size_t
bpf_num_tables
(
void
*
program
);
size_t
bpf_num_tables
(
void
*
program
);
size_t
bpf_table_id
(
void
*
program
,
const
char
*
table_name
);
int
bpf_table_fd
(
void
*
program
,
const
char
*
table_name
);
int
bpf_table_fd
(
void
*
program
,
const
char
*
table_name
);
int
bpf_table_fd_id
(
void
*
program
,
size_t
id
);
int
bpf_table_fd_id
(
void
*
program
,
size_t
id
);
const
char
*
bpf_table_name
(
void
*
program
,
size_t
id
);
const
char
*
bpf_table_name
(
void
*
program
,
size_t
id
);
...
@@ -50,10 +51,8 @@ size_t bpf_table_leaf_size(void *program, const char *table_name);
...
@@ -50,10 +51,8 @@ size_t bpf_table_leaf_size(void *program, const char *table_name);
size_t
bpf_table_leaf_size_id
(
void
*
program
,
size_t
id
);
size_t
bpf_table_leaf_size_id
(
void
*
program
,
size_t
id
);
int
bpf_table_key_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
);
int
bpf_table_key_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
);
int
bpf_table_leaf_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
);
int
bpf_table_leaf_snprintf
(
void
*
program
,
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
);
//int bpf_table_key_sscanf(void *program, size_t id, const char *buf, void *key);
int
bpf_table_key_sscanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
key
);
//int bpf_table_leaf_sscanf(void *program, size_t id, const char *buf, void *leaf);
int
bpf_table_leaf_sscanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
leaf
);
int
bpf_table_update
(
void
*
program
,
const
char
*
table_name
,
const
char
*
key
,
const
char
*
leaf
);
int
bpf_table_update_id
(
void
*
program
,
size_t
id
,
const
char
*
key
,
const
char
*
leaf
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
src/cc/bpf_module.cc
View file @
8cea2e95
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include <linux/bpf.h>
#include <linux/bpf.h>
#include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/STLExtras.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/IRReader/IRReader.h>
...
@@ -64,6 +63,9 @@ using std::unique_ptr;
...
@@ -64,6 +63,9 @@ using std::unique_ptr;
using
std
::
vector
;
using
std
::
vector
;
using
namespace
llvm
;
using
namespace
llvm
;
typedef
int
(
*
sscanf_fn
)
(
const
char
*
,
void
*
);
typedef
int
(
*
snprintf_fn
)
(
char
*
,
size_t
,
const
void
*
);
const
string
BPFModule
::
FN_PREFIX
=
BPF_FN_PREFIX
;
const
string
BPFModule
::
FN_PREFIX
=
BPF_FN_PREFIX
;
// Snooping class to remember the sections as the JIT creates them
// Snooping class to remember the sections as the JIT creates them
...
@@ -147,9 +149,9 @@ static void parse_type(IRBuilder<> &B, vector<Value *> *args, string *fmt,
...
@@ -147,9 +149,9 @@ static void parse_type(IRBuilder<> &B, vector<Value *> *args, string *fmt,
else
if
(
it
->
getBitWidth
()
<=
16
)
else
if
(
it
->
getBitWidth
()
<=
16
)
*
fmt
+=
"%h"
;
*
fmt
+=
"%h"
;
else
if
(
it
->
getBitWidth
()
<=
32
)
else
if
(
it
->
getBitWidth
()
<=
32
)
*
fmt
+=
"%
l
"
;
*
fmt
+=
"%"
;
else
else
*
fmt
+=
"%l
l
"
;
*
fmt
+=
"%l"
;
if
(
is_writer
)
if
(
is_writer
)
*
fmt
+=
"x"
;
*
fmt
+=
"x"
;
else
else
...
@@ -171,15 +173,11 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
...
@@ -171,15 +173,11 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
IRBuilder
<>
B
(
*
ctx_
);
// The JIT currently supports a limited number of function prototypes, use the
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
// int (*) (int, char **, const char **) version
vector
<
Type
*>
fn_args
({
B
.
getInt32Ty
(),
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"reader"
+
std
::
to_string
(
readers_
.
size
()),
mod
);
"reader"
+
std
::
to_string
(
readers_
.
size
()),
mod
);
auto
arg_it
=
fn
->
arg_begin
();
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_argc
=
arg_it
++
;
arg_argc
->
setName
(
"argc"
);
Argument
*
arg_in
=
arg_it
++
;
Argument
*
arg_in
=
arg_it
++
;
arg_in
->
setName
(
"in"
);
arg_in
->
setName
(
"in"
);
Argument
*
arg_out
=
arg_it
++
;
Argument
*
arg_out
=
arg_it
++
;
...
@@ -197,6 +195,9 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
...
@@ -197,6 +195,9 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
args
[
1
]
=
B
.
CreateInBoundsGEP
(
fmt_gvar
,
vector
<
Value
*>
({
B
.
getInt64
(
0
),
B
.
getInt64
(
0
)}));
args
[
1
]
=
B
.
CreateInBoundsGEP
(
fmt_gvar
,
vector
<
Value
*>
({
B
.
getInt64
(
0
),
B
.
getInt64
(
0
)}));
if
(
0
)
debug_printf
(
mod
,
B
,
"%p %p
\n
"
,
vector
<
Value
*>
({
arg_in
,
arg_out
}));
vector
<
Type
*>
sscanf_fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt8PtrTy
()});
vector
<
Type
*>
sscanf_fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt8PtrTy
()});
FunctionType
*
sscanf_fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
sscanf_fn_args
,
/*isVarArg=*/
true
);
FunctionType
*
sscanf_fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
sscanf_fn_args
,
/*isVarArg=*/
true
);
Function
*
sscanf_fn
=
mod
->
getFunction
(
"sscanf"
);
Function
*
sscanf_fn
=
mod
->
getFunction
(
"sscanf"
);
...
@@ -234,17 +235,15 @@ Function * BPFModule::make_writer(Module *mod, Type *type) {
...
@@ -234,17 +235,15 @@ Function * BPFModule::make_writer(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
IRBuilder
<>
B
(
*
ctx_
);
// The JIT currently supports a limited number of function prototypes, use the
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt64Ty
(),
PointerType
::
getUnqual
(
type
)});
// int (*) (int, char **, const char **) version
vector
<
Type
*>
fn_args
({
B
.
getInt32Ty
(),
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"writer"
+
std
::
to_string
(
writers_
.
size
()),
mod
);
"writer"
+
std
::
to_string
(
writers_
.
size
()),
mod
);
auto
arg_it
=
fn
->
arg_begin
();
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_len
=
arg_it
++
;
arg_len
->
setName
(
"len"
);
Argument
*
arg_out
=
arg_it
++
;
Argument
*
arg_out
=
arg_it
++
;
arg_out
->
setName
(
"out"
);
arg_out
->
setName
(
"out"
);
Argument
*
arg_len
=
arg_it
++
;
arg_len
->
setName
(
"len"
);
Argument
*
arg_in
=
arg_it
++
;
Argument
*
arg_in
=
arg_it
++
;
arg_in
->
setName
(
"in"
);
arg_in
->
setName
(
"in"
);
...
@@ -331,18 +330,18 @@ int BPFModule::annotate() {
...
@@ -331,18 +330,18 @@ int BPFModule::annotate() {
if
(
st
->
getNumElements
()
<
2
)
continue
;
if
(
st
->
getNumElements
()
<
2
)
continue
;
Type
*
key_type
=
st
->
elements
()[
0
];
Type
*
key_type
=
st
->
elements
()[
0
];
Type
*
leaf_type
=
st
->
elements
()[
1
];
Type
*
leaf_type
=
st
->
elements
()[
1
];
table
.
key_
reader
=
make_reader
(
&*
m
,
key_type
);
table
.
key_
sscanf
=
make_reader
(
&*
m
,
key_type
);
if
(
!
table
.
key_
reader
)
if
(
!
table
.
key_
sscanf
)
errs
()
<<
"Failed to compile
reader
for "
<<
*
key_type
<<
"
\n
"
;
errs
()
<<
"Failed to compile
sscanf
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
reader
=
make_reader
(
&*
m
,
leaf_type
);
table
.
leaf_
sscanf
=
make_reader
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
reader
)
if
(
!
table
.
leaf_
sscanf
)
errs
()
<<
"Failed to compile
reader
for "
<<
*
leaf_type
<<
"
\n
"
;
errs
()
<<
"Failed to compile
sscanf
for "
<<
*
leaf_type
<<
"
\n
"
;
table
.
key_
writer
=
make_writer
(
&*
m
,
key_type
);
table
.
key_
snprintf
=
make_writer
(
&*
m
,
key_type
);
if
(
!
table
.
key_
writer
)
if
(
!
table
.
key_
snprintf
)
errs
()
<<
"Failed to compile
writer
for "
<<
*
key_type
<<
"
\n
"
;
errs
()
<<
"Failed to compile
snprintf
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
writer
=
make_writer
(
&*
m
,
leaf_type
);
table
.
leaf_
snprintf
=
make_writer
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
writer
)
if
(
!
table
.
leaf_
snprintf
)
errs
()
<<
"Failed to compile
writer
for "
<<
*
leaf_type
<<
"
\n
"
;
errs
()
<<
"Failed to compile
snprintf
for "
<<
*
leaf_type
<<
"
\n
"
;
}
}
}
}
}
}
...
@@ -474,10 +473,14 @@ size_t BPFModule::num_tables() const {
...
@@ -474,10 +473,14 @@ size_t BPFModule::num_tables() const {
return
tables_
->
size
();
return
tables_
->
size
();
}
}
int
BPFModule
::
table_f
d
(
const
string
&
name
)
const
{
size_t
BPFModule
::
table_i
d
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
auto
it
=
table_names_
.
find
(
name
);
if
(
it
==
table_names_
.
end
())
return
-
1
;
if
(
it
==
table_names_
.
end
())
return
~
0ull
;
return
table_fd
(
it
->
second
);
return
it
->
second
;
}
int
BPFModule
::
table_fd
(
const
string
&
name
)
const
{
return
table_fd
(
table_id
(
name
));
}
}
int
BPFModule
::
table_fd
(
size_t
id
)
const
{
int
BPFModule
::
table_fd
(
size_t
id
)
const
{
...
@@ -497,9 +500,7 @@ const char * BPFModule::table_key_desc(size_t id) const {
...
@@ -497,9 +500,7 @@ const char * BPFModule::table_key_desc(size_t id) const {
}
}
const
char
*
BPFModule
::
table_key_desc
(
const
string
&
name
)
const
{
const
char
*
BPFModule
::
table_key_desc
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
return
table_key_desc
(
table_id
(
name
));
if
(
it
==
table_names_
.
end
())
return
nullptr
;
return
table_key_desc
(
it
->
second
);
}
}
const
char
*
BPFModule
::
table_leaf_desc
(
size_t
id
)
const
{
const
char
*
BPFModule
::
table_leaf_desc
(
size_t
id
)
const
{
...
@@ -509,18 +510,14 @@ const char * BPFModule::table_leaf_desc(size_t id) const {
...
@@ -509,18 +510,14 @@ const char * BPFModule::table_leaf_desc(size_t id) const {
}
}
const
char
*
BPFModule
::
table_leaf_desc
(
const
string
&
name
)
const
{
const
char
*
BPFModule
::
table_leaf_desc
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
return
table_leaf_desc
(
table_id
(
name
));
if
(
it
==
table_names_
.
end
())
return
nullptr
;
return
table_leaf_desc
(
it
->
second
);
}
}
size_t
BPFModule
::
table_key_size
(
size_t
id
)
const
{
size_t
BPFModule
::
table_key_size
(
size_t
id
)
const
{
if
(
id
>=
tables_
->
size
())
return
0
;
if
(
id
>=
tables_
->
size
())
return
0
;
return
(
*
tables_
)[
id
].
key_size
;
return
(
*
tables_
)[
id
].
key_size
;
}
}
size_t
BPFModule
::
table_key_size
(
const
string
&
name
)
const
{
size_t
BPFModule
::
table_key_size
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
return
table_key_size
(
table_id
(
name
));
if
(
it
==
table_names_
.
end
())
return
0
;
return
table_key_size
(
it
->
second
);
}
}
size_t
BPFModule
::
table_leaf_size
(
size_t
id
)
const
{
size_t
BPFModule
::
table_leaf_size
(
size_t
id
)
const
{
...
@@ -528,42 +525,7 @@ size_t BPFModule::table_leaf_size(size_t id) const {
...
@@ -528,42 +525,7 @@ size_t BPFModule::table_leaf_size(size_t id) const {
return
(
*
tables_
)[
id
].
leaf_size
;
return
(
*
tables_
)[
id
].
leaf_size
;
}
}
size_t
BPFModule
::
table_leaf_size
(
const
string
&
name
)
const
{
size_t
BPFModule
::
table_leaf_size
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
return
table_leaf_size
(
table_id
(
name
));
if
(
it
==
table_names_
.
end
())
return
0
;
return
table_leaf_size
(
it
->
second
);
}
int
BPFModule
::
table_update
(
const
string
&
name
,
const
char
*
key_str
,
const
char
*
leaf_str
)
{
auto
it
=
table_names_
.
find
(
name
);
if
(
it
==
table_names_
.
end
())
return
0
;
return
table_update
(
it
->
second
,
key_str
,
leaf_str
);
}
int
BPFModule
::
table_update
(
size_t
id
,
const
char
*
key_str
,
const
char
*
leaf_str
)
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
desc
.
fd
<
0
)
return
-
1
;
if
(
!
rw_engine_
||
!
desc
.
key_reader
||
!
desc
.
leaf_reader
)
{
fprintf
(
stderr
,
"Table sscanf not available
\n
"
);
return
-
1
;
}
unique_ptr
<
uint8_t
[]
>
key
(
new
uint8_t
[
desc
.
key_size
]);
unique_ptr
<
uint8_t
[]
>
leaf
(
new
uint8_t
[
desc
.
leaf_size
]);
GenericValue
rc
;
rc
=
rw_engine_
->
runFunction
(
desc
.
key_reader
,
vector
<
GenericValue
>
({
GenericValue
(),
GenericValue
((
void
*
)
key_str
),
GenericValue
((
void
*
)
key
.
get
())}));
if
(
rc
.
IntVal
!=
0
)
return
-
1
;
rc
=
rw_engine_
->
runFunction
(
desc
.
leaf_reader
,
vector
<
GenericValue
>
({
GenericValue
(),
GenericValue
((
void
*
)
leaf_str
),
GenericValue
((
void
*
)
leaf
.
get
())}));
if
(
rc
.
IntVal
!=
0
)
return
-
1
;
return
bpf_update_elem
(
desc
.
fd
,
key
.
get
(),
leaf
.
get
(),
0
);
}
}
struct
TableIterator
{
struct
TableIterator
{
...
@@ -576,52 +538,90 @@ struct TableIterator {
...
@@ -576,52 +538,90 @@ struct TableIterator {
};
};
int
BPFModule
::
table_key_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
)
{
int
BPFModule
::
table_key_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
)
{
if
(
id
>=
tables_
->
size
())
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
fprintf
(
stderr
,
"table id %zu out of range
\n
"
,
id
);
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
key_snprintf
)
{
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
snprintf_fn
fn
=
(
snprintf_fn
)
rw_engine_
->
getPointerToFunction
(
desc
.
key_snprintf
);
if
(
!
fn
)
{
fprintf
(
stderr
,
"Key snprintf not available in JIT Engine
\n
"
);
return
-
1
;
return
-
1
;
}
}
int
rc
=
(
*
fn
)(
buf
,
buflen
,
key
);
if
(
rc
<
0
)
{
perror
(
"snprintf"
);
return
-
1
;
}
if
((
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
return
-
1
;
}
return
0
;
}
int
BPFModule
::
table_leaf_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
)
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
key_writer
)
{
if
(
!
desc
.
leaf_snprintf
)
{
fprintf
(
stderr
,
"table snprintf not implemented for %s key
\n
"
,
desc
.
name
.
c_str
());
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
snprintf_fn
fn
=
(
snprintf_fn
)
rw_engine_
->
getPointerToFunction
(
desc
.
leaf_snprintf
);
if
(
!
fn
)
{
fprintf
(
stderr
,
"Leaf snprintf not available in JIT Engine
\n
"
);
return
-
1
;
return
-
1
;
}
}
GenericValue
gv_buflen
;
int
rc
=
(
*
fn
)(
buf
,
buflen
,
leaf
);
gv_buflen
.
IntVal
=
APInt
(
32
,
buflen
,
true
);
if
(
rc
<
0
)
{
vector
<
GenericValue
>
args
({
gv_buflen
,
GenericValue
((
void
*
)
buf
),
GenericValue
((
void
*
)
key
)});
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
key_writer
,
args
);
if
(
rc
.
IntVal
.
isNegative
())
{
perror
(
"snprintf"
);
perror
(
"snprintf"
);
return
-
1
;
return
-
1
;
}
}
if
(
rc
.
IntVal
.
sge
(
buflen
)
)
{
if
(
(
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
}
}
int
BPFModule
::
table_leaf_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
)
{
int
BPFModule
::
table_key_scanf
(
size_t
id
,
const
char
*
key_str
,
void
*
key
)
{
if
(
id
>=
tables_
->
size
())
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
fprintf
(
stderr
,
"table id %zu out of range
\n
"
,
id
);
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
key_sscanf
)
{
fprintf
(
stderr
,
"Key sscanf not available
\n
"
);
return
-
1
;
return
-
1
;
}
}
sscanf_fn
fn
=
(
sscanf_fn
)
rw_engine_
->
getPointerToFunction
(
desc
.
key_sscanf
);
if
(
!
fn
)
{
fprintf
(
stderr
,
"Key sscanf not available in JIT Engine
\n
"
);
return
-
1
;
}
int
rc
=
(
*
fn
)(
key_str
,
key
);
if
(
rc
!=
0
)
{
perror
(
"sscanf"
);
return
-
1
;
}
return
0
;
}
int
BPFModule
::
table_leaf_scanf
(
size_t
id
,
const
char
*
leaf_str
,
void
*
leaf
)
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
leaf_
writer
)
{
if
(
!
desc
.
leaf_
sscanf
)
{
fprintf
(
stderr
,
"
table snprintf not implemented for %s leaf
\n
"
,
desc
.
name
.
c_str
()
);
fprintf
(
stderr
,
"
Key sscanf not available
\n
"
);
return
-
1
;
return
-
1
;
}
}
GenericValue
gv_buflen
;
gv_buflen
.
IntVal
=
buflen
;
sscanf_fn
fn
=
(
sscanf_fn
)
rw_engine_
->
getPointerToFunction
(
desc
.
leaf_sscanf
);
vector
<
GenericValue
>
args
({
gv_buflen
,
GenericValue
((
void
*
)
buf
),
GenericValue
((
void
*
)
leaf
)});
if
(
!
fn
)
{
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
leaf_writer
,
args
);
fprintf
(
stderr
,
"Leaf sscanf not available in JIT Engine
\n
"
);
if
(
rc
.
IntVal
.
isNegative
())
{
perror
(
"snprintf"
);
return
-
1
;
return
-
1
;
}
}
if
(
rc
.
IntVal
.
sge
(
buflen
))
{
int
rc
=
(
*
fn
)(
leaf_str
,
leaf
);
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
if
(
rc
!=
0
)
{
perror
(
"sscanf"
);
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
...
...
src/cc/bpf_module.h
View file @
8cea2e95
...
@@ -64,6 +64,7 @@ class BPFModule {
...
@@ -64,6 +64,7 @@ class BPFModule {
size_t
function_size
(
size_t
id
)
const
;
size_t
function_size
(
size_t
id
)
const
;
size_t
function_size
(
const
std
::
string
&
name
)
const
;
size_t
function_size
(
const
std
::
string
&
name
)
const
;
size_t
num_tables
()
const
;
size_t
num_tables
()
const
;
size_t
table_id
(
const
std
::
string
&
name
)
const
;
int
table_fd
(
size_t
id
)
const
;
int
table_fd
(
size_t
id
)
const
;
int
table_fd
(
const
std
::
string
&
name
)
const
;
int
table_fd
(
const
std
::
string
&
name
)
const
;
const
char
*
table_name
(
size_t
id
)
const
;
const
char
*
table_name
(
size_t
id
)
const
;
...
@@ -72,13 +73,13 @@ class BPFModule {
...
@@ -72,13 +73,13 @@ class BPFModule {
size_t
table_key_size
(
size_t
id
)
const
;
size_t
table_key_size
(
size_t
id
)
const
;
size_t
table_key_size
(
const
std
::
string
&
name
)
const
;
size_t
table_key_size
(
const
std
::
string
&
name
)
const
;
int
table_key_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
);
int
table_key_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
);
int
table_key_scanf
(
size_t
id
,
const
char
*
buf
,
void
*
key
);
const
char
*
table_leaf_desc
(
size_t
id
)
const
;
const
char
*
table_leaf_desc
(
size_t
id
)
const
;
const
char
*
table_leaf_desc
(
const
std
::
string
&
name
)
const
;
const
char
*
table_leaf_desc
(
const
std
::
string
&
name
)
const
;
size_t
table_leaf_size
(
size_t
id
)
const
;
size_t
table_leaf_size
(
size_t
id
)
const
;
size_t
table_leaf_size
(
const
std
::
string
&
name
)
const
;
size_t
table_leaf_size
(
const
std
::
string
&
name
)
const
;
int
table_leaf_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
);
int
table_leaf_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
);
int
table_update
(
size_t
id
,
const
char
*
key
,
const
char
*
leaf
);
int
table_leaf_scanf
(
size_t
id
,
const
char
*
buf
,
void
*
leaf
);
int
table_update
(
const
std
::
string
&
name
,
const
char
*
key
,
const
char
*
leaf
);
char
*
license
()
const
;
char
*
license
()
const
;
unsigned
kern_version
()
const
;
unsigned
kern_version
()
const
;
private:
private:
...
...
src/cc/table_desc.h
View file @
8cea2e95
...
@@ -31,10 +31,10 @@ struct TableDesc {
...
@@ -31,10 +31,10 @@ struct TableDesc {
size_t
max_entries
;
size_t
max_entries
;
std
::
string
key_desc
;
std
::
string
key_desc
;
std
::
string
leaf_desc
;
std
::
string
leaf_desc
;
llvm
::
Function
*
key_
reader
;
llvm
::
Function
*
key_
sscanf
;
llvm
::
Function
*
leaf_
reader
;
llvm
::
Function
*
leaf_
sscanf
;
llvm
::
Function
*
key_
writer
;
llvm
::
Function
*
key_
snprintf
;
llvm
::
Function
*
leaf_
writer
;
llvm
::
Function
*
leaf_
snprintf
;
};
};
}
// namespace ebpf
}
// namespace ebpf
src/python/bpf/__init__.py
View file @
8cea2e95
...
@@ -39,14 +39,26 @@ lib.bpf_function_start.restype = ct.c_void_p
...
@@ -39,14 +39,26 @@ lib.bpf_function_start.restype = ct.c_void_p
lib
.
bpf_function_start
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_function_start
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_function_size
.
restype
=
ct
.
c_size_t
lib
.
bpf_function_size
.
restype
=
ct
.
c_size_t
lib
.
bpf_function_size
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_function_size
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_id
.
restype
=
ct
.
c_ulonglong
lib
.
bpf_table_id
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_fd
.
restype
=
ct
.
c_int
lib
.
bpf_table_fd
.
restype
=
ct
.
c_int
lib
.
bpf_table_fd
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_fd
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_key_desc
.
restype
=
ct
.
c_char_p
lib
.
bpf_table_key_desc
.
restype
=
ct
.
c_char_p
lib
.
bpf_table_key_desc
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_key_desc
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_leaf_desc
.
restype
=
ct
.
c_char_p
lib
.
bpf_table_leaf_desc
.
restype
=
ct
.
c_char_p
lib
.
bpf_table_leaf_desc
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_leaf_desc
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
]
lib
.
bpf_table_update
.
restype
=
ct
.
c_int
lib
.
bpf_table_key_snprintf
.
restype
=
ct
.
c_int
lib
.
bpf_table_update
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_char_p
]
lib
.
bpf_table_key_snprintf
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_ulonglong
,
ct
.
c_char_p
,
ct
.
c_ulonglong
,
ct
.
c_void_p
]
lib
.
bpf_table_leaf_snprintf
.
restype
=
ct
.
c_int
lib
.
bpf_table_leaf_snprintf
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_ulonglong
,
ct
.
c_char_p
,
ct
.
c_ulonglong
,
ct
.
c_void_p
]
lib
.
bpf_table_key_sscanf
.
restype
=
ct
.
c_int
lib
.
bpf_table_key_sscanf
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_ulonglong
,
ct
.
c_char_p
,
ct
.
c_void_p
]
lib
.
bpf_table_leaf_sscanf
.
restype
=
ct
.
c_int
lib
.
bpf_table_leaf_sscanf
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_ulonglong
,
ct
.
c_char_p
,
ct
.
c_void_p
]
# keep in sync with libbpf.h
# keep in sync with libbpf.h
lib
.
bpf_get_next_key
.
restype
=
ct
.
c_int
lib
.
bpf_get_next_key
.
restype
=
ct
.
c_int
...
@@ -92,12 +104,49 @@ class BPF(object):
...
@@ -92,12 +104,49 @@ class BPF(object):
self
.
fd
=
fd
self
.
fd
=
fd
class
Table
(
MutableMapping
):
class
Table
(
MutableMapping
):
def
__init__
(
self
,
bpf
,
map_fd
,
keytype
,
leaftype
):
def
__init__
(
self
,
bpf
,
map_
id
,
map_
fd
,
keytype
,
leaftype
):
self
.
bpf
=
bpf
self
.
bpf
=
bpf
self
.
map_id
=
map_id
self
.
map_fd
=
map_fd
self
.
map_fd
=
map_fd
self
.
Key
=
keytype
self
.
Key
=
keytype
self
.
Leaf
=
leaftype
self
.
Leaf
=
leaftype
def
key_sprintf
(
self
,
key
):
key_p
=
ct
.
pointer
(
key
)
buf
=
ct
.
create_string_buffer
(
ct
.
sizeof
(
self
.
Key
)
*
8
)
res
=
lib
.
bpf_table_key_snprintf
(
self
.
bpf
.
module
,
self
.
map_id
,
buf
,
len
(
buf
),
key_p
)
if
res
<
0
:
raise
Exception
(
"Could not printf key"
)
return
buf
.
value
def
leaf_sprintf
(
self
,
leaf
):
leaf_p
=
ct
.
pointer
(
leaf
)
buf
=
ct
.
create_string_buffer
(
ct
.
sizeof
(
self
.
Leaf
)
*
8
)
res
=
lib
.
bpf_table_leaf_snprintf
(
self
.
bpf
.
module
,
self
.
map_id
,
buf
,
len
(
buf
),
leaf_p
)
if
res
<
0
:
raise
Exception
(
"Could not printf leaf"
)
return
buf
.
value
def
key_scanf
(
self
,
key_str
):
key
=
self
.
Key
()
key_p
=
ct
.
pointer
(
key
)
res
=
lib
.
bpf_table_key_sscanf
(
self
.
bpf
.
module
,
self
.
map_id
,
key_str
,
key_p
)
if
res
<
0
:
raise
Exception
(
"Could not scanf key"
)
return
key
def
leaf_scanf
(
self
,
leaf_str
):
leaf
=
self
.
Leaf
()
leaf_p
=
ct
.
pointer
(
leaf
)
res
=
lib
.
bpf_table_leaf_sscanf
(
self
.
bpf
.
module
,
self
.
map_id
,
leaf_str
,
leaf_p
)
if
res
<
0
:
raise
Exception
(
"Could not scanf leaf"
)
return
leaf
def
__getitem__
(
self
,
key
):
def
__getitem__
(
self
,
key
):
key_p
=
ct
.
pointer
(
key
)
key_p
=
ct
.
pointer
(
key
)
leaf
=
self
.
Leaf
()
leaf
=
self
.
Leaf
()
...
@@ -245,6 +294,7 @@ class BPF(object):
...
@@ -245,6 +294,7 @@ class BPF(object):
return
cls
return
cls
def
get_table
(
self
,
name
,
keytype
=
None
,
leaftype
=
None
):
def
get_table
(
self
,
name
,
keytype
=
None
,
leaftype
=
None
):
map_id
=
lib
.
bpf_table_id
(
self
.
module
,
name
.
encode
(
"ascii"
))
map_fd
=
lib
.
bpf_table_fd
(
self
.
module
,
name
.
encode
(
"ascii"
))
map_fd
=
lib
.
bpf_table_fd
(
self
.
module
,
name
.
encode
(
"ascii"
))
if
map_fd
<
0
:
if
map_fd
<
0
:
raise
Exception
(
"Failed to find BPF Table %s"
%
name
)
raise
Exception
(
"Failed to find BPF Table %s"
%
name
)
...
@@ -258,13 +308,7 @@ class BPF(object):
...
@@ -258,13 +308,7 @@ class BPF(object):
if
not
leaf_desc
:
if
not
leaf_desc
:
raise
Exception
(
"Failed to load BPF Table %s leaf desc"
%
name
)
raise
Exception
(
"Failed to load BPF Table %s leaf desc"
%
name
)
leaftype
=
BPF
.
_decode_table_type
(
json
.
loads
(
leaf_desc
.
decode
()))
leaftype
=
BPF
.
_decode_table_type
(
json
.
loads
(
leaf_desc
.
decode
()))
return
BPF
.
Table
(
self
,
map_fd
,
keytype
,
leaftype
)
return
BPF
.
Table
(
self
,
map_id
,
map_fd
,
keytype
,
leaftype
)
def
update_table
(
self
,
name
,
key
,
leaf
):
res
=
lib
.
bpf_table_update
(
self
.
module
,
name
.
encode
(
"ascii"
),
key
.
encode
(
"ascii"
),
leaf
.
encode
(
"ascii"
))
if
res
<
0
:
raise
Exception
(
"update_table failed"
)
@
staticmethod
@
staticmethod
def
attach_raw_socket
(
fn
,
dev
):
def
attach_raw_socket
(
fn
,
dev
):
...
...
tests/cc/test_clang.py
View file @
8cea2e95
...
@@ -55,9 +55,11 @@ int foo(void *ctx) {
...
@@ -55,9 +55,11 @@ int foo(void *ctx) {
"""
"""
b
=
BPF
(
text
=
text
,
debug
=
0
)
b
=
BPF
(
text
=
text
,
debug
=
0
)
fn
=
b
.
load_func
(
"foo"
,
BPF
.
KPROBE
)
fn
=
b
.
load_func
(
"foo"
,
BPF
.
KPROBE
)
b
.
update_table
(
"stats"
,
"2"
,
"{ 2 3 0x1000000004 { 5 6 }}"
)
t
=
b
.
get_table
(
"stats"
)
t
=
b
.
get_table
(
"stats"
)
l
=
t
[
t
.
Key
(
2
)]
s1
=
t
.
key_sprintf
(
t
.
Key
(
2
))
self
.
assertEqual
(
s1
,
b"0x2"
)
s2
=
t
.
leaf_sprintf
(
t
.
Leaf
(
2
,
3
,
4
,
1
,
(
5
,
6
)))
l
=
t
.
leaf_scanf
(
s2
)
self
.
assertEqual
(
l
.
a
,
2
)
self
.
assertEqual
(
l
.
a
,
2
)
self
.
assertEqual
(
l
.
b
,
3
)
self
.
assertEqual
(
l
.
b
,
3
)
self
.
assertEqual
(
l
.
c
,
4
)
self
.
assertEqual
(
l
.
c
,
4
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment