Commit 3a898644 authored by Yonghong Song's avatar Yonghong Song

fix and improve test brb/brb2

   o disable ipv6 for newly-created net devices to avoid unaccountable pkt counting
   o explicitly enable ip_forward in router namespace
   o proper cleanup in case of validation failure
   o in test_brb, use different tc_index to differentiate the packet source (pem or router_ns)
   o change bpf program return value to 1 so that the packet will be dropped instead of being
     passed up to the stack
Signed-off-by: default avatarYonghong Song <yhs@plumgrid.com>
parent 0fa99f4d
...@@ -101,13 +101,12 @@ int pem(struct __sk_buff *skb) { ...@@ -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) __attribute__((always_inline));
static int br_common(struct __sk_buff *skb, int which_br) { static int br_common(struct __sk_buff *skb, int which_br) {
u8 *cursor = 0; u8 *cursor = 0;
bpf_metadata_t meta = {};
u16 proto; u16 proto;
u16 arpop; u16 arpop;
eth_addr_t dmac; eth_addr_t dmac;
...@@ -118,20 +117,16 @@ static int br_common(struct __sk_buff *skb, int which_br) { ...@@ -118,20 +117,16 @@ static int br_common(struct __sk_buff *skb, int which_br) {
bpf_dest_t *dest_p; bpf_dest_t *dest_p;
u32 index, *rtrif_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)); struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
/* handle ethernet packet header */
{ {
dmac.addr = ethernet->dst; dmac.addr = ethernet->dst;
if (meta.prog_id != 0) { /* skb->tc_index may be preserved accross router namespace if router simply rewrite packet
/* send to the router */ * 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) { if (dmac.addr == 0xffffffffffffULL) {
index = 0; index = 0;
if (which_br == 1) if (which_br == 1)
...@@ -149,9 +144,11 @@ static int br_common(struct __sk_buff *skb, int which_br) { ...@@ -149,9 +144,11 @@ static int br_common(struct __sk_buff *skb, int which_br) {
if (rtrif_p) if (rtrif_p)
bpf_clone_redirect(skb, *rtrif_p, 0); 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) { switch (ethernet->type) {
case ETH_P_IP: goto ip; case ETH_P_IP: goto ip;
case ETH_P_ARP: goto arp; case ETH_P_ARP: goto arp;
...@@ -217,7 +214,7 @@ xmit: ...@@ -217,7 +214,7 @@ xmit:
} }
EOP: EOP:
return 0; return 1;
} }
int br1(struct __sk_buff *skb) { int br1(struct __sk_buff *skb) {
......
...@@ -65,7 +65,6 @@ from ctypes import c_ubyte, c_ushort, c_uint, c_ulonglong, Structure ...@@ -65,7 +65,6 @@ from ctypes import c_ubyte, c_ushort, c_uint, c_ulonglong, Structure
from netaddr import IPAddress, EUI from netaddr import IPAddress, EUI
from bpf import BPF from bpf import BPF
from pyroute2 import IPRoute from pyroute2 import IPRoute
from socket import socket, AF_INET, SOCK_DGRAM
import sys import sys
from time import sleep from time import sleep
from unittest import main, TestCase from unittest import main, TestCase
...@@ -80,10 +79,12 @@ class TestBPFSocket(TestCase): ...@@ -80,10 +79,12 @@ class TestBPFSocket(TestCase):
subprocess.call(["ip", "netns", "add", ns]) subprocess.call(["ip", "netns", "add", ns])
subprocess.call(["ip", "link", "set", veth_in, "netns", 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", "netns", "exec", ns, "ip", "link", "set", veth_in, "name", "eth0"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth_out+ ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth_out, "up"]) subprocess.call(["ip", "link", "set", veth_out, "up"])
def config_vm_ns(self, ns, ip_addr, net_mask, ip_gw): 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", "addr", "add", ip_addr + "/24", "dev", "eth0"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth0.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth0", "up"]) 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]) subprocess.call(["ip", "netns", "exec", ns, "ip", "route", "add", net_mask + "/24", "via", ip_gw])
...@@ -95,14 +96,19 @@ class TestBPFSocket(TestCase): ...@@ -95,14 +96,19 @@ class TestBPFSocket(TestCase):
subprocess.call(["ip", "link", "add", veth2_in, "type", "veth", "peer", "name", veth2_out]) 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", "link", "set", veth2_in, "netns", ns])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", veth2_in, "name", "eth1"]) subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", veth2_in, "name", "eth1"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth1_out+ ".disable_ipv6=1"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth2_out+ ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth1_out, "up"]) subprocess.call(["ip", "link", "set", veth1_out, "up"])
subprocess.call(["ip", "link", "set", veth2_out, "up"]) subprocess.call(["ip", "link", "set", veth2_out, "up"])
def config_router_ns(self, ns, ip_eth0, ip_eth1): 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", "addr", "add", ip_eth0 + "/24", "dev", "eth0"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth0.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth0", "up"]) 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", "addr", "add", ip_eth1 + "/24", "dev", "eth1"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth1.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth1", "up"]) subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth1", "up"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-w", "net.ipv4.ip_forward=1"])
def set_default_const(self): def set_default_const(self):
self.ns1 = "ns1" self.ns1 = "ns1"
...@@ -206,56 +212,58 @@ class TestBPFSocket(TestCase): ...@@ -206,56 +212,58 @@ class TestBPFSocket(TestCase):
self.attach_filter(ip, self.nsrtr_eth0_out, br1_fn.fd, br1_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) self.attach_filter(ip, self.nsrtr_eth1_out, br2_fn.fd, br2_fn.name)
def setUp(self):
# set up the environment
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
self.config_maps()
def test_brb(self): def test_brb(self):
# our bridge is not smart enough, so send arping for router learning to prevent router try:
# from sending out arp request # set up the environment
subprocess.call(["ip", "netns", "exec", self.ns1, "arping", "-w", "1", "-c", "1", "-I", "eth0", self.set_default_const()
self.vm1_rtr_ip]) self.setup_vm_ns(self.ns1, self.ns1_eth_in, self.ns1_eth_out)
subprocess.call(["ip", "netns", "exec", self.ns2, "arping", "-w", "1", "-c", "1", "-I", "eth0", self.setup_vm_ns(self.ns2, self.ns2_eth_in, self.ns2_eth_out)
self.vm2_rtr_ip]) self.config_vm_ns(self.ns1, self.vm1_ip, self.vm2_rtr_mask, self.vm1_rtr_ip)
# ping self.config_vm_ns(self.ns2, self.vm2_ip, self.vm1_rtr_mask, self.vm2_rtr_ip)
subprocess.call(["ip", "netns", "exec", self.ns1, "ping", self.vm2_ip, "-c", "2"]) self.setup_router_ns(self.ns_router, self.nsrtr_eth0_in, self.nsrtr_eth0_out,
# minimum one arp reply, 5 icmp reply self.nsrtr_eth1_in, self.nsrtr_eth1_out)
self.assertGreater(self.pem_stats[c_uint(0)].value, 5) self.config_router_ns(self.ns_router, self.vm1_rtr_ip, self.vm2_rtr_ip)
# iperf, run server on the background # get vm mac address
subprocess.Popen(["ip", "netns", "exec", self.ns2, "iperf", "-s", "-xSCD"]) self.vm1_mac = subprocess.check_output(["ip", "netns", "exec", self.ns1, "cat", "/sys/class/net/eth0/address"])
sleep(1) self.vm1_mac = self.vm1_mac.strip()
subprocess.call(["ip", "netns", "exec", self.ns1, "iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"]) self.vm2_mac = subprocess.check_output(["ip", "netns", "exec", self.ns2, "cat", "/sys/class/net/eth0/address"])
subprocess.call(["ip", "netns", "exec", self.ns2, "killall", "iperf"]) self.vm2_mac = self.vm2_mac.strip()
# netperf, run server on the background # load the program and configure maps
subprocess.Popen(["ip", "netns", "exec", self.ns2, "netserver"]) self.config_maps()
sleep(1)
subprocess.call(["ip", "netns", "exec", self.ns1, "netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"]) # our bridge is not smart enough, so send arping for router learning to prevent router
subprocess.call(["ip", "netns", "exec", self.ns1, "netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"]) # from sending out arp request
subprocess.call(["ip", "netns", "exec", self.ns2, "killall", "netserver"]) subprocess.call(["ip", "netns", "exec", self.ns1, "arping", "-w", "1", "-c", "1", "-I", "eth0",
self.vm1_rtr_ip])
# cleanup, tear down the veths and namespaces subprocess.call(["ip", "netns", "exec", self.ns2, "arping", "-w", "1", "-c", "1", "-I", "eth0",
subprocess.call(["ip", "netns", "del", self.ns1]) self.vm2_rtr_ip])
subprocess.call(["ip", "netns", "del", self.ns2]) # ping
subprocess.call(["ip", "netns", "del", self.ns_router]) subprocess.call(["ip", "netns", "exec", self.ns1, "ping", self.vm2_ip, "-c", "2"])
# 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"])
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"])
# netperf, run server on the background
subprocess.Popen(["ip", "netns", "exec", self.ns2, "netserver"])
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"])
finally:
# cleanup, tear down the veths and namespaces
ns_list = subprocess.check_output(["ip", "netns", "list"]).split()
if self.ns1 in ns_list: subprocess.call(["ip", "netns", "del", self.ns1])
if self.ns2 in ns_list: subprocess.call(["ip", "netns", "del", self.ns2])
if self.ns_router in ns_list: subprocess.call(["ip", "netns", "del", self.ns_router])
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -24,5 +24,5 @@ int pem(struct __sk_buff *skb) { ...@@ -24,5 +24,5 @@ int pem(struct __sk_buff *skb) {
bpf_clone_redirect(skb, *ifindex_p, 0); bpf_clone_redirect(skb, *ifindex_p, 0);
} }
return 0; return 1;
} }
...@@ -58,7 +58,6 @@ from ctypes import c_ubyte, c_ushort, c_uint, c_ulonglong, Structure ...@@ -58,7 +58,6 @@ from ctypes import c_ubyte, c_ushort, c_uint, c_ulonglong, Structure
from netaddr import IPAddress from netaddr import IPAddress
from bpf import BPF from bpf import BPF
from pyroute2 import IPRoute from pyroute2 import IPRoute
from socket import socket, AF_INET, SOCK_DGRAM
import sys import sys
from time import sleep from time import sleep
from unittest import main, TestCase from unittest import main, TestCase
...@@ -72,10 +71,12 @@ class TestBPFSocket(TestCase): ...@@ -72,10 +71,12 @@ class TestBPFSocket(TestCase):
subprocess.call(["ip", "netns", "add", ns]) subprocess.call(["ip", "netns", "add", ns])
subprocess.call(["ip", "link", "set", veth_in, "netns", 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", "netns", "exec", ns, "ip", "link", "set", veth_in, "name", "eth0"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth_out+ ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth_out, "up"]) subprocess.call(["ip", "link", "set", veth_out, "up"])
def config_vm_ns(self, ns, ip_addr, net_mask, ip_gw): 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", "addr", "add", ip_addr + "/24", "dev", "eth0"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth0.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth0", "up"]) 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]) subprocess.call(["ip", "netns", "exec", ns, "route", "add", "-net", net_mask + "/24", "gw", ip_gw])
...@@ -87,25 +88,33 @@ class TestBPFSocket(TestCase): ...@@ -87,25 +88,33 @@ class TestBPFSocket(TestCase):
subprocess.call(["ip", "link", "add", veth2_in, "type", "veth", "peer", "name", veth2_out]) 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", "link", "set", veth2_in, "netns", ns])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", veth2_in, "name", "eth1"]) subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", veth2_in, "name", "eth1"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth1_out+ ".disable_ipv6=1"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth2_out+ ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth1_out, "up"]) subprocess.call(["ip", "link", "set", veth1_out, "up"])
subprocess.call(["ip", "link", "set", veth2_out, "up"]) subprocess.call(["ip", "link", "set", veth2_out, "up"])
def config_router_ns(self, ns, ip_eth0, ip_eth1): 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", "addr", "add", ip_eth0 + "/24", "dev", "eth0"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth0.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth0", "up"]) 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", "addr", "add", ip_eth1 + "/24", "dev", "eth1"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-q", "-w", "net.ipv6.conf.eth1.disable_ipv6=1"])
subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth1", "up"]) subprocess.call(["ip", "netns", "exec", ns, "ip", "link", "set", "eth1", "up"])
subprocess.call(["ip", "netns", "exec", ns, "sysctl", "-w", "net.ipv4.ip_forward=1"])
def setup_br(self, br, veth_rt_2_br): def setup_br(self, br, veth_rt_2_br):
# set up the bridge and add router interface as one of its slaves # 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", "add", "name", br, "type", "bridge"])
subprocess.call(["ip", "link", "set", "dev", veth_rt_2_br, "master", br]) subprocess.call(["ip", "link", "set", "dev", veth_rt_2_br, "master", br])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + br + ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", br, "up"]) subprocess.call(["ip", "link", "set", br, "up"])
def br_add_pem_link(self, br, veth_pem_2_br, veth_br_2_pem): 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", "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", "dev", veth_pem_2_br, "master", br])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth_pem_2_br + ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth_pem_2_br, "up"]) subprocess.call(["ip", "link", "set", veth_pem_2_br, "up"])
subprocess.call(["sysctl", "-q", "-w", "net.ipv6.conf." + veth_br_2_pem + ".disable_ipv6=1"])
subprocess.call(["ip", "link", "set", veth_br_2_pem, "up"]) subprocess.call(["ip", "link", "set", veth_br_2_pem, "up"])
def set_default_const(self): def set_default_const(self):
...@@ -164,55 +173,57 @@ class TestBPFSocket(TestCase): ...@@ -164,55 +173,57 @@ class TestBPFSocket(TestCase):
self.attach_filter(ip, self.veth_br1_2_pem, 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(ip, self.veth_br2_2_pem, pem_fn.fd, pem_fn.name)
def setUp(self):
# set up the environment
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)
# load the program and configure maps
self.config_maps()
def test_brb2(self): def test_brb2(self):
# ping try:
subprocess.call(["ip", "netns", "exec", self.ns1, "ping", self.vm2_ip, "-c", "2"]) # set up the environment
# minimum one arp request/reply, 5 icmp request/reply self.set_default_const()
self.assertGreater(self.pem_stats[c_uint(0)].value, 11) 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)
# iperf, run server on the background self.config_vm_ns(self.ns1, self.vm1_ip, self.vm2_rtr_mask, self.vm1_rtr_ip)
subprocess.Popen(["ip", "netns", "exec", self.ns2, "iperf", "-s", "-xSCD"]) self.config_vm_ns(self.ns2, self.vm2_ip, self.vm1_rtr_mask, self.vm2_rtr_ip)
sleep(1) self.setup_router_ns(self.ns_router, self.nsrtr_eth0_in, self.nsrtr_eth0_out,
subprocess.call(["ip", "netns", "exec", self.ns1, "iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"]) self.nsrtr_eth1_in, self.nsrtr_eth1_out)
subprocess.call(["ip", "netns", "exec", self.ns2, "killall", "iperf"]) self.config_router_ns(self.ns_router, self.vm1_rtr_ip, self.vm2_rtr_ip)
# netperf, run server on the background # for each VM connecting to pem, there will be a corresponding veth
subprocess.Popen(["ip", "netns", "exec", self.ns2, "netserver"]) # connecting to the bridge
sleep(1) self.setup_br(self.br1, self.nsrtr_eth0_out)
subprocess.call(["ip", "netns", "exec", self.ns1, "netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"]) self.br_add_pem_link(self.br1, self.veth_pem_2_br1, self.veth_br1_2_pem)
subprocess.call(["ip", "netns", "exec", self.ns1, "netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"]) self.setup_br(self.br2, self.nsrtr_eth1_out)
subprocess.call(["ip", "netns", "exec", self.ns2, "killall", "netserver"]) self.br_add_pem_link(self.br2, self.veth_pem_2_br2, self.veth_br2_2_pem)
# cleanup, tear down the veths and namespaces # load the program and configure maps
subprocess.call(["ip", "link", "del", self.veth_br1_2_pem]) self.config_maps()
subprocess.call(["ip", "link", "del", self.veth_br2_2_pem])
subprocess.call(["ip", "link", "del", self.br1]) # ping
subprocess.call(["ip", "link", "del", self.br2]) subprocess.call(["ip", "netns", "exec", self.ns1, "ping", self.vm2_ip, "-c", "2"])
subprocess.call(["ip", "netns", "del", self.ns1]) # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
subprocess.call(["ip", "netns", "del", self.ns2]) self.assertEqual(self.pem_stats[c_uint(0)].value, 12)
subprocess.call(["ip", "netns", "del", self.ns_router])
# iperf, run server on the background
subprocess.Popen(["ip", "netns", "exec", self.ns2, "iperf", "-s", "-xSCD"])
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"])
# netperf, run server on the background
subprocess.Popen(["ip", "netns", "exec", self.ns2, "netserver"])
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"])
finally:
# cleanup, tear down the veths and namespaces
net_list = subprocess.check_output(["ls", "/sys/class/net"]).split()
ns_list = subprocess.check_output(["ip", "netns", "list"]).split()
if self.veth_br1_2_pem in net_list: subprocess.call(["ip", "link", "del", self.veth_br1_2_pem])
if self.veth_br2_2_pem in net_list: subprocess.call(["ip", "link", "del", self.veth_br2_2_pem])
if self.br1 in net_list: subprocess.call(["ip", "link", "del", self.br1])
if self.br2 in net_list: subprocess.call(["ip", "link", "del", self.br2])
if self.ns1 in ns_list: subprocess.call(["ip", "netns", "del", self.ns1])
if self.ns2 in ns_list: subprocess.call(["ip", "netns", "del", self.ns2])
if self.ns_router in ns_list: subprocess.call(["ip", "netns", "del", self.ns_router])
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment