Esempio n. 1
0
 def initContainerNetwork(self, network=None):
     if not network:
         try:
             network = Network(None)
             network.name = 'cygnet_internal'
             network.address = self['internal_ip']
             if not self.ovs_client.bridgeExists(network.name):
                 self.ovs_client.addBridge(network.name)
                 self.ovs_client.setBridgeProperty(network.name,
                                                   'stp_enable',
                                                   True)
         except KeyError as e:
             print("OpenvSwitch: CYGNET_INTERNAL_IP \
                     environment variable not found")
             raise e
     else:
         network.name = "cygnet_" + network.id[:8]
         if not self.ovs_client.bridgeExists(network.name):
             self.ovs_client.addBridge(network.name)
             self.ovs_client.setBridgeProperty(network.name,
                                               'stp_enable',
                                               True)
     ip = IPDB()
     ifaces = ip.interfaces
     ifaces[network.name].begin()
     ifaces[network.name].add_ip(network.address, network.mask)
     ifaces[network.name].up()
     ifaces[network.name].commit()
     ip.release()
     self.interfaces.append(network)
     return network
Esempio n. 2
0
    def test_create_gre(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        with self.ip.create(kind='dummy', ifname=ifL) as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        self.ip.create(kind='gre',
                       ifname=ifV,
                       gre_local='172.16.0.1',
                       gre_remote='172.16.0.2',
                       gre_ttl=16).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].gre_local == '172.16.0.1'
            assert ifdb[ifV].gre_remote == '172.16.0.2'
            assert ifdb[ifV].gre_ttl == 16
        except Exception:
            raise
        finally:
            ip2.release()
Esempio n. 3
0
    def test_create_vxlan(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind='dummy',
                       ifname=ifL).commit()
        self.ip.create(kind='vxlan',
                       ifname=ifV,
                       vxlan_link=ifdb[ifL],
                       vxlan_id=101,
                       vxlan_group='239.1.1.1').commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces

        try:
            assert ifdb[ifV].vxlan_link == ifdb[ifL].index
            assert ifdb[ifV].vxlan_group == '239.1.1.1'
            assert ifdb[ifV].vxlan_id == 101
        except Exception:
            raise
        finally:
            ip2.release()
Esempio n. 4
0
    def __ovs_setup(self):
        if not self.ovs_client.bridgeExists('cygnet0'):
            self.ovs_client.addBridge('cygnet0')
            self.ovs_client.addPort('cygnet0', self.external_iface)
        elif not self.ovs_client.portExists(self.external_iface):
            self.ovs_client.addPort('cygnet0', self.external_iface)
        ip = IPDB()
        ifaces = ip.interfaces
        ifaces.cygnet0.begin()
        addrs= ip.interfaces[self.external_iface].ipaddr.raw
        addr = None
        for address, attrs in addrs.items():
            if __getIPv4Addr__([address]) == None:
                continue
            addr = address
        ifaces.cygnet0.add_ip(addr[0], int(addr[1]))
        ifaces.cygnet0.up()
        ifaces.cygnet0.commit()
        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].down()
        ifaces[self.external_iface].commit()

        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].up()
        ifaces[self.external_iface].commit()

        ip.release()
Esempio n. 5
0
    def test_commit_barrier(self):
        require_user("root")

        ifname = uifname()

        # barrier 0
        try:
            ip = IPDB()
            config.commit_barrier = 0
            ts1 = time.time()
            ip.create(ifname=ifname, kind="dummy").commit()
            ts2 = time.time()
            assert 0 < (ts2 - ts1) < 1
        except:
            raise
        finally:
            config.commit_barrier = 0.2
            ip.interfaces[ifname].remove().commit()
            ip.release()

        # barrier 5
        try:
            ip = IPDB()
            config.commit_barrier = 5
            ts1 = time.time()
            ip.create(ifname=ifname, kind="dummy").commit()
            ts2 = time.time()
            assert 5 < (ts2 - ts1) < 6
        except:
            raise
        finally:
            config.commit_barrier = 0.2
            ip.interfaces[ifname].remove().commit()
            ip.release()
Esempio n. 6
0
    def test_create_gretap(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        with self.ip.create(kind='dummy', ifname=ifL) as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        self.ip.create(kind='gretap',
                       ifname=ifV,
                       gre_local='172.16.0.1',
                       gre_ikey=1,
                       gre_okey=2,
                       gre_iflags=0x0020,
                       gre_oflags=0x0020,
                       gre_collect_metadata=True,
                       gre_ttl=16).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].gre_local == '172.16.0.1'
            assert ifdb[ifV].gre_ikey == 1
            assert ifdb[ifV].gre_okey == 2
            assert ifdb[ifV].gre_iflags == 0x0020
            assert ifdb[ifV].gre_oflags == 0x0020
            if kernel_version_ge(4, 3):
                assert ifdb[ifV].gre_collect_metadata
            assert ifdb[ifV].gre_ttl == 16
        except Exception:
            raise
        finally:
            ip2.release()
Esempio n. 7
0
 def test_dummy0_unloaded(object):
     require_user('root')
     # firstly unload the dummy module
     with open(os.devnull, 'w') as fnull:
         subprocess.call(['modprobe', '-r', 'dummy'],
                         stdout=fnull,
                         stderr=fnull)
     ip = None
     try:
         # now create the dummy0 -- it will cause the
         # module autoload
         ip = IPDB()
         # that must succeed
         ip.create(ifname='dummy0', kind='dummy').commit()
         # just in case: the second attempt must fail on the
         # create() stage, even w/o any commit()
         try:
             ip.create(ifname='dummy0', kind='dummy')
         except CreateException:
             pass
     except Exception:
         raise
     finally:
         if ip is not None:
             ip.release()
Esempio n. 8
0
    def test_move_ns_pid(self):
        foo = str(uuid4())
        bar = str(uuid4())
        ifA = uifname()
        netnsmod.create(foo)
        netnsmod.create(bar)

        ns_foo = IPDB(nl=NetNS(foo))
        ns_bar = IPDB(nl=NetNS(bar))

        try:
            ns_foo.create(ifname=ifA, kind='dummy').commit()
            with ns_foo.interfaces[ifA] as iface:
                iface.net_ns_pid = ns_bar.nl.server.pid

            assert ifA in ns_bar.interfaces.keys()
            assert ifA not in ns_foo.interfaces.keys()

            with ns_bar.interfaces[ifA] as iface:
                iface.net_ns_pid = ns_foo.nl.server.pid

            assert ifA not in ns_bar.interfaces.keys()
            assert ifA in ns_foo.interfaces.keys()

        finally:
            ns_foo.release()
            ns_bar.release()
            netnsmod.remove(foo)
            netnsmod.remove(bar)
Esempio n. 9
0
 def test_fail_released(self):
     ip = IPDB()
     ip.release()
     try:
         ip.interfaces.lo.up()
     except RuntimeError:
         pass
Esempio n. 10
0
class TestDirect(object):

    def setup(self):
        self.ifname = uifname()
        self.ip = IPDB(mode='direct')
        try:
            self.ip.create(ifname=self.ifname, kind='dummy')
        except:
            pass

    def teardown(self):
        try:
            self.ip.interfaces[self.ifname].remove()
        except KeyError:
            pass
        self.ip.release()

    def test_context_fail(self):
        require_user('root')
        try:
            with self.ip.interfaces[self.ifname] as i:
                i.down()
        except TypeError:
            pass

    def test_create(self):
        require_user('root')
        ifname = uifname()
        assert ifname not in self.ip.interfaces
        self.ip.create(ifname=ifname, kind='dummy')
        assert ifname in self.ip.interfaces
        self.ip.interfaces[ifname].remove()
        assert ifname not in self.ip.interfaces

    def test_updown(self):
        require_user('root')

        assert not (self.ip.interfaces[self.ifname].flags & 1)
        self.ip.interfaces[self.ifname].up()

        assert self.ip.interfaces[self.ifname].flags & 1
        self.ip.interfaces[self.ifname].down()

        assert not (self.ip.interfaces[self.ifname].flags & 1)

    def test_exceptions_last(self):
        try:
            self.ip.interfaces.lo.last()
        except TypeError:
            pass

    def test_exception_review(self):
        try:
            self.ip.interfaces.lo.review()
        except TypeError:
            pass
Esempio n. 11
0
 def test_ipdb(self):
     require_user('root')
     ip = IPDB()
     try:
         assert ip._nl_async is False
         assert len(ip.interfaces.keys()) > 1
     except:
         raise
     finally:
         ip.release()
Esempio n. 12
0
	def destroyInterface(self):
		ipdb = IPDB()

		with ipdb.interfaces[self.bridge_iface] as i:
			i.del_port(ipdb.interfaces[self.veth0])

		with ipdb.interfaces[self.veth0] as i:
			i.remove()

		ipdb.release()
Esempio n. 13
0
def deleteService(name, terminalName):
    if_svc_name = name
    if_terminal_name = name + '_' + terminalName
    ip_host = IPDB()
    with ip_host.interfaces[if_terminal_name] as veth:
        veth.remove()
    ip_host.release()
    subprocess.call(["ovs-vsctl", "del-port", "vs-" + name, if_svc_name])
    subprocess.call(["ovs-vsctl", "del-port", "br0", if_terminal_name])
    subprocess.call(["ovs-vsctl", "del-br", "vs-" + name])
    return json.dumps({ 'status' : 'deleted service'})
Esempio n. 14
0
class _TestDhcpClient(object):

    def setup(self):
        require_user('root')
        require_executable('busybox')
        self.ip = IPDB()
        # create internal network
        self.if1 = uifname()
        self.if2 = uifname()
        self.ip.create(kind='veth', ifname=self.if1, peer=self.if2).commit()
        # set interfaces up
        with self.ip.interfaces[self.if1] as i:
            i.add_ip('172.16.101.1/24')
            i.up()

        with self.ip.interfaces[self.if2] as i:
            i.up()
        # prepare configuration for udhcpd
        with open('udhcpd.conf.in', 'r') as conf_in:
            with open('udhcpd.conf', 'w') as conf_out:
                conf_out.write('interface %s\n' % self.if1)
                conf_out.write(conf_in.read())
        # run busybox dhcp server on $if1
        with open(os.devnull, 'w') as fnull:
            subprocess.check_call(['busybox', 'udhcpd', 'udhcpd.conf'],
                                  stdout=fnull,
                                  stderr=fnull)

    def teardown(self):
        # read pid from file and kill the server
        with open('udhcpd.pid', 'r') as pid_file:
            pid = int(pid_file.read())
            os.kill(pid, 15)
        # teardown interfaces (enough to remove only master)
        self.ip.interfaces[self.if1].remove().commit()
        # release IPDB
        self.ip.release()
        # remove configuration file
        os.unlink('udhcpd.conf')
        # collect garbage
        gc.collect()

    def test_defaults(self):
        msg = dhclient.action(self.if2)
        assert msg['yiaddr'].startswith('172.16.101.')
        assert msg['op'] == BOOTREPLY
        assert msg['options']['message_type'] == DHCPACK
        assert msg['options']['router'] == ['172.16.101.1']
        assert msg['options']['server_id'] == '172.16.101.1'
        assert msg['options']['subnet_mask'] == '255.255.255.0'
        assert set(msg['options']['name_server']) ==\
            set(('172.16.101.1', '172.16.101.2'))
Esempio n. 15
0
 def initalize(self):
     ip = IPDB()
     try:
         # Check if public interface is up
         self.addr = __getIPv4Addr__(list(ip.interfaces.br1.ipaddr))
         self.addr = self.addr[0], str(self.addr[1])
         self.interfaces.append(('br1', self.addr))
     except Exception as e:
         print(e)
     finally:
         ip.release()
     self.range_buckets[int(self.addr[0].split(".")[-1])] = 1
     return self.addr
Esempio n. 16
0
def createService(name, terminalName, svcId):
    subprocess.call(["ovs-vsctl", "add-br", "vs-" + name])
    if_svc_name = name
    if_terminal_name = name + '_' + terminalName
    ip_host = IPDB()
    ip_host.create(ifname=if_svc_name, kind='veth', peer=if_terminal_name).commit()
    with ip_host.interfaces[if_svc_name] as veth:
        veth.up()
    with ip_host.interfaces[if_terminal_name] as veth:
        veth.up()
    ip_host.release()
    subprocess.call(["ovs-vsctl", "add-port", "vs-" + name, if_svc_name])
    subprocess.call(["ovs-vsctl", "add-port", "br0", if_terminal_name])
    subprocess.call(["ovs-vsctl", "set", "port", if_terminal_name, "tag=" + str(svcId)])
    return json.dumps({ 'status' : 'created service'})
Esempio n. 17
0
	def createInterface(self):
		ipdb = IPDB()
		ipdb.create(ifname=self.veth0, kind='veth', peer=self.veth1).commit()

		with ipdb.interfaces[self.veth0] as i:
			i.up()

		with ipdb.interfaces[self.veth1] as i:
			i.up()
			i.net_ns_fd = self.nsname

		with ipdb.interfaces[self.bridge_iface] as i:
			i.add_port(ipdb.interfaces[self.veth0])

		ipdb.release()
Esempio n. 18
0
 def initalize(self):
     # check if our setup already exists
     self.__ovs_setup()
     ip = IPDB()
     try:
         # Check if public interface is up
         self.addr = __getIPv4Addr__(list(ip.interfaces.cygnet0.ipaddr))
         self.addr = self.addr[0], str(self.addr[1])
         #self.interfaces.append(('cygnet0', self.addr))
     except Exception as e:
         raise e
     finally:
         ip.release()
     self.range_buckets[int(self.addr[0].split(".")[-1])] = 1
     return self.addr
Esempio n. 19
0
def createEndpoint(name, svcName, endpointtype):
    if endpointtype == 'ns':
        ip_host = IPDB()
        ip_host.create(ifname=name, kind='veth', peer=name + '_' + svcName).commit()
        ip_ns = IPDB(nl=NetNS(name))
        with ip_host.interfaces[name] as veth:
            veth.net_ns_fd = name
            veth.up()
        with ip_host.interfaces[name + '_' + svcName] as veth:
            veth.up()
        subprocess.call(["ovs-vsctl", "add-port", "vs-" + svcName, name + '_' + svcName])
        ip_host.release()
        ip_ns.release()
        nsp = NSPopen(name, ['dhclient', '-lf', '/tmp/' + name + '.lease', name], stdout=subprocess.PIPE)
        nsp.wait()
        nsp.release()
    if endpointtype == 'lxc':
        subprocess.call(['/usr/bin/lxc-clone','template',name])
        lxcUpOvsScript = '#!/bin/bash\n'
        lxcUpOvsScript += 'BRIDGE="vs-'+ svcName + '"\n'
        lxcUpOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        lxcUpOvsScript += 'ovs-vsctl add-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsup.sh','w+')
        f.write(lxcUpOvsScript)
        f.close()
        lxcDownOvsScript = '#!/bin/bash\n'
        lxcDownOvsScript += 'BRIDGE="vs-'+ svcName + '"\n'
        lxcDownOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsdown.sh','w+')
        f.write(lxcDownOvsScript)
        f.close()
        os.chmod('/var/lib/lxc/' + name + '/ovsup.sh',stat.S_IRWXU)
        os.chmod('/var/lib/lxc/' + name + '/ovsdown.sh',stat.S_IRWXU)
        lxcConfig = 'lxc.include = /usr/share/lxc/config/ubuntu.common.conf\n'
        lxcConfig += 'lxc.arch = x86_64\n' 
        lxcConfig += 'lxc.rootfs = /var/lib/lxc/' + name + '/rootfs\n'
        lxcConfig += 'lxc.utsname = ' + name + '\n'
        lxcConfig += 'lxc.network.type = veth\n'
        lxcConfig += 'lxc.network.veth.pair = ' + name + '\n'
        lxcConfig += 'lxc.network.script.up = /var/lib/lxc/' + name + '/ovsup.sh\n'
        lxcConfig += 'lxc.network.script.down = /var/lib/lxc/' + name + '/ovsdown.sh\n'
        lxcConfig += 'lxc.network.flags = up\n'
        f = open('/var/lib/lxc/' + name + '/config','w+')
        f.write(lxcConfig)
        f.close()
        subprocess.call(['/usr/bin/lxc-start','-d','-n',name])
        pass
    return json.dumps({ 'status' : 'created endpoint'})
Esempio n. 20
0
    def test_create(self):
        require_user('root')

        nsid = str(uuid4())
        ipdb_main = IPDB()
        ipdb_test = IPDB(nl=NetNS(nsid))
        if1 = uifname()
        if2 = uifname()

        # create VETH pair
        ipdb_main.create(ifname=if1, kind='veth', peer=if2).commit()

        # move the peer to netns
        with ipdb_main.interfaces[if2] as veth:
            veth.net_ns_fd = nsid

        # assign addresses
        with ipdb_main.interfaces[if1] as veth:
            veth.add_ip('172.16.200.1/24')
            veth.up()

        with ipdb_test.interfaces[if2] as veth:
            veth.add_ip('172.16.200.2/24')
            veth.up()

        # ping peer
        try:
            with open('/dev/null', 'w') as fnull:
                subprocess.check_call(['ping', '-c', '1', '172.16.200.2'],
                                      stdout=fnull, stderr=fnull)
            ret_ping = True
        except Exception:
            ret_ping = False

        # check ARP
        time.sleep(0.5)
        ret_arp = '172.16.200.1' in list(ipdb_test.interfaces[if2].neighbours)
        # ret_arp = list(ipdb_test.interfaces.v0p1.neighbours)

        # cleanup
        ipdb_main.interfaces[if1].remove().commit()
        ipdb_main.release()
        ipdb_test.release()
        netnsmod.remove(nsid)

        assert ret_ping
        assert ret_arp
        assert nsid not in netnsmod.listnetns()
Esempio n. 21
0
 def test_dummy0_loaded(object):
     require_user("root")
     # assert the module is loaded
     ifA = uifname()
     ip = IPDB()
     ip.create(ifname=ifA, kind="dummy").commit()
     try:
         # try to create and fail in create()
         ip.create(ifname="dummy0", kind="dummy")
     except CreateException:
         pass
     except Exception:
         raise
     finally:
         ip.interfaces[ifA].remove().commit()
         ip.release()
Esempio n. 22
0
class TestPopen(TestBasic):

    def setup(self):
        self.ipdb = IPDB()
        self.io = io.BytesIO()
        self.con = subprocess.Popen(['python', '%s/bin/ipdb' % TMPDIR],
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)

    def teardown(self):
        self.ipdb.release()

    def feed(self, script):
        out, err = self.con.communicate(script.encode('ascii'))
        self.io.write(out)
        self.con.wait()
Esempio n. 23
0
class TestDhcpClient(object):
    def setup(self):
        require_user("root")
        require_executable("busybox")
        self.ip = IPDB()
        # create internal network
        self.if1 = "dh1-%i" % os.getpid()
        self.if2 = "dh2-%i" % os.getpid()
        self.ip.create(kind="veth", ifname=self.if1, peer=self.if2).commit()
        # set interfaces up
        with self.ip.interfaces[self.if1] as i:
            i.add_ip("172.16.101.1/24")
            i.up()

        with self.ip.interfaces[self.if2] as i:
            i.up()
        # prepare configuration for udhcpd
        with open("udhcpd.conf.in", "r") as conf_in:
            with open("udhcpd.conf", "w") as conf_out:
                conf_out.write("interface %s\n" % self.if1)
                conf_out.write(conf_in.read())
        # run busybox dhcp server on $if1
        with open(os.devnull, "w") as fnull:
            subprocess.check_call(["busybox", "udhcpd", "udhcpd.conf"], stdout=fnull, stderr=fnull)

    def teardown(self):
        # read pid from file and kill the server
        with open("udhcpd.pid", "r") as pid_file:
            pid = int(pid_file.read())
            os.kill(pid, 15)
        # teardown interfaces (enough to remove only master)
        self.ip.interfaces[self.if1].remove().commit()
        # release IPDB
        self.ip.release()
        # remove configuration file
        os.unlink("udhcpd.conf")

    def test_defaults(self):
        msg = dhclient.action(self.if2)
        assert msg["yiaddr"].startswith("172.16.101.")
        assert msg["op"] == BOOTREPLY
        assert msg["options"]["message_type"] == DHCPACK
        assert msg["options"]["router"] == ["172.16.101.1"]
        assert msg["options"]["server_id"] == "172.16.101.1"
        assert msg["options"]["subnet_mask"] == "255.255.255.0"
        assert set(msg["options"]["name_server"]) == set(("172.16.101.1", "172.16.101.2"))
Esempio n. 24
0
    def _create_macvx_mode(self, kind, mode):
        require_user("root")
        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind="dummy", ifname=ifL).commit()
        self.ip.create(**{"kind": kind, "link": ifdb[ifL], "ifname": ifV, "%s_mode" % kind: mode}).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].link == ifdb[ifL].index
            assert ifdb[ifV]["%s_mode" % kind] == mode
        except Exception:
            raise
        finally:
            ip2.release()
Esempio n. 25
0
    def test_rename_plus_ipv6(self):
        require_user('root')

        mtu = 1280  # mtu must be >= 1280 if you plan to use IPv6
        txqlen = 2000
        nsid = str(uuid4())
        ipdb_main = IPDB()
        ipdb_test = IPDB(nl=NetNS(nsid))
        if1 = uifname()
        if2 = uifname()
        if3 = uifname()

        # create
        ipdb_main.create(kind='veth',
                         ifname=if1,
                         peer=if2,
                         mtu=mtu,
                         txqlen=txqlen).commit()

        # move
        with ipdb_main.interfaces[if2] as veth:
            veth.net_ns_fd = nsid

        # set it up
        with ipdb_test.interfaces[if2] as veth:
            veth.add_ip('fdb3:84e5:4ff4:55e4::1/64')
            veth.add_ip('fdff:ffff:ffff:ffc0::1/64')
            veth.mtu = mtu
            veth.txqlen = txqlen
            veth.up()
            veth.ifname = if3

        veth = ipdb_test.interfaces.get(if3, None)
        ipdb_main.release()
        ipdb_test.release()
        netnsmod.remove(nsid)

        # check everything
        assert ('fdb3:84e5:4ff4:55e4::1', 64) in veth.ipaddr
        assert ('fdff:ffff:ffff:ffc0::1', 64) in veth.ipaddr
        assert veth.flags & 1
        assert veth.mtu == mtu
        assert veth.txqlen == txqlen
Esempio n. 26
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')
Esempio n. 27
0
 def find_ip(iface):
     if not iface or iface == 'any':
         return ('0.0.0.0','')
     if_ip4 = None
     if_ip6 = None
     ipdb = IPDB()
     try:
         for ip in ipdb.interfaces[iface].ipaddr:
             if_ip = ipaddress.ip_address(ip[0])
             if isinstance(if_ip, ipaddress.IPv4Address):
                 if_ip4 = ip[0]
             elif isinstance(if_ip, ipaddress.IPv6Address):
                 if not if_ip.is_link_local:
                     if_ip6 = ip[0]
             if if_ip4 and if_ip6:
                 break
     except Exception as e:
         pass
     finally:
         ipdb.release()
     return (if_ip4, if_ip6)
Esempio n. 28
0
    def test_create_gre(self):
        require_user("root")

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        with self.ip.create(kind="dummy", ifname=ifL) as i:
            i.add_ip("172.16.0.1/24")
            i.up()

        self.ip.create(kind="gre", ifname=ifV, gre_local="172.16.0.1", gre_remote="172.16.0.2", gre_ttl=16).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].gre_local == "172.16.0.1"
            assert ifdb[ifV].gre_remote == "172.16.0.2"
            assert ifdb[ifV].gre_ttl == 16
        except Exception:
            raise
        finally:
            ip2.release()
Esempio n. 29
0
class TestDirect(object):

    def setup(self):
        create_link('dummyX', 'dummy')
        self.ip = IPDB(mode='direct')

    def teardown(self):
        self.ip.release()
        remove_link('dummyX')

    def test_context_fail(self):
        try:
            with self.ip.interfaces.lo as i:
                i.down()
        except TypeError:
            pass
        print("cfail done")

    def test_updown(self):
        require_user('root')

        assert not (self.ip.interfaces['dummyX'].flags & 1)
        self.ip.interfaces['dummyX'].up()

        assert self.ip.interfaces['dummyX'].flags & 1
        self.ip.interfaces['dummyX'].down()

        assert not (self.ip.interfaces['dummyX'].flags & 1)

    def test_exceptions_last(self):
        try:
            self.ip.interfaces.lo.last()
        except TypeError:
            pass

    def test_exception_review(self):
        try:
            self.ip.interfaces.lo.review()
        except TypeError:
            pass
Esempio n. 30
0
 def create(self):
     iface = self.containerName + "veth0"
     ifacePeer = self.containerName + "veth1"
     ip_main = IPDB()
     ip_sub = IPDB(nl=NetNS(self.containerName))
     ip_main.create(ifname=iface, kind="veth", peer=ifacePeer).commit()
     with ip_main.interfaces[ifacePeer] as veth:
         veth.net_ns_fd = self.containerName
     with ip_main.interfaces[iface] as veth:
         veth.up()
     ip_main.release()
     with ip_sub.interfaces[ifacePeer] as veth:
         # if not self.containerDhcp:
         if not hasattr(self, "containerDhcp"):
             veth.add_ip(self.containerIp)
         if hasattr(self, "containerMac"):
             veth.address = self.containerMac
     ip_sub.release()
     ns = NetNS(self.containerName)
     idx = ns.link_lookup(ifname=ifacePeer)[0]
     ns.link("set", index=idx, net_ns_fs=self.containerName, ifname="eth0")
     ns.link("set", index=idx, net_ns_fs=self.containerName, state="up")
     if hasattr(self, "containerGateway"):
         request = {"dst": "0.0.0.0/0", "gateway": self.containerGateway}
         ns.route("add", **IPRouteRequest(request))
     ns.close()
     subprocess.call(["ovs-vsctl", "add-port", "br0", iface])
     dockerControl = DockerControl(self.containerObject)
     if hasattr(self, "containerDhcp"):
         dhcpCmd = "dhclient eth0"
         dockerControl.runCmd(dhcpCmd)
     addressCmd = "ip address show dev eth0"
     addressInfo = dockerControl.runCmd(addressCmd)
     addressInfoList = addressInfo.splitlines()
     macAddressInfo = addressInfoList[1].split()[1]
     ipAddressInfo = addressInfoList[2].split()[1]
     ipAddressInfoDict = dict(
         {"containerName": self.containerName, "macAddress": macAddressInfo, "ipAddress": ipAddressInfo}
     )
     return json.dumps(ipAddressInfoDict)
Esempio n. 31
0
    def test_freeze_del(self):
        require_user('root')

        interface = self.ip.interfaces[self.ifd]

        # set up the interface
        with interface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.1.1/24')
            i.up()

        # check
        assert ('172.16.0.1', 24) in interface.ipaddr
        assert ('172.16.1.1', 24) in interface.ipaddr
        assert interface.flags & 1

        interface.freeze()

        # delete interface with an external routine
        remove_link(interface.ifname)

        # wait for a second
        time.sleep(1)

        # check if it is back
        ipdb = IPDB()
        try:
            ifc = ipdb.interfaces[self.ifd]
            assert ('172.16.0.1', 24) in ifc.ipaddr
            assert ('172.16.1.1', 24) in ifc.ipaddr
            assert ifc.flags & 1
        except:
            raise
        finally:
            interface.unfreeze()
            ipdb.release()
Esempio n. 32
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')
Esempio n. 33
0
class ConfigApplier(object):
    def __init__(self):
        self.ip = IPDB()

    def _setIpConfig(self, iface):
        ipv4 = iface.ipv4
        ipv6 = iface.ipv6
        if ipv4.address or ipv6.address:
            self.removeIpConfig(iface)
        if ipv4.address:
            with self.ip.interfaces[iface.name] as i:
                i.add_ip(ipv4.address + '/' + ipv4.netmask)
            if ipv4.gateway and ipv4.defaultRoute:
                self.ip.routes.add({
                    'dst': 'default',
                    'gateway': ipv4.gateway
                }).commit()
        if ipv6.address:
            with self.ip.interfaces[iface.name] as i:
                i.add_ip(ipv6.address)
            if ipv6.gateway:
                self.ip.routes.add({
                    'dst': 'default',
                    'gateway': ipv6.gateway
                }).commit()
        if ipv6.ipv6autoconf is not None:
            with open('/proc/sys/net/ipv6/conf/%s/autoconf' % iface.name,
                      'w') as ipv6_autoconf:
                ipv6_autoconf.write('1' if ipv6.ipv6autoconf else '0')

    def removeIpConfig(self, iface):
        ipwrapper.addrFlush(iface.name)

    def setIfaceMtu(self, iface, mtu):
        with self.ip.interfaces[iface] as i:
            i['mtu'] = int(mtu)

    def setBondingMtu(self, iface, mtu):
        self.setIfaceMtu(iface, mtu)

    def ifup(self, iface):
        with self.ip.interfaces[iface.name] as i:
            i.up()
        if iface.ipv4.bootproto == 'dhcp':
            dhclient.run(iface.name, 4, iface.ipv4.defaultRoute,
                         iface.duid_source, iface.blockingdhcp)
        if iface.ipv6.dhcpv6:
            dhclient.run(iface.name, 6, iface.ipv6.defaultRoute,
                         iface.duid_source, iface.blockingdhcp)

    def ifdown(self, iface):
        with self.ip.interfaces[iface.name] as i:
            i.down()
        dhclient.stop(iface.name)

    def setIfaceConfigAndUp(self, iface):
        if iface.ipv4 or iface.ipv6:
            self._setIpConfig(iface)
        if iface.mtu:
            self.setIfaceMtu(iface.name, iface.mtu)
        self.ifup(iface)

    def addBridge(self, bridge):
        self.ip.create(kind='bridge', ifname=bridge.name).commit()

    def addBridgePort(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.add_port(self.ip.interfaces[bridge.port.name])

    def removeBridge(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.remove()

    def removeBridgePort(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.del_port(self.ip.interfaces[bridge.port.name])

    def addVlan(self, vlan):
        link = self.ip.interfaces[vlan.device.name].index
        self.ip.create(kind='vlan',
                       ifname=vlan.name,
                       link=link,
                       vlan_id=vlan.tag).commit()

    def removeVlan(self, vlan):
        with self.ip.interfaces[vlan.name] as i:
            i.remove()

    def addBond(self, bond):
        if bond.name not in netinfo.bondings():
            self.ip.create(kind='bond', ifname=bond.name).commit()

    def removeBond(self, bond):
        with self.ip.interfaces[bond.name] as i:
            i.remove()

    def addBondSlave(self, bond, slave):
        self.ifdown(slave)
        with self.ip.interfaces[bond.name] as i:
            i.add_port(self.ip.interfaces[slave.name])
        self.ifup(slave)

    def removeBondSlave(self, bond, slave):
        with self.ip.interfaces[bond.name] as i:
            i.del_port(self.ip.interfaces[slave.name])

    def addBondOptions(self, bond):
        logging.debug('Add bond options %s', bond.options)
        # 'custom' is not a real bond option, it just piggybacks custom values
        options = remove_custom_bond_option(bond.options)
        for option in options.split():
            key, value = option.split('=')
            with open(netinfo.BONDING_OPT % (bond.name, key), 'w') as f:
                f.write(value)

    def createLibvirtNetwork(self, network, bridged=True, iface=None):
        netXml = libvirt.createNetworkDef(network, bridged, iface)
        libvirt.createNetwork(netXml)

    def removeLibvirtNetwork(self, network):
        libvirt.removeNetwork(network)

    def releaseSocket(self):
        self.ip.release()
Esempio n. 34
0
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'})
Esempio n. 35
0
def main():
    ip = IPDB()
    s = set([interface.ifname for interface in ip.interfaces.values()])

    try:
        s.remove('lo')
        s.remove('metadata')
    except:
        logger.error("Metadata or lo not found!\n")

    try:
        with open('/monroe/config') as configfile:
            config = json.load(configfile)
            nodeid = config['nodeid']
    except:
        nodeid = 'could-not-get-id'
    try:
        with open('/monroe/config') as configfile:
            config = json.load(configfile)
            operator = config['operator']
    except:
        operator = 'N/A'

    subprocess.call(['mkdir', '/tmp/res/'])
    result_files = []

    for item in s:
        if item in ['op0', 'op1', 'op2']:
            logger.debug("Running on interface: " + item)
            try:
                subprocess.call(['route', 'del', 'default'])
                subprocess.call(['route', 'add', 'default', 'dev', item])
                add_dns(item)
                process = subprocess.Popen(
                    ['java', '-jar', '/opt/monroe/NetalyzrCLI.jar'],
                    stdout=subprocess.PIPE)
                result = process.communicate()[0]
                wr_str = "/tmp/res/mnr-" + nodeid + "_" + item

                try:
                    dnsproc = subprocess.Popen(['cat', '/etc/resolv.conf'],
                                               stdout=subprocess.PIPE)
                    result_dns = dnsproc.communicate()[0]
                except Exception as e:
                    result_dns = e

                with open(wr_str, 'w') as wr_file:
                    wr_file.write("ID: " + str(nodeid) + "\n")
                    wr_file.write("Interface: " + item + "\n")
                    wr_file.write("Operator: " + str(operator) + "\n")
                    wr_file.write("Resolv.conf:\n" + str(result_dns) + "\n")

                result_files.append(wr_str)
                with open(wr_str, 'a') as wr_file:
                    wr_file.write(result)
                process = subprocess.Popen([
                    'curl', 'https://stat.ripe.net/data/whats-my-ip/data.json'
                ],
                                           stdout=subprocess.PIPE)
                result = process.communicate()[0]
                with open(wr_str, 'a') as wr_file:
                    wr_file.write(result)
            except Exception as e:
                logger.error(e)

    for result_file in result_files:
        try:
            subprocess.call(['/usr/bin/mv', result_file, '/monroe/results/'])
        except:
            pass
    ip.release()
Esempio n. 36
0
class ConfigApplier(object):
    def __init__(self):
        self.ip = IPDB()

    def _setIpConfig(self, iface):
        ipConfig = iface.ipConfig
        if ipConfig.ipaddr:
            self.removeIpConfig(iface)
            with self.ip.interfaces[iface.name] as i:
                i.add_ip('%s/%s' % (ipConfig.ipaddr, ipConfig.netmask))
            if ipConfig.gateway and ipConfig.defaultRoute:
                ipwrapper.routeAdd(['default', 'via', ipConfig.gateway])

    def removeIpConfig(self, iface):
        ipwrapper.addrFlush(iface.name)

    def setIfaceMtu(self, iface, mtu):
        with self.ip.interfaces[iface] as i:
            i['mtu'] = int(mtu)

    def setBondingMtu(self, iface, mtu):
        self.setIfaceMtu(iface, mtu)

    def ifup(self, iface):
        with self.ip.interfaces[iface.name] as i:
            i.up()
        if iface.ipConfig.bootproto == 'dhcp':
            dhclient = DhcpClient(iface.name)
            dhclient.start(iface.ipConfig.async)

    def ifdown(self, iface):
        with self.ip.interfaces[iface.name] as i:
            i.down()
        dhclient = DhcpClient(iface.name)
        dhclient.shutdown()

    def setIfaceConfigAndUp(self, iface):
        if iface.ip:
            self._setIpConfig(iface)
        if iface.mtu:
            self.setIfaceMtu(iface.name, iface.mtu)
        self.ifup(iface)

    def addBridge(self, bridge):
        self.ip.create(kind='bridge', ifname=bridge.name).commit()

    def addBridgePort(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.add_port(self.ip.interfaces[bridge.port.name])

    def removeBridge(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.remove()

    def removeBridgePort(self, bridge):
        with self.ip.interfaces[bridge.name] as i:
            i.del_port(self.ip.interfaces[bridge.port.name])

    def addVlan(self, vlan):
        link = self.ip.interfaces[vlan.device.name].index
        self.ip.create(kind='vlan', ifname=vlan.name,
                       link=link, vlan_id=vlan.tag).commit()

    def removeVlan(self, vlan):
        with self.ip.interfaces[vlan.name] as i:
            i.remove()

    def addBond(self, bond):
        if bond.name not in netinfo.bondings():
            self.ip.create(kind='bond', ifname=bond.name).commit()

    def removeBond(self, bond):
        with self.ip.interfaces[bond.name] as i:
            i.remove()

    def addBondSlave(self, bond, slave):
        self.ifdown(slave)
        with self.ip.interfaces[bond.name] as i:
            i.add_port(self.ip.interfaces[slave.name])
        self.ifup(slave)

    def removeBondSlave(self, bond, slave):
        with self.ip.interfaces[bond.name] as i:
            i.del_port(self.ip.interfaces[slave.name])

    def addBondOptions(self, bond):
        logging.debug('Add bond options %s', bond.options)
        for option in bond.options.split():
            key, value = option.split('=')
            with open(netinfo.BONDING_OPT % (bond.name, key), 'w') as f:
                f.write(value)

    def createLibvirtNetwork(self, network, bridged, iface, qosInbound=None,
                             qosOutbound=None):
        netXml = libvirt.createNetworkDef(network, bridged, iface,
                                          qosInbound, qosOutbound)
        libvirt.createNetwork(netXml)

    def removeLibvirtNetwork(self, network):
        libvirt.removeNetwork(network)

    def releaseSocket(self):
        self.ip.release()
Esempio n. 37
0
class TestExplicit(object):
    ip = None
    mode = 'explicit'

    def setup(self):
        create_link('dummyX', 'dummy')
        self.ip = IPDB(mode=self.mode)

    def teardown(self):
        for name in ('bala_port0', 'bala_port1', 'dummyX',
                     'bala', 'bv101'):
            try:
                with self.ip.interfaces[name] as i:
                    i.remove()
            except KeyError:
                pass
            except NetlinkError as e:
                if e.code != 19:  # No such device
                    raise
        self.ip.release()

    def test_simple(self):
        assert len(list(self.ip.interfaces.keys())) > 0

    def test_empty_transaction(self):
        assert 'lo' in self.ip.interfaces
        with self.ip.interfaces.lo as i:
            assert isinstance(i.mtu, int)

    def test_idx_len(self):
        assert len(self.ip.by_name.keys()) == len(self.ip.by_index.keys())

    def test_idx_set(self):
        assert set(self.ip.by_name.values()) == set(self.ip.by_index.values())

    def test_idx_types(self):
        assert all(isinstance(i, int) for i in self.ip.by_index.keys())
        assert all(isinstance(i, basestring) for i in self.ip.by_name.keys())

    def test_ips(self):
        for name in self.ip.by_name:
            assert len(self.ip.interfaces[name]['ipaddr']) == \
                len(get_ip_addr(name))

    def test_reprs(self):
        assert isinstance(repr(self.ip.interfaces.lo.ipaddr), basestring)
        assert isinstance(repr(self.ip.interfaces.lo), basestring)

    def test_dotkeys(self):
        # self.ip.lo hint for ipython
        assert 'lo' in dir(self.ip.interfaces)
        assert 'lo' in self.ip.interfaces
        assert self.ip.interfaces.lo == self.ip.interfaces['lo']
        # create attribute
        self.ip.interfaces['newitem'] = True
        self.ip.interfaces.newattr = True
        self.ip.interfaces.newitem = None
        assert self.ip.interfaces.newitem == self.ip.interfaces['newitem']
        assert self.ip.interfaces.newitem is None
        # delete attribute
        del self.ip.interfaces.newitem
        del self.ip.interfaces.newattr
        assert 'newattr' not in dir(self.ip.interfaces)

    def test_callback_positive(self):
        require_user('root')
        assert 'dummyX' in self.ip.interfaces

        # test callback, that adds an address by itself --
        # just to check the possibility
        def cb(snapshot, transaction):
            self.ip.nl.addr('add',
                            self.ip.interfaces.dummyX.index,
                            address='172.16.22.1',
                            mask=24)

        # register callback and check CB chain length
        self.ip.interfaces.dummyX.register_callback(cb)
        assert len(self.ip.interfaces.dummyX._callbacks) == 1

        # create a transaction and commit it
        if self.ip.interfaces.dummyX._mode == 'explicit':
            self.ip.interfaces.dummyX.begin()
        self.ip.interfaces.dummyX.add_ip('172.16.21.1/24')
        self.ip.interfaces.dummyX.commit()

        # the second address added w/o watchdogs,
        # so we have to wait
        time.sleep(1)

        # added address should be there
        assert ('172.16.21.1', 24) in self.ip.interfaces.dummyX.ipaddr
        # and the one, added by the callback, too
        assert ('172.16.22.1', 24) in self.ip.interfaces.dummyX.ipaddr

        # unregister callback
        self.ip.interfaces.dummyX.unregister_callback(cb)
        assert len(self.ip.interfaces.dummyX._callbacks) == 0

    def test_callback_negative(self):
        require_user('root')
        assert 'dummyX' in self.ip.interfaces

        # test exception to differentiate
        class CBException(Exception):
            pass

        # test callback, that always fail
        def cb(snapshot, transaction):
            raise CBException()

        # register callback and check CB chain length
        self.ip.interfaces.dummyX.register_callback(cb)
        assert len(self.ip.interfaces.dummyX._callbacks) == 1

        # create a transaction and commit it; should fail
        # 'cause of the callback
        if self.ip.interfaces.dummyX._mode == 'explicit':
            self.ip.interfaces.dummyX.begin()
        self.ip.interfaces.dummyX.add_ip('172.16.21.1/24')
        try:
            self.ip.interfaces.dummyX.commit()
        except CBException:
            pass

        # added address should be removed
        assert ('172.16.21.1', 24) not in self.ip.interfaces.dummyX.ipaddr

        # unregister callback
        self.ip.interfaces.dummyX.unregister_callback(cb)
        assert len(self.ip.interfaces.dummyX._callbacks) == 0

    def test_review(self):
        assert len(self.ip.interfaces.lo._tids) == 0
        if self.ip.interfaces.lo._mode == 'explicit':
            self.ip.interfaces.lo.begin()
        self.ip.interfaces.lo.add_ip('172.16.21.1/24')
        r = self.ip.interfaces.lo.review()
        assert len(r['+ipaddr']) == 1
        assert len(r['-ipaddr']) == 0
        assert len(r['+ports']) == 0
        assert len(r['-ports']) == 0
        # +/-ipaddr, +/-ports
        assert len([i for i in r if r[i] is not None]) == 4
        self.ip.interfaces.lo.drop()

    def test_rename(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        assert 'dummyX' in self.ip.interfaces

        if self.ip.interfaces.dummyX._mode == 'explicit':
            self.ip.interfaces.dummyX.begin()
        self.ip.interfaces.dummyX.ifname = 'bala'
        self.ip.interfaces.dummyX.commit()

        assert 'bala' in self.ip.interfaces
        assert 'dummyX' not in self.ip.interfaces

        if self.ip.interfaces.bala._mode == 'explicit':
            self.ip.interfaces.bala.begin()
        self.ip.interfaces.bala.ifname = 'dummyX'
        self.ip.interfaces.bala.commit()

        assert 'bala' not in self.ip.interfaces
        assert 'dummyX' in self.ip.interfaces

    def test_routes(self):
        require_user('root')
        assert '172.16.0.0/24' not in self.ip.routes

        # create a route
        with self.ip.routes.add({'dst': '172.16.0.0/24',
                                 'gateway': '127.0.0.1'}) as r:
            pass
        assert '172.16.0.0/24' in self.ip.routes
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.1')

        # change a route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.gateway = '127.0.0.2'
        assert self.ip.routes['172.16.0.0/24'].gateway == '127.0.0.2'
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.2')

        # delete a route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.remove()
        assert '172.16.0.0/24' not in self.ip.routes
        assert not grep('ip ro', pattern='172.16.0.0/24')

    def _test_shadow(self, kind):
        a = self.ip.create(ifname='bala', kind=kind).commit()
        if a._mode == 'explicit':
            a.begin()
        a.shadow().commit()
        assert 'bala' in self.ip.interfaces
        assert not grep('ip link', pattern='bala')
        b = self.ip.create(ifname='bala', kind=kind).commit()
        assert a == b
        assert grep('ip link', pattern='bala')

    def test_shadow_bond(self):
        require_user('root')
        require_bond()
        self._test_shadow('bond')

    def test_shadow_bridge(self):
        require_user('root')
        require_bridge()
        self._test_shadow('bridge')

    def test_shadow_dummy(self):
        require_user('root')
        self._test_shadow('dummy')

    def test_updown(self):
        require_user('root')
        assert not (self.ip.interfaces.dummyX.flags & 1)

        if self.ip.interfaces.dummyX._mode == 'explicit':
            self.ip.interfaces.dummyX.begin()
        self.ip.interfaces.dummyX.up()
        self.ip.interfaces.dummyX.commit()
        assert self.ip.interfaces.dummyX.flags & 1

        if self.ip.interfaces.dummyX._mode == 'explicit':
            self.ip.interfaces.dummyX.begin()
        self.ip.interfaces.dummyX.down()
        self.ip.interfaces.dummyX.commit()
        assert not (self.ip.interfaces.dummyX.flags & 1)

    def test_cfail_rollback(self):
        require_user('root')
        require_bridge()

        # create ports
        with self.ip.create(kind='dummy', ifname='bala_port0'):
            pass
        with self.ip.create(kind='dummy', ifname='bala_port1'):
            pass
        assert 'bala_port0' in self.ip.interfaces
        assert 'bala_port1' in self.ip.interfaces

        # commits should fail
        clear_fail_bit(_FAIL_COMMIT)
        clear_fail_bit(_FAIL_ROLLBACK)
        try:
            # create bridge
            with self.ip.create(kind='bridge', ifname='bala') as i:
                i.add_ip('172.16.0.1/24')
                i.add_ip('172.16.0.2/24')
                i.add_port(self.ip.interfaces.bala_port0)
                i.add_port(self.ip.interfaces.bala_port1)

        except RuntimeError:
            pass

        finally:
            # set bit again
            set_fail_bit(_FAIL_COMMIT)
            set_fail_bit(_FAIL_ROLLBACK)

        # expected results:
        # 1. interface created
        # 2. no addresses
        # 3. no ports
        assert 'bala' in self.ip.interfaces
        assert 'bala_port0' in self.ip.interfaces
        assert 'bala_port1' in self.ip.interfaces
        assert ('172.16.0.1', 24) not in self.ip.interfaces.bala.ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces.bala.ipaddr
        assert self.ip.interfaces.bala_port0.index not in \
            self.ip.interfaces.bala.ports
        assert self.ip.interfaces.bala_port1.index not in \
            self.ip.interfaces.bala.ports

    def test_cfail_commit(self):
        require_user('root')
        require_bridge()

        # create ports
        with self.ip.create(kind='dummy', ifname='bala_port0'):
            pass
        with self.ip.create(kind='dummy', ifname='bala_port1'):
            pass
        assert 'bala_port0' in self.ip.interfaces
        assert 'bala_port1' in self.ip.interfaces

        # commits should fail
        clear_fail_bit(_FAIL_COMMIT)
        try:
            # create bridge
            with self.ip.create(kind='bridge', ifname='bala') as i:
                i.add_ip('172.16.0.1/24')
                i.add_ip('172.16.0.2/24')
                i.add_port(self.ip.interfaces.bala_port0)
                i.add_port(self.ip.interfaces.bala_port1)

        except AssertionError:
            pass

        finally:
            # set bit again
            set_fail_bit(_FAIL_COMMIT)

        # expected results:
        # 1. interface created
        # 2. no addresses
        # 3. no ports
        assert 'bala' in self.ip.interfaces
        assert 'bala_port0' in self.ip.interfaces
        assert 'bala_port1' in self.ip.interfaces
        assert ('172.16.0.1', 24) not in self.ip.interfaces.bala.ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces.bala.ipaddr
        assert self.ip.interfaces.bala_port0.index not in \
            self.ip.interfaces.bala.ports
        assert self.ip.interfaces.bala_port1.index not in \
            self.ip.interfaces.bala.ports

    def test_fail_ipaddr(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        i = self.ip.create(ifname='bala', kind='dummy').commit()
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.add_ip('123.456.789.1024/153')
        try:
            i.commit()
        except socket.error as e:
            if not e.args[0].startswith('illegal IP'):
                raise
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.remove().commit()
        assert 'bala' not in self.ip.interfaces

    def test_create_fail(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        # create with mac 11:22:33:44:55:66 should fail
        i = self.ip.create(kind='dummy',
                           ifname='bala',
                           address='11:22:33:44:55:66')
        try:
            i.commit()
        except NetlinkError:
            pass

        assert i._mode == 'invalid'
        assert 'bala' not in self.ip.interfaces

    def test_create_dqn(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        i = self.ip.create(kind='dummy', ifname='bala')
        i.add_ip('172.16.0.1/255.255.255.0')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface='bala')

    def test_create_plain(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        i = self.ip.create(kind='dummy', ifname='bala')
        i.add_ip('172.16.0.1/24')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface='bala')

    def test_create_and_remove(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces

        with self.ip.create(kind='dummy', ifname='bala') as i:
            i.add_ip('172.16.0.1/24')
        assert ('172.16.0.1', 24) in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface='bala')

        with self.ip.interfaces.bala as i:
            i.remove()
        assert 'bala' not in self.ip.interfaces

    def _create_master(self, kind, **kwarg):
        require_user('root')
        assert 'bala' not in self.ip.interfaces
        assert 'bala_port0' not in self.ip.interfaces
        assert 'bala_port1' not in self.ip.interfaces

        self.ip.create(kind='dummy', ifname='bala_port0').commit()
        self.ip.create(kind='dummy', ifname='bala_port1').commit()

        with self.ip.create(kind=kind, ifname='bala', **kwarg) as i:
            i.add_port(self.ip.interfaces.bala_port0)
            i.add_port(self.ip.interfaces.bala_port1)
            i.add_ip('172.16.0.1/24')

        assert ('172.16.0.1', 24) in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface='bala')
        assert self.ip.interfaces.bala_port0.if_master == \
            self.ip.interfaces.bala.index
        assert self.ip.interfaces.bala_port1.if_master == \
            self.ip.interfaces.bala.index

        with self.ip.interfaces.bala as i:
            i.del_port(self.ip.interfaces.bala_port0)
            i.del_port(self.ip.interfaces.bala_port1)
            i.del_ip('172.16.0.1/24')

        assert ('172.16.0.1', 24) not in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface='bala')
        assert self.ip.interfaces.bala_port0.if_master is None
        assert self.ip.interfaces.bala_port1.if_master is None

    def test_create_bridge(self):
        require_bridge()
        self._create_master('bridge')

    def test_create_bond(self):
        require_bond()
        self._create_master('bond')

    def test_create_bond2(self):
        require_bond()
        self._create_master('bond', bond_mode=2)

    def test_create_vlan_by_interface(self):
        require_user('root')
        require_8021q()
        assert 'bala' not in self.ip.interfaces
        assert 'bv101' not in self.ip.interfaces

        self.ip.create(kind='dummy',
                       ifname='bala').commit()
        self.ip.create(kind='vlan',
                       ifname='bv101',
                       link=self.ip.interfaces.bala,
                       vlan_id=101).commit()

        assert self.ip.interfaces.bv101.if_master == \
            self.ip.interfaces.bala.index

    def test_create_vlan_by_index(self):
        require_user('root')
        require_8021q()
        assert 'bala' not in self.ip.interfaces
        assert 'bv101' not in self.ip.interfaces

        self.ip.create(kind='dummy',
                       ifname='bala').commit()
        self.ip.create(kind='vlan',
                       ifname='bv101',
                       link=self.ip.interfaces.bala.index,
                       vlan_id=101).commit()

        assert self.ip.interfaces.bv101.if_master == \
            self.ip.interfaces.bala.index

    def test_remove_secondaries(self):
        require_user('root')
        assert 'bala' not in self.ip.interfaces

        with self.ip.create(kind='dummy', ifname='bala') as i:
            i.add_ip('172.16.0.1', 24)
            i.add_ip('172.16.0.2', 24)

        assert 'bala' in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces.bala.ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface='bala')
        assert '172.16.0.2/24' in get_ip_addr(interface='bala')

        if i._mode == 'explicit':
            i.begin()

        i.del_ip('172.16.0.1', 24)
        i.del_ip('172.16.0.2', 24)
        i.commit()

        assert ('172.16.0.1', 24) not in self.ip.interfaces.bala.ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces.bala.ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface='bala')
        assert '172.16.0.2/24' not in get_ip_addr(interface='bala')
Esempio n. 38
0
if sys.platform[:3] == 'win':
    print('Intended to be executed in a mininet Linux environment.')
    raise RuntimeError()

try:
    from pyroute2 import IPDB
except ImportError:
    print('Dependency missing: pip install pyroute2')
    sys.exit(1)
ip = IPDB()
SIM_BCAST = ip.interfaces[[
    x for x in ip.interfaces if ip.interfaces[x]['state'] == 'up'
    and isinstance(x, str) and str(x) != 'lo'
][0]].ipaddr[0]['broadcast']
ip.release()
del ip

SIM_PORT = 20202  # UDP port used for the simulation information exchange between the different RTUs
BUFFER_SIZE = 512
DATA_FMT = '<IIIIIff'  # Sender-ID Receiver-ID Message-ID IARG-0 IARG-1 FARG-0 FARG-1

# Message ID
MSG_WERE = 0
MSG_ISAT = 1
MSG_GETV = 2
MSG_VOLT = 3
MSG_GREQ = 4
MSG_TREQ = 5
MSG_UKWN = 99
Esempio n. 39
0
def prepare_namespaces(graph, dry_run=False, instance_id=None):
    """
    Create a veth-connected mesh from :data:`graph`

    :param networkx.Graph graph: The graph defining the test mesh
    :param bool dry_run: If set makes Meshinery not touch any namespaces
    :param str instance_id: If set changes the middle section of each
    namespace's name; current PID by default
    :return networkx.Graph: The same graph containing runtime attributes
    """
    if instance_id is None:
        instance_id = os.getpid()
    # Create namespaces
    for node_name in graph.nodes:
        ns_name = 'meshinery-{}-{}'.format(instance_id, node_name)
        logging.info('Adding namespace "{}"'.format(ns_name))
        if not dry_run:
            # Establish the namespace
            ns = NetNS(ns_name)
            ipdb = IPDB(nl=ns)
            ipdb.interfaces['lo'].up().commit()
            ipdb.commit()
            ipdb.release()

            # Enable forwarding
            sysctl_cmd = shlex.split(
                'sysctl -w net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1'
            )
            subprocess.run(sysctl_cmd,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE).check_returncode()

            graph.node[node_name]['netns'] = ns_name
            graph.node[node_name]['interfaces'] = [
            ]  # Needed so that we can safely append later

    # Create veth bridges
    for node_name, neigh_name in graph.edges:
        neighbors = graph[node_name]

        node = graph.node[node_name]
        neigh = graph.node[neigh_name]

        # If an edge hasn't been created yet
        node_iface = '{}-{}'.format(node_name, neigh_name)
        neigh_iface = '{}-{}'.format(neigh_name, node_name)

        if not dry_run:
            node_ns_handle = NetNS(node['netns'])
            neigh_ns_handle = NetNS(neigh['netns'])

            ipdb = IPDB()

            # Create namespace-aware IPDB handles
            node_ipdb = IPDB(nl=node_ns_handle)
            neigh_ipdb = IPDB(nl=neigh_ns_handle)

            # Create a veth pair
            ipdb.create(ifname=node_iface, kind='veth',
                        peer=neigh_iface).commit()

            # Assign node IP
            ipdb.interfaces[node_iface]['net_ns_fd'] = node['netns']
            ipdb.commit()
            node_ipdb.interfaces[node_iface].add_ip(node['ip'])
            node_ipdb.interfaces[node_iface].up().commit()

            # Assign neighbor IP
            ipdb.interfaces[neigh_iface].add_ip(neigh['ip'])
            ipdb.interfaces[neigh_iface]['net_ns_fd'] = neigh['netns']
            ipdb.commit()
            neigh_ipdb.interfaces[neigh_iface].add_ip(neigh['ip'])
            neigh_ipdb.interfaces[neigh_iface].up().commit()

            ipdb.release()

            node_ipdb.release()
            neigh_ipdb.release()

            node['interfaces'].append(node_iface)
            neigh['interfaces'].append(neigh_iface)

        logging.debug('Created %s and %s interfaces' %
                      (node_iface, neigh_iface))

    ipdb.release()
                with ip.interfaces[iface] as i:
                    i.up()

                ip_ns = IPDB(nl=nns)
                try:
                    with ip_ns.interfaces.lo as lo:
                        lo.up()
                    with ip_ns.interfaces[iface1] as i:
                        if args.ipv4:
                            i.add_ip(local_addr4 + str(ifn + 8) + '/24')
                        if args.ipv6:
                            i.add_ip(local_addr6 + str(ifn + 8) + '/64')
                        i.up()
                finally:
                    ip_ns.release()

                nsp = NSPopen(nns.netns, [
                    "tc", "qdisc", "add", "dev", iface1, "root", "netem",
                    "delay",
                    str(args.delay) + "ms",
                    str(int(args.delay / 2)) + "ms", "loss",
                    str(args.loss) + "%", "25%"
                ],
                              stdout=subprocess.PIPE)
                #print(nsp.communicate()[0].decode())
                nsp.communicate()
                nsp.wait()
                nsp.release()

            if args.ipv4:
Esempio n. 41
0
    class NetworkBackendBridgedPyroute2(
            NetworkBackendBridged.NetworkBackendBridged()):
        """
        Use pyroute2 to setup the network.
        """
        def __init__(self, network_backend_boot_strapper):
            super(NetworkBackendBridgedPyroute2,
                  self).__init__(network_backend_boot_strapper)
            self.ipdb = None

        def get_ipdb(self):
            global ipdb
            if self.ipdb is None:
                from pyroute2 import IPDB
                # ipdb = IPDB()
                # https://github.com/svinota/pyroute2/issues/304#issuecomment-259275184
                import pyroute2.netlink.rtnl as rtnl
                GROUPS = rtnl.RTNLGRP_LINK | rtnl.RTNLGRP_NEIGH | rtnl.RTNLGRP_IPV4_IFADDR | rtnl.RTNLGRP_IPV6_IFADDR | rtnl.RTNLGRP_IPV4_ROUTE | rtnl.RTNLGRP_IPV6_ROUTE | rtnl.RTNLGRP_IPV4_MROUTE
                GROUPS = \
                    rtnl.RTNLGRP_LINK | \
                    rtnl.RTNLGRP_NEIGH | \
                    rtnl.RTNLGRP_IPV4_IFADDR | \
                    rtnl.RTNLGRP_IPV4_ROUTE | \
                    rtnl.RTNLGRP_IPV4_MROUTE | \
                    rtnl.RTNLGRP_IPV6_IFADDR | \
                    rtnl.RTNLGRP_IPV6_ROUTE | \
                    rtnl.RTNLGRP_MPLS_ROUTE

                # rtnl.RTNLGRP_NONE |\
                # rtnl.RTNLGRP_NOTIFY |\
                # rtnl.RTNLGRP_IPV4_RULE |\
                # rtnl.RTNLGRP_DECnet_IFADDR |\
                # rtnl.RTNLGRP_DECnet_ROUTE |\
                # rtnl.RTNLGRP_DECnet_RULE |\
                # rtnl.RTNLGRP_IPV6_MROUTE |\

                # rtnl.RTNLGRP_IPV6_IFINFO |\
                # rtnl.RTNLGRP_IPV6_PREFIX |\
                # rtnl.RTNLGRP_IPV6_RULE | \
                # rtnl.RTNLGRP_NOP2 |\
                # rtnl.RTNLGRP_NOP4 |\
                # rtnl.RTNLGRP_TC |\

                # .*_ROUTE
                # AttributeError: 'IPDB' object has no attribute 'routes'
                # .*_IFADDR
                # AttributeError: 'IPDB' object has no attribute 'by_name'
                self.ipdb = IPDB(nl_async="process", nl_bind_groups=GROUPS)
                # import pyroute2
                # ipr = pyroute2.IPRoute()
                # ipb = pyroute2.IPBatch()
                # ipb.link("add", index=550, kind="dummy", ifname="test2")
                # ipr.sendto(ipb.batch, (0, 0))
                # ipdb = IPDB(nl_async="process")
                # run_shell("renice -n {} {}".format(-20, self.ipdb.mnl.async_cache.pid))
                run_shell("chrt -f -p {} {}".format(
                    1, self.ipdb.mnl.async_cache.pid))

            return self.ipdb

        def do_network_topology_change(self):
            # TOOD: REMOVE?
            with lock:
                super(NetworkBackendBridgedPyroute2,
                      self).do_network_topology_change()
                try:
                    ipdb = self.get_ipdb()
                    get_ipdb_logger().info("commit()")
                    ipdb.commit()
                    # for interface in ipdb.by_name.keys():
                    #     ifc = ipdb.interfaces[interface]
                    #     tx = None
                    #     e_count = 0
                    #     while True:
                    #         try:
                    #             if tx is None:
                    #                 tx = ifc.current_tx
                    #             if tx is not None:
                    #                 ifc.commit(transaction=tx)
                    #                 ifc.drop()
                    #
                    #                 IPRoute.get_links()
                    #
                    #             break
                    #         except:
                    #             e_count += 1
                    #             if e_count > 3:
                    #                 break
                except Exception as e:
                    try:
                        log.critical(e.__dict__)
                    except BaseException:
                        pass

                    # try:
                    #     log.critical(e.debug['traceback'])
                    # except:
                    #     pass

                    # try:
                    #     log.critical(e.debug['transaction'])
                    # except:
                    #     pass

                    raise

        def reset(self):
            super(NetworkBackendBridgedPyroute2, self).reset()
            log.debug("stopping ipdb instance")
            if self.ipdb:
                self.ipdb.release()
                self.ipdb = None
Esempio n. 42
0
 def test_fail_released(self):
     ip = IPDB()
     ip.release()
     assert len(ip.interfaces.keys()) == 0
Esempio n. 43
0
class TestExplicit(object):
    ip = None
    mode = 'explicit'

    def setup(self):
        self.ifaces = []
        self.ifd = self.get_ifname()
        create_link(self.ifd, kind='dummy')
        self.ip = IPDB(mode=self.mode)

    def get_ifname(self):
        ifname = uifname()
        self.ifaces.append(ifname)
        return ifname

    def teardown(self):
        for name in self.ifaces:
            try:
                # just a hardcore removal
                self.ip.nl.link_remove(self.ip.interfaces[name].index)
            except Exception:
                pass
        self.ip.release()
        self.ifaces = []

    def test_simple(self):
        assert len(list(self.ip.interfaces.keys())) > 0

    def test_empty_transaction(self):
        assert 'lo' in self.ip.interfaces
        with self.ip.interfaces.lo as i:
            assert isinstance(i.mtu, int)

    def test_idx_len(self):
        assert len(self.ip.by_name.keys()) == len(self.ip.by_index.keys())

    def test_idx_set(self):
        assert set(self.ip.by_name.values()) == set(self.ip.by_index.values())

    def test_idx_types(self):
        assert all(isinstance(i, int) for i in self.ip.by_index.keys())
        assert all(isinstance(i, basestring) for i in self.ip.by_name.keys())

    def test_addr_attributes(self):
        require_user('root')

        if1 = self.get_ifname()
        if2 = self.get_ifname()

        with self.ip.create(ifname=if1, kind='dummy') as i:
            # +scope host (=> broadcast == None)
            i.add_ip('172.16.102.1/24', scope=254)

        with self.ip.create(ifname=if2, kind='dummy') as i:
            # +broadcast (default scope == 0)
            i.add_ip('172.16.103.1/24', broadcast='172.16.103.128')

        index = self.ip.interfaces[if1]['index']
        addr = self.ip.nl.get_addr(index=index)[0]
        assert addr['scope'] == 254
        assert addr.get_attr('IFA_BROADCAST') is None

        index = self.ip.interfaces[if2]['index']
        addr = self.ip.nl.get_addr(index=index)[0]
        assert addr['scope'] == 0
        assert addr.get_attr('IFA_BROADCAST') == '172.16.103.128'

    def test_addr_loaded(self):
        for name in self.ip.by_name:
            assert len(self.ip.interfaces[name]['ipaddr']) == \
                len(get_ip_addr(name))

    def test_reprs(self):
        assert isinstance(repr(self.ip.interfaces.lo.ipaddr), basestring)
        assert isinstance(repr(self.ip.interfaces.lo), basestring)

    def test_dotkeys(self):
        # self.ip.lo hint for ipython
        assert 'lo' in dir(self.ip.interfaces)
        assert 'lo' in self.ip.interfaces
        assert self.ip.interfaces.lo == self.ip.interfaces['lo']
        # create attribute
        self.ip.interfaces['newitem'] = True
        self.ip.interfaces.newattr = True
        self.ip.interfaces.newitem = None
        assert self.ip.interfaces.newitem == self.ip.interfaces['newitem']
        assert self.ip.interfaces.newitem is None
        # delete attribute
        del self.ip.interfaces.newitem
        del self.ip.interfaces.newattr
        assert 'newattr' not in dir(self.ip.interfaces)

    @skip_if_not_supported
    def test_vlan_slave_bridge(self):
        # https://github.com/svinota/pyroute2/issues/58
        # based on the code by Petr Horáček
        dXname = self.get_ifname()
        vXname = self.get_ifname()
        vYname = self.get_ifname()
        brname = self.get_ifname()

        require_user('root')
        dX = self.ip.create(ifname=dXname, kind='dummy').commit()
        vX = self.ip.create(ifname=vXname, kind='vlan', link=dX,
                            vlan_id=101).commit()
        vY = self.ip.create(ifname=vYname, kind='vlan', link=dX,
                            vlan_id=102).commit()
        with self.ip.create(ifname=brname, kind='bridge') as i:
            i.add_port(vX)
            i.add_port(vY['index'])

        assert vX['index'] in self.ip.interfaces[brname]['ports']
        assert vY['index'] in self.ip.interfaces[brname].ports
        assert vX['link'] == dX['index']
        assert vY['link'] == dX['index']
        assert vX['master'] == self.ip.interfaces[brname]['index']
        assert vY['master'] == self.ip.interfaces[brname].index

    def _test_commit_hook_positive(self):
        require_user('root')

        # test callback, that adds an address by itself --
        # just to check the possibility
        def cb(interface, snapshot, transaction):
            self.ip.nl.addr('add',
                            self.ip.interfaces[self.ifd].index,
                            address='172.16.22.1',
                            mask=24)

        # register callback and check CB chain length
        self.ip.interfaces[self.ifd].register_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 1

        # create a transaction and commit it
        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].add_ip('172.16.21.1/24')
        self.ip.interfaces[self.ifd].commit()

        # added address should be there
        assert ('172.16.21.1', 24) in \
            self.ip.interfaces[self.ifd].ipaddr
        # and the one, added by the callback, too
        assert ('172.16.22.1', 24) in \
            self.ip.interfaces[self.ifd].ipaddr

        # unregister callback
        self.ip.interfaces[self.ifd].unregister_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 0

    def _test_commit_hook_negative(self):
        require_user('root')

        # test exception to differentiate
        class CBException(Exception):
            pass

        # test callback, that always fail
        def cb(interface, snapshot, transaction):
            raise CBException()

        # register callback and check CB chain length
        self.ip.interfaces[self.ifd].register_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 1

        # create a transaction and commit it; should fail
        # 'cause of the callback
        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].add_ip('172.16.21.1/24')
        try:
            self.ip.interfaces[self.ifd].commit()
        except CBException:
            pass

        # added address should be removed
        assert ('172.16.21.1', 24) not in \
            self.ip.interfaces[self.ifd].ipaddr

        # unregister callback
        self.ip.interfaces[self.ifd].unregister_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 0

    def test_review(self):
        assert len(self.ip.interfaces.lo._tids) == 0
        if self.ip.interfaces.lo._mode == 'explicit':
            self.ip.interfaces.lo.begin()
        self.ip.interfaces.lo.add_ip('172.16.21.1/24')
        r = self.ip.interfaces.lo.review()
        assert len(r['+ipaddr']) == 1
        assert len(r['-ipaddr']) == 0
        assert len(r['+ports']) == 0
        assert len(r['-ports']) == 0
        # +/-ipaddr, +/-ports
        assert len([i for i in r if r[i] is not None]) == 4
        self.ip.interfaces.lo.drop()

    def test_rename(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        self.ip.create(ifname=ifA, kind='dummy').commit()

        if self.ip.interfaces[ifA]._mode == 'explicit':
            self.ip.interfaces[ifA].begin()
        self.ip.interfaces[ifA].ifname = ifB
        self.ip.interfaces[ifA].commit()

        assert ifB in self.ip.interfaces
        assert ifA not in self.ip.interfaces

        if self.ip.interfaces[ifB]._mode == 'explicit':
            self.ip.interfaces[ifB].begin()
        self.ip.interfaces[ifB].ifname = ifA
        self.ip.interfaces[ifB].commit()

        assert ifB not in self.ip.interfaces
        assert ifA in self.ip.interfaces

    def test_routes_keys(self):
        assert '172.16.0.0/24' not in self.ip.routes
        # create but not commit
        self.ip.routes.add(dst='172.16.0.0/24', gateway='127.0.0.1')
        # checks
        assert '172.16.0.0/24' in self.ip.routes
        assert '172.16.0.0/24' in list(self.ip.routes.keys())

    def test_routes(self):
        require_user('root')
        assert '172.16.0.0/24' not in self.ip.routes

        # create a route
        with self.ip.routes.add({
                'dst': '172.16.0.0/24',
                'gateway': '127.0.0.1'
        }) as r:
            pass
        assert '172.16.0.0/24' in self.ip.routes.keys()
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.1')

        # change the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.gateway = '127.0.0.2'
        assert self.ip.routes['172.16.0.0/24'].gateway == '127.0.0.2'
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.2')

        # delete the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.remove()
        assert '172.16.0.0/24' not in self.ip.routes.keys()
        assert not grep('ip ro', pattern='172.16.0.0/24')

    def test_routes_multipath_gateway(self):
        require_user('root')
        ifR = self.get_ifname()

        with self.ip.create(ifname=ifR, kind='dummy') as i:
            i.add_ip('172.16.231.1/24')
            i.up()

        r = self.ip.routes.add({
            'dst':
            '172.16.232.0/24',
            'multipath': [{
                'gateway': '172.16.231.2',
                'hops': 20
            }, {
                'gateway': '172.16.231.3',
                'hops': 30
            }, {
                'gateway': '172.16.231.4'
            }]
        })
        r.commit()
        assert grep('ip ro', pattern='172.16.232.0/24')
        assert grep('ip ro', pattern='nexthop.*172.16.231.2.*weight.*21')
        assert grep('ip ro', pattern='nexthop.*172.16.231.3.*weight.*31')
        assert grep('ip ro', pattern='nexthop.*172.16.231.4.*weight.*1')

        with self.ip.routes['172.16.232.0/24'] as r:
            r.add_nh({'gateway': '172.16.231.5', 'hops': 50})
            r.del_nh({'gateway': '172.16.231.2'})
        assert grep('ip ro', pattern='172.16.232.0/24')
        assert grep('ip ro', pattern='nexthop.*172.16.231.5.*weight.*51')
        assert grep('ip ro', pattern='nexthop.*172.16.231.3.*weight.*31')
        assert grep('ip ro', pattern='nexthop.*172.16.231.4.*weight.*1')

    def test_routes_metrics(self):
        require_user('root')
        assert '172.16.0.0/24' not in self.ip.routes.keys()

        # create a route
        self.ip.routes.add({
            'dst': '172.16.0.0/24',
            'gateway': '127.0.0.1',
            'metrics': {
                'mtu': 1360
            }
        }).commit()
        assert grep('ip ro', pattern='172.16.0.0/24.*mtu 1360')

        # change metrics
        with self.ip.routes['172.16.0.0/24'] as r:
            r.metrics.mtu = 1400
        assert self.ip.routes['172.16.0.0/24']['metrics']['mtu'] == 1400
        assert grep('ip ro', pattern='172.16.0.0/24.*mtu 1400')

        # delete the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.remove()

        assert '172.16.0.0/24' not in self.ip.routes.keys()
        assert not grep('ip ro', pattern='172.16.0.0/24')

    @skip_if_not_supported
    def _test_shadow(self, kind):
        ifA = self.get_ifname()

        a = self.ip.create(ifname=ifA, kind=kind).commit()
        if a._mode == 'explicit':
            a.begin()
        a.shadow().commit()
        assert ifA in self.ip.interfaces
        assert not grep('ip link', pattern=ifA)
        time.sleep(0.5)
        b = self.ip.create(ifname=ifA, kind=kind).commit()
        assert a == b
        assert grep('ip link', pattern=ifA)

    def test_shadow_bond(self):
        require_user('root')
        self._test_shadow('bond')

    def test_shadow_bridge(self):
        require_user('root')
        self._test_shadow('bridge')

    def test_shadow_dummy(self):
        require_user('root')
        self._test_shadow('dummy')

    def test_updown(self):
        require_user('root')

        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].up()
        self.ip.interfaces[self.ifd].commit()
        assert self.ip.interfaces[self.ifd].flags & 1

        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].down()
        self.ip.interfaces[self.ifd].commit()
        assert not (self.ip.interfaces[self.ifd].flags & 1)

    def test_slave_data(self):
        require_user('root')

        ifBR = self.get_ifname()
        ifP = self.get_ifname()
        self.ip.debug = True

        bridge = self.ip.create(ifname=ifBR, kind='bridge').commit()
        port = self.ip.create(ifname=ifP, kind='dummy').commit()

        if self.ip.mode == 'explicit':
            bridge.begin()
        bridge.add_port(port)
        bridge.up()
        bridge.commit()

        li = port.nlmsg.get_attr('IFLA_LINKINFO')
        skind = li.get_attr('IFLA_INFO_SLAVE_KIND')
        sdata = li.get_attr('IFLA_INFO_SLAVE_DATA')
        self.ip.debug = False
        if skind is None or sdata is None:
            raise SkipTest('slave data not provided')

        assert sdata.get_attr('IFLA_BRPORT_STATE') is not None
        assert sdata.get_attr('IFLA_BRPORT_MODE') is not None

    def test_fail_ipaddr(self):
        require_user('root')

        ifA = self.get_ifname()

        i = self.ip.create(ifname=ifA, kind='dummy').commit()
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.add_ip('123.456.789.1024/153')
        try:
            i.commit()
        except socket.error as e:
            if not e.args[0].startswith('illegal IP'):
                raise
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.remove().commit()
        assert ifA not in self.ip.interfaces

    def test_json_dump(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        # set up the interface
        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.0.2/24')
            i.up()

        # make a backup
        backup = self.ip.interfaces[ifA].dump()
        assert isinstance(backup, dict)

        # remove index and protinfo -- make it portable
        del backup['index']
        if 'protinfo' in backup:
            del backup['protinfo']

        # serialize
        backup = json.dumps(backup)

        # remove the interface
        with self.ip.interfaces[ifA] as i:
            i.remove()

        # create again, but with different name
        self.ip.create(kind='dummy', ifname=ifB).commit()

        # load the backup
        # 1. prepare to the restore: bring it down
        with self.ip.interfaces[ifB] as i:
            i.down()
        # 2. please notice, the interface will be renamed after the backup
        with self.ip.interfaces[ifB] as i:
            i.load(json.loads(backup))

        # check :)
        assert ifA in self.ip.interfaces
        assert ifB not in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifA].ipaddr
        assert self.ip.interfaces[ifA].flags & 1

    def test_freeze_del(self):
        require_user('root')

        interface = self.ip.interfaces[self.ifd]

        # set up the interface
        with interface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.1.1/24')
            i.up()

        # check
        assert ('172.16.0.1', 24) in interface.ipaddr
        assert ('172.16.1.1', 24) in interface.ipaddr
        assert interface.flags & 1

        interface.freeze()

        # delete interface with an external routine
        remove_link(interface.ifname)

        # wait for a second
        time.sleep(1)

        # check if it is back
        ipdb = IPDB()
        try:
            ifc = ipdb.interfaces[self.ifd]
            assert ('172.16.0.1', 24) in ifc.ipaddr
            assert ('172.16.1.1', 24) in ifc.ipaddr
            assert ifc.flags & 1
        except:
            raise
        finally:
            interface.unfreeze()
            ipdb.release()

    def test_freeze(self):
        require_user('root')

        interface = self.ip.interfaces[self.ifd]

        # set up the interface
        with interface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.1.1/24')
            i.up()

        # check
        assert ('172.16.0.1', 24) in interface.ipaddr
        assert ('172.16.1.1', 24) in interface.ipaddr
        assert interface.flags & 1

        # assert routine
        def probe():
            # The freeze results are dynamic: it is not a real freeze,
            # it is a restore routine. So it takes time for results
            # to stabilize
            err = None
            for _ in range(3):
                err = None
                interface.ipaddr.set_target(
                    (('172.16.0.1', 24), ('172.16.1.1', 24)))
                interface.ipaddr.target.wait()
                try:
                    assert ('172.16.0.1', 24) in interface.ipaddr
                    assert ('172.16.1.1', 24) in interface.ipaddr
                    assert interface.flags & 1
                    break
                except AssertionError as e:
                    err = e
                    continue
                except Exception as e:
                    err = e
                    break
            if err is not None:
                interface.unfreeze()
                i2.close()
                raise err

        # freeze
        interface.freeze()

        # change the interface somehow
        i2 = IPRoute()
        i2.addr('delete', interface.index, '172.16.0.1', 24)
        i2.addr('delete', interface.index, '172.16.1.1', 24)
        probe()

        # unfreeze
        self.ip.interfaces[self.ifd].unfreeze()

        try:
            i2.addr('delete', interface.index, '172.16.0.1', 24)
            i2.addr('delete', interface.index, '172.16.1.1', 24)
        except:
            pass
        finally:
            i2.close()

        # should be up, but w/o addresses
        interface.ipaddr.set_target(set())
        interface.ipaddr.target.wait(3)
        assert ('172.16.0.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert ('172.16.1.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

    def test_snapshots(self):
        require_user('root')

        ifB = self.get_ifname()

        # set up the interface
        with self.ip.interfaces[self.ifd] as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        # check it
        assert ('172.16.0.1', 24) in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

        # make a snapshot
        s = self.ip.interfaces[self.ifd].snapshot()
        i = self.ip.interfaces[self.ifd]

        # check it
        assert i.last_snapshot_id() == s

        # unset the interface
        with self.ip.interfaces[self.ifd] as i:
            i.del_ip('172.16.0.1/24')
            i.down()

        # we can not rename the interface while it is up,
        # so do it in two turns
        with self.ip.interfaces[self.ifd] as i:
            i.ifname = ifB

        # check it
        assert ifB in self.ip.interfaces
        assert self.ifd not in self.ip.interfaces
        y = self.ip.interfaces[ifB]
        assert i == y
        assert ('172.16.0.1', 24) not in y.ipaddr
        assert not (y.flags & 1)

        # revert snapshot
        y.revert(s).commit()

        # check it
        assert ifB not in self.ip.interfaces
        assert self.ifd in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

    @skip_if_not_supported
    def _test_ipv(self, ipv, kind):
        require_user('root')

        ifA = self.get_ifname()

        i = self.ip.create(kind=kind, ifname=ifA).commit()
        if self.ip.interfaces[ifA]._mode == 'explicit':
            self.ip.interfaces[ifA].begin()

        if ipv == 4:
            addr = '172.16.0.1/24'
        elif ipv == 6:
            addr = 'fdb3:84e5:4ff4:55e4::1/64'
        else:
            raise Exception('bad IP version')

        i.add_ip(addr).commit()
        pre_target = addr.split('/')
        target = (pre_target[0], int(pre_target[1]))
        assert target in i['ipaddr']

    def test_ipv4_dummy(self):
        self._test_ipv(4, 'dummy')

    def test_ipv4_bond(self):
        self._test_ipv(4, 'bond')

    def test_ipv4_bridge(self):
        self._test_ipv(4, 'bridge')

    def test_ipv6_dummy(self):
        self._test_ipv(6, 'dummy')

    def test_ipv6_bond(self):
        self._test_ipv(6, 'bond')

    def test_ipv6_bridge(self):
        self._test_ipv(6, 'bridge')

    @skip_if_not_supported
    def test_create_tuntap_fail(self):
        try:
            self.ip.create(ifname='fAiL', kind='tuntap', mode='fail').commit()
        except:
            assert not grep('ip link', pattern='fAiL')
            return
        raise Exception('tuntap create succeded')

    @skip_if_not_supported
    def test_create_tuntap(self):
        require_user('root')

        ifA = self.get_ifname()
        self.ip.create(ifname=ifA, kind='tuntap', mode='tap', uid=1,
                       gid=1).commit()

        assert ifA in self.ip.interfaces
        assert grep('ip link', pattern=ifA)

    @skip_if_not_supported
    def test_ovs_kind_aliases(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        self.ip.create(ifname=ifA, kind='ovs-bridge').commit()
        self.ip.create(ifname=ifB, kind='openvswitch').commit()

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert grep('ip link', pattern=ifA)
        assert grep('ip link', pattern=ifB)

    @skip_if_not_supported
    def test_ovs_add_remove_port(self):
        require_user('root')

        ifOVS = self.get_ifname()
        self.ip.create(ifname=ifOVS, kind='ovs-bridge').commit()
        ifA = self.get_ifname()
        ifB = self.get_ifname()
        self.ip.create(ifname=ifA, kind='dummy')
        self.ip.create(ifname=ifB, peer='x' + ifB, kind='veth')
        self.ip.commit()

        # add ports
        if self.ip.mode == 'explicit':
            self.ip.interfaces[ifOVS].begin()
        self.ip.interfaces[ifOVS].\
            add_port(self.ip.interfaces[ifA]).\
            add_port(self.ip.interfaces[ifB]).\
            commit()

        #
        assert self.ip.interfaces[ifA].master == \
            self.ip.interfaces[ifOVS].index
        assert self.ip.interfaces[ifB].master == \
            self.ip.interfaces[ifOVS].index
        assert self.ip.interfaces[ifA].index in \
            self.ip.interfaces[ifOVS].ports
        assert self.ip.interfaces[ifB].index in \
            self.ip.interfaces[ifOVS].ports

        # remove ports
        if self.ip.mode == 'explicit':
            self.ip.interfaces[ifOVS].begin()
        self.ip.interfaces[ifOVS].\
            del_port(self.ip.interfaces[ifA]).\
            del_port(self.ip.interfaces[ifB]).\
            commit()

        #
        assert self.ip.interfaces[ifA].get('master') is None
        assert self.ip.interfaces[ifB].get('master') is None
        assert not self.ip.interfaces[ifOVS].ports

    def test_global_create(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        self.ip.create(ifname=ifA, kind='dummy')
        self.ip.create(ifname=ifB, kind='dummy')
        self.ip.commit()

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert grep('ip link', pattern=ifA)
        assert grep('ip link', pattern=ifB)

    def test_global_priorities(self):
        require_user('root')
        ifA = self.get_ifname()
        ifB = self.get_ifname()
        ifC = self.get_ifname()
        a = self.ip.create(ifname=ifA, kind='dummy').commit()
        #
        if a._mode == 'explicit':
            a.begin()

        # prepare transaction: two interface creations
        # and one failure on an existing interface
        a.set_address('11:22:33:44:55:66')
        b = self.ip.create(ifname=ifB, kind='dummy')
        c = self.ip.create(ifname=ifC, kind='dummy')
        # now assign priorities
        b.ipdb_priority = 15  # will be execute first
        a.ipdb_priority = 10  # second -- and fail
        c.ipdb_priority = 5  # should not be executed
        # prepare watchdogs
        wdb = self.ip.watchdog(ifname=ifB)
        wdc = self.ip.watchdog(ifname=ifC)
        # run the transaction
        try:
            self.ip.commit()
        except NetlinkError:
            pass
        # control system state
        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert ifC in self.ip.interfaces
        assert a.ipdb_scope == 'system'
        assert b.ipdb_scope == 'create'
        assert c.ipdb_scope == 'create'
        assert a.address != '11:22:33:44:55:66'
        assert grep('ip link', pattern=ifA)
        assert not grep('ip link', pattern=ifB)
        assert not grep('ip link', pattern=ifC)
        wdb.wait(1)
        wdc.wait(1)
        assert wdb.is_set
        assert not wdc.is_set

    def test_global_veth(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        self.ip.create(ifname=ifA, peer=ifB, kind='veth')
        self.ip.commit()

        assert self.ip.interfaces[ifA]['ipdb_scope'] == 'system'
        assert self.ip.interfaces[ifB]['ipdb_scope'] == 'system'

        if self.ip.mode == 'explicit':
            self.ip.interfaces[ifA].begin()
            self.ip.interfaces[ifB].begin()
        self.ip.interfaces[ifA].remove()
        self.ip.interfaces[ifB].remove()
        self.ip.commit()

        assert ifA not in self.ip.interfaces
        assert ifB not in self.ip.interfaces

    def test_global_rollback(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        a = self.ip.create(ifname=ifA, kind='dummy').commit()
        #
        if a._mode == 'explicit':
            a.begin()
        a.remove()
        b = self.ip.create(ifname=ifB, kind='dummy')
        b.set_mtu(1500).set_address('11:22:33:44:55:66')
        try:
            self.ip.commit()
        except NetlinkError:
            pass

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert b.ipdb_scope == 'create'
        assert grep('ip link', pattern=ifA)
        assert not grep('ip link', pattern=ifB)

    def test_global_netns(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        ns = str(uuid.uuid4())

        with IPDB(nl=NetNS(ns)) as nsdb:
            v1 = self.ip.create(ifname='x' + ifA, kind='veth', peer=ifA)
            v2 = self.ip.create(ifname='x' + ifB, kind='veth', peer=ifB)
            if v1._mode == 'explicit':
                v1.begin()
                v2.begin()
            v1.net_ns_fd = ns
            v2.net_ns_fd = ns
            self.ip.commit()
            nsdb.interfaces['x' + ifA].ifname = 'eth0'
            nsdb.interfaces['x' + ifB].ifname = 'eth1'
            nsdb.commit()
            if self.ip.interfaces[ifA]._mode == 'explicit':
                self.ip.interfaces[ifA].begin()
                self.ip.interfaces[ifB].begin()
            self.ip.interfaces[ifA].up()
            self.ip.interfaces[ifB].up()
            self.ip.commit()

        assert 'x' + ifA not in self.ip.interfaces
        assert 'x' + ifB not in self.ip.interfaces
        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert self.ip.interfaces[ifA].flags & 1
        assert self.ip.interfaces[ifB].flags & 1

        if self.ip.interfaces[ifA]._mode == 'explicit':
            self.ip.interfaces[ifA].begin()
            self.ip.interfaces[ifB].begin()
        self.ip.interfaces[ifA].remove()
        self.ip.interfaces[ifB].remove()
        self.ip.commit()
        netns.remove(ns)

    @skip_if_not_supported
    def test_create_veth(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        self.ip.create(ifname=ifA, kind='veth', peer=ifB).commit()

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces

    def test_create_fail(self):
        require_user('root')

        ifA = self.get_ifname()

        # create with mac 11:22:33:44:55:66 should fail
        i = self.ip.create(kind='dummy',
                           ifname=ifA,
                           address='11:22:33:44:55:66')
        try:
            i.commit()
        except NetlinkError:
            pass

        assert i._mode == 'invalid'
        assert ifA not in self.ip.interfaces

    def test_create_dqn(self):
        require_user('root')
        ifA = self.get_ifname()

        i = self.ip.create(kind='dummy', ifname=ifA)
        i.add_ip('172.16.0.1/255.255.255.0')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

    def test_create_double_reuse(self):
        require_user('root')

        ifA = self.get_ifname()
        # create an interface
        i1 = self.ip.create(kind='dummy', ifname=ifA).commit()
        try:
            # this call should fail on the very first step:
            # `bala` interface already exists
            self.ip.create(kind='dummy', ifname=ifA)
        except CreateException:
            pass
        # add `reuse` keyword -- now should pass
        i2 = self.ip.create(kind='dummy', ifname=ifA, reuse=True).commit()
        # assert that we have got references to the same interface
        assert i1 == i2

    @skip_if_not_supported
    def _create_double(self, kind):
        require_user('root')
        ifA = self.get_ifname()

        self.ip.create(kind=kind, ifname=ifA).commit()
        try:
            self.ip.create(kind=kind, ifname=ifA).commit()
        except CreateException:
            pass

    def test_create_double_dummy(self):
        self._create_double('dummy')

    def test_create_double_bridge(self):
        self._create_double('bridge')

    def test_create_double_bond(self):
        self._create_double('bond')

    def test_create_plain(self):
        require_user('root')
        ifA = self.get_ifname()

        i = self.ip.create(kind='dummy', ifname=ifA)
        i.add_ip('172.16.0.1/24')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

    def test_create_and_remove(self):
        require_user('root')

        ifA = self.get_ifname()

        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1/24')
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

        with self.ip.interfaces[ifA] as i:
            i.remove()
        assert ifA not in self.ip.interfaces

    def test_dqn_mask(self):
        require_user('root')

        iface = self.ip.interfaces[self.ifd]
        with iface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.0.2', mask=24)
            i.add_ip('172.16.0.3/255.255.255.0')
            i.add_ip('172.16.0.4', mask='255.255.255.0')

        assert ('172.16.0.1', 24) in iface.ipaddr
        assert ('172.16.0.2', 24) in iface.ipaddr
        assert ('172.16.0.3', 24) in iface.ipaddr
        assert ('172.16.0.4', 24) in iface.ipaddr

    @skip_if_not_supported
    def _create_master(self, kind, **kwarg):

        ifM = self.get_ifname()
        ifP1 = self.get_ifname()
        ifP2 = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifP1).commit()
        self.ip.create(kind='dummy', ifname=ifP2).commit()

        with self.ip.create(kind=kind, ifname=ifM, **kwarg) as i:
            i.add_port(self.ip.interfaces[ifP1])
            i.add_ip('172.16.0.1/24')

        with self.ip.interfaces[ifM] as i:
            i.add_port(self.ip.interfaces[ifP2])
            i.add_ip('172.16.0.2/24')

        assert ('172.16.0.1', 24) in self.ip.interfaces[ifM].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifM].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifM)
        assert '172.16.0.2/24' in get_ip_addr(interface=ifM)
        assert self.ip.interfaces[ifP1].if_master == \
            self.ip.interfaces[ifM].index
        assert self.ip.interfaces[ifP2].if_master == \
            self.ip.interfaces[ifM].index

        with self.ip.interfaces[ifM] as i:
            i.del_port(self.ip.interfaces[ifP1])
            i.del_port(self.ip.interfaces[ifP2])
            i.del_ip('172.16.0.1/24')
            i.del_ip('172.16.0.2/24')

        assert ('172.16.0.1', 24) not in self.ip.interfaces[ifM].ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces[ifM].ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface=ifM)
        assert '172.16.0.2/24' not in get_ip_addr(interface=ifM)
        assert self.ip.interfaces[ifP1].if_master is None
        assert self.ip.interfaces[ifP2].if_master is None

    def test_create_bridge(self):
        require_user('root')
        self._create_master('bridge')

    def test_create_bond(self):
        require_user('root')
        self._create_master('bond')

    def test_create_team(self):
        require_user('root')
        self._create_master('team')

    def test_create_ovs(self):
        require_user('root')
        self._create_master('openvswitch')

    def test_create_bond2(self):
        require_user('root')
        self._create_master('bond', bond_mode=2)

    @skip_if_not_supported
    def _create_macvx_mode(self, kind, mode):
        require_user('root')
        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(**{
            'kind': kind,
            'link': ifdb[ifL],
            'ifname': ifV,
            '%s_mode' % kind: mode
        }).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].link == ifdb[ifL].index
            assert ifdb[ifV]['%s_mode' % kind] == mode
        except Exception:
            raise
        finally:
            ip2.release()

    def test_create_macvtap_vepa(self):
        return self._create_macvx_mode('macvtap', 'vepa')

    def test_create_macvtap_bridge(self):
        return self._create_macvx_mode('macvtap', 'bridge')

    def test_create_macvlan_vepa(self):
        return self._create_macvx_mode('macvlan', 'vepa')

    def test_create_macvlan_bridge(self):
        return self._create_macvx_mode('macvlan', 'bridge')

    def test_create_utf_name(self):
        require_user('root')
        ifO = 'ༀ'
        self.ip.create(kind='dummy', ifname=ifO).commit()
        assert ifO in self.ip.interfaces
        assert self.ip.nl.link_lookup(ifname=ifO)
        if self.ip.interfaces[ifO]._mode == 'explicit':
            self.ip.interfaces[ifO].begin()
        self.ip.interfaces[ifO].remove().commit()

    @skip_if_not_supported
    def test_create_gre(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        with self.ip.create(kind='dummy', ifname=ifL) as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        self.ip.create(kind='gre',
                       ifname=ifV,
                       gre_local='172.16.0.1',
                       gre_remote='172.16.0.2',
                       gre_ttl=16).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].gre_local == '172.16.0.1'
            assert ifdb[ifV].gre_remote == '172.16.0.2'
            assert ifdb[ifV].gre_ttl == 16
        except Exception:
            raise
        finally:
            ip2.release()

    @skip_if_not_supported
    def test_create_vxlan(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vxlan',
                       ifname=ifV,
                       vxlan_link=ifdb[ifL],
                       vxlan_id=101,
                       vxlan_group='239.1.1.1').commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces

        try:
            assert ifdb[ifV].vxlan_link == ifdb[ifL].index
            assert ifdb[ifV].vxlan_group == '239.1.1.1'
            assert ifdb[ifV].vxlan_id == 101
        except Exception:
            raise
        finally:
            ip2.release()

    def test_create_vlan_by_interface(self):
        require_user('root')
        require_8021q()
        ifL = self.get_ifname()
        ifV = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vlan',
                       ifname=ifV,
                       link=self.ip.interfaces[ifL],
                       vlan_id=101).commit()

        assert self.ip.interfaces[ifV].link == \
            self.ip.interfaces[ifL].index

    def test_create_vlan_by_index(self):
        require_user('root')
        require_8021q()
        ifL = self.get_ifname()
        ifV = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vlan',
                       ifname=ifV,
                       link=self.ip.interfaces[ifL].index,
                       vlan_id=101).commit()

        assert self.ip.interfaces[ifV].link == \
            self.ip.interfaces[ifL].index

    def test_remove_secondaries(self):
        require_user('root')

        ifA = self.get_ifname()

        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1', 24)
            i.add_ip('172.16.0.2', 24)

        assert ifA in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)
        assert '172.16.0.2/24' in get_ip_addr(interface=ifA)

        if i._mode == 'explicit':
            i.begin()

        i.del_ip('172.16.0.1', 24)
        i.del_ip('172.16.0.2', 24)
        i.commit()

        assert ('172.16.0.1', 24) not in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface=ifA)
        assert '172.16.0.2/24' not in get_ip_addr(interface=ifA)
Esempio n. 44
0
class TestExplicit(object):
    ip = None
    mode = 'explicit'

    def setup(self):
        self.ap = AddrPool()
        self.iftmp = 'pr2x{0}'
        self.ifaces = []
        self.ifd = self.get_ifname()
        create_link(self.ifd, kind='dummy')
        self.ip = IPDB(mode=self.mode)

    def get_ifname(self):
        naddr = self.ap.alloc()
        ifname = self.iftmp.format(naddr)
        self.ifaces.append(ifname)
        return ifname

    def teardown(self):
        for name in self.ifaces:
            try:
                with self.ip.interfaces[name] as i:
                    i.remove()
            except:
                pass
        self.ip.release()
        self.ifaces = []

    def test_simple(self):
        assert len(list(self.ip.interfaces.keys())) > 0

    def test_empty_transaction(self):
        assert 'lo' in self.ip.interfaces
        with self.ip.interfaces.lo as i:
            assert isinstance(i.mtu, int)

    def test_idx_len(self):
        assert len(self.ip.by_name.keys()) == len(self.ip.by_index.keys())

    def test_idx_set(self):
        assert set(self.ip.by_name.values()) == set(self.ip.by_index.values())

    def test_idx_types(self):
        assert all(isinstance(i, int) for i in self.ip.by_index.keys())
        assert all(isinstance(i, basestring) for i in self.ip.by_name.keys())

    def test_ips(self):
        for name in self.ip.by_name:
            assert len(self.ip.interfaces[name]['ipaddr']) == \
                len(get_ip_addr(name))

    def test_reprs(self):
        assert isinstance(repr(self.ip.interfaces.lo.ipaddr), basestring)
        assert isinstance(repr(self.ip.interfaces.lo), basestring)

    def test_dotkeys(self):
        # self.ip.lo hint for ipython
        assert 'lo' in dir(self.ip.interfaces)
        assert 'lo' in self.ip.interfaces
        assert self.ip.interfaces.lo == self.ip.interfaces['lo']
        # create attribute
        self.ip.interfaces['newitem'] = True
        self.ip.interfaces.newattr = True
        self.ip.interfaces.newitem = None
        assert self.ip.interfaces.newitem == self.ip.interfaces['newitem']
        assert self.ip.interfaces.newitem is None
        # delete attribute
        del self.ip.interfaces.newitem
        del self.ip.interfaces.newattr
        assert 'newattr' not in dir(self.ip.interfaces)

    def test_vlan_slave_bridge(self):
        # https://github.com/svinota/pyroute2/issues/58
        # based on the code by Petr Horáček
        dXname = self.get_ifname()
        vXname = self.get_ifname()
        vYname = self.get_ifname()
        brname = self.get_ifname()

        require_user('root')
        dX = self.ip.create(ifname=dXname, kind='dummy').commit()
        vX = self.ip.create(ifname=vXname, kind='vlan', link=dX,
                            vlan_id=101).commit()
        vY = self.ip.create(ifname=vYname, kind='vlan', link=dX,
                            vlan_id=102).commit()
        with self.ip.create(ifname=brname, kind='bridge') as i:
            i.add_port(vX)
            i.add_port(vY['index'])

        assert vX['index'] in self.ip.interfaces[brname]['ports']
        assert vY['index'] in self.ip.interfaces[brname].ports
        assert vX['link'] == dX['index']
        assert vY['link'] == dX['index']
        assert vX['master'] == self.ip.interfaces[brname]['index']
        assert vY['master'] == self.ip.interfaces[brname].index

    def _test_commit_hook_positive(self):
        require_user('root')

        # test callback, that adds an address by itself --
        # just to check the possibility
        def cb(interface, snapshot, transaction):
            self.ip.nl.addr('add',
                            self.ip.interfaces[self.ifd].index,
                            address='172.16.22.1',
                            mask=24)

        # register callback and check CB chain length
        self.ip.interfaces[self.ifd].register_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 1

        # create a transaction and commit it
        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].add_ip('172.16.21.1/24')
        self.ip.interfaces[self.ifd].commit()

        # added address should be there
        assert ('172.16.21.1', 24) in \
            self.ip.interfaces[self.ifd].ipaddr
        # and the one, added by the callback, too
        assert ('172.16.22.1', 24) in \
            self.ip.interfaces[self.ifd].ipaddr

        # unregister callback
        self.ip.interfaces[self.ifd].unregister_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 0

    def _test_commit_hook_negative(self):
        require_user('root')

        # test exception to differentiate
        class CBException(Exception):
            pass

        # test callback, that always fail
        def cb(interface, snapshot, transaction):
            raise CBException()

        # register callback and check CB chain length
        self.ip.interfaces[self.ifd].register_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 1

        # create a transaction and commit it; should fail
        # 'cause of the callback
        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].add_ip('172.16.21.1/24')
        try:
            self.ip.interfaces[self.ifd].commit()
        except CBException:
            pass

        # added address should be removed
        assert ('172.16.21.1', 24) not in \
            self.ip.interfaces[self.ifd].ipaddr

        # unregister callback
        self.ip.interfaces[self.ifd].unregister_commit_hook(cb)
        assert len(self.ip.interfaces[self.ifd]._commit_hooks) == 0

    def test_review(self):
        assert len(self.ip.interfaces.lo._tids) == 0
        if self.ip.interfaces.lo._mode == 'explicit':
            self.ip.interfaces.lo.begin()
        self.ip.interfaces.lo.add_ip('172.16.21.1/24')
        r = self.ip.interfaces.lo.review()
        assert len(r['+ipaddr']) == 1
        assert len(r['-ipaddr']) == 0
        assert len(r['+ports']) == 0
        assert len(r['-ports']) == 0
        # +/-ipaddr, +/-ports
        assert len([i for i in r if r[i] is not None]) == 4
        self.ip.interfaces.lo.drop()

    def test_rename(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        self.ip.create(ifname=ifA, kind='dummy').commit()

        if self.ip.interfaces[ifA]._mode == 'explicit':
            self.ip.interfaces[ifA].begin()
        self.ip.interfaces[ifA].ifname = ifB
        self.ip.interfaces[ifA].commit()

        assert ifB in self.ip.interfaces
        assert ifA not in self.ip.interfaces

        if self.ip.interfaces[ifB]._mode == 'explicit':
            self.ip.interfaces[ifB].begin()
        self.ip.interfaces[ifB].ifname = ifA
        self.ip.interfaces[ifB].commit()

        assert ifB not in self.ip.interfaces
        assert ifA in self.ip.interfaces

    def test_routes(self):
        require_user('root')
        assert '172.16.0.0/24' not in self.ip.routes

        # create a route
        with self.ip.routes.add({
                'dst': '172.16.0.0/24',
                'gateway': '127.0.0.1'
        }) as r:
            pass
        assert '172.16.0.0/24' in self.ip.routes.keys()
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.1')

        # change the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.gateway = '127.0.0.2'
        assert self.ip.routes['172.16.0.0/24'].gateway == '127.0.0.2'
        assert grep('ip ro', pattern='172.16.0.0/24.*127.0.0.2')

        # delete the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.remove()
        assert '172.16.0.0/24' not in self.ip.routes.keys()
        assert not grep('ip ro', pattern='172.16.0.0/24')

    def test_route_metrics(self):
        require_user('root')
        assert '172.16.0.0/24' not in self.ip.routes.keys()

        # create a route
        self.ip.routes.add({
            'dst': '172.16.0.0/24',
            'gateway': '127.0.0.1',
            'metrics': {
                'mtu': 1360
            }
        }).commit()
        assert grep('ip ro', pattern='172.16.0.0/24.*mtu 1360')

        # change metrics
        with self.ip.routes['172.16.0.0/24'] as r:
            r.metrics.mtu = 1400
        assert self.ip.routes['172.16.0.0/24']['metrics']['mtu'] == 1400
        assert grep('ip ro', pattern='172.16.0.0/24.*mtu 1400')

        # delete the route
        with self.ip.routes['172.16.0.0/24'] as r:
            r.remove()

        assert '172.16.0.0/24' not in self.ip.routes.keys()
        assert not grep('ip ro', pattern='172.16.0.0/24')

    def _test_shadow(self, kind):
        ifA = self.get_ifname()

        a = self.ip.create(ifname=ifA, kind=kind).commit()
        if a._mode == 'explicit':
            a.begin()
        a.shadow().commit()
        assert ifA in self.ip.interfaces
        assert not grep('ip link', pattern=ifA)
        b = self.ip.create(ifname=ifA, kind=kind).commit()
        assert a == b
        assert grep('ip link', pattern=ifA)

    def test_shadow_bond(self):
        require_user('root')
        require_bond()
        self._test_shadow('bond')

    def test_shadow_bridge(self):
        require_user('root')
        require_bridge()
        self._test_shadow('bridge')

    def test_shadow_dummy(self):
        require_user('root')
        self._test_shadow('dummy')

    def test_updown(self):
        require_user('root')

        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].up()
        self.ip.interfaces[self.ifd].commit()
        assert self.ip.interfaces[self.ifd].flags & 1

        if self.ip.interfaces[self.ifd]._mode == 'explicit':
            self.ip.interfaces[self.ifd].begin()
        self.ip.interfaces[self.ifd].down()
        self.ip.interfaces[self.ifd].commit()
        assert not (self.ip.interfaces[self.ifd].flags & 1)

    def test_fail_ipaddr(self):
        require_user('root')

        ifA = self.get_ifname()

        i = self.ip.create(ifname=ifA, kind='dummy').commit()
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.add_ip('123.456.789.1024/153')
        try:
            i.commit()
        except socket.error as e:
            if not e.args[0].startswith('illegal IP'):
                raise
        assert not len(i.ipaddr)
        if i._mode == 'explicit':
            i.begin()
        i.remove().commit()
        assert ifA not in self.ip.interfaces

    def test_json_dump(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        # set up the interface
        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.0.2/24')
            i.up()

        # make a backup
        backup = self.ip.interfaces[ifA].dump()
        assert isinstance(backup, dict)

        # remove index -- make it portable
        del backup['index']
        # serialize
        backup = json.dumps(backup)

        # remove the interface
        with self.ip.interfaces[ifA] as i:
            i.remove()

        # create again, but with different name
        self.ip.create(kind='dummy', ifname=ifB).commit()

        # load the backup
        # 1. prepare to the restore: bring it down
        with self.ip.interfaces[ifB] as i:
            i.down()
        # 2. please notice, the interface will be renamed after the backup
        t = self.ip.interfaces[ifB].load(json.loads(backup))
        self.ip.interfaces[ifB].commit(transaction=t)

        # check :)
        assert ifA in self.ip.interfaces
        assert ifB not in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifA].ipaddr
        assert self.ip.interfaces[ifA].flags & 1

    def test_freeze(self):
        require_user('root')

        interface = self.ip.interfaces[self.ifd]

        # set up the interface
        with interface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.1.1/24')
            i.up()

        # check
        assert ('172.16.0.1', 24) in interface.ipaddr
        assert ('172.16.1.1', 24) in interface.ipaddr
        assert interface.flags & 1

        # assert routine
        def probe():
            # The freeze results are dynamic: it is not a real freeze,
            # it is a restore routine. So it takes time for results
            # to stabilize
            err = None
            for _ in range(3):
                err = None
                interface.ipaddr.set_target(
                    (('172.16.0.1', 24), ('172.16.1.1', 24)))
                interface.ipaddr.target.wait()
                try:
                    assert ('172.16.0.1', 24) in interface.ipaddr
                    assert ('172.16.1.1', 24) in interface.ipaddr
                    assert interface.flags & 1
                    break
                except AssertionError as e:
                    err = e
                    continue
                except Exception as e:
                    err = e
                    break
            if err is not None:
                interface.unfreeze()
                i2.close()
                raise err

        # freeze
        interface.freeze()

        # change the interface somehow
        i2 = IPRoute()
        i2.addr('delete', interface.index, '172.16.0.1', 24)
        i2.addr('delete', interface.index, '172.16.1.1', 24)
        probe()

        # unfreeze
        self.ip.interfaces[self.ifd].unfreeze()

        try:
            i2.addr('delete', interface.index, '172.16.0.1', 24)
            i2.addr('delete', interface.index, '172.16.1.1', 24)
        except:
            pass
        finally:
            i2.close()

        # should be up, but w/o addresses
        interface.ipaddr.set_target(set())
        interface.ipaddr.target.wait(3)
        assert ('172.16.0.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert ('172.16.1.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

    def test_snapshots(self):
        require_user('root')

        ifB = self.get_ifname()

        # set up the interface
        with self.ip.interfaces[self.ifd] as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        # check it
        assert ('172.16.0.1', 24) in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

        # make a snapshot
        s = self.ip.interfaces[self.ifd].snapshot()
        i = self.ip.interfaces[self.ifd]

        # check it
        assert i.last_snapshot_id() == s

        # unset the interface
        with self.ip.interfaces[self.ifd] as i:
            i.del_ip('172.16.0.1/24')
            i.down()

        # we can not rename the interface while it is up,
        # so do it in two turns
        with self.ip.interfaces[self.ifd] as i:
            i.ifname = ifB

        # check it
        assert ifB in self.ip.interfaces
        assert self.ifd not in self.ip.interfaces
        y = self.ip.interfaces[ifB]
        assert i == y
        assert ('172.16.0.1', 24) not in y.ipaddr
        assert not (y.flags & 1)

        # revert snapshot
        y.revert(s).commit()

        # check it
        assert ifB not in self.ip.interfaces
        assert self.ifd in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1

    def _test_ipv(self, ipv, kind):
        require_user('root')

        ifA = self.get_ifname()

        i = self.ip.create(kind=kind, ifname=ifA).commit()
        if self.ip.interfaces[ifA]._mode == 'explicit':
            self.ip.interfaces[ifA].begin()

        if ipv == 4:
            addr = '172.16.0.1/24'
        elif ipv == 6:
            addr = 'fdb3:84e5:4ff4:55e4::1/64'
        else:
            raise Exception('bad IP version')

        i.add_ip(addr).commit()
        pre_target = addr.split('/')
        target = (pre_target[0], int(pre_target[1]))
        assert target in i['ipaddr']

    def test_ipv4_dummy(self):
        self._test_ipv(4, 'dummy')

    def test_ipv4_bond(self):
        self._test_ipv(4, 'bond')

    def test_ipv4_bridge(self):
        self._test_ipv(4, 'bridge')

    def test_ipv6_dummy(self):
        self._test_ipv(6, 'dummy')

    def test_ipv6_bond(self):
        self._test_ipv(6, 'bond')

    def test_ipv6_bridge(self):
        self._test_ipv(6, 'bridge')

    def test_create_tuntap_fail(self):
        try:
            self.ip.create(ifname='fAiL', kind='tuntap', mode='fail').commit()
        except:
            assert not grep('ip link', pattern='fAiL')
            return
        raise Exception('tuntap create succeded')

    def test_create_tuntap(self):
        require_user('root')

        ifA = self.get_ifname()
        self.ip.create(ifname=ifA, kind='tuntap', mode='tap', uid=1,
                       gid=1).commit()

        assert ifA in self.ip.interfaces
        assert grep('ip link', pattern=ifA)

    def test_ovs_kind_aliases(self):
        require_user('root')
        require_executable('ovs-vsctl')

        ifA = self.get_ifname()
        ifB = self.get_ifname()
        self.ip.create(ifname=ifA, kind='ovs-bridge').commit()
        self.ip.create(ifname=ifB, kind='openvswitch').commit()

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces
        assert grep('ip link', pattern=ifA)
        assert grep('ip link', pattern=ifB)

    def test_create_veth(self):
        require_user('root')

        ifA = self.get_ifname()
        ifB = self.get_ifname()

        self.ip.create(ifname=ifA, kind='veth', peer=ifB).commit()

        assert ifA in self.ip.interfaces
        assert ifB in self.ip.interfaces

    def test_create_fail(self):
        require_user('root')

        ifA = self.get_ifname()

        # create with mac 11:22:33:44:55:66 should fail
        i = self.ip.create(kind='dummy',
                           ifname=ifA,
                           address='11:22:33:44:55:66')
        try:
            i.commit()
        except NetlinkError:
            pass

        assert i._mode == 'invalid'
        assert ifA not in self.ip.interfaces

    def test_create_dqn(self):
        require_user('root')
        ifA = self.get_ifname()

        i = self.ip.create(kind='dummy', ifname=ifA)
        i.add_ip('172.16.0.1/255.255.255.0')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

    def test_create_double_reuse(self):
        require_user('root')

        ifA = self.get_ifname()
        # create an interface
        i1 = self.ip.create(kind='dummy', ifname=ifA).commit()
        try:
            # this call should fail on the very first step:
            # `bala` interface already exists
            self.ip.create(kind='dummy', ifname=ifA)
        except CreateException:
            pass
        # add `reuse` keyword -- now should pass
        i2 = self.ip.create(kind='dummy', ifname=ifA, reuse=True).commit()
        # assert that we have got references to the same interface
        assert i1 == i2

    def _create_double(self, kind):
        require_user('root')
        ifA = self.get_ifname()

        self.ip.create(kind=kind, ifname=ifA).commit()
        try:
            self.ip.create(kind=kind, ifname=ifA).commit()
        except CreateException:
            pass

    def test_create_double_dummy(self):
        self._create_double('dummy')

    def test_create_double_bridge(self):
        self._create_double('bridge')

    def test_create_double_bond(self):
        self._create_double('bond')

    def test_create_plain(self):
        require_user('root')
        ifA = self.get_ifname()

        i = self.ip.create(kind='dummy', ifname=ifA)
        i.add_ip('172.16.0.1/24')
        i.commit()
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

    def test_create_and_remove(self):
        require_user('root')

        ifA = self.get_ifname()

        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1/24')
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)

        with self.ip.interfaces[ifA] as i:
            i.remove()
        assert ifA not in self.ip.interfaces

    def test_dqn_mask(self):
        require_user('root')

        iface = self.ip.interfaces[self.ifd]
        with iface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.0.2', mask=24)
            i.add_ip('172.16.0.3/255.255.255.0')
            i.add_ip('172.16.0.4', mask='255.255.255.0')

        assert ('172.16.0.1', 24) in iface.ipaddr
        assert ('172.16.0.2', 24) in iface.ipaddr
        assert ('172.16.0.3', 24) in iface.ipaddr
        assert ('172.16.0.4', 24) in iface.ipaddr

    def _create_master(self, kind, **kwarg):

        ifM = self.get_ifname()
        ifP1 = self.get_ifname()
        ifP2 = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifP1).commit()
        self.ip.create(kind='dummy', ifname=ifP2).commit()

        with self.ip.create(kind=kind, ifname=ifM, **kwarg) as i:
            i.add_port(self.ip.interfaces[ifP1])
            i.add_ip('172.16.0.1/24')

        with self.ip.interfaces[ifM] as i:
            i.add_port(self.ip.interfaces[ifP2])
            i.add_ip('172.16.0.2/24')

        assert ('172.16.0.1', 24) in self.ip.interfaces[ifM].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifM].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifM)
        assert '172.16.0.2/24' in get_ip_addr(interface=ifM)
        assert self.ip.interfaces[ifP1].if_master == \
            self.ip.interfaces[ifM].index
        assert self.ip.interfaces[ifP2].if_master == \
            self.ip.interfaces[ifM].index

        with self.ip.interfaces[ifM] as i:
            i.del_port(self.ip.interfaces[ifP1])
            i.del_port(self.ip.interfaces[ifP2])
            i.del_ip('172.16.0.1/24')
            i.del_ip('172.16.0.2/24')

        assert ('172.16.0.1', 24) not in self.ip.interfaces[ifM].ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces[ifM].ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface=ifM)
        assert '172.16.0.2/24' not in get_ip_addr(interface=ifM)
        assert self.ip.interfaces[ifP1].if_master is None
        assert self.ip.interfaces[ifP2].if_master is None

    def test_create_bridge(self):
        require_user('root')
        require_bridge()
        self._create_master('bridge')

    def test_create_bond(self):
        require_user('root')
        require_bond()
        self._create_master('bond')

    def test_create_team(self):
        require_user('root')
        require_executable('teamd')
        require_executable('teamdctl')
        self._create_master('team')

    def test_create_ovs(self):
        require_user('root')
        require_executable('ovs-vsctl')
        self._create_master('openvswitch')

    def test_create_bond2(self):
        require_user('root')
        require_bond()
        self._create_master('bond', bond_mode=2)

    def _create_macvx_mode(self, kind, mode):
        require_user('root')
        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(**{
            'kind': kind,
            'link': ifdb[ifL],
            'ifname': ifV,
            '%s_mode' % kind: mode
        }).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].link == ifdb[ifL].index
            assert ifdb[ifV]['%s_mode' % kind] == mode
        except Exception:
            raise
        finally:
            ip2.release()

    def test_create_macvtap_vepa(self):
        return self._create_macvx_mode('macvtap', 'vepa')

    def test_create_macvtap_bridge(self):
        return self._create_macvx_mode('macvtap', 'bridge')

    def test_create_macvlan_vepa(self):
        return self._create_macvx_mode('macvlan', 'vepa')

    def test_create_macvlan_bridge(self):
        return self._create_macvx_mode('macvlan', 'bridge')

    def test_create_gre(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        with self.ip.create(kind='dummy', ifname=ifL) as i:
            i.add_ip('172.16.0.1/24')
            i.up()

        self.ip.create(kind='gre',
                       ifname=ifV,
                       gre_local='172.16.0.1',
                       gre_remote='172.16.0.2',
                       gre_ttl=16).commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces
        try:
            assert ifdb[ifV].gre_local == '172.16.0.1'
            assert ifdb[ifV].gre_remote == '172.16.0.2'
            assert ifdb[ifV].gre_ttl == 16
        except Exception:
            raise
        finally:
            ip2.release()

    def test_create_vxlan(self):
        require_user('root')

        ifL = self.get_ifname()
        ifV = self.get_ifname()
        ifdb = self.ip.interfaces

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vxlan',
                       ifname=ifV,
                       vxlan_link=ifdb[ifL],
                       vxlan_id=101,
                       vxlan_group='239.1.1.1').commit()

        ip2 = IPDB()
        ifdb = ip2.interfaces

        try:
            assert ifdb[ifV].vxlan_link == ifdb[ifL].index
            assert ifdb[ifV].vxlan_group == '239.1.1.1'
            assert ifdb[ifV].vxlan_id == 101
        except Exception:
            raise
        finally:
            ip2.release()

    def test_create_vlan_by_interface(self):
        require_user('root')
        require_8021q()
        ifL = self.get_ifname()
        ifV = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vlan',
                       ifname=ifV,
                       link=self.ip.interfaces[ifL],
                       vlan_id=101).commit()

        assert self.ip.interfaces[ifV].link == \
            self.ip.interfaces[ifL].index

    def test_create_vlan_by_index(self):
        require_user('root')
        require_8021q()
        ifL = self.get_ifname()
        ifV = self.get_ifname()

        self.ip.create(kind='dummy', ifname=ifL).commit()
        self.ip.create(kind='vlan',
                       ifname=ifV,
                       link=self.ip.interfaces[ifL].index,
                       vlan_id=101).commit()

        assert self.ip.interfaces[ifV].link == \
            self.ip.interfaces[ifL].index

    def test_remove_secondaries(self):
        require_user('root')

        ifA = self.get_ifname()

        with self.ip.create(kind='dummy', ifname=ifA) as i:
            i.add_ip('172.16.0.1', 24)
            i.add_ip('172.16.0.2', 24)

        assert ifA in self.ip.interfaces
        assert ('172.16.0.1', 24) in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' in get_ip_addr(interface=ifA)
        assert '172.16.0.2/24' in get_ip_addr(interface=ifA)

        if i._mode == 'explicit':
            i.begin()

        i.del_ip('172.16.0.1', 24)
        i.del_ip('172.16.0.2', 24)
        i.commit()

        assert ('172.16.0.1', 24) not in self.ip.interfaces[ifA].ipaddr
        assert ('172.16.0.2', 24) not in self.ip.interfaces[ifA].ipaddr
        assert '172.16.0.1/24' not in get_ip_addr(interface=ifA)
        assert '172.16.0.2/24' not in get_ip_addr(interface=ifA)
Esempio n. 45
0
class TestBasic(object):
    def readfunc(self, prompt):
        ret = self.queue.get()
        if ret is None:
            raise Exception("EOF")
        else:
            return ret

    def setup(self):
        self.ipdb = IPDB()
        if sys.version_info[0] == 2:
            self.io = io.BytesIO()
        else:
            self.io = io.StringIO()
        self.queue = Queue()
        self.con = Console(stdout=self.io)
        self.con.isatty = False
        self.thread = threading.Thread(target=self.con.interact,
                                       args=[
                                           self.readfunc,
                                       ])
        self.thread.start()

    def feed(self, script):
        for line in script.split("\n"):
            self.queue.put(line)
        self.queue.put(None)
        self.thread.join()
        self.thread = None
        self.io.flush()

    def teardown(self):
        if self.thread is not None:
            self.queue.put(None)
            self.thread.join()
        self.ipdb.release()
        try:
            self.con.close()
        except:
            pass

    # 8<---------------- test routines ------------------------------

    def test_dump_lo(self):
        self.feed(scripts['test_dump_lo'])
        interface = json.loads(self.io.getvalue())
        assert interface['address'] == '00:00:00:00:00:00'
        #
        # ip addresses not present in the NDB dumps yet
        #
        # assert ('127.0.0.1', 8) in interface['ipaddr']

    def _test_ensure(self):
        require_user('root')
        self.feed(scripts['test_ensure'])
        assert 'test01' in self.ipdb.interfaces
        assert ('172.16.189.5', 24) in self.ipdb.interfaces.test01.ipaddr
        self.ipdb.interfaces.test01.remove().commit()

    def test_comments_bang(self):
        require_user('root')
        self.feed(scripts['test_comments_bang'])
        interface = json.loads(self.io.getvalue())
        assert interface['address'] == '00:11:22:33:44:55'
        assert interface['ifname'] == 'test01'

    def test_comments_hash(self):
        require_user('root')
        self.feed(scripts['test_comments_hash'])
        interface = json.loads(self.io.getvalue())
        assert interface['address'] == '00:11:22:33:44:55'
        assert interface['ifname'] == 'test01'

    def test_comments_mixed(self):
        require_user('root')
        self.feed(scripts['test_comments_mixed'])
        interface = json.loads(self.io.getvalue())
        assert interface['address'] == '00:11:22:33:44:55'
        assert interface['ifname'] == 'test01'
Esempio n. 46
0
class Console(code.InteractiveConsole):
    def __init__(self, stdout=None):
        global HAS_READLINE
        self.ipdb = IPDB()
        self.ptr = self.ipdb
        self.ptrname = None
        self.stack = []
        self.matches = []
        self.isatty = sys.stdin.isatty()
        self.prompt = ''
        self.stdout = stdout or sys.stdout
        self.set_prompt()
        code.InteractiveConsole.__init__(self)
        if HAS_READLINE:
            readline.parse_and_bind('tab: complete')
            readline.set_completer(self.completer)
            readline.set_completion_display_matches_hook(self.display)

    def close(self):
        self.ipdb.release()

    def write(self, text=''):
        self.lprint(text)

    def pprint(self, text=''):
        pprint(text, stream=self.stdout)
        self.stdout.flush()

    def lprint(self, text='', end='\n'):
        print(text, file=self.stdout, end=end)
        self.stdout.flush()

    def help(self):
        self.lprint("Built-in commands: \n"
                    "debug\t-- run pdb (if installed)\n"
                    "exit\t-- exit cli\n"
                    "ls\t-- list current namespace\n"
                    ".\t-- print the current object\n"
                    ".. or ;\t-- one level up\n")

    def set_prompt(self, prompt=None):
        if self.isatty:
            if isinstance(self.ptr, Interface):
                self.prompt = 'if : %s > ' % (self.ptr.ifname)
            elif prompt is not None:
                self.prompt = '%s > ' % (prompt)
            else:
                self.prompt = '%s > ' % (self.ptr.__class__.__name__)
            self.prompt = '%s@%s : %s' % (getpass.getuser(),
                                          (socket.gethostname().split('.')[0]),
                                          self.prompt)

    def convert(self, arg):
        if re.match('^[0-9]+$', arg):
            return int(arg)
        else:
            return arg

    def interact(self, readfunc=None):

        if readfunc is None:
            readfunc = self.raw_input

        if self.isatty:
            self.lprint("IPDB cli prototype")
        while True:
            try:
                cmd = readfunc(self.prompt)
            except:
                self.lprint()
                break

            # strip comments
            fbang = cmd.find('!')
            fhash = cmd.find('#')
            if fbang >= 0:
                cmd = cmd[:fbang]
            if cmd.find('#') >= 0:
                cmd = cmd[:fhash]

            # skip empty strings
            if not len(cmd.strip()):
                continue

            # calculate leading whitespaces
            lcmd = cmd.lstrip()
            lspaces = len(cmd) - len(lcmd)
            # strip all whitespaces
            cmd = cmd.strip()

            # compare spaces with self.ptr
            if not self.isatty:
                while self.stack and self.stack[-1][2] >= lspaces:
                    # pop stack
                    self.ptr, self.ptrname, spaces = self.stack.pop()
                    # compare spaces
                    if spaces == lspaces:
                        break
                    elif spaces < lspaces:
                        self.lprint('indentation warning: <%s>' % cmd)
                        break
                self.set_prompt(self.ptrname)

            if not cmd:
                continue
            elif cmd == 'debug':
                if HAS_PDB:
                    pdb.set_trace()
                else:
                    self.lprint("pdb is not available")
            elif cmd == 'exit':
                break
            elif cmd == 'ls':
                self.lprint(dir(self.ptr))
            elif cmd == 'help':
                self.help()
            elif cmd == '.':
                self.lprint(repr(self.ptr))
            elif cmd in ('..', ';'):
                if self.stack:
                    self.ptr, self.ptrname, lspaces = self.stack.pop()
                self.set_prompt(self.ptrname)
            else:
                # parse the command line into tokens
                #
                # symbols .:/ etc. are needed to represent IP addresses
                # as whole tokens
                #
                # quotes should be stripped
                #
                parser = shlex.shlex(cmd)
                parser.wordchars += '.:/-+*'
                pre_tokens = list(parser)
                tokens = []
                for token in pre_tokens:
                    if token[0] == token[-1] and token[0] in ("\"'"):
                        tokens.append(token[1:-1])
                    else:
                        tokens.append(token)

                # an attribute
                obj = getattr(self.ptr, tokens[0], None)
                if obj is None:
                    # try a kay
                    try:
                        obj = self.ptr[self.convert(cmd)]
                    except Exception:
                        self.lprint('object not found')
                        continue
                if hasattr(obj, '__call__'):
                    argv = []
                    kwarg = {}
                    length = len(tokens)
                    x = 1
                    while x < len(tokens):
                        # is it a kwarg?
                        if x < length - 2 and tokens[x + 1] == '=':
                            kwarg[tokens[x]] = self.convert(tokens[x + 2])
                            x += 3
                        else:
                            argv.append(self.convert(tokens[x]))
                            x += 1
                    try:
                        ret = obj(*argv, **kwarg)
                        if ret and not isinstance(ret, (Transactional, IPDB)):
                            self.pprint(ret)
                    except:
                        self.showtraceback()
                else:
                    if isinstance(obj, (basestring, int, float)):
                        # is it a simple attribute?
                        if isinstance(self.ptr, Transactional) and \
                                len(tokens) > 1:
                            # set it
                            self.ptr[tokens[0]] = self.convert(tokens[1])
                        else:
                            # or print it
                            self.pprint(self.ptr[tokens[0]])
                    else:
                        # otherwise change the context
                        self.stack.append((self.ptr, self.ptrname, lspaces))
                        self.ptr = obj
                        self.ptrname = tokens[0]
                        self.set_prompt(tokens[0])

    def completer(self, text, state):
        if state == 0:
            d = [x for x in dir(self.ptr) if x.startswith(text)]
            if isinstance(self.ptr, dict):
                keys = [str(y) for y in self.ptr.keys()]
                d.extend([x for x in keys if x.startswith(text)])
            self.matches = d
        try:
            return self.matches[state]
        except:
            pass

    def display(self, line, matches, length):
        self.lprint()
        self.lprint(matches)
        self.lprint('%s%s' % (self.prompt, line), end='')
Esempio n. 47
0
                disable_ipv6=True))

        # For each namespace that want to connect to the ebpf bridge
        # We link it to the dummy interface behind which we run ebpf learning/forwarding code
        # logically: Attaching individual namespace interface into the ebpf bridge.
        # programmatically: running ebpf engress code on each interface
        temp_index=1
        for host in host_info:
            ipr.tc("add", "ingress", host[1].index, "ffff:")
            ipr.tc("add-filter", "bpf", host[1].index, ":1", fd=ingress_fn.fd,
                   name=ingress_fn.name, parent="ffff:", action="drop", classid=1)
            # Passing namespace interface info to dataplane module.
            conf[c_int(temp_index)] = c_int(host[1].index)
            temp_index=temp_index+1

try:
    sim = BridgeSimulation(ipdb)
    sim.start()
    input("Press enter to quit:")
except Exception,e:
    print str(e)
    if "sim" in locals():
        for p in sim.processes: p.kill(); p.wait(); p.release()
finally:
    if "ebpf_br" in ipdb.interfaces: ipdb.interfaces["ebpf_br"].remove().commit()
    if "sim" in locals(): sim.release()
    ipdb.release()
    null.close()


Esempio n. 48
0
def clean(graph, dry_run=False, instance_id=None, strays=False):
    """
    Remove namespaces listed in :data:`graph` and stop scripts

    :param networkx.Graph graph: The graph for which we want to clean up
    :param bool dry_run: If set makes Meshinery not touch any namespaces
    :param str instance_id: If set changes the middle section of each
    namespace's name; current PID by default

    :return networkx.Graph: The same graph after cleanup
    """
    if instance_id is None:
        instance_id = os.getpid()

    # Remove namespaces and kill running commands if applicable
    for node_name in graph:
        node = graph.node[node_name]
        netns_name = 'meshinery-{}-{}'.format(instance_id, node_name)
        try:
            if not dry_run:
                netns.remove(netns_name)
                logging.info('Removed namespace {}'.format(netns_name))

        # The namespace does not exist
        except FileNotFoundError as e:
            logging.debug('Namespace {} doesn\'t exist - not removing'.format(
                netns_name))

        # Grab the per-node command and see if it's still running
        cmd_handle = node.get('command_handle')
        if cmd_handle is not None:
            if cmd_handle.poll() is not None:
                logging.warn('{}: "{}" was not running at cleanup time'.format(
                    node_name, node['command']))

            # Play nice - send initial SIGTERM
            cmd_handle.terminate()
            logging.debug('{}: Sent SIGTERM to PID {} ("{}")'.format(
                node['netns'], cmd_handle.pid, node['command']))

            # Wait the specified/default time before nuclear option
            command_exit_delay = node.get('command_exit_delay',
                                          DEFAULT_COMMAND_EXIT_TIMEOUT)
            time.sleep(command_exit_delay)

            # Send the SIGKILL if applicable
            if cmd_handle.poll() is None:
                cmd_handle.kill()
                logging.debug(
                    '{nn}: "{cmd}" was SIGKILLed (was PID {pid})'.format(
                        nn=node_name, cmd=node['command'], pid=cmd_handle.pid))
            else:
                logging.debug(
                    '{nn}: "{cmd}" quit gracefully. (was PID {pid})'.format(
                        nn=node_name, cmd=node['command'], pid=cmd_handle.pid))

            stdout, stderr = cmd_handle.communicate()
            logging.debug('{nn}: "{cmd}" stdout:\n{out}'.format(
                nn=node_name, cmd=node['command'], out=str(stdout, 'utf-8')))
            logging.debug('{nn}: "{cmd}" stderr:\n{err}'.format(
                nn=node_name, cmd=node['command'], err=str(stderr, 'utf-8')))
        else:
            logging.debug('{}: No command to stop.'.format(node_name))

    # Remove stray interfaces
    if strays:
        ipdb = IPDB()
        for node_name_a, node_name_b in graph.edges:
            if_name = '{}-{}'.format(node_name_a, node_name_b)
            try:
                ipdb.interfaces[if_name].remove()
                logging.info('Removed stray interface {}'.format(if_name))
            except KeyError as e:
                logging.debug(
                    'Stray interface {} doesn\'t exist -- not removing'.format(
                        if_name))
        ipdb.commit()
        ipdb.release()