class _TestIPDBRaces(object): def setup(self): self.ip = IPDB() def teardown(self): self.ip.release() def test_initdb(self): tnum = len(threading.enumerate()) for _ in range(RESPAWNS): len(self.ip.interfaces.keys()) len(self.ip.routes.keys()) len(self.ip.rules.keys()) self.ip.initdb() assert len(threading.enumerate()) <= tnum def _ports_mtu_race(self, kind): port1 = (self.ip .create(ifname=uifname(), kind='dummy', mtu=1280) .commit()) port2 = (self.ip .create(ifname=uifname(), kind='dummy') .commit()) master = (self.ip .create(ifname=uifname(), kind=kind) .commit()) try: master.add_port(port1).commit() master.add_port(port2).commit() except: raise finally: port1.remove().commit() port2.remove().commit() master.remove().commit() def test_bridge_mtu(self): require_user('root') for _ in range(300): self._ports_mtu_race('bridge')
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() 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 _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("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() ns_ipdb.interfaces.lo.up().commit() 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 _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)