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
2582ecfc
Commit
2582ecfc
authored
Aug 12, 2015
by
Brenden Blanco
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add testing for scanf/printf in python, deprecate table_update
Signed-off-by:
Brenden Blanco
<
bblanco@plumgrid.com
>
parent
f8ee5bf0
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
153 additions
and
151 deletions
+153
-151
src/cc/bpf_common.cc
src/cc/bpf_common.cc
+12
-18
src/cc/bpf_common.h
src/cc/bpf_common.h
+1
-2
src/cc/bpf_module.cc
src/cc/bpf_module.cc
+77
-113
src/cc/bpf_module.h
src/cc/bpf_module.h
+1
-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 @
2582ecfc
...
...
@@ -104,6 +104,12 @@ size_t bpf_num_tables(void *program) {
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
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
-
1
;
...
...
@@ -170,38 +176,26 @@ size_t bpf_table_leaf_size_id(void *program, size_t id) {
return
mod
->
table_leaf_size
(
id
);
}
int
bpf_table_update
(
void
*
program
,
const
char
*
table_name
,
const
char
*
key
,
const
char
*
leaf
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
return
mod
->
table_update
(
table_name
,
key
,
leaf
);
}
int
bpf_table_update_id
(
void
*
program
,
size_t
id
,
const
char
*
key
,
const
char
*
leaf
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
return
mod
->
table_update
(
id
,
key
,
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
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
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
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
return
mod
->
table_
key
_printf
(
id
,
buf
,
buflen
,
leaf
);
if
(
!
mod
)
return
-
1
;
return
mod
->
table_
leaf
_printf
(
id
,
buf
,
buflen
,
leaf
);
}
int
bpf_table_key_sscanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
key
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
if
(
!
mod
)
return
-
1
;
return
mod
->
table_key_scanf
(
id
,
buf
,
key
);
}
int
bpf_table_leaf_sscanf
(
void
*
program
,
size_t
id
,
const
char
*
buf
,
void
*
leaf
)
{
auto
mod
=
static_cast
<
ebpf
::
BPFModule
*>
(
program
);
if
(
!
mod
)
return
0
;
return
mod
->
table_
key
_scanf
(
id
,
buf
,
leaf
);
if
(
!
mod
)
return
-
1
;
return
mod
->
table_
leaf
_scanf
(
id
,
buf
,
leaf
);
}
}
src/cc/bpf_common.h
View file @
2582ecfc
...
...
@@ -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
(
void
*
program
,
const
char
*
name
);
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_id
(
void
*
program
,
size_t
id
);
const
char
*
bpf_table_name
(
void
*
program
,
size_t
id
);
...
...
@@ -52,8 +53,6 @@ int bpf_table_key_snprintf(void *program, size_t id, char *buf, size_t buflen, c
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_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
}
...
...
src/cc/bpf_module.cc
View file @
2582ecfc
...
...
@@ -26,7 +26,6 @@
#include <linux/bpf.h>
#include <llvm/ADT/STLExtras.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IRReader/IRReader.h>
...
...
@@ -64,6 +63,9 @@ using std::unique_ptr;
using
std
::
vector
;
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
;
// 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,
else
if
(
it
->
getBitWidth
()
<=
16
)
*
fmt
+=
"%h"
;
else
if
(
it
->
getBitWidth
()
<=
32
)
*
fmt
+=
"%
l
"
;
*
fmt
+=
"%"
;
else
*
fmt
+=
"%l
l
"
;
*
fmt
+=
"%l"
;
if
(
is_writer
)
*
fmt
+=
"x"
;
else
...
...
@@ -171,15 +173,11 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
// The JIT currently supports a limited number of function prototypes, use the
// int (*) (int, char **, const char **) version
vector
<
Type
*>
fn_args
({
B
.
getInt32Ty
(),
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"reader"
+
std
::
to_string
(
readers_
.
size
()),
mod
);
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_argc
=
arg_it
++
;
arg_argc
->
setName
(
"argc"
);
Argument
*
arg_in
=
arg_it
++
;
arg_in
->
setName
(
"in"
);
Argument
*
arg_out
=
arg_it
++
;
...
...
@@ -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
)}));
if
(
0
)
debug_printf
(
mod
,
B
,
"%p %p
\n
"
,
vector
<
Value
*>
({
arg_in
,
arg_out
}));
vector
<
Type
*>
sscanf_fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt8PtrTy
()});
FunctionType
*
sscanf_fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
sscanf_fn_args
,
/*isVarArg=*/
true
);
Function
*
sscanf_fn
=
mod
->
getFunction
(
"sscanf"
);
...
...
@@ -234,17 +235,15 @@ Function * BPFModule::make_writer(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
// The JIT currently supports a limited number of function prototypes, use the
// int (*) (int, char **, const char **) version
vector
<
Type
*>
fn_args
({
B
.
getInt32Ty
(),
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt64Ty
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"writer"
+
std
::
to_string
(
writers_
.
size
()),
mod
);
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_len
=
arg_it
++
;
arg_len
->
setName
(
"len"
);
Argument
*
arg_out
=
arg_it
++
;
arg_out
->
setName
(
"out"
);
Argument
*
arg_len
=
arg_it
++
;
arg_len
->
setName
(
"len"
);
Argument
*
arg_in
=
arg_it
++
;
arg_in
->
setName
(
"in"
);
...
...
@@ -331,18 +330,18 @@ int BPFModule::annotate() {
if
(
st
->
getNumElements
()
<
2
)
continue
;
Type
*
key_type
=
st
->
elements
()[
0
];
Type
*
leaf_type
=
st
->
elements
()[
1
];
table
.
key_
reader
=
make_reader
(
&*
m
,
key_type
);
if
(
!
table
.
key_
reader
)
errs
()
<<
"Failed to compile
reader
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
reader
=
make_reader
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
reader
)
errs
()
<<
"Failed to compile
reader
for "
<<
*
leaf_type
<<
"
\n
"
;
table
.
key_
writer
=
make_writer
(
&*
m
,
key_type
);
if
(
!
table
.
key_
writer
)
errs
()
<<
"Failed to compile
writer
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
writer
=
make_writer
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
writer
)
errs
()
<<
"Failed to compile
writer
for "
<<
*
leaf_type
<<
"
\n
"
;
table
.
key_
sscanf
=
make_reader
(
&*
m
,
key_type
);
if
(
!
table
.
key_
sscanf
)
errs
()
<<
"Failed to compile
sscanf
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
sscanf
=
make_reader
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
sscanf
)
errs
()
<<
"Failed to compile
sscanf
for "
<<
*
leaf_type
<<
"
\n
"
;
table
.
key_
snprintf
=
make_writer
(
&*
m
,
key_type
);
if
(
!
table
.
key_
snprintf
)
errs
()
<<
"Failed to compile
snprintf
for "
<<
*
key_type
<<
"
\n
"
;
table
.
leaf_
snprintf
=
make_writer
(
&*
m
,
leaf_type
);
if
(
!
table
.
leaf_
snprintf
)
errs
()
<<
"Failed to compile
snprintf
for "
<<
*
leaf_type
<<
"
\n
"
;
}
}
}
...
...
@@ -474,10 +473,14 @@ size_t BPFModule::num_tables() const {
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
);
if
(
it
==
table_names_
.
end
())
return
-
1
;
return
table_fd
(
it
->
second
);
if
(
it
==
table_names_
.
end
())
return
~
0ull
;
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
{
...
...
@@ -497,9 +500,7 @@ const char * BPFModule::table_key_desc(size_t id) const {
}
const
char
*
BPFModule
::
table_key_desc
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
if
(
it
==
table_names_
.
end
())
return
nullptr
;
return
table_key_desc
(
it
->
second
);
return
table_key_desc
(
table_id
(
name
));
}
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
{
auto
it
=
table_names_
.
find
(
name
);
if
(
it
==
table_names_
.
end
())
return
nullptr
;
return
table_leaf_desc
(
it
->
second
);
return
table_leaf_desc
(
table_id
(
name
));
}
size_t
BPFModule
::
table_key_size
(
size_t
id
)
const
{
if
(
id
>=
tables_
->
size
())
return
0
;
return
(
*
tables_
)[
id
].
key_size
;
}
size_t
BPFModule
::
table_key_size
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
name
);
if
(
it
==
table_names_
.
end
())
return
0
;
return
table_key_size
(
it
->
second
);
return
table_key_size
(
table_id
(
name
));
}
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
;
}
size_t
BPFModule
::
table_leaf_size
(
const
string
&
name
)
const
{
auto
it
=
table_names_
.
find
(
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
);
return
table_leaf_size
(
table_id
(
name
));
}
struct
TableIterator
{
...
...
@@ -576,25 +538,23 @@ struct TableIterator {
};
int
BPFModule
::
table_key_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
key
)
{
if
(
id
>=
tables_
->
size
())
{
fprintf
(
stderr
,
"table id %zu out of range
\n
"
,
id
);
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
key_snprintf
)
{
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
key_writer
)
{
fprintf
(
stderr
,
"table snprintf not implemented for %s key
\n
"
,
desc
.
name
.
c_str
());
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
;
}
GenericValue
gv_buflen
;
gv_buflen
.
IntVal
=
APInt
(
32
,
buflen
,
true
);
vector
<
GenericValue
>
args
({
gv_buflen
,
GenericValue
((
void
*
)
buf
),
GenericValue
((
void
*
)
key
)});
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
key_writer
,
args
);
if
(
rc
.
IntVal
.
isNegative
())
{
int
rc
=
(
*
fn
)(
buf
,
buflen
,
key
);
if
(
rc
<
0
)
{
perror
(
"snprintf"
);
return
-
1
;
}
if
(
rc
.
IntVal
.
sge
(
buflen
)
)
{
if
(
(
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
return
-
1
;
}
...
...
@@ -602,25 +562,23 @@ int BPFModule::table_key_printf(size_t id, char *buf, size_t buflen, const void
}
int
BPFModule
::
table_leaf_printf
(
size_t
id
,
char
*
buf
,
size_t
buflen
,
const
void
*
leaf
)
{
if
(
id
>=
tables_
->
size
())
{
fprintf
(
stderr
,
"table id %zu out of range
\n
"
,
id
);
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
leaf_snprintf
)
{
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
!
desc
.
leaf_writer
)
{
fprintf
(
stderr
,
"table snprintf not implemented for %s leaf
\n
"
,
desc
.
name
.
c_str
());
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
;
}
GenericValue
gv_buflen
;
gv_buflen
.
IntVal
=
buflen
;
vector
<
GenericValue
>
args
({
gv_buflen
,
GenericValue
((
void
*
)
buf
),
GenericValue
((
void
*
)
leaf
)});
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
leaf_writer
,
args
);
if
(
rc
.
IntVal
.
isNegative
())
{
int
rc
=
(
*
fn
)(
buf
,
buflen
,
leaf
);
if
(
rc
<
0
)
{
perror
(
"snprintf"
);
return
-
1
;
}
if
(
rc
.
IntVal
.
sge
(
buflen
)
)
{
if
(
(
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
return
-
1
;
}
...
...
@@ -629,37 +587,43 @@ int BPFModule::table_leaf_printf(size_t id, char *buf, size_t buflen, const void
int
BPFModule
::
table_key_scanf
(
size_t
id
,
const
char
*
key_str
,
void
*
key
)
{
if
(
id
>=
tables_
->
size
())
return
-
1
;
const
TableDesc
&
desc
=
(
*
tables_
)[
id
];
if
(
desc
.
fd
<
0
)
return
-
1
;
if
(
!
rw_engine_
||
!
desc
.
key_reader
)
{
fprintf
(
stderr
,
"Table sscanf not available
\n
"
);
if
(
!
desc
.
key_sscanf
)
{
fprintf
(
stderr
,
"Key sscanf not available
\n
"
);
return
-
1
;
}
vector
<
GenericValue
>
args
({
GenericValue
(),
GenericValue
((
void
*
)
key_str
),
GenericValue
(
key
)});
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
key_reader
,
args
);
if
(
rc
.
IntVal
!=
0
)
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
];
if
(
desc
.
fd
<
0
)
return
-
1
;
if
(
!
rw_engine_
||
!
desc
.
leaf_reader
)
{
fprintf
(
stderr
,
"Table sscanf not available
\n
"
);
if
(
!
desc
.
leaf_sscanf
)
{
fprintf
(
stderr
,
"Key sscanf not available
\n
"
);
return
-
1
;
}
vector
<
GenericValue
>
args
({
GenericValue
(),
GenericValue
((
void
*
)
leaf_str
),
GenericValue
(
leaf
)}
);
GenericValue
rc
=
rw_engine_
->
runFunction
(
desc
.
leaf_reader
,
args
);
if
(
rc
.
IntVal
!=
0
)
sscanf_fn
fn
=
(
sscanf_fn
)
rw_engine_
->
getPointerToFunction
(
desc
.
leaf_sscanf
);
if
(
!
fn
)
{
fprintf
(
stderr
,
"Leaf sscanf not available in JIT Engine
\n
"
);
return
-
1
;
}
int
rc
=
(
*
fn
)(
leaf_str
,
leaf
);
if
(
rc
!=
0
)
{
perror
(
"sscanf"
);
return
-
1
;
}
return
0
;
}
...
...
src/cc/bpf_module.h
View file @
2582ecfc
...
...
@@ -64,6 +64,7 @@ class BPFModule {
size_t
function_size
(
size_t
id
)
const
;
size_t
function_size
(
const
std
::
string
&
name
)
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
(
const
std
::
string
&
name
)
const
;
const
char
*
table_name
(
size_t
id
)
const
;
...
...
@@ -79,8 +80,6 @@ class BPFModule {
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_scanf
(
size_t
id
,
const
char
*
buf
,
void
*
leaf
);
int
table_update
(
size_t
id
,
const
char
*
key
,
const
char
*
leaf
);
int
table_update
(
const
std
::
string
&
name
,
const
char
*
key
,
const
char
*
leaf
);
char
*
license
()
const
;
unsigned
kern_version
()
const
;
private:
...
...
src/cc/table_desc.h
View file @
2582ecfc
...
...
@@ -31,10 +31,10 @@ struct TableDesc {
size_t
max_entries
;
std
::
string
key_desc
;
std
::
string
leaf_desc
;
llvm
::
Function
*
key_
reader
;
llvm
::
Function
*
leaf_
reader
;
llvm
::
Function
*
key_
writer
;
llvm
::
Function
*
leaf_
writer
;
llvm
::
Function
*
key_
sscanf
;
llvm
::
Function
*
leaf_
sscanf
;
llvm
::
Function
*
key_
snprintf
;
llvm
::
Function
*
leaf_
snprintf
;
};
}
// namespace ebpf
src/python/bpf/__init__.py
View file @
2582ecfc
...
...
@@ -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_size
.
restype
=
ct
.
c_size_t
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
.
argtypes
=
[
ct
.
c_void_p
,
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_leaf_desc
.
restype
=
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_update
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_char_p
]
lib
.
bpf_table_key_snprintf
.
restype
=
ct
.
c_int
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
lib
.
bpf_get_next_key
.
restype
=
ct
.
c_int
...
...
@@ -92,12 +104,49 @@ class BPF(object):
self
.
fd
=
fd
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
.
map_id
=
map_id
self
.
map_fd
=
map_fd
self
.
Key
=
keytype
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
):
key_p
=
ct
.
pointer
(
key
)
leaf
=
self
.
Leaf
()
...
...
@@ -245,6 +294,7 @@ class BPF(object):
return
cls
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"
))
if
map_fd
<
0
:
raise
Exception
(
"Failed to find BPF Table %s"
%
name
)
...
...
@@ -258,13 +308,7 @@ class BPF(object):
if
not
leaf_desc
:
raise
Exception
(
"Failed to load BPF Table %s leaf desc"
%
name
)
leaftype
=
BPF
.
_decode_table_type
(
json
.
loads
(
leaf_desc
.
decode
()))
return
BPF
.
Table
(
self
,
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"
)
return
BPF
.
Table
(
self
,
map_id
,
map_fd
,
keytype
,
leaftype
)
@
staticmethod
def
attach_raw_socket
(
fn
,
dev
):
...
...
tests/cc/test_clang.py
View file @
2582ecfc
...
...
@@ -55,9 +55,11 @@ int foo(void *ctx) {
"""
b
=
BPF
(
text
=
text
,
debug
=
0
)
fn
=
b
.
load_func
(
"foo"
,
BPF
.
KPROBE
)
b
.
update_table
(
"stats"
,
"2"
,
"{ 2 3 0x1000000004 { 5 6 }}"
)
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
.
b
,
3
)
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