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
826136e3
Commit
826136e3
authored
Jun 04, 2015
by
4ast
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #27 from plumgrid/bblanco_dev
Convert to using pyroute2 for tc
parents
7249beaf
bb7200ce
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
80 additions
and
128 deletions
+80
-128
scripts/bpf_demo.ks.erb
scripts/bpf_demo.ks.erb
+0
-1
src/bpf.py
src/bpf.py
+0
-12
src/cc/CMakeLists.txt
src/cc/CMakeLists.txt
+1
-1
src/cc/b_frontend_action.cc
src/cc/b_frontend_action.cc
+1
-1
src/cc/bpf_helpers.h
src/cc/bpf_helpers.h
+3
-0
src/cc/codegen_llvm.cc
src/cc/codegen_llvm.cc
+4
-4
src/cc/libbpf.c
src/cc/libbpf.c
+2
-83
src/cc/proto.h
src/cc/proto.h
+12
-0
src/libbpf.h
src/libbpf.h
+0
-2
tests/cc/CMakeLists.txt
tests/cc/CMakeLists.txt
+2
-2
tests/cc/test_call1.c
tests/cc/test_call1.c
+4
-4
tests/cc/test_call1.py
tests/cc/test_call1.py
+6
-1
tests/cc/test_xlate1.c
tests/cc/test_xlate1.c
+19
-4
tests/cc/test_xlate1.py
tests/cc/test_xlate1.py
+26
-12
tests/wrapper.sh.in
tests/wrapper.sh.in
+0
-1
No files found.
scripts/bpf_demo.ks.erb
View file @
826136e3
...
...
@@ -34,7 +34,6 @@ bc
kexec-tools
cmake
clang
libmnl-devel
libstdc++-static
python-netaddr
%end
...
...
src/bpf.py
View file @
826136e3
...
...
@@ -35,8 +35,6 @@ lib.bpf_open_raw_sock.restype = ct.c_int
lib
.
bpf_open_raw_sock
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_attach_socket
.
restype
=
ct
.
c_int
lib
.
bpf_attach_socket
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_int
]
lib
.
bpf_attach_filter
.
restype
=
ct
.
c_int
lib
.
bpf_attach_filter
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_uint
,
ct
.
c_ubyte
,
ct
.
c_uint
]
lib
.
bpf_prog_load
.
restype
=
ct
.
c_int
lib
.
bpf_prog_load
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_void_p
,
ct
.
c_size_t
,
ct
.
c_char_p
,
ct
.
c_uint
]
...
...
@@ -163,16 +161,6 @@ class BPF(object):
%
(
dev
,
errstr
))
fn
.
sock
=
sock
@
staticmethod
def
attach_classifier
(
fn
,
ifname
,
prio
=
10
,
classid
=
1
):
with
open
(
"/sys/class/net/%s/ifindex"
%
ifname
)
as
f
:
ifindex
=
int
(
f
.
read
())
if
not
isinstance
(
fn
,
BPF
.
Function
):
raise
Exception
(
"arg 1 must be of type BPF.Function"
)
res
=
lib
.
bpf_attach_filter
(
fn
.
fd
,
fn
.
name
.
encode
(
"ascii"
),
ifindex
,
prio
,
classid
)
if
res
<
0
:
raise
Exception
(
"Failed to filter with BPF"
)
@
staticmethod
def
attach_kprobe
(
fn
,
event
,
pid
=-
1
,
cpu
=
0
,
group_fd
=-
1
):
if
not
isinstance
(
fn
,
BPF
.
Function
):
...
...
src/cc/CMakeLists.txt
View file @
826136e3
...
...
@@ -23,4 +23,4 @@ set(clang_libs ${libclangFrontend} ${libclangSerialization} ${libclangDriver} ${
${
libclangAST
}
${
libclangLex
}
${
libclangBasic
}
)
# Link against LLVM libraries
target_link_libraries
(
bpfprog
${
clang_libs
}
${
llvm_libs
}
LLVMBPFCodeGen
mnl
)
target_link_libraries
(
bpfprog
${
clang_libs
}
${
llvm_libs
}
LLVMBPFCodeGen
)
src/cc/b_frontend_action.cc
View file @
826136e3
...
...
@@ -187,7 +187,7 @@ bool BTypeVisitor::VisitImplicitCastExpr(ImplicitCastExpr *E) {
uint64_t
ofs
=
C
.
getFieldOffset
(
F
);
uint64_t
sz
=
F
->
isBitField
()
?
F
->
getBitWidthValue
(
C
)
:
C
.
getTypeSize
(
F
->
getType
());
string
base
=
rewriter_
.
getRewrittenText
(
SourceRange
(
Base
->
getLocStart
(),
Base
->
getLocEnd
()));
string
text
=
"bpf_dext_pkt(skb, (u64)"
+
base
+
"+"
+
to_string
(
ofs
>>
3
)
string
text
=
"bpf_dext_pkt(skb,
_parse_base +
(u64)"
+
base
+
"+"
+
to_string
(
ofs
>>
3
)
+
", "
+
to_string
(
ofs
&
0x7
)
+
", "
+
to_string
(
sz
)
+
")"
;
rewriter_
.
ReplaceText
(
SourceRange
(
E
->
getLocStart
(),
E
->
getLocEnd
()),
text
);
}
...
...
src/cc/bpf_helpers.h
View file @
826136e3
...
...
@@ -2,6 +2,8 @@
#define __BPF_HELPERS_H
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/if_packet.h>
#include <linux/version.h>
/* helper macro to place programs, maps, license in
...
...
@@ -30,6 +32,7 @@ struct _name##_table_t _name
BPF_EXPORT(name) int _##name(struct __sk_buff *skb)
#define BEGIN(next) \
u64 _parse_cursor = 0; \
u64 _parse_base = skb->pkt_type == PACKET_OUTGOING ? 0 : BPF_LL_OFF; \
goto next
#define PROTO(name) \
...
...
src/cc/codegen_llvm.cc
View file @
826136e3
...
...
@@ -1024,7 +1024,7 @@ StatusTuple CodegenLLVM::visit_integer_variable_decl_stmt_node(IntegerVariableDe
StatusTuple
CodegenLLVM
::
visit_struct_decl_stmt_node
(
StructDeclStmtNode
*
n
)
{
++
indent_
;
StructType
*
struct_type
=
StructType
::
create
(
ctx
(),
"struct."
+
n
->
id_
->
name_
);
StructType
*
struct_type
=
StructType
::
create
(
ctx
(),
"
_
struct."
+
n
->
id_
->
name_
);
vector
<
Type
*>
fields
;
for
(
auto
it
=
n
->
stmts_
.
begin
();
it
!=
n
->
stmts_
.
end
();
++
it
)
fields
.
push_back
(
B
.
getIntNTy
((
*
it
)
->
bit_width_
));
...
...
@@ -1089,9 +1089,9 @@ StatusTuple CodegenLLVM::visit_table_decl_stmt_node(TableDeclStmtNode *n) {
else
return
mkstatus_
(
n
,
"Table type %s not implemented"
,
n
->
type_id
()
->
name_
.
c_str
());
StructType
*
decl_struct
=
mod_
->
getTypeByName
(
"struct."
+
n
->
id_
->
name_
);
StructType
*
decl_struct
=
mod_
->
getTypeByName
(
"
_
struct."
+
n
->
id_
->
name_
);
if
(
!
decl_struct
)
decl_struct
=
StructType
::
create
(
ctx
(),
"struct."
+
n
->
id_
->
name_
);
decl_struct
=
StructType
::
create
(
ctx
(),
"
_
struct."
+
n
->
id_
->
name_
);
if
(
decl_struct
->
isOpaque
())
decl_struct
->
setBody
(
std
::
vector
<
Type
*>
({
Type
::
getInt32Ty
(
ctx
()),
Type
::
getInt32Ty
(
ctx
()),
Type
::
getInt32Ty
(
ctx
()),
Type
::
getInt32Ty
(
ctx
())}),
...
...
@@ -1156,7 +1156,7 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
StructType
*
stype
;
//TRY2(lookup_struct_type(formal, &stype));
auto
var
=
(
StructVariableDeclStmtNode
*
)
formal
;
stype
=
mod_
->
getTypeByName
(
"struct."
+
var
->
struct_id_
->
name_
);
stype
=
mod_
->
getTypeByName
(
"
_
struct."
+
var
->
struct_id_
->
name_
);
if
(
!
stype
)
return
mkstatus_
(
n
,
"could not find type %s"
,
var
->
struct_id_
->
c_str
());
formals
.
push_back
(
PointerType
::
getUnqual
(
stype
));
}
else
{
...
...
src/cc/libbpf.c
View file @
826136e3
...
...
@@ -2,7 +2,6 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <libmnl/libmnl.h>
#include <linux/bpf.h>
#include <linux/if_packet.h>
#include <linux/pkt_cls.h>
...
...
@@ -12,9 +11,11 @@
#include <linux/version.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "libbpf.h"
...
...
@@ -135,88 +136,6 @@ int bpf_attach_socket(int sock, int prog) {
return
setsockopt
(
sock
,
SOL_SOCKET
,
50
/*SO_ATTACH_BPF*/
,
&
prog
,
sizeof
(
prog
));
}
static
int
cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
struct
nlmsgerr
*
err
;
if
(
nlh
->
nlmsg_type
==
NLMSG_ERROR
)
{
err
=
mnl_nlmsg_get_payload
(
nlh
);
if
(
err
->
error
!=
0
)
{
fprintf
(
stderr
,
"bpf tc netlink command failed (%d): %s
\n
"
,
err
->
error
,
strerror
(
-
1
*
err
->
error
));
return
-
1
;
}
else
{
return
0
;
}
}
else
{
return
-
1
;
}
}
int
bpf_attach_filter
(
int
progfd
,
const
char
*
prog_name
,
uint32_t
ifindex
,
uint8_t
prio
,
uint32_t
classid
)
{
int
rc
=
-
1
;
char
buf
[
1024
];
struct
nlmsghdr
*
nlh
;
struct
tcmsg
*
tc
;
struct
nlattr
*
opt
;
struct
mnl_socket
*
nl
=
NULL
;
unsigned
int
portid
;
ssize_t
bytes
;
int
seq
=
getpid
();
memset
(
buf
,
0
,
sizeof
(
buf
));
nlh
=
mnl_nlmsg_put_header
(
buf
);
nlh
->
nlmsg_type
=
RTM_NEWTFILTER
;
nlh
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_ACK
|
NLM_F_EXCL
;
nlh
->
nlmsg_seq
=
seq
;
tc
=
mnl_nlmsg_put_extra_header
(
nlh
,
sizeof
(
*
tc
));
tc
->
tcm_family
=
AF_UNSPEC
;
tc
->
tcm_info
=
TC_H_MAKE
(
prio
<<
16
,
htons
(
ETH_P_ALL
));
tc
->
tcm_ifindex
=
ifindex
;
mnl_attr_put_strz
(
nlh
,
TCA_KIND
,
"bpf"
);
opt
=
mnl_attr_nest_start
(
nlh
,
TCA_OPTIONS
);
mnl_attr_put_u32
(
nlh
,
TCA_BPF_FD
,
progfd
);
mnl_attr_put_strz
(
nlh
,
TCA_BPF_NAME
,
prog_name
);
mnl_attr_put_u32
(
nlh
,
TCA_BPF_CLASSID
,
classid
);
mnl_attr_nest_end
(
nlh
,
opt
);
nl
=
mnl_socket_open
(
NETLINK_ROUTE
);
if
(
!
nl
||
(
uintptr_t
)
nl
==
(
uintptr_t
)
-
1
)
{
perror
(
"mnl_socket_open"
);
goto
cleanup
;
}
if
(
mnl_socket_bind
(
nl
,
0
,
MNL_SOCKET_AUTOPID
)
<
0
)
{
perror
(
"mnl_socket_bind"
);
goto
cleanup
;
}
portid
=
mnl_socket_get_portid
(
nl
);
if
(
mnl_socket_sendto
(
nl
,
nlh
,
nlh
->
nlmsg_len
)
<
0
)
{
perror
(
"mnl_socket_sendto"
);
goto
cleanup
;
}
if
((
bytes
=
mnl_socket_recvfrom
(
nl
,
buf
,
sizeof
(
buf
)))
<
0
)
{
perror
(
"mnl_socket_recvfrom"
);
goto
cleanup
;
}
if
(
mnl_cb_run
(
buf
,
bytes
,
seq
,
portid
,
cb
,
NULL
)
<
0
)
{
perror
(
"mnl_cb_run"
);
goto
cleanup
;
}
rc
=
0
;
cleanup:
if
(
nl
&&
(
uintptr_t
)
nl
!=
(
uintptr_t
)
-
1
)
if
(
mnl_socket_close
(
nl
)
<
0
)
perror
(
"mnl_socket_close"
);
return
rc
;
}
static
int
bpf_attach_tracing_event
(
int
progfd
,
const
char
*
event_path
,
pid_t
pid
,
int
cpu
,
int
group_fd
)
{
int
efd
=
-
1
,
rc
=
-
1
,
pfd
=
-
1
;
...
...
src/cc/proto.h
View file @
826136e3
...
...
@@ -13,6 +13,18 @@ struct dot1q_t {
u16
type
;
}
__attribute__
((
packed
));
struct
arp_t
{
u16
htype
;
u16
ptype
;
u8
hlen
;
u8
plen
;
u16
oper
;
u64
sha
:
48
;
u64
spa
:
32
;
u64
tha
:
48
;
u32
tpa
;
}
__attribute__
((
packed
));
struct
ip_t
{
u8
ver
:
4
;
// byte 0
u8
hlen
:
4
;
...
...
src/libbpf.h
View file @
826136e3
...
...
@@ -21,8 +21,6 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
const
struct
bpf_insn
*
insns
,
int
insn_len
,
const
char
*
license
,
unsigned
kern_version
);
int
bpf_attach_socket
(
int
sockfd
,
int
progfd
);
int
bpf_attach_filter
(
int
progfd
,
const
char
*
prog_name
,
uint32_t
ifindex
,
uint8_t
prio
,
uint32_t
classid
);
/* create RAW socket and bind to interface 'name' */
int
bpf_open_raw_sock
(
const
char
*
name
);
...
...
tests/cc/CMakeLists.txt
View file @
826136e3
...
...
@@ -2,8 +2,8 @@ add_test(NAME py_test_stat1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND
${
TEST_WRAPPER
}
py_stat1_b namespace
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_stat1.py test_stat1.b proto.b
)
add_test
(
NAME py_test_stat1_c WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_stat1_c namespace
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_stat1.py test_stat1.c
)
add_test
(
NAME py_test_xlate1_b WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_xlate1_b namespace
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_xlate1.py test_xlate1.b proto.b
)
#
add_test(NAME py_test_xlate1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
#
COMMAND ${TEST_WRAPPER} py_xlate1_b namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_xlate1.py test_xlate1.b proto.b)
add_test
(
NAME py_test_xlate1_c WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_xlate1_c namespace
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_xlate1.py test_xlate1.c
)
add_test
(
NAME py_test_call1 WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
...
...
tests/cc/test_call1.c
View file @
826136e3
...
...
@@ -24,7 +24,7 @@ int parse_ether(struct __sk_buff *skb) {
case
0x0806
:
jump
.
call
(
skb
,
S_ARP
);
}
jump
.
call
(
skb
,
S_EOP
);
return
0
;
return
1
;
}
BPF_EXPORT
(
parse_arp
)
...
...
@@ -37,7 +37,7 @@ int parse_arp(struct __sk_buff *skb) {
if
(
leaf
)
(
*
leaf
)
++
;
jump
.
call
(
skb
,
S_EOP
);
return
0
;
return
1
;
}
BPF_EXPORT
(
parse_ip
)
...
...
@@ -50,7 +50,7 @@ int parse_ip(struct __sk_buff *skb) {
if
(
leaf
)
(
*
leaf
)
++
;
jump
.
call
(
skb
,
S_EOP
);
return
0
;
return
1
;
}
BPF_EXPORT
(
eop
)
...
...
@@ -58,5 +58,5 @@ int eop(struct __sk_buff *skb) {
int
key
=
S_EOP
;
u64
*
leaf
=
stats
.
lookup
(
&
key
);
if
(
leaf
)
(
*
leaf
)
++
;
return
0
;
return
1
;
}
tests/cc/test_call1.py
View file @
826136e3
...
...
@@ -3,6 +3,7 @@
from
ctypes
import
c_ushort
,
c_int
,
c_ulonglong
from
netaddr
import
IPAddress
from
bpf
import
BPF
from
pyroute2
import
IPRoute
from
socket
import
socket
,
AF_INET
,
SOCK_DGRAM
import
sys
from
time
import
sleep
...
...
@@ -22,7 +23,10 @@ class TestBPFSocket(TestCase):
arp_fn
=
b
.
load_func
(
"parse_arp"
,
BPF
.
SCHED_CLS
)
ip_fn
=
b
.
load_func
(
"parse_ip"
,
BPF
.
SCHED_CLS
)
eop_fn
=
b
.
load_func
(
"eop"
,
BPF
.
SCHED_CLS
)
BPF
.
attach_classifier
(
ether_fn
,
"eth0"
)
ip
=
IPRoute
()
ifindex
=
ip
.
link_lookup
(
ifname
=
"eth0"
)[
0
]
ip
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":1"
,
fd
=
ether_fn
.
fd
,
name
=
ether_fn
.
name
,
parent
=
"0:"
,
action
=
"ok"
,
classid
=
1
)
self
.
jump
=
b
.
get_table
(
"jump"
,
c_int
,
c_int
)
self
.
jump
.
update
(
c_int
(
S_ARP
),
c_int
(
arp_fn
.
fd
))
self
.
jump
.
update
(
c_int
(
S_IP
),
c_int
(
ip_fn
.
fd
))
...
...
@@ -32,6 +36,7 @@ class TestBPFSocket(TestCase):
def
test_jumps
(
self
):
udp
=
socket
(
AF_INET
,
SOCK_DGRAM
)
udp
.
sendto
(
b"a"
*
10
,
(
"172.16.1.1"
,
5000
))
udp
.
close
()
self
.
assertGreater
(
self
.
stats
.
lookup
(
c_int
(
S_IP
)).
value
,
0
)
self
.
assertGreater
(
self
.
stats
.
lookup
(
c_int
(
S_ARP
)).
value
,
0
)
self
.
assertGreater
(
self
.
stats
.
lookup
(
c_int
(
S_EOP
)).
value
,
1
)
...
...
tests/cc/test_xlate1.c
View file @
826136e3
...
...
@@ -7,21 +7,23 @@ struct IPKey {
struct
IPLeaf
{
u32
xdip
;
u32
xsip
;
u64
xlated_pkts
;
u64
ip_xlated_pkts
;
u64
arp_xlated_pkts
;
};
BPF_TABLE
(
"hash"
,
struct
IPKey
,
struct
IPLeaf
,
xlate
,
1024
);
BPF_EXPORT
(
on_packet
)
int
on_packet
(
struct
__sk_buff
*
skb
)
{
BEGIN
(
ethernet
);
u32
orig_dip
=
0
;
u32
orig_sip
=
0
;
struct
IPLeaf
*
xleaf
;
BEGIN
(
ethernet
);
PROTO
(
ethernet
)
{
switch
(
ethernet
->
type
)
{
case
0x0800
:
goto
ip
;
case
0x0806
:
goto
arp
;
case
0x8100
:
goto
dot1q
;
}
goto
EOP
;
...
...
@@ -29,10 +31,23 @@ int on_packet(struct __sk_buff *skb) {
PROTO
(
dot1q
)
{
switch
(
dot1q
->
type
)
{
case
0x0806
:
goto
arp
;
case
0x0800
:
goto
ip
;
}
goto
EOP
;
}
PROTO
(
arp
)
{
orig_dip
=
arp
->
tpa
;
orig_sip
=
arp
->
spa
;
struct
IPKey
key
=
{.
dip
=
orig_dip
,
.
sip
=
orig_sip
};
xleaf
=
xlate
.
lookup
(
&
key
);
if
(
xleaf
)
{
arp
->
tpa
=
xleaf
->
xdip
;
arp
->
spa
=
xleaf
->
xsip
;
lock_xadd
(
&
xleaf
->
arp_xlated_pkts
,
1
);
}
goto
EOP
;
}
PROTO
(
ip
)
{
orig_dip
=
ip
->
dst
;
...
...
@@ -44,7 +59,7 @@ int on_packet(struct __sk_buff *skb) {
incr_cksum_l3
(
&
ip
->
hchecksum
,
orig_dip
,
xleaf
->
xdip
);
ip
->
src
=
xleaf
->
xsip
;
incr_cksum_l3
(
&
ip
->
hchecksum
,
orig_sip
,
xleaf
->
xsip
);
lock_xadd
(
&
xleaf
->
xlated_pkts
,
1
);
lock_xadd
(
&
xleaf
->
ip_
xlated_pkts
,
1
);
}
switch
(
ip
->
nextp
)
{
case
6
:
goto
tcp
;
...
...
@@ -70,5 +85,5 @@ int on_packet(struct __sk_buff *skb) {
}
EOP:
return
0
;
return
1
;
}
tests/cc/test_xlate1.py
View file @
826136e3
...
...
@@ -3,7 +3,9 @@
from
ctypes
import
c_uint
,
c_ulonglong
,
Structure
from
netaddr
import
IPAddress
from
bpf
import
BPF
from
pyroute2
import
IPRoute
from
socket
import
socket
,
AF_INET
,
SOCK_DGRAM
from
subprocess
import
call
import
sys
from
time
import
sleep
from
unittest
import
main
,
TestCase
...
...
@@ -19,24 +21,36 @@ class Key(Structure):
class
Leaf
(
Structure
):
_fields_
=
[(
"xdip"
,
c_uint
),
(
"xsip"
,
c_uint
),
(
"xlated_pkts"
,
c_ulonglong
)]
(
"ip_xlated_pkts"
,
c_ulonglong
),
(
"arp_xlated_pkts"
,
c_ulonglong
)]
class
TestBPF
Socket
(
TestCase
):
class
TestBPF
Filter
(
TestCase
):
def
setUp
(
self
):
b
=
BPF
(
arg1
,
arg2
,
debug
=
1
)
b
=
BPF
(
arg1
,
arg2
,
debug
=
0
)
fn
=
b
.
load_func
(
"on_packet"
,
BPF
.
SCHED_CLS
)
BPF
.
attach_classifier
(
fn
,
"eth0"
)
ip
=
IPRoute
()
ifindex
=
ip
.
link_lookup
(
ifname
=
"eth0"
)[
0
]
ip
.
addr
(
"del"
,
index
=
ifindex
,
address
=
"172.16.1.2"
,
mask
=
24
)
ip
.
addr
(
"add"
,
index
=
ifindex
,
address
=
"192.168.1.2"
,
mask
=
24
)
ip
.
tc
(
"add"
,
"ingress"
,
ifindex
,
"ffff:"
)
ip
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":1"
,
fd
=
fn
.
fd
,
name
=
fn
.
name
,
parent
=
"ffff:"
,
action
=
"ok"
,
classid
=
1
)
ip
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":2"
,
fd
=
fn
.
fd
,
name
=
fn
.
name
,
parent
=
"0:"
,
action
=
"ok"
,
classid
=
1
)
self
.
xlate
=
b
.
get_table
(
"xlate"
,
Key
,
Leaf
)
def
test_xlate
(
self
):
key
=
Key
(
IPAddress
(
"172.16.1.1"
).
value
,
IPAddress
(
"172.16.1.2"
).
value
)
leaf
=
Leaf
(
IPAddress
(
"192.168.1.1"
).
value
,
IPAddress
(
"192.168.1.2"
).
value
,
0
)
self
.
xlate
.
update
(
key
,
leaf
)
udp
=
socket
(
AF_INET
,
SOCK_DGRAM
)
udp
.
sendto
(
b"a"
*
10
,
(
"172.16.1.1"
,
5000
))
leaf
=
self
.
xlate
.
lookup
(
key
)
self
.
assertGreater
(
leaf
.
xlated_pkts
,
0
)
udp
.
close
()
key1
=
Key
(
IPAddress
(
"172.16.1.2"
).
value
,
IPAddress
(
"172.16.1.1"
).
value
)
leaf1
=
Leaf
(
IPAddress
(
"192.168.1.2"
).
value
,
IPAddress
(
"192.168.1.1"
).
value
,
0
,
0
)
self
.
xlate
.
update
(
key1
,
leaf1
)
key2
=
Key
(
IPAddress
(
"192.168.1.1"
).
value
,
IPAddress
(
"192.168.1.2"
).
value
)
leaf2
=
Leaf
(
IPAddress
(
"172.16.1.1"
).
value
,
IPAddress
(
"172.16.1.2"
).
value
,
0
,
0
)
self
.
xlate
.
update
(
key2
,
leaf2
)
call
([
"ping"
,
"-c1"
,
"192.168.1.1"
])
leaf
=
self
.
xlate
.
lookup
(
key1
)
self
.
assertGreater
(
leaf
.
ip_xlated_pkts
,
0
)
self
.
assertGreater
(
leaf
.
arp_xlated_pkts
,
0
)
leaf
=
self
.
xlate
.
lookup
(
key2
)
self
.
assertGreater
(
leaf
.
ip_xlated_pkts
,
0
)
self
.
assertGreater
(
leaf
.
arp_xlated_pkts
,
0
)
if
__name__
==
"__main__"
:
main
()
tests/wrapper.sh.in
View file @
826136e3
...
...
@@ -25,7 +25,6 @@ function ns_run() {
sudo
ip
link
add
$ns
.in
type
veth peer name
$ns
.out
sudo
ip
link set
$ns
.in netns
$ns
sudo
ip netns
exec
$ns
ip
link set
$ns
.in name eth0
sudo
ip netns
exec
$ns
tc qdisc add dev eth0 root prio
sudo
ip netns
exec
$ns
ip addr add dev eth0 172.16.1.2/24
sudo
ip netns
exec
$ns
ip
link set
eth0 up
sudo
ip netns
exec
$ns
ethtool
-K
eth0 tx off
...
...
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