Пример #1
0
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')
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)