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
ffaee08c
Commit
ffaee08c
authored
Jul 11, 2015
by
Brenden Blanco
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #83 from iovisor/yhs_dev
Yhs dev
parents
0fa99f4d
00eb0883
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
222 additions
and
273 deletions
+222
-273
examples/simulation.py
examples/simulation.py
+32
-10
tests/cc/simulation.py
tests/cc/simulation.py
+1
-0
tests/cc/test_brb.c
tests/cc/test_brb.c
+12
-15
tests/cc/test_brb.py
tests/cc/test_brb.py
+84
-127
tests/cc/test_brb2.c
tests/cc/test_brb2.c
+1
-1
tests/cc/test_brb2.py
tests/cc/test_brb2.py
+92
-120
No files found.
examples/simulation.py
View file @
ffaee08c
import
atexit
import
subprocess
from
pyroute2
import
IPRoute
,
NetNS
,
IPDB
,
NSPopen
class
Simulation
(
object
):
...
...
@@ -14,15 +14,22 @@ class Simulation(object):
self
.
processes
=
[]
self
.
released
=
False
# helper function to create a namespace and a veth connecting it
def
_create_ns
(
self
,
name
,
in_ifc
=
None
,
out_ifc
=
None
,
ipaddr
=
None
,
macaddr
=
None
,
fn
=
None
,
cmd
=
None
,
action
=
"ok"
):
# helper function to add additional ifc to namespace
# if called directly outside Simulation class, "ifc_base_name" should be
# different from "name", the "ifc_base_name" and "name" are the same for
# the first ifc created by namespace
def
_ns_add_ifc
(
self
,
name
,
ns_ifc
,
ifc_base_name
,
in_ifc
=
None
,
out_ifc
=
None
,
ipaddr
=
None
,
macaddr
=
None
,
fn
=
None
,
cmd
=
None
,
action
=
"ok"
,
disable_ipv6
=
False
):
if
name
in
self
.
ipdbs
:
ns_ipdb
=
self
.
ipdbs
[
name
]
else
:
ns_ipdb
=
IPDB
(
nl
=
NetNS
(
name
))
if
in_ifc
:
in_ifname
=
in_ifc
.
ifname
else
:
out_ifc
=
self
.
ipdb
.
create
(
ifname
=
"%sa"
%
name
,
kind
=
"veth"
,
peer
=
"%sb"
%
name
).
commit
()
out_ifc
=
self
.
ipdb
.
create
(
ifname
=
"%sa"
%
ifc_base_
name
,
kind
=
"veth"
,
peer
=
"%sb"
%
ifc_base_
name
).
commit
()
in_ifc
=
self
.
ipdb
.
interfaces
[
out_ifc
.
peer
]
in_ifname
=
in_ifc
.
ifname
with
in_ifc
as
v
:
...
...
@@ -31,21 +38,36 @@ class Simulation(object):
in_ifc
=
ns_ipdb
.
interfaces
[
in_ifname
]
if
out_ifc
:
out_ifc
.
up
().
commit
()
with
in_ifc
as
v
:
v
.
ifname
=
"eth0"
v
.
ifname
=
ns_ifc
if
ipaddr
:
v
.
add_ip
(
"%s"
%
ipaddr
)
if
macaddr
:
v
.
address
=
macaddr
v
.
up
()
# if required, disable ipv6 before attaching the filter
if
disable_ipv6
:
subprocess
.
call
([
"sysctl"
,
"-q"
,
"-w"
,
"net.ipv6.conf."
+
out_ifc
.
ifname
+
".disable_ipv6=1"
])
nsp
=
NSPopen
(
ns_ipdb
.
nl
.
netns
,
[
"sysctl"
,
"-q"
,
"-w"
,
"net.ipv6.conf."
+
ns_ifc
+
".disable_ipv6=1"
])
nsp
.
wait
();
nsp
.
release
()
if
fn
and
out_ifc
:
self
.
ipdb
.
nl
.
tc
(
"add"
,
"ingress"
,
out_ifc
[
"index"
],
"ffff:"
)
self
.
ipdb
.
nl
.
tc
(
"add-filter"
,
"bpf"
,
out_ifc
[
"index"
],
":1"
,
fd
=
fn
.
fd
,
name
=
fn
.
name
,
parent
=
"ffff:"
,
action
=
action
,
classid
=
1
)
self
.
ipdbs
[
ns_ipdb
.
nl
.
netns
]
=
ns_ipdb
self
.
namespaces
.
append
(
ns_ipdb
.
nl
)
if
cmd
:
self
.
processes
.
append
(
NSPopen
(
ns_ipdb
.
nl
.
netns
,
cmd
))
return
(
ns_ipdb
,
out_ifc
,
in_ifc
)
# helper function to create a namespace and a veth connecting it
def
_create_ns
(
self
,
name
,
in_ifc
=
None
,
out_ifc
=
None
,
ipaddr
=
None
,
macaddr
=
None
,
fn
=
None
,
cmd
=
None
,
action
=
"ok"
,
disable_ipv6
=
False
):
(
ns_ipdb
,
out_ifc
,
in_ifc
)
=
self
.
_ns_add_ifc
(
name
,
"eth0"
,
name
,
in_ifc
,
out_ifc
,
ipaddr
,
macaddr
,
fn
,
cmd
,
action
,
disable_ipv6
)
self
.
ipdbs
[
ns_ipdb
.
nl
.
netns
]
=
ns_ipdb
self
.
namespaces
.
append
(
ns_ipdb
.
nl
)
return
(
ns_ipdb
,
out_ifc
,
in_ifc
)
def
release
(
self
):
if
self
.
released
:
return
self
.
released
=
True
...
...
tests/cc/simulation.py
0 → 120000
View file @
ffaee08c
..
/
..
/
examples
/
simulation
.
py
\ No newline at end of file
tests/cc/test_brb.c
View file @
ffaee08c
...
...
@@ -101,13 +101,12 @@ int pem(struct __sk_buff *skb) {
}
}
return
0
;
return
1
;
}
static
int
br_common
(
struct
__sk_buff
*
skb
,
int
which_br
)
__attribute__
((
always_inline
));
static
int
br_common
(
struct
__sk_buff
*
skb
,
int
which_br
)
{
u8
*
cursor
=
0
;
bpf_metadata_t
meta
=
{};
u16
proto
;
u16
arpop
;
eth_addr_t
dmac
;
...
...
@@ -118,20 +117,16 @@ static int br_common(struct __sk_buff *skb, int which_br) {
bpf_dest_t
*
dest_p
;
u32
index
,
*
rtrif_p
;
if
(
skb
->
tc_index
==
0
)
{
skb
->
tc_index
=
1
;
skb
->
cb
[
0
]
=
skb
->
cb
[
1
]
=
0
;
meta
.
prog_id
=
meta
.
rx_port_id
=
0
;
}
else
{
meta
.
prog_id
=
skb
->
cb
[
0
];
meta
.
rx_port_id
=
skb
->
cb
[
1
];
}
struct
ethernet_t
*
ethernet
=
cursor_advance
(
cursor
,
sizeof
(
*
ethernet
));
/* handle ethernet packet header */
{
dmac
.
addr
=
ethernet
->
dst
;
if
(
meta
.
prog_id
!=
0
)
{
/* send to the router */
/* skb->tc_index may be preserved accross router namespace if router simply rewrite packet
* and send it back.
*/
if
(
skb
->
tc_index
==
1
)
{
/* packet from pem, send to the router, set tc_index to 2 */
skb
->
tc_index
=
2
;
if
(
dmac
.
addr
==
0xffffffffffffULL
)
{
index
=
0
;
if
(
which_br
==
1
)
...
...
@@ -149,9 +144,11 @@ static int br_common(struct __sk_buff *skb, int which_br) {
if
(
rtrif_p
)
bpf_clone_redirect
(
skb
,
*
rtrif_p
,
0
);
}
return
0
;
return
1
;
}
/* set the tc_index to 1 so pem knows it is from internal */
skb
->
tc_index
=
1
;
switch
(
ethernet
->
type
)
{
case
ETH_P_IP
:
goto
ip
;
case
ETH_P_ARP
:
goto
arp
;
...
...
@@ -217,7 +214,7 @@ xmit:
}
EOP:
return
0
;
return
1
;
}
int
br1
(
struct
__sk_buff
*
skb
)
{
...
...
tests/cc/test_brb.py
View file @
ffaee08c
...
...
@@ -61,68 +61,31 @@
# 8:
# 8: OK
from
ctypes
import
c_u
byte
,
c_ushort
,
c_uint
,
c_ulonglong
,
Structure
from
ctypes
import
c_u
int
from
netaddr
import
IPAddress
,
EUI
from
bpf
import
BPF
from
pyroute2
import
IPRoute
from
socket
import
socket
,
AF_INET
,
SOCK_DGRAM
from
pyroute2
import
IPRoute
,
NetNS
,
IPDB
,
NSPopen
import
sys
from
time
import
sleep
from
unittest
import
main
,
TestCase
import
subprocess
import
struct
from
simulation
import
Simulation
arg1
=
sys
.
argv
.
pop
(
1
)
ipr
=
IPRoute
()
ipdb
=
IPDB
(
nl
=
ipr
)
sim
=
Simulation
(
ipdb
)
class
TestBPFSocket
(
TestCase
):
def
setup_vm_ns
(
self
,
ns
,
veth_in
,
veth_out
):
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth_out
])
subprocess
.
call
([
"ip"
,
"netns"
,
"add"
,
ns
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth_in
,
"name"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_out
,
"up"
])
def
config_vm_ns
(
self
,
ns
,
ip_addr
,
net_mask
,
ip_gw
):
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_addr
+
"/24"
,
"dev"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth0"
,
"up"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"route"
,
"add"
,
net_mask
+
"/24"
,
"via"
,
ip_gw
])
def
setup_router_ns
(
self
,
ns
,
veth1_in
,
veth1_out
,
veth2_in
,
veth2_out
):
subprocess
.
call
([
"ip"
,
"netns"
,
"add"
,
ns
])
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth1_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth1_out
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth1_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth1_in
,
"name"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth2_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth2_out
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth2_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth2_in
,
"name"
,
"eth1"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth1_out
,
"up"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth2_out
,
"up"
])
def
config_router_ns
(
self
,
ns
,
ip_eth0
,
ip_eth1
):
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_eth0
+
"/24"
,
"dev"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth0"
,
"up"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_eth1
+
"/24"
,
"dev"
,
"eth1"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth1"
,
"up"
])
def
set_default_const
(
self
):
self
.
ns1
=
"ns1"
self
.
ns1_eth_in
=
"v1"
self
.
ns1_eth_out
=
"v2"
self
.
ns2
=
"ns2"
self
.
ns2_eth_in
=
"v3"
self
.
ns2_eth_out
=
"v4"
self
.
ns_router
=
"ns_router"
self
.
nsrtr_eth0_in
=
"v10"
self
.
nsrtr_eth0_out
=
"v11"
self
.
nsrtr_eth1_in
=
"v12"
self
.
nsrtr_eth1_out
=
"v13"
self
.
vm1_ip
=
"100.1.1.1"
self
.
vm2_ip
=
"200.1.1.1"
self
.
vm1_rtr_ip
=
"100.1.1.254"
self
.
vm2_rtr_ip
=
"200.1.1.254"
self
.
vm1_rtr_mask
=
"100.1.1.0"
self
.
vm2_rtr_mask
=
"200.1.1.0"
self
.
vm1_rtr_mask
=
"100.1.1.0
/24
"
self
.
vm2_rtr_mask
=
"200.1.1.0
/24
"
def
get_table
(
self
,
b
):
self
.
jump
=
b
.
get_table
(
"jump"
)
...
...
@@ -141,29 +104,15 @@ class TestBPFSocket(TestCase):
self
.
br2_rtr
=
b
.
get_table
(
"br2_rtr"
)
def
connect_ports
(
self
,
prog_id_pem
,
prog_id_br
,
curr_pem_pid
,
curr_br_pid
,
ip
,
br_dest_map
,
br_mac_map
,
ns_eth_out
,
vm_mac
,
vm_ip
):
br_dest_map
,
br_mac_map
,
ifindex
,
vm_mac
,
vm_ip
):
self
.
pem_dest
[
c_uint
(
curr_pem_pid
)]
=
self
.
pem_dest
.
Leaf
(
prog_id_br
,
curr_br_pid
)
br_dest_map
[
c_uint
(
curr_br_pid
)]
=
br_dest_map
.
Leaf
(
prog_id_pem
,
curr_pem_pid
)
ifindex
=
ip
.
link_lookup
(
ifname
=
ns_eth_out
)[
0
]
self
.
pem_port
[
c_uint
(
curr_pem_pid
)]
=
c_uint
(
ifindex
)
self
.
pem_ifindex
[
c_uint
(
ifindex
)]
=
c_uint
(
curr_pem_pid
)
mac_addr
=
br_mac_map
.
Key
(
int
(
EUI
(
vm_mac
.
decode
())))
br_mac_map
[
mac_addr
]
=
c_uint
(
curr_br_pid
)
def
attach_filter
(
self
,
ip
,
ifname
,
fd
,
name
):
ifindex
=
ip
.
link_lookup
(
ifname
=
ifname
)[
0
]
ip
.
tc
(
"add"
,
"ingress"
,
ifindex
,
"ffff:"
)
ip
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":1"
,
fd
=
fd
,
name
=
name
,
parent
=
"ffff:"
,
action
=
"drop"
,
classid
=
1
)
def
config_maps
(
self
):
b
=
BPF
(
src_file
=
arg1
,
debug
=
0
)
pem_fn
=
b
.
load_func
(
"pem"
,
BPF
.
SCHED_CLS
)
br1_fn
=
b
.
load_func
(
"br1"
,
BPF
.
SCHED_CLS
)
br2_fn
=
b
.
load_func
(
"br2"
,
BPF
.
SCHED_CLS
)
ip
=
IPRoute
()
# program id
prog_id_pem
=
1
prog_id_br1
=
2
...
...
@@ -173,89 +122,97 @@ class TestBPFSocket(TestCase):
curr_pem_pid
=
0
curr_br1_pid
=
0
curr_br2_pid
=
0
self
.
get_table
(
b
)
# configure jump table
self
.
jump
[
c_uint
(
prog_id_pem
)]
=
c_uint
(
pem_fn
.
fd
)
self
.
jump
[
c_uint
(
prog_id_br1
)]
=
c_uint
(
br1_fn
.
fd
)
self
.
jump
[
c_uint
(
prog_id_br2
)]
=
c_uint
(
br2_fn
.
fd
)
self
.
jump
[
c_uint
(
prog_id_pem
)]
=
c_uint
(
self
.
pem_fn
.
fd
)
self
.
jump
[
c_uint
(
prog_id_br1
)]
=
c_uint
(
self
.
br1_fn
.
fd
)
self
.
jump
[
c_uint
(
prog_id_br2
)]
=
c_uint
(
self
.
br2_fn
.
fd
)
# connect pem and br1
curr_pem_pid
=
curr_pem_pid
+
1
curr_br1_pid
=
curr_br1_pid
+
1
self
.
connect_ports
(
prog_id_pem
,
prog_id_br1
,
curr_pem_pid
,
curr_br1_pid
,
ip
,
self
.
br1_dest
,
self
.
br1_mac
,
self
.
ns1_eth_out
,
self
.
vm1_mac
,
self
.
vm1_ip
)
self
.
br1_dest
,
self
.
br1_mac
,
self
.
ns1_eth_out
.
index
,
self
.
vm1_mac
,
self
.
vm1_ip
)
# connect pem and br2
curr_pem_pid
=
curr_pem_pid
+
1
curr_br2_pid
=
curr_br2_pid
+
1
self
.
connect_ports
(
prog_id_pem
,
prog_id_br2
,
curr_pem_pid
,
curr_br2_pid
,
ip
,
self
.
br2_dest
,
self
.
br2_mac
,
self
.
ns2_eth_out
,
self
.
vm2_mac
,
self
.
vm2_ip
)
self
.
br2_dest
,
self
.
br2_mac
,
self
.
ns2_eth_out
.
index
,
self
.
vm2_mac
,
self
.
vm2_ip
)
# connect <br1, rtr> and <br2, rtr>
ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
nsrtr_eth0_out
)[
0
]
self
.
br1_rtr
[
c_uint
(
0
)]
=
c_uint
(
ifindex
)
ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
nsrtr_eth1_out
)[
0
]
self
.
br2_rtr
[
c_uint
(
0
)]
=
c_uint
(
ifindex
)
self
.
br1_rtr
[
c_uint
(
0
)]
=
c_uint
(
self
.
nsrtr_eth0_out
.
index
)
self
.
br2_rtr
[
c_uint
(
0
)]
=
c_uint
(
self
.
nsrtr_eth1_out
.
index
)
# tc filter setup with bpf programs attached
self
.
attach_filter
(
ip
,
self
.
ns1_eth_out
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
ns2_eth_out
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
nsrtr_eth0_out
,
br1_fn
.
fd
,
br1_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
nsrtr_eth1_out
,
br2_fn
.
fd
,
br2_fn
.
name
)
def
setUp
(
self
):
def
test_brb
(
self
):
try
:
b
=
BPF
(
src_file
=
arg1
,
debug
=
0
)
self
.
pem_fn
=
b
.
load_func
(
"pem"
,
BPF
.
SCHED_CLS
)
self
.
br1_fn
=
b
.
load_func
(
"br1"
,
BPF
.
SCHED_CLS
)
self
.
br2_fn
=
b
.
load_func
(
"br2"
,
BPF
.
SCHED_CLS
)
self
.
get_table
(
b
)
# set up the environment
# set up the topology
self
.
set_default_const
()
self
.
setup_vm_ns
(
self
.
ns1
,
self
.
ns1_eth_in
,
self
.
ns1_eth_out
)
self
.
setup_vm_ns
(
self
.
ns2
,
self
.
ns2_eth_in
,
self
.
ns2_eth_out
)
self
.
config_vm_ns
(
self
.
ns1
,
self
.
vm1_ip
,
self
.
vm2_rtr_mask
,
self
.
vm1_rtr_ip
)
self
.
config_vm_ns
(
self
.
ns2
,
self
.
vm2_ip
,
self
.
vm1_rtr_mask
,
self
.
vm2_rtr_ip
)
self
.
setup_router_ns
(
self
.
ns_router
,
self
.
nsrtr_eth0_in
,
self
.
nsrtr_eth0_out
,
self
.
nsrtr_eth1_in
,
self
.
nsrtr_eth1_out
)
self
.
config_router_ns
(
self
.
ns_router
,
self
.
vm1_rtr_ip
,
self
.
vm2_rtr_ip
)
# get vm mac address
self
.
vm1_mac
=
subprocess
.
check_output
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"cat"
,
"/sys/class/net/eth0/address"
])
self
.
vm1_mac
=
self
.
vm1_mac
.
strip
()
self
.
vm2_mac
=
subprocess
.
check_output
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"cat"
,
"/sys/class/net/eth0/address"
])
self
.
vm2_mac
=
self
.
vm2_mac
.
strip
()
# load the program and configure maps
(
ns1_ipdb
,
self
.
ns1_eth_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns1
,
ipaddr
=
self
.
vm1_ip
+
'/24'
,
fn
=
self
.
pem_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
(
ns2_ipdb
,
self
.
ns2_eth_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns2
,
ipaddr
=
self
.
vm2_ip
+
'/24'
,
fn
=
self
.
pem_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
ns1_ipdb
.
routes
.
add
({
'dst'
:
self
.
vm2_rtr_mask
,
'gateway'
:
self
.
vm1_rtr_ip
}).
commit
()
ns2_ipdb
.
routes
.
add
({
'dst'
:
self
.
vm1_rtr_mask
,
'gateway'
:
self
.
vm2_rtr_ip
}).
commit
()
self
.
vm1_mac
=
ns1_ipdb
.
interfaces
[
'eth0'
].
address
self
.
vm2_mac
=
ns2_ipdb
.
interfaces
[
'eth0'
].
address
(
_
,
self
.
nsrtr_eth0_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns_router
,
ipaddr
=
self
.
vm1_rtr_ip
+
'/24'
,
fn
=
self
.
br1_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
(
rt_ipdb
,
self
.
nsrtr_eth1_out
,
_
)
=
sim
.
_ns_add_ifc
(
self
.
ns_router
,
"eth1"
,
"ns_router2"
,
ipaddr
=
self
.
vm2_rtr_ip
+
'/24'
,
fn
=
self
.
br2_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
nsp
=
NSPopen
(
rt_ipdb
.
nl
.
netns
,
[
"sysctl"
,
"-w"
,
"net.ipv4.ip_forward=1"
])
nsp
.
wait
();
nsp
.
release
()
# configure maps
self
.
config_maps
()
def
test_brb
(
self
):
# our bridge is not smart enough, so send arping for router learning to prevent router
# from sending out arp request
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"arping"
,
"-w"
,
"1"
,
"-c"
,
"1"
,
"-I"
,
"eth0"
,
self
.
vm1_rtr_ip
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"arping"
,
"-w"
,
"1"
,
"-c"
,
"1"
,
"-I"
,
"eth0"
,
self
.
vm2_rtr_ip
])
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"arping"
,
"-w"
,
"1"
,
"-c"
,
"1"
,
"-I"
,
"eth0"
,
self
.
vm1_rtr_ip
])
nsp
.
wait
();
nsp
.
release
()
nsp
=
NSPopen
(
ns2_ipdb
.
nl
.
netns
,
[
"arping"
,
"-w"
,
"1"
,
"-c"
,
"1"
,
"-I"
,
"eth0"
,
self
.
vm2_rtr_ip
])
nsp
.
wait
();
nsp
.
release
()
# ping
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"ping"
,
self
.
vm2_ip
,
"-c"
,
"2"
])
# minimum one arp reply, 5 icmp reply
self
.
assertGreater
(
self
.
pem_stats
[
c_uint
(
0
)].
value
,
5
)
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"ping"
,
self
.
vm2_ip
,
"-c"
,
"2"
])
nsp
.
wait
();
nsp
.
release
()
# pem_stats only counts pem->bridge traffic, each VM has 4: arping/arp request/2 icmp request
# total 8 packets should be counted
self
.
assertEqual
(
self
.
pem_stats
[
c_uint
(
0
)].
value
,
8
)
# iperf, run server on the background
subprocess
.
Popen
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"iperf"
,
"-s"
,
"-xSCD"
])
nsp_server
=
NSPopen
(
ns2_ipdb
.
nl
.
netns
,
[
"iperf"
,
"-s"
,
"-xSC"
])
sleep
(
1
)
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"iperf"
,
"-c"
,
self
.
vm2_ip
,
"-t"
,
"1"
,
"-xSC"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"killall"
,
"iperf"
])
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"iperf"
,
"-c"
,
self
.
vm2_ip
,
"-t"
,
"1"
,
"-xSC"
])
nsp
.
wait
();
nsp
.
release
()
nsp_server
.
kill
();
nsp_server
.
wait
();
nsp_server
.
release
()
# netperf, run server on the background
subprocess
.
Popen
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"netserver"
])
nsp_server
=
NSPopen
(
ns2_ipdb
.
nl
.
netns
,
[
"netserver"
,
"-D"
])
sleep
(
1
)
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"--"
,
"-m"
,
"65160"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"-t"
,
"TCP_RR"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"killall"
,
"netserver"
])
# cleanup, tear down the veths and namespaces
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns1
])
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns2
])
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns_router
])
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"--"
,
"-m"
,
"65160"
])
nsp
.
wait
();
nsp
.
release
()
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"-t"
,
"TCP_RR"
])
nsp
.
wait
();
nsp
.
release
()
nsp_server
.
kill
();
nsp_server
.
wait
();
nsp_server
.
release
()
finally
:
sim
.
release
()
ipdb
.
release
()
if
__name__
==
"__main__"
:
...
...
tests/cc/test_brb2.c
View file @
ffaee08c
...
...
@@ -24,5 +24,5 @@ int pem(struct __sk_buff *skb) {
bpf_clone_redirect
(
skb
,
*
ifindex_p
,
0
);
}
return
0
;
return
1
;
}
tests/cc/test_brb2.py
View file @
ffaee08c
...
...
@@ -54,72 +54,41 @@
# 9:
# 9: OK
from
ctypes
import
c_ubyte
,
c_ushort
,
c_uint
,
c_ulonglong
,
Structure
from
netaddr
import
IPAddress
from
ctypes
import
c_uint
from
bpf
import
BPF
from
pyroute2
import
IPRoute
from
socket
import
socket
,
AF_INET
,
SOCK_DGRAM
from
pyroute2
import
IPRoute
,
NetNS
,
IPDB
,
NSPopen
import
sys
from
time
import
sleep
from
unittest
import
main
,
TestCase
import
subprocess
from
simulation
import
Simulation
arg1
=
sys
.
argv
.
pop
(
1
)
ipr
=
IPRoute
()
ipdb
=
IPDB
(
nl
=
ipr
)
sim
=
Simulation
(
ipdb
)
class
TestBPFSocket
(
TestCase
):
def
setup_vm_ns
(
self
,
ns
,
veth_in
,
veth_out
):
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth_out
])
subprocess
.
call
([
"ip"
,
"netns"
,
"add"
,
ns
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth_in
,
"name"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_out
,
"up"
])
def
config_vm_ns
(
self
,
ns
,
ip_addr
,
net_mask
,
ip_gw
):
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_addr
+
"/24"
,
"dev"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth0"
,
"up"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"route"
,
"add"
,
"-net"
,
net_mask
+
"/24"
,
"gw"
,
ip_gw
])
def
setup_router_ns
(
self
,
ns
,
veth1_in
,
veth1_out
,
veth2_in
,
veth2_out
):
subprocess
.
call
([
"ip"
,
"netns"
,
"add"
,
ns
])
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth1_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth1_out
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth1_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth1_in
,
"name"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth2_in
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth2_out
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth2_in
,
"netns"
,
ns
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
veth2_in
,
"name"
,
"eth1"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth1_out
,
"up"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth2_out
,
"up"
])
def
config_router_ns
(
self
,
ns
,
ip_eth0
,
ip_eth1
):
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_eth0
+
"/24"
,
"dev"
,
"eth0"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth0"
,
"up"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"addr"
,
"add"
,
ip_eth1
+
"/24"
,
"dev"
,
"eth1"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
ns
,
"ip"
,
"link"
,
"set"
,
"eth1"
,
"up"
])
def
setup_br
(
self
,
br
,
veth_rt_2_br
):
# set up the bridge and add router interface as one of its slaves
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
"name"
,
br
,
"type"
,
"bridge"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
"dev"
,
veth_rt_2_br
,
"master"
,
br
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
br
,
"up"
])
def
setup_br
(
self
,
br
,
veth_rt_2_br
,
veth_pem_2_br
,
veth_br_2_pem
):
# create veth which connecting pem and br
with
ipdb
.
create
(
ifname
=
veth_pem_2_br
,
kind
=
"veth"
,
peer
=
veth_br_2_pem
)
as
v
:
v
.
up
()
ipdb
.
interfaces
[
veth_br_2_pem
].
up
().
commit
()
subprocess
.
call
([
"sysctl"
,
"-q"
,
"-w"
,
"net.ipv6.conf."
+
veth_pem_2_br
+
".disable_ipv6=1"
])
subprocess
.
call
([
"sysctl"
,
"-q"
,
"-w"
,
"net.ipv6.conf."
+
veth_br_2_pem
+
".disable_ipv6=1"
])
def
br_add_pem_link
(
self
,
br
,
veth_pem_2_br
,
veth_br_2_pem
):
subprocess
.
call
([
"ip"
,
"link"
,
"add"
,
veth_pem_2_br
,
"type"
,
"veth"
,
"peer"
,
"name"
,
veth_br_2_pem
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
"dev"
,
veth_pem_2_br
,
"master"
,
br
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_pem_2_br
,
"up"
])
subprocess
.
call
([
"ip"
,
"link"
,
"set"
,
veth_br_2_pem
,
"up"
])
# set up the bridge and add router interface as one of its slaves
with
ipdb
.
create
(
ifname
=
br
,
kind
=
"bridge"
)
as
br1
:
br1
.
add_port
(
ipdb
.
interfaces
[
veth_pem_2_br
])
br1
.
add_port
(
ipdb
.
interfaces
[
veth_rt_2_br
])
br1
.
up
()
subprocess
.
call
([
"sysctl"
,
"-q"
,
"-w"
,
"net.ipv6.conf."
+
br
+
".disable_ipv6=1"
])
def
set_default_const
(
self
):
self
.
ns1
=
"ns1"
self
.
ns1_eth_in
=
"v1"
self
.
ns1_eth_out
=
"v2"
self
.
ns2
=
"ns2"
self
.
ns2_eth_in
=
"v3"
self
.
ns2_eth_out
=
"v4"
self
.
ns_router
=
"ns_router"
self
.
nsrtr_eth0_in
=
"v10"
self
.
nsrtr_eth0_out
=
"v11"
self
.
nsrtr_eth1_in
=
"v12"
self
.
nsrtr_eth1_out
=
"v13"
self
.
br1
=
"br1"
self
.
veth_pem_2_br1
=
"v20"
self
.
veth_br1_2_pem
=
"v21"
...
...
@@ -131,88 +100,91 @@ class TestBPFSocket(TestCase):
self
.
vm2_ip
=
"200.1.1.1"
self
.
vm1_rtr_ip
=
"100.1.1.254"
self
.
vm2_rtr_ip
=
"200.1.1.254"
self
.
vm1_rtr_mask
=
"100.1.1.0"
self
.
vm2_rtr_mask
=
"200.1.1.0"
self
.
vm1_rtr_mask
=
"100.1.1.0
/24
"
self
.
vm2_rtr_mask
=
"200.1.1.0
/24
"
def
attach_filter
(
self
,
i
p
,
i
fname
,
fd
,
name
):
ifindex
=
ip
.
link_lookup
(
ifname
=
ifname
)[
0
]
ip
.
tc
(
"add"
,
"ingress"
,
ifindex
,
"ffff:"
)
ip
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":1"
,
fd
=
fd
,
name
=
name
,
def
attach_filter
(
self
,
ifname
,
fd
,
name
):
ifindex
=
ip
db
.
interfaces
[
ifname
].
index
ip
r
.
tc
(
"add"
,
"ingress"
,
ifindex
,
"ffff:"
)
ip
r
.
tc
(
"add-filter"
,
"bpf"
,
ifindex
,
":1"
,
fd
=
fd
,
name
=
name
,
parent
=
"ffff:"
,
action
=
"drop"
,
classid
=
1
)
def
config_maps
(
self
):
b
=
BPF
(
src_file
=
arg1
,
debug
=
0
)
pem_fn
=
b
.
load_func
(
"pem"
,
BPF
.
SCHED_CLS
)
self
.
pem_dest
=
b
.
get_table
(
"pem_dest"
)
self
.
pem_stats
=
b
.
get_table
(
"pem_stats"
)
ip
=
IPRoute
()
# pem just relays packets between VM and its corresponding
# slave link in the bridge interface
ns1_ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
ns1_eth_out
)[
0
]
ns2_ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
ns2_eth_out
)[
0
]
br1_ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
veth_br1_2_pem
)[
0
]
br2_ifindex
=
ip
.
link_lookup
(
ifname
=
self
.
veth_br2_2_pem
)[
0
]
ns1_ifindex
=
self
.
ns1_eth_out
.
index
ns2_ifindex
=
self
.
ns2_eth_out
.
index
br1_ifindex
=
ip
db
.
interfaces
[
self
.
veth_br1_2_pem
].
index
br2_ifindex
=
ip
db
.
interfaces
[
self
.
veth_br2_2_pem
].
index
self
.
pem_dest
[
c_uint
(
ns1_ifindex
)]
=
c_uint
(
br1_ifindex
)
self
.
pem_dest
[
c_uint
(
br1_ifindex
)]
=
c_uint
(
ns1_ifindex
)
self
.
pem_dest
[
c_uint
(
ns2_ifindex
)]
=
c_uint
(
br2_ifindex
)
self
.
pem_dest
[
c_uint
(
br2_ifindex
)]
=
c_uint
(
ns2_ifindex
)
# tc filter setup with bpf programs attached
self
.
attach_filter
(
ip
,
self
.
ns1_eth_out
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
ns2_eth_out
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
veth_br1_2_pem
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
ip
,
self
.
veth_br2_2_pem
,
pem_fn
.
fd
,
pem_fn
.
name
)
self
.
attach_filter
(
self
.
veth_br1_2_pem
,
self
.
pem_fn
.
fd
,
self
.
pem_fn
.
name
)
self
.
attach_filter
(
self
.
veth_br2_2_pem
,
self
.
pem_fn
.
fd
,
self
.
pem_fn
.
name
)
def
setUp
(
self
):
def
test_brb2
(
self
):
try
:
b
=
BPF
(
src_file
=
arg1
,
debug
=
0
)
self
.
pem_fn
=
b
.
load_func
(
"pem"
,
BPF
.
SCHED_CLS
)
self
.
pem_dest
=
b
.
get_table
(
"pem_dest"
)
self
.
pem_stats
=
b
.
get_table
(
"pem_stats"
)
# set up the environment
# set up the topology
self
.
set_default_const
()
self
.
setup_vm_ns
(
self
.
ns1
,
self
.
ns1_eth_in
,
self
.
ns1_eth_out
)
self
.
setup_vm_ns
(
self
.
ns2
,
self
.
ns2_eth_in
,
self
.
ns2_eth_out
)
self
.
config_vm_ns
(
self
.
ns1
,
self
.
vm1_ip
,
self
.
vm2_rtr_mask
,
self
.
vm1_rtr_ip
)
self
.
config_vm_ns
(
self
.
ns2
,
self
.
vm2_ip
,
self
.
vm1_rtr_mask
,
self
.
vm2_rtr_ip
)
self
.
setup_router_ns
(
self
.
ns_router
,
self
.
nsrtr_eth0_in
,
self
.
nsrtr_eth0_out
,
self
.
nsrtr_eth1_in
,
self
.
nsrtr_eth1_out
)
self
.
config_router_ns
(
self
.
ns_router
,
self
.
vm1_rtr_ip
,
self
.
vm2_rtr_ip
)
# for each VM connecting to pem, there will be a corresponding veth
# connecting to the bridge
self
.
setup_br
(
self
.
br1
,
self
.
nsrtr_eth0_out
)
self
.
br_add_pem_link
(
self
.
br1
,
self
.
veth_pem_2_br1
,
self
.
veth_br1_2_pem
)
self
.
setup_br
(
self
.
br2
,
self
.
nsrtr_eth1_out
)
self
.
br_add_pem_link
(
self
.
br2
,
self
.
veth_pem_2_br2
,
self
.
veth_br2_2_pem
)
(
ns1_ipdb
,
self
.
ns1_eth_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns1
,
ipaddr
=
self
.
vm1_ip
+
'/24'
,
fn
=
self
.
pem_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
(
ns2_ipdb
,
self
.
ns2_eth_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns2
,
ipaddr
=
self
.
vm2_ip
+
'/24'
,
fn
=
self
.
pem_fn
,
action
=
'drop'
,
disable_ipv6
=
True
)
ns1_ipdb
.
routes
.
add
({
'dst'
:
self
.
vm2_rtr_mask
,
'gateway'
:
self
.
vm1_rtr_ip
}).
commit
()
ns2_ipdb
.
routes
.
add
({
'dst'
:
self
.
vm1_rtr_mask
,
'gateway'
:
self
.
vm2_rtr_ip
}).
commit
()
(
_
,
self
.
nsrtr_eth0_out
,
_
)
=
sim
.
_create_ns
(
self
.
ns_router
,
ipaddr
=
self
.
vm1_rtr_ip
+
'/24'
,
disable_ipv6
=
True
)
(
rt_ipdb
,
self
.
nsrtr_eth1_out
,
_
)
=
sim
.
_ns_add_ifc
(
self
.
ns_router
,
"eth1"
,
"ns_router2"
,
ipaddr
=
self
.
vm2_rtr_ip
+
'/24'
,
disable_ipv6
=
True
)
# enable ip forwarding in router ns
nsp
=
NSPopen
(
rt_ipdb
.
nl
.
netns
,
[
"sysctl"
,
"-w"
,
"net.ipv4.ip_forward=1"
])
nsp
.
wait
();
nsp
.
release
()
# for each VM connecting to pem, there will be a corresponding veth connecting to the bridge
self
.
setup_br
(
self
.
br1
,
self
.
nsrtr_eth0_out
.
ifname
,
self
.
veth_pem_2_br1
,
self
.
veth_br1_2_pem
)
self
.
setup_br
(
self
.
br2
,
self
.
nsrtr_eth1_out
.
ifname
,
self
.
veth_pem_2_br2
,
self
.
veth_br2_2_pem
)
# load the program and configure maps
self
.
config_maps
()
def
test_brb2
(
self
):
# ping
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"ping"
,
self
.
vm2_ip
,
"-c"
,
"2"
]
)
# minimum one arp request/reply, 5 icmp request/reply
self
.
assertGreater
(
self
.
pem_stats
[
c_uint
(
0
)].
value
,
11
)
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"ping"
,
self
.
vm2_ip
,
"-c"
,
"2"
]);
nsp
.
wait
();
nsp
.
release
(
)
# one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
self
.
assertEqual
(
self
.
pem_stats
[
c_uint
(
0
)].
value
,
12
)
# iperf, run server on the background
subprocess
.
Popen
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"iperf"
,
"-s"
,
"-xSCD"
])
nsp_server
=
NSPopen
(
ns2_ipdb
.
nl
.
netns
,
[
"iperf"
,
"-s"
,
"-xSC"
])
sleep
(
1
)
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"iperf"
,
"-c"
,
self
.
vm2_ip
,
"-t"
,
"1"
,
"-xSC"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"killall"
,
"iperf"
])
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"iperf"
,
"-c"
,
self
.
vm2_ip
,
"-t"
,
"1"
,
"-xSC"
])
nsp
.
wait
();
nsp
.
release
()
nsp_server
.
kill
();
nsp_server
.
wait
();
nsp_server
.
release
()
# netperf, run server on the background
subprocess
.
Popen
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"netserver"
])
nsp_server
=
NSPopen
(
ns2_ipdb
.
nl
.
netns
,
[
"netserver"
,
"-D"
])
sleep
(
1
)
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"--"
,
"-m"
,
"65160"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns1
,
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"-t"
,
"TCP_RR"
])
subprocess
.
call
([
"ip"
,
"netns"
,
"exec"
,
self
.
ns2
,
"killall"
,
"netserver"
])
# cleanup, tear down the veths and namespaces
subprocess
.
call
([
"ip"
,
"link"
,
"del"
,
self
.
veth_br1_2_pem
])
subprocess
.
call
([
"ip"
,
"link"
,
"del"
,
self
.
veth_br2_2_pem
])
subprocess
.
call
([
"ip"
,
"link"
,
"del"
,
self
.
br1
])
subprocess
.
call
([
"ip"
,
"link"
,
"del"
,
self
.
br2
])
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns1
])
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns2
])
subprocess
.
call
([
"ip"
,
"netns"
,
"del"
,
self
.
ns_router
])
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"--"
,
"-m"
,
"65160"
])
nsp
.
wait
();
nsp
.
release
()
nsp
=
NSPopen
(
ns1_ipdb
.
nl
.
netns
,
[
"netperf"
,
"-l"
,
"1"
,
"-H"
,
self
.
vm2_ip
,
"-t"
,
"TCP_RR"
])
nsp
.
wait
();
nsp
.
release
()
nsp_server
.
kill
();
nsp_server
.
wait
();
nsp_server
.
release
()
finally
:
if
self
.
br1
in
ipdb
.
interfaces
:
ipdb
.
interfaces
[
self
.
br1
].
remove
().
commit
()
if
self
.
br2
in
ipdb
.
interfaces
:
ipdb
.
interfaces
[
self
.
br2
].
remove
().
commit
()
if
self
.
veth_pem_2_br1
in
ipdb
.
interfaces
:
ipdb
.
interfaces
[
self
.
veth_pem_2_br1
].
remove
().
commit
()
if
self
.
veth_pem_2_br2
in
ipdb
.
interfaces
:
ipdb
.
interfaces
[
self
.
veth_pem_2_br2
].
remove
().
commit
()
sim
.
release
()
ipdb
.
release
()
if
__name__
==
"__main__"
:
...
...
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