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_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 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 _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_flush_routes(self): require_user('root') self.ip.link('set', index=self.ifaces[0], state='up') self.ip.addr('add', self.ifaces[0], address='172.16.0.2', mask=24) self.ip.route('add', prefix='172.16.1.0', mask=24, gateway='172.16.0.1', table=100) self.ip.route('add', prefix='172.16.2.0', mask=24, gateway='172.16.0.1', table=100) assert grep('ip route show table 100', pattern='172.16.1.0/24.*172.16.0.1') assert grep('ip route show table 100', pattern='172.16.2.0/24.*172.16.0.1') self.ip.flush_routes(table=100) assert not grep('ip route show table 100', pattern='172.16.1.0/24.*172.16.0.1') assert not grep('ip route show table 100', pattern='172.16.2.0/24.*172.16.0.1')
def test_route_replace_existing(self): # route('replace', ...) should succeed, if route exists require_user('root') naddr = str(self.ipnets[1].network) ifaddr1 = self.ifaddr() ifaddr2 = self.ifaddr() ifaddr3 = self.ifaddr() self.ip.link('set', index=self.ifaces[0], state='up') self.ip.addr('add', self.ifaces[0], address=ifaddr1, mask=24) self.ip.route('replace', dst=naddr, mask=24, gateway=ifaddr2, table=100) assert grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr2)) self.ip.route('replace', dst=naddr, mask=24, gateway=ifaddr3, table=100) assert not grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr2)) assert grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr3)) self.ip.flush_routes(table=100) assert not grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr3))
def test_ancient_bridge(self): require_user('root') # 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 set_ancient(True) # create bridge try: 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) finally: set_ancient(False) 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) in self.ip.interfaces.bala.ipaddr assert ('172.16.0.2', 24) in self.ip.interfaces.bala.ipaddr assert self.ip.interfaces.bala_port0.index in \ self.ip.interfaces.bala.ports assert self.ip.interfaces.bala_port1.index in \ self.ip.interfaces.bala.ports
def test_generic_callback(self): require_user('root') def cb(ipdb, obj, action): if action == 'RTM_NEWLINK' and \ obj['ifname'].startswith('bala_port'): with ipdb.exclusive: ipdb.interfaces.bala.add_port(obj) ipdb.interfaces.bala.commit() # create bridge self.ip.create(kind='bridge', ifname='bala').commit() # wait the bridge to be created self.ip.wait_interface(ifname='bala') # register callback self.ip.register_callback(cb) # create ports self.ip.create(kind='dummy', ifname='bala_port0').commit() self.ip.create(kind='dummy', ifname='bala_port1').commit() # sleep for interfaces self.ip.wait_interface(ifname='bala_port0') self.ip.wait_interface(ifname='bala_port1') time.sleep(1) # check that ports are attached assert self.ip.interfaces.bala_port0.index in \ self.ip.interfaces.bala.ports assert self.ip.interfaces.bala_port1.index in \ self.ip.interfaces.bala.ports
def setup(self): require_user('root') self._nofile = resource.getrlimit(resource.RLIMIT_NOFILE) soft, hard = self._nofile new_limit = (min(soft, RESPAWNS / 2), min(hard, RESPAWNS / 2)) resource.setrlimit(resource.RLIMIT_NOFILE, new_limit) self._socket_fd_count = count_socket_fds()
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_generic_post_callback(self): require_user('root') require_bridge() def cb(ipdb, msg, action): if action == 'RTM_NEWLINK' and \ msg.get_attr('IFLA_IFNAME', '').startswith('bala_port'): with ipdb.exclusive: obj = ipdb.interfaces[msg['index']] ipdb.interfaces.bala.add_port(obj) ipdb.interfaces.bala.commit() wd0 = self.ip.watchdog(ifname='bala') wd1 = self.ip.watchdog(ifname='bala_port0') wd2 = self.ip.watchdog(ifname='bala_port1') # create bridge self.ip.create(kind='bridge', ifname='bala').commit() wd0.wait() # register callback self.ip.register_callback(cb) # create ports self.ip.create(kind='dummy', ifname='bala_port0').commit() self.ip.create(kind='dummy', ifname='bala_port1').commit() wd1.wait() wd2.wait() time.sleep(1) # check that ports are attached assert self.ip.interfaces.bala_port0.index in \ self.ip.interfaces.bala.ports assert self.ip.interfaces.bala_port1.index in \ self.ip.interfaces.bala.ports # unregister callback self.ip.unregister_callback(cb)
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_mass_ipv6(self): # # Achtung! This test is time consuming. # It is really time consuming, I'm not not # kidding you. Beware. # require_user('root') base = 'fdb3:84e5:4ff4:55e4::{0}' limit = int(os.environ.get('PYROUTE2_SLIMIT', '0x800'), 16) # add addresses for idx in range(limit): self.ip.addr('add', self.ifaces[0], base.format(hex(idx)[2:]), 48) # assert addresses in two steps, to ease debug addrs = self.ip.get_addr(10) assert len(addrs) >= limit # clean up addresses # # it is not required, but if you don't do that, # you'll get this on the interface removal: # # >> kernel:BUG: soft lockup - CPU#0 stuck for ... # # so, not to scare people, remove addresses gracefully # one by one # # it also verifies all the addresses are in place for idx in reversed(range(limit)): self.ip.addr('delete', self.ifaces[0], base.format(hex(idx)[2:]), 48)
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)
def test_remove_link(self): require_user('root') try: self.ip.link_remove(self.ifaces[0]) except NetlinkError: pass assert len(self.ip.link_lookup(ifname=self.dev)) == 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()
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_symbolic_flags_ifaddrmsg(self): require_user('root') self.ip.link('set', index=self.ifaces[0], state='up') self.ip.addr('add', self.ifaces[0], '172.16.1.1', 24) addr = [x for x in self.ip.get_addr() if x.get_attr('IFA_LOCAL') == '172.16.1.1'][0] assert 'IFA_F_PERMANENT' in addr.flags2names(addr['flags'])
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_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()
def test_generic_post_callback(self): require_user('root') require_bridge() ifP1 = self.get_ifname() ifP2 = self.get_ifname() ifM = self.get_ifname() def cb(ipdb, msg, action): if action == 'RTM_NEWLINK' and \ msg.get_attr('IFLA_IFNAME', '') in (ifP1, ifP2): obj = ipdb.interfaces[msg['index']] ipdb.interfaces[ifM].add_port(obj) ipdb.interfaces[ifM].commit() wd0 = self.ip.watchdog(ifname=ifM) wd1 = self.ip.watchdog(ifname=ifP1) wd2 = self.ip.watchdog(ifname=ifP2) # create bridge self.ip.create(kind='bridge', ifname=ifM).commit() wd0.wait() # register callback self.ip.register_callback(cb) # create ports self.ip.create(kind='dummy', ifname=ifP1).commit() self.ip.create(kind='dummy', ifname=ifP2).commit() wd1.wait() wd2.wait() # check that ports are attached assert self.ip.interfaces[ifP1].index in \ self.ip.interfaces[ifM].ports assert self.ip.interfaces[ifP2].index in \ self.ip.interfaces[ifM].ports # unregister callback self.ip.unregister_callback(cb)
def setup(self): require_user('root') self.if_simple = None self.interfaces = self.create_interfaces() self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, sources=self.nl_class(**self.nl_kwarg))
def test_context_fail(self): require_user("root") try: with self.ip.interfaces[self.ifname] as i: i.down() except TypeError: pass
def setup(self): require_user('root') self.rlink = Rlink() try: self.rlink.bind('EXMPL_GENL', rcmd) except NetlinkError: raise SkipTest('module not loaded')
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)
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_lwtunnel_multipath_mpls(self): require_kernel(4, 4) require_user('root') require_kernel(4, 5) naddr = str(self.ipnets[1].network) self.ip.route('add', dst='%s/24' % naddr, multipath=[{'encap': {'type': 'mpls', 'labels': 500}, 'oif': 1}, {'encap': {'type': 'mpls', 'labels': '600/700'}, 'gateway': '127.0.0.4'}]) routes = self.ip.route('dump', dst='%s/24' % naddr) assert len(routes) == 1 mp = routes[0].get_attr('RTA_MULTIPATH') assert len(mp) == 2 assert mp[0]['oif'] == 1 assert mp[0].get_attr('RTA_ENCAP_TYPE') == 1 labels = mp[0].get_attr('RTA_ENCAP').get_attr('MPLS_IPTUNNEL_DST') assert len(labels) == 1 assert labels[0]['bos'] == 1 assert labels[0]['label'] == 500 assert mp[1].get_attr('RTA_ENCAP_TYPE') == 1 labels = mp[1].get_attr('RTA_ENCAP').get_attr('MPLS_IPTUNNEL_DST') assert len(labels) == 2 assert labels[0]['bos'] == 0 assert labels[0]['label'] == 600 assert labels[1]['bos'] == 1 assert labels[1]['label'] == 700 self.ip.route('del', dst='%s/24' % naddr)
def _create_master(self, kind): 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') 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_addr_broadcast_default(self): require_user('root') self.ip.addr('add', self.ifaces[0], address='172.16.0.1', mask=24, broadcast=True) assert '172.16.0.255' in get_ip_brd()
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_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_create(self): require_user('root') nsid = str(uuid4()) ipdb_main = IPDB() ipdb_test = IPDB(nl=NetNS(nsid)) # create VETH pair ipdb_main.create(ifname='v0p0', kind='veth', peer='v0p1').commit() # move the peer to netns with ipdb_main.interfaces.v0p1 as veth: veth.net_ns_fd = nsid # assign addresses with ipdb_main.interfaces.v0p0 as veth: veth.add_ip('172.16.200.1/24') veth.up() with ipdb_test.interfaces.v0p1 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.v0p1.neighbors) # ret_arp = list(ipdb_test.interfaces.v0p1.neighbors) # cleanup ipdb_main.interfaces.v0p0.remove().commit() ipdb_main.release() ipdb_test.release() netnsmod.remove(nsid) assert ret_ping assert ret_arp assert nsid not in netnsmod.listnetns()
def test_addr_filter(self): require_user('root') self.ip.addr('add', index=self.ifaces[0], address='172.16.0.1', prefixlen=24, broadcast='172.16.0.255') self.ip.addr('add', index=self.ifaces[0], address='172.16.0.2', prefixlen=24, broadcast='172.16.0.255') assert len(self.ip.get_addr(index=self.ifaces[0])) == 2 assert len(self.ip.get_addr(address='172.16.0.1')) == 1 assert len(self.ip.get_addr(broadcast='172.16.0.255')) == 2 assert len(self.ip.get_addr(match=lambda x: x['index'] == self.ifaces[0])) == 2
def test_route_mpls_swap_newdst_list(self): require_kernel(4, 4) require_user('root') req = {'family': AF_MPLS, 'oif': self.ifaces[0], 'dst': {'label': 0x20, 'bos': 1}, 'newdst': [{'label': 0x21, 'bos': 1}]} self.ip.route('add', **req) rt = self.ip.get_routes(oif=self.ifaces[0], family=AF_MPLS)[0] assert rt.get_attr('RTA_DST')[0]['label'] == 0x20 assert len(rt.get_attr('RTA_DST')) == 1 assert rt.get_attr('RTA_NEWDST')[0]['label'] == 0x21 assert len(rt.get_attr('RTA_NEWDST')) == 1 self.ip.route('del', **req) assert len(self.ip.get_routes(oif=self.ifaces[0], family=AF_MPLS)) == 0
def setup(self): require_user("root") self.l2tp = L2tp() self.log_id = str(uuid.uuid4()) self.ndb = NDB( log="../ndb-%s-%s.log" % (os.getpid(), self.log_id), rtnl_debug=True, ) self.netif = uifname() self.l2tpeth0 = uifname() self.localnet = allocate_network() self.remotenet = allocate_network() self.localrange = [str(x) for x in self.localnet] self.remoterange = [str(x) for x in self.remotenet] # create the "network" interface (self.ndb.interfaces.create(ifname=self.netif, kind="dummy").set( "state", "up").add_ip("%s/24" % (self.localrange[1])).commit())
def test_route_onlink_multipath_strflags(self): require_user('root') naddr = str(self.ipnets[1].network) ifaddr1 = self.ifaddr() ifaddr2 = self.ifaddr() self.ip.route('add', dst='%s/24' % naddr, multipath=[{'gateway': ifaddr1, 'oif': 1, 'flags': ['onlink']}, {'gateway': ifaddr2, 'oif': 1, 'flags': RTNH_F_ONLINK}]) assert grep('ip route show', pattern='%s/24' % naddr) assert grep('ip route show', pattern='nexthop.*%s.*onlink' % ifaddr1) assert grep('ip route show', pattern='nexthop.*%s.*onlink' % ifaddr2) self.ip.route('del', dst=naddr, mask=24)
def setup(self): require_user('root') try: netns.create(NS_NAME) except OSError as e: if e.errno == errno.EEXIST: netns.remove(NS_NAME) netns.create(NS_NAME) else: raise try: check_output([NFT_BIN_PATH, "-f", "nftables.ruleset"]) except OSError as e: if e.errno == errno.ENOENT: raise SkipTest("You must install nftables for the test") else: raise
def test_route_onlink_multipath_strflags(self): require_user('root') self.ip.route('add', dst='172.16.245.0/24', multipath=[{ 'gateway': '10.100.1.1', 'oif': 1, 'flags': ['onlink'] }, { 'gateway': '10.100.1.2', 'oif': 1, 'flags': RTNH_F_ONLINK }]) assert grep('ip route show', pattern='172.16.245.0/24') assert grep('ip route show', pattern='nexthop.*10.100.1.1.*onlink') assert grep('ip route show', pattern='nexthop.*10.100.1.2.*onlink') self.ip.route('del', dst='172.16.245.0', mask=24)
def test_counters(self): require_user('root') name = str(uuid4())[:16] ipaddr = '172.16.202.202' self.ip.create(name, counters=True) self.ip.add(name, ipaddr) assert ipaddr in self.list_ipset(name) assert self.list_ipset(name)[ipaddr][0] == 0 # Bytes assert self.list_ipset(name)[ipaddr][1] == 0 # Packets self.ip.destroy(name) self.ip.create(name, counters=False) self.ip.add(name, ipaddr) assert ipaddr in self.list_ipset(name) assert self.list_ipset(name)[ipaddr][0] is None assert self.list_ipset(name)[ipaddr][1] is None self.ip.destroy(name)
def test_flush_rules(self): require_user('root') init = len(self.ip.get_rules(family=socket.AF_INET)) assert len(self.ip.get_rules(priority=lambda x: 100 < x < 500)) == 0 self.ip.rule('add', table=10, priority=110) self.ip.rule('add', table=15, priority=150, action='FR_ACT_PROHIBIT') self.ip.rule('add', table=20, priority=200, src='172.16.200.1') self.ip.rule('add', table=25, priority=250, dst='172.16.250.1') assert len(self.ip.get_rules(priority=lambda x: 100 < x < 500)) == 4 assert len(self.ip.get_rules(src='172.16.200.1')) == 1 assert len(self.ip.get_rules(dst='172.16.250.1')) == 1 self.ip.flush_rules(family=socket.AF_INET, priority=lambda x: 100 < x < 500) assert len(self.ip.get_rules(priority=lambda x: 100 < x < 500)) == 0 assert len(self.ip.get_rules(src='172.16.200.1')) == 0 assert len(self.ip.get_rules(dst='172.16.250.1')) == 0 assert len(self.ip.get_rules(family=socket.AF_INET)) == init
def test_net_and_iface_stypes(self): require_user('root') name = str(uuid4())[:16] test_values = (('hash:net', ('192.168.1.0/31', '192.168.12.0/24')), ('hash:net,iface', ('192.168.1.0/24,eth0', '192.168.2.0/24,wlan0'))) for stype, test_values in test_values: self.ip.create(name, stype=stype) etype = stype.split(':', 1)[1] assert self.get_ipset(name) for entry in test_values: self.ip.add(name, entry, etype=etype) assert entry in self.list_ipset(name) self.ip.delete(name, entry, etype=etype) assert entry not in self.list_ipset(name) self.ip.destroy(name) assert not self.get_ipset(name)
def _test_create(self, ns_name, ns_fd=None): require_user('root') ipdb_main = IPDB() ipdb_test = IPDB(nl=NetNS(ns_name)) 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 = ns_fd or ns_name # 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() assert ret_ping assert ret_arp
def _test_nla_operators(self): require_user('root') self.ip.addr('add', self.ifaces[0], address='172.16.0.1', mask=24) self.ip.addr('add', self.ifaces[0], address='172.16.0.2', mask=24) r = [x for x in self.ip.get_addr() if x['index'] == self.ifaces[0]] complement = r[0] - r[1] intersection = r[0] & r[1] assert complement.get_attr('IFA_ADDRESS') == '172.16.0.1' assert complement.get_attr('IFA_LABEL') is None assert complement['prefixlen'] == 0 assert complement['index'] == 0 assert intersection.get_attr('IFA_ADDRESS') is None assert intersection.get_attr('IFA_LABEL') == self.dev assert intersection['prefixlen'] == 24 assert intersection['index'] == self.ifaces[0]
def test_basic(self): require_user('root') nsid = self.alloc_nsname() # create NS and run a child nsp = NSPopen(nsid, ['ip', '-o', 'link'], stdout=subprocess.PIPE, flags=os.O_CREAT) ret = nsp.communicate()[0].decode('utf-8') host_links = [x.get_attr('IFLA_IFNAME') for x in self.ip.get_links()] netns_links = [x.split(':')[1].split('@')[0].strip() for x in ret.split('\n') if len(x)] assert nsp.wait() == nsp.returncode == 0 assert set(host_links) & set(netns_links) == set(netns_links) assert set(netns_links) < set(host_links) assert not set(netns_links) > set(host_links) nsp.release()
def 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_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 test_vlan_filter_dump(self): require_user('root') (an, ax) = self.create('bridge') (bn, bx) = self.create('bridge') self.ip.link('set', index=ax, state='up') self.ip.link('set', index=bx, state='up') assert len(self.ip.get_vlans()) >= 2 for name in (an, bn): assert len(self.ip.get_vlans(ifname=name)) == 1 assert (self .ip .get_vlans(ifname=name)[0] .get_attr('IFLA_IFNAME')) == name assert (self .ip .get_vlans(ifname=name)[0] .get_nested('IFLA_AF_SPEC', 'IFLA_BRIDGE_VLAN_INFO'))['vid'] == 1
def test_hashnet_with_comment(self, sock=None): require_user('root') comment = "abcdef" myset = WiSet(name=self.name, attr_type="hash:net", comment=True, sock=sock) myset.create() inherit_sock = sock is not None myset = load_ipset(self.name, sock=sock, inherit_sock=inherit_sock) assert myset.comment myset.add("192.168.1.1", comment=comment) myset.update_content() assert myset.content["192.168.1.1/32"].comment == comment myset.destroy()
def test_add_delete(self): require_user('root') name = str(uuid4())[:16] ipaddr = '192.168.1.1' # create ipset self.ip.create(name) assert self.get_ipset(name) # add an entry self.ip.add(name, ipaddr) # check it assert ipaddr in self.list_ipset(name) # delete an entry self.ip.delete(name, ipaddr) # check it assert ipaddr not in self.list_ipset(name) # remove ipset self.ip.destroy(name) assert not self.get_ipset(name)
def test_generic_pre_callback(self): require_user('root') def cb(ipdb, msg, action): if action == 'RTM_NEWLINK': # fake the incoming message msg['flags'] = 1234 # register callback self.ip.register_callback(cb, mode='pre') # create an interface bala self.ip.create(kind='dummy', ifname='bala').commit() # assert flags assert self.ip.interfaces.bala.flags == 1234 # cleanup self.ip.unregister_callback(cb, mode='pre') self.ip.interfaces.bala.remove() self.ip.interfaces.bala.commit()
def test_route_replace_not_existing(self): # route('replace', ...) should succeed, if route doesn't exist require_user('root') naddr = str(self.ipnets[1].network) ifaddr1 = self.ifaddr() ifaddr2 = self.ifaddr() self.ip.link('set', index=self.ifaces[0], state='up') self.ip.addr('add', self.ifaces[0], address=ifaddr1, mask=24) self.ip.route('replace', dst=naddr, mask=24, gateway=ifaddr2, table=100) assert grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr2)) self.ip.flush_routes(table=100) assert not grep('ip route show table 100', pattern='%s/24.*%s' % (naddr, ifaddr2))
def test_context_exception_in_code(self): require_user('root') try: with IPDB(mode='explicit') as ip: with ip.interfaces[self.ifname] as i: i.add_ip('172.16.9.1/24') # normally, this code is never reached # but we should test it anyway del i['flags'] # hands up! raise _TestException() except _TestException: pass # check that the netlink socket is properly closed # and transaction was really dropped with IPDB() as ip: assert ('172.16.9.1', 24) not in ip.interfaces[self.ifname].ipaddr
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_stats_consistency(self, sock=None): """ Test several way to fill the statistics of one IPSet """ require_user('root') entries = ["1.2.3.4", "1.2.3.5", "1.2.3.6"] myset = WiSet(name=self.name, sock=sock) myset.create() myset.insert_list(entries) myset_lists = load_all_ipsets(sock=sock, content=True)[self.name] for value in entries: assert value in myset_lists.content myset_list = load_ipset(self.name, sock=sock, content=True) for value in entries: assert value in myset_list.content myset.destroy()
def test_neigh_filter(self): require_user('root') # inject arp records self.ip.neigh('add', dst='172.16.45.1', lladdr='00:11:22:33:44:55', ifindex=self.ifaces[0]) self.ip.neigh('add', dst='172.16.45.2', lladdr='00:11:22:33:44:55', ifindex=self.ifaces[0]) # assert two arp records on the interface assert len(self.ip.get_neighbours(ifindex=self.ifaces[0])) == 2 # filter by dst assert len(self.ip.get_neighbours(dst='172.16.45.1')) == 1 # filter with lambda assert len(self.ip.get_neighbours(match=lambda x: x['ifindex'] == self.ifaces[0])) == 2
def test_route_multipath_raw(self): require_user('root') self.ip.route('add', dst='172.16.241.0', mask=24, multipath=[{ 'hops': 20, 'oif': 1, 'attrs': [['RTA_GATEWAY', '127.0.0.2']] }, { 'hops': 30, 'oif': 1, 'attrs': [['RTA_GATEWAY', '127.0.0.3']] }]) assert grep('ip route show', pattern='172.16.241.0/24') assert grep('ip route show', pattern='nexthop.*127.0.0.2.*weight 21') assert grep('ip route show', pattern='nexthop.*127.0.0.3.*weight 31') self.ip.route('del', dst='172.16.241.0', mask=24)
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_route_proto(self, proto, fake, spec=''): require_user('root') os.system('ip route add 172.16.3.0/24 via 127.0.0.1 %s' % spec) time.sleep(1) assert grep('ip ro', pattern='172.16.3.0/24.*127.0.0.1') try: self.ip.route('del', dst='172.16.3.0/24', gateway='127.0.0.1', proto=fake) except NetlinkError: pass self.ip.route('del', dst='172.16.3.0/24', gateway='127.0.0.1', proto=proto) assert not grep('ip ro', pattern='172.16.3.0/24.*127.0.0.1')
def test_lwtunnel_mpls_1_int_label(self): require_user('root') self.ip.route('add', dst='172.16.245.0/24', encap={ 'type': 'mpls', 'labels': 245 }, oif=1) routes = self.ip.route('dump', dst='172.16.245.0/24') assert len(routes) == 1 route = routes[0] assert route.get_attr('RTA_ENCAP_TYPE') == 1 assert route.get_attr('RTA_OIF') == 1 labels = route.get_attr('RTA_ENCAP').get_attr('MPLS_IPTUNNEL_DST') assert len(labels) == 1 assert labels[0]['bos'] == 1 assert labels[0]['label'] == 245 self.ip.route('del', dst='172.16.245.0/24')
def setup(self): require_user('root') if not with_concurrent: raise SkipTest('no concurrent.futures') utils = TestTools.Utils self.ss_bin = utils.which('ss') ss2_script = './bin/ss2' try: self.ss2 = imp.load_source('ss2', ss2_script) except ImportError: raise SkipTest('ss2 not imported') if sys.version_info[0] == 2: import cStringIO self.stream_sink = cStringIO.StringIO() else: self.stream_sink = io.StringIO()