def run_unmanaged(self, command, user=os.getenv("USER")): """ Executes a command under the given user from this virtual node. Returns an NSPopen object to control the process. NSOpen has the same API as subprocess.Popen. This NSPopen object needs to be manually release. In general you should prefer using run, where this is done automatically by the context manager. """ sudo_command = [ 'sudo', '-E', '-u', user, 'env', 'PATH=' + os.getenv("PATH") ] + command return NSPopen(self.namespace, sudo_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, start_new_session=True)
def test_basic(self): require_user('root') nsid = self.alloc_nsname() # create NS and run a child nsp = NSPopen(nsid, ['ip', '-o', 'link'], stdout=subprocess.PIPE, flags=os.O_CREAT) ret = nsp.communicate()[0].decode('utf-8') host_links = [x.get_attr('IFLA_IFNAME') for x in self.ip.get_links()] netns_links = [ x.split(':')[1].split('@')[0].strip() for x in ret.split('\n') if len(x) ] assert nsp.wait() == nsp.returncode == 0 assert set(host_links) & set(netns_links) == set(netns_links) assert set(netns_links) < set(host_links) assert not set(netns_links) > set(host_links) nsp.release()
def start(self): # each entry is tuple of ns_ipdb, out_ifc, in_ifc host_info = [] for i in range(0, num_hosts): print("Launching host %i of %i" % (i + 1, num_hosts)) ipaddr = "172.16.1.%d/24" % (100 + i) host_info.append(self._create_ns("host%d" % i, ipaddr=ipaddr, disable_ipv6=True)) if multicast: cmd = ["python", "tunnel.py", str(i)] else: cmd = ["python", "tunnel_mesh.py", str(num_hosts), str(i), str(dhcp), str(gretap)] p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE) self.processes.append(p) with self.ipdb.create(ifname="br-fabric", kind="bridge") as br: for host in host_info: br.add_port(host[1]) br.up() # get host0 bridge ip's host0_br_ips = [] if dhcp == 1: print("Waiting for host0 br1/br2 ip addresses available") for j in range(0, 2): interface = host_info[0][0].interfaces["br%d" % j] interface.wait_ip("99.1.0.0", 16, timeout=60) host0_br_ips = [x[0] for x in interface.ipaddr if x[0].startswith("99.1")] else: host0_br_ips.append("99.1.0.1") host0_br_ips.append("99.1.1.1") # traffic test print("Validating connectivity") for i in range(1, num_hosts): for j in range(0, 2): interface = host_info[i][0].interfaces["br%d" % j] interface.wait_ip("99.1.0.0", 16, timeout=60) print("VNI%d between host0 and host%d" % (10000 + j, i)) call(["ip", "netns", "exec", "host%d" % i, "ping", host0_br_ips[j], "-c", "3", "-i", "0.2", "-q"])
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 topology self.set_default_const() (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() # ping 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) nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"]) sleep(1) 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() nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"]) sleep(1) 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()
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 topology self.set_default_const() (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() # our bridge is not smart enough, so send arping for router learning to prevent router # from sending out arp request 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 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) nsp_server = NSPopenWithCheck(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"]) sleep(1) 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() nsp_server = NSPopenWithCheck(ns2_ipdb.nl.netns, ["netserver", "-D"]) sleep(1) nsp = NSPopenWithCheck( 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()
def _ns_add_ifc(self, name, ns_ifc, ifc_base_name=None, 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: try: nl = NetNS(name) self.namespaces.append(nl) except KeyboardInterrupt: # remove the namespace if it has been created pyroute2.netns.remove(name) raise ns_ipdb = IPDB(nl) self.ipdbs[nl.netns] = ns_ipdb if disable_ipv6: cmd1 = [ "sysctl", "-q", "-w", "net.ipv6.conf.default.disable_ipv6=1" ] nsp = NSPopen(ns_ipdb.nl.netns, cmd1) nsp.wait() nsp.release() ns_ipdb.interfaces.lo.up().commit() if in_ifc: in_ifname = in_ifc.ifname with in_ifc as v: # move half of veth into namespace v.net_ns_fd = ns_ipdb.nl.netns else: # delete the potentially leaf-over veth interfaces ipr = IPRoute() for i in ipr.link_lookup(ifname='%sa' % ifc_base_name): ipr.link_remove(i) ipr.close() try: 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: v.net_ns_fd = ns_ipdb.nl.netns except KeyboardInterrupt: # explicitly remove the interface out_ifname = "%sa" % ifc_base_name if out_ifname in self.ipdb.interfaces: self.ipdb.interfaces[out_ifname].remove().commit() raise if out_ifc: out_ifc.up().commit() ns_ipdb.interfaces.lo.up().commit() in_ifc = ns_ipdb.interfaces[in_ifname] with in_ifc as v: v.ifname = ns_ifc if ipaddr: v.add_ip("%s" % ipaddr) if macaddr: v.address = macaddr v.up() if disable_ipv6: cmd1 = [ "sysctl", "-q", "-w", "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname ] subprocess.call(cmd1) 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) if cmd: self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd)) return (ns_ipdb, out_ifc, in_ifc)
if args.debug: fname = f'{nsname}-ndb.db' print(f'dump: netns topology database {fname}') netns.schema.backup(fname) netns.close() # set up the emulation QDisc nsp = NSPopen( nsname, [ 'tc', 'qdisc', 'add', 'dev', veth, 'root', 'netem', 'delay', f'{args.delay}ms', f'{int(args.delay)/2}ms', 'loss', f'{args.loss}%', '25%', ], stdout=subprocess.PIPE, ) nsp.communicate() nsp.wait() nsp.release() if args.verbose: print(f'netem: add {nsname}/{veth}, ' f'{args.delay}, {args.loss}')
def start(self): # each entry is tuple of ns_ipdb, out_ifc, in_ifc host_info = [] for i in range(0, num_hosts): print("Launching host %i of %i" % (i + 1, num_hosts)) ipaddr = "172.16.1.%d/24" % (100 + i) host_info.append( self._create_ns("host%d" % i, ipaddr=ipaddr, disable_ipv6=True)) if multicast: cmd = ["python", "tunnel.py", str(i)] else: cmd = [ "python", "tunnel_mesh.py", str(num_hosts), str(i), str(dhcp) ] p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE) self.processes.append(p) with self.ipdb.create(ifname="br-fabric", kind="bridge") as br: for host in host_info: br.add_port(host[1]) br.up() # get host0 bridge ip's host0_br_ips = [] if dhcp == 1: print("Waiting for host0 br1/br2 ip addresses available") for j in range(0, 2): retry = -1 ip_out = None while retry < 0: check = Popen([ "ip", "netns", "exec", "host0", "ip", "addr", "show", "br%d" % j ], stdout=PIPE, stderr=PIPE) ip_out = check.stdout.read() checkip = "99.1.%d" % j retry = ip_out.find(checkip) p = re.compile(("99.1.%d." % j) + "\d+") host0_br_ips.append(p.findall(ip_out)[0]) else: host0_br_ips.append("99.1.0.1") host0_br_ips.append("99.1.1.1") # traffic test print("Validating connectivity") for i in range(1, num_hosts): for j in range(0, 2): retry = -1 while retry < 0: check = Popen([ "ip", "netns", "exec", "host%d" % i, "ip", "addr", "show", "br%d" % j ], stdout=PIPE, stderr=PIPE) out = check.stdout.read() checkip = "99.1.%d" % j retry = out.find(checkip) print("VNI%d between host0 and host%d" % (10000 + j, i)) call([ "ip", "netns", "exec", "host%d" % i, "ping", host0_br_ips[j], "-c", "3", "-i", "0.2", "-q" ])
def _ns_add_ifc(self, name, ns_ifc, ifc_base_name=None, 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: try: nl = NetNS(name) self.namespaces.append(nl) except KeyboardInterrupt: # remove the namespace if it has been created pyroute2.netns.remove(name) raise ns_ipdb = IPDB(nl) self.ipdbs[nl.netns] = ns_ipdb if disable_ipv6: cmd1 = [ "sysctl", "-q", "-w", "net.ipv6.conf.default.disable_ipv6=1" ] nsp = NSPopen(ns_ipdb.nl.netns, cmd1) nsp.wait() nsp.release() try: ns_ipdb.interfaces.lo.up().commit() except pyroute2.ipdb.exceptions.CommitException: print( "Warning, commit for lo failed, operstate may be unknown") if in_ifc: in_ifname = in_ifc.ifname with in_ifc as v: # move half of veth into namespace v.net_ns_fd = ns_ipdb.nl.netns else: # delete the potentially leaf-over veth interfaces ipr = IPRoute() for i in ipr.link_lookup(ifname='%sa' % ifc_base_name): ipr.link("del", index=i) ipr.close() try: 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: v.net_ns_fd = ns_ipdb.nl.netns except KeyboardInterrupt: # explicitly remove the interface out_ifname = "%sa" % ifc_base_name if out_ifname in self.ipdb.interfaces: self.ipdb.interfaces[out_ifname].remove().commit() raise if out_ifc: out_ifc.up().commit() try: # this is a workaround for fc31 and possible other disto's. # when interface 'lo' is already up, do another 'up().commit()' # has issues in fc31. # the workaround may become permanent if we upgrade pyroute2 # in all machines. if 'state' in ns_ipdb.interfaces.lo.keys(): if ns_ipdb.interfaces.lo['state'] != 'up': ns_ipdb.interfaces.lo.up().commit() else: ns_ipdb.interfaces.lo.up().commit() except pyroute2.ipdb.exceptions.CommitException: print("Warning, commit for lo failed, operstate may be unknown") ns_ipdb.initdb() in_ifc = ns_ipdb.interfaces[in_ifname] with in_ifc as v: v.ifname = ns_ifc if ipaddr: v.add_ip("%s" % ipaddr) if macaddr: v.address = macaddr v.up() if disable_ipv6: cmd1 = [ "sysctl", "-q", "-w", "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname ] subprocess.call(cmd1) 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) if cmd: self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd)) return (ns_ipdb, out_ifc, in_ifc)
def execCmd(self, cmd): cmdList = cmd.split() nsp = NSPopen(self.nSname, cmdList, stdout=subprocess.PIPE) nsp.wait() nsp.release()
def createService(data): print data name = data['name'] svcId = data['Id'] svcIdString = str(data['Id']) ip = data['dhcpip'] network = data['subnet'] customer = data['customer'] routetarget = data['routetarget'] terminal = data['terminal'] vr = data['virtualrouter'] if 'move' in data: move = data['move'] oldvr = data['oldvr'] oldId = data['oldId'] else: move = False if 'add' in data: add = data['add'] else: add = False print name if_svc_name = name + '_' + svcIdString if_svc_peer_name = name + '_' + svcIdString + '_v' ip_ns = IPDB(nl=NetNS(name + '_' + svcIdString)) ip_host = IPDB() ip_host.create(ifname=if_svc_name, kind='veth', peer=if_svc_peer_name).commit() subprocess.call(["ovs-vsctl", "add-port", "br0", if_svc_name]) subprocess.call(["ovs-vsctl", "set", "port", if_svc_name, "tag=" + str(svcId)]) netmask = network.split('/')[1] ip = ip + '/' + netmask createDhcpConfig(name, network, vr, customer, svcIdString) with ip_host.interfaces[if_svc_name] as veth: veth.up() with ip_host.interfaces[if_svc_peer_name] as veth: veth.net_ns_fd = name + '_' + svcIdString with ip_ns.interfaces[if_svc_peer_name] as veth: veth.address = 'de:ad:be:ef:ba:be' veth.add_ip(ip) veth.up() ip_host.release() ip_ns.release() nsp = NSPopen(name + '_' + svcIdString, ['dnsmasq', '-C', '/etc/dnsmasq.d/' + name + '.conf'], stdout=subprocess.PIPE) nsp.wait() nsp.release() if not move or add: try: vn = createVirtualNetwork(customer, name, network, routetarget) except: print 'failed to create VN' phInt = getPhysicalInterface(vr, serviceInterface) lif = createLogicalInterface(phInt, name + '_' + svcIdString, str(svcId)) if move: oldlif = getLogicalInterface(oldvr, name + '_' + str(oldId)) if oldlif.get_virtual_machine_interface_refs(): for vmInt in oldlif.get_virtual_machine_interface_refs(): vmIntObj = vnc_client.virtual_machine_interface_read(id = vmInt['uuid']) ''' if vmIntObj.get_instance_ip_back_refs(): for instIp in vmIntObj.get_instance_ip_back_refs(): instIpObj = vnc_client.instance_ip_read(id = instIp['uuid']) epIp = instIpObj.get_instance_ip_address() epMac = vmIntObj.get_virtual_machine_interface_mac_addresses().get_mac_address()[0] vn = getVirtualNetwork(customer, name) vmInterface = createVirtualMachineInterface(customer, name, epMac) createInstanceIp(epIp, vmInterface, vn) lif.add_virtual_machine_interface(vmInterface) ''' oldlif.del_virtual_machine_interface(vmIntObj) lif.add_virtual_machine_interface(vmIntObj) vnc_client.logical_interface_update(oldlif) vnc_client.logical_interface_update(lif) ''' if os.path.isfile('/mnt/' + name + '.lease'): f = open('/mnt/' + name + '.lease', 'r') leases = f.readlines() f.close() for lease in leases: epMac = lease.split(' ')[1] epIp = lease.split(' ')[2] vn = getVirtualNetwork(customer, name) vmInterface = createVirtualMachineInterface(customer, name, epMac) createInstanceIp(epIp, vmInterface, vn) lif.add_virtual_machine_interface(vmInterface) vnc_client.logical_interface_update(lif) ''' return json.dumps({ 'status' : 'created service'})
def start(self): # Ingress = attached to tc ingress class on bridge # Egress = attached to tc engress class on namespace (outside) interface # Loading bpf functions/maps. brb_code = BPF(src_file="brb_topology_with_patch_pannel.c") pvm_fn = brb_code.load_func("pvm_function_p2v", BPF.SCHED_CLS) patchpanel_fn = brb_code.load_func("patch_panel_function", BPF.SCHED_CLS) broadcaster_fn = brb_code.load_func("broadcaster", BPF.SCHED_CLS) br1_fn = brb_code.load_func("br1_function", BPF.SCHED_CLS) print("loading router code") rt_fn = brb_code.load_func("router_function", BPF.SCHED_CLS) br2_fn = brb_code.load_func("br2_function", BPF.SCHED_CLS) vnf_prog = brb_code.get_table("vnf_prog") pvm_ifc2vi = brb_code.get_table("pvm_ifc2vi") forward_vi = brb_code.get_table("forwarder_vi") mac2host_br1 = brb_code.get_table("mac2host_br1") conf_br1 = brb_code.get_table("conf_br1") mac2host_br2 = brb_code.get_table("mac2host_br2") conf_br2 = brb_code.get_table("conf_br2") router_host = brb_code.get_table("router_host") #arp_table = brb_code.get_table("arp_table") vnf_prog[c_int(0)] = c_int(patchpanel_fn.fd) vnf_prog[c_int(1)] = c_int(pvm_fn.fd) vnf_prog[c_int(2)] = c_int(br1_fn.fd) vnf_prog[c_int(3)] = c_int(rt_fn.fd) vnf_prog[c_int(4)] = c_int(br2_fn.fd) #Need to add pem into this list. # Setup namespace and their interfaces for demostration of br1. host_info_br1 = [] for i in range(0, num_hosts): print("Launching host %i of %i in br1" % (i + 1, num_hosts)) ipaddr = "172.16.1.%d/24" % (100 + i) host_info_br1.append(self._create_ns("host%d" % i, ipaddr=ipaddr, disable_ipv6=True)) # Setup namespace and their interfaces for demostration of br2. host_info_br2 = [] for i in range(0, num_hosts): print("Launching host %i of %i in br2" % (i + 1, num_hosts)) ipaddr = "192.168.1.%d/24" % (100 + i) host_info_br2.append(self._create_ns("host%d" % (i+4), ipaddr=ipaddr, disable_ipv6=True)) # creating broadcaster, to help broadcast the unknown packets from bridge print("creating broadcaster interface") broadcaster = ipdb.create(ifname="bc", kind="dummy").up().commit() ipr.tc("add", "ingress", broadcaster.index, "ffff:") ipr.tc("add-filter", "bpf", broadcaster.index, ":1", fd=broadcaster_fn.fd, name=broadcaster_fn.name, parent="ffff:", action="drop", classid=1) print("adding it into bridges") conf_br1[c_uint(0)] = conf_br1.Leaf(c_uint(broadcaster.index)) conf_br2[c_uint(0)] = conf_br2.Leaf(c_uint(broadcaster.index)) print("attaching router between the bridges br1 and br2") conf_br1[c_uint(1)] = conf_br1.Leaf(c_uint(2000)) conf_br2[c_uint(1)] = conf_br2.Leaf(c_uint(4000)) forward_vi[c_int(2000)] = forward_vi.Leaf(1, c_uint(5000), c_uint(3) , 0) forward_vi[c_int(5000)] = forward_vi.Leaf(1, c_uint(2000), c_uint(2) , 0) forward_vi[c_int(4000)] = forward_vi.Leaf(1, c_uint(5001), c_uint(3) , 0) forward_vi[c_int(5001)] = forward_vi.Leaf(1, c_uint(4000), c_uint(4) , 0) #now tell router about it's interfaces router_host[c_int(5000)] = router_host.Leaf(self.ip2bin("172.16.1.1"), self.mac2bin("0d:b5:2f:b4:0b:1f"),0,0,0) router_host[c_int(5001)] = router_host.Leaf(self.ip2bin("192.168.1.1"), self.mac2bin("64:65:9c:b4:85:2d"),0,0,0) print("creating virutal topology for br1") # For each namespace that want to connect to the ebpf bridge index = 1 for host in host_info_br1: ipr.tc("add", "ingress", host[1].index, "ffff:") ipr.tc("add-filter", "bpf", host[1].index, ":1", fd=pvm_fn.fd, name=pvm_fn.name, parent="ffff:", action="drop", classid=1) # Passing namespace interface info to dataplane module. pvm_ifc2vi[c_uint(host[1].index)] = c_uint(index+1000) forward_vi[c_int(index+1000)] = forward_vi.Leaf(1, c_uint(index+2000), c_uint(2) , 0) forward_vi[c_int(index+2000)] = forward_vi.Leaf(0, c_uint(host[1].index), 0 , 0) conf_br1[c_uint(index+1)]= conf_br1.Leaf(c_uint(index+2000)) cmd1 = ["route", "add", "default", "gw","172.16.1.1"] nsp = NSPopen(host[0].nl.netns, cmd1) nsp.wait(); nsp.release() cmd1 = ["arping", "-c", "1", "172.16.1.1","-q"] nsp = NSPopen(host[0].nl.netns, cmd1) nsp.wait(); nsp.release() index = index+1 print("creating virtual topology for br2") # For each namespace that want to connect to the ebpf bridge index = 1 for host in host_info_br2: ipr.tc("add", "ingress", host[1].index, "ffff:") ipr.tc("add-filter", "bpf", host[1].index, ":1", fd=pvm_fn.fd, name=pvm_fn.name, parent="ffff:", action="drop", classid=1) # Passing namespace interface info to dataplane module. pvm_ifc2vi[c_uint(host[1].index)] = c_uint(index+3000) forward_vi[c_int(index+3000)] = forward_vi.Leaf(1, c_uint(index+4000), c_uint(4) , 0) forward_vi[c_int(index+4000)] = forward_vi.Leaf(0, c_uint(host[1].index), 0 , 0) conf_br2[c_uint(index+1)]= conf_br2.Leaf(c_uint(index+4000)) index = index+1 cmd1 = ["route", "add", "default", "gw","192.168.1.1"] nsp = NSPopen(host[0].nl.netns, cmd1) nsp.wait(); nsp.release() cmd1 = ["arping", "-c", "1", "192.168.1.1","-q"] nsp = NSPopen(host[0].nl.netns, cmd1) nsp.wait(); nsp.release() index = index+1