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
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 __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()
def test_fail_released(self): ip = IPDB() ip.release() try: ip.interfaces.lo.up() except RuntimeError: pass
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_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()
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 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()
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()
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'})
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'))
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
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)
def __createNetns(self, phyIfaceIndex): netnsName = self.__getNetnsName() (pvdIfaceName, pvdIfaceIndex) = self.__getPvdIfaceParams() netns.create(netnsName) LOG.debug('network namespace {0} created'.format(netnsName)) # create a virtual interface where PvD parameters are going to be configured, then move the interface to the new network namespace self.ipRoot.link_create(ifname=pvdIfaceName, index=pvdIfaceIndex, kind=self.__PVD_IFACE_TYPE, link=phyIfaceIndex) LOG.debug('macvlan {0} created in default network namespace'.format(pvdIfaceName)) pvdIfaceIndex = self.ipRoot.link_lookup(ifname=pvdIfaceName) self.ipRoot.link('set', index=pvdIfaceIndex[0], net_ns_fd=netnsName) LOG.debug('macvlan {0} moved to network namespace {1}'.format(pvdIfaceName, netnsName)) # change the namespace and get new NETLINK handles to operate in new namespace netns.setns(netnsName) LOG.debug('network namespace switched to {0}'.format(netnsName)) ip = IPRoute() ipdb = IPDB() ipdb.register_callback(self.__onIfaceStateChange) # disable kernel to auto-configure the interface associated with the PvD, let the pvdman to solely control interface configuration acceptRaConfFile = self.__ACCEPT_RA_CONF_FILE.replace(self.__IFACENAME_REPLACE_PATTERN, pvdIfaceName) acceptRaConfFile = open(acceptRaConfFile, 'w') acceptRaConfFile.write('0') LOG.debug('processing of RAs by kernel disabled in {0}'.format(acceptRaConfFile.name)) # return to a default network namespace to not cause a colision with other modules # ip and ipdb handles continue to work in the target network namespace netns.setns(self.__NETNS_DEFAULT_NAME) LOG.debug('network namespace switched to default') # get new index since interface has been moved to a different namespace loIfaceIndex = ip.link_lookup(ifname=self.__LOOPBACK_IFACE_NAME) if (len(loIfaceIndex) > 0): loIfaceIndex = loIfaceIndex[0] pvdIfaceIndex = ip.link_lookup(ifname=pvdIfaceName) if (len(pvdIfaceIndex) > 0): pvdIfaceIndex = pvdIfaceIndex[0] # start interfaces ip.link_up(loIfaceIndex) ip.link_up(pvdIfaceIndex) # clear network configuration if exists ip.flush_addr(index=pvdIfaceIndex) ip.flush_routes(index=pvdIfaceIndex) ip.flush_rules(index=pvdIfaceIndex) LOG.debug('macvlan {0} in network namespace {1} initialized'.format(pvdIfaceName, netnsName)) return (netnsName, pvdIfaceName, ip)
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()
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'})
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
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 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 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 setup(self): self.ifname = uifname() self.ip = IPDB(mode='direct') try: self.ip.create(ifname=self.ifname, kind='dummy') except: pass
def setup(self): self.ifname = uifname() self.ip = IPDB(mode="direct") try: self.ip.create(ifname=self.ifname, kind="dummy") except: pass
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"))
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()
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 _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()
class _TestIPDBRaces(object): def setup(self): self.ip = IPDB() def teardown(self): self.ip.release() def test_initdb(self): tnum = len(threading.enumerate()) for _ in range(RESPAWNS): len(self.ip.interfaces.keys()) len(self.ip.routes.keys()) len(self.ip.rules.keys()) self.ip.initdb() assert len(threading.enumerate()) <= tnum def _ports_mtu_race(self, kind): port1 = (self.ip .create(ifname=uifname(), kind='dummy', mtu=1280) .commit()) port2 = (self.ip .create(ifname=uifname(), kind='dummy') .commit()) master = (self.ip .create(ifname=uifname(), kind=kind) .commit()) try: master.add_port(port1).commit() master.add_port(port2).commit() except: raise finally: port1.remove().commit() port2.remove().commit() master.remove().commit() def test_bridge_mtu(self): require_user('root') for _ in range(300): self._ports_mtu_race('bridge')
def 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)
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 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 execRequest(self, action, data): if action == 'Plugin.Activate': return HttpResponse(200, 'json', { 'Implements': ['NetworkDriver', 'IPAM'] }).response if action == 'NetworkDriver.GetCapabilities': return HttpResponse(200, 'json', {'Scope': 'local'}).response if action == 'IPAM.GetDefaultAddressSpaces': requestPool = {} return HttpResponse(200, 'json', requestPool).response if action == 'IPAM.RequestPool': self.subnet = data['Pool'] requestPool = {} requestPool['Pool'] = self.subnet return HttpResponse(200, 'json', requestPool).response if action == 'IPAM.RequestAddress': plen = self.subnet.split('/')[1] requestAddress = {} if 'Address' not in data: reply = { 'error': 'missing gateway, specify one with --gateway' } return HttpResponse(500, 'json', reply).response requestAddress['Address'] = data['Address'] + '/' + plen return HttpResponse(200, 'json', requestAddress).response if action == 'IPAM.ReleaseAddress': address = {} address['Address'] = data['Address'] return HttpResponse(200, 'json', address).response if action == 'IPAM.ReleasePool': pool = {} return HttpResponse(200, 'json', pool).response if action == 'NetworkDriver.CreateNetwork': subnet = data['IPv4Data'][0]['Pool'] gateway = data['IPv4Data'][0]['Gateway'].split('/')[0] rtList = [] if 'rt' in data['Options']['com.docker.network.generic']: rt = data['Options']['com.docker.network.generic']['rt'] rtList = rt.split(',') openContrailVN = OpenContrailVN(data['NetworkID']).createNw( subnet, gateway, rtList) return HttpResponse(200, 'json', {}).response if action == 'NetworkDriver.DeleteNetwork': openContrailVN = OpenContrailVN(data['NetworkID']).deleteNw() return HttpResponse(200, 'json', {}).response if action == 'NetworkDriver.CreateEndpoint': networkId = data['NetworkID'] endpointId = data['EndpointID'] hostId = endpointId[:8] ipAddress = data['Interface']['Address'] result = OpenContrailVirtualMachineInterface(hostId).createVmi( networkId, ipAddress) interface = {} interface['Interface'] = {} interface['Interface']['MacAddress'] = result['mac'] return HttpResponse(200, 'json', interface).response if action == 'NetworkDriver.DeleteEndpoint': endpointId = data['EndpointID'] hostId = endpointId[:8] OpenContrailVirtualMachineInterface(hostId).deleteVmi() endpointId = data['EndpointID'] vethIdHost = 'veth' + endpointId[:8] + 'p0' ip = IPDB() with ip.interfaces[vethIdHost] as veth: veth.remove() return HttpResponse(200, 'json', {}).response if action == 'NetworkDriver.EndpointOperInfo': endpointInfo = {} endpointInfo['NetworkID'] = data['NetworkID'] endpointInfo['EndpointID'] = data['EndpointID'] return HttpResponse(200, 'json', endpointInfo).response if action == 'NetworkDriver.Join': endpointId = data['EndpointID'] hostId = endpointId[:8] networkId = data['NetworkID'] vethIdHost = 'veth' + endpointId[:8] + 'p0' vethIdContainer = 'veth' + endpointId[:8] vn = OpenContrailVN(networkId).VNget() subnet = vn.network_ipam_refs[0]['attr'].ipam_subnets[0] gateway = subnet.default_gateway mac = OpenContrailVirtualMachineInterface(hostId).getMac() ip = IPDB() ip.create(ifname=vethIdHost, kind='veth', peer=vethIdContainer).commit() with ip.interfaces[vethIdHost] as veth: veth.up() with ip.interfaces[vethIdContainer] as veth: veth.address = mac joinInfo = {} joinInfo['InterfaceName'] = {} joinInfo['InterfaceName']['SrcName'] = vethIdContainer joinInfo['InterfaceName']['DstPrefix'] = 'eth' joinInfo['Gateway'] = gateway #joinInfo['GatewayIPv6'] = '2000::2' joinInfo['StaticRoutes'] = [] #staticRoute = {} #staticRoute['Destination'] = '2.2.2.0/24' #staticRoute['RouteType'] = 0 #staticRoute['NextHop'] = '1.1.1.1' #joinInfo['StaticRoutes'].append(staticRoute) return HttpResponse(200, 'json', joinInfo).response if action == 'NetworkDriver.Leave': return HttpResponse(200, 'json', {}).response
def get_interfaces(): return IPDB().interfaces
def __init__(self): self._ipdb = IPDB()
def ipv4_address(ifname): with IPDB() as ipdb: addrset = [x[0] for x in ipdb.interfaces[ifname].ipaddr if '.' in x[0]] if len(addrset) > 0: # Should return the first IPv4 address of the interface...if there are any return addrset[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')
def setup(self): create_link('dummyX', 'dummy') self.ip = IPDB(mode=self.mode, fork=True)
def test_context_manager(self): with IPDB() as ip: assert ip.interfaces.lo.index == 1
""" from __future__ import absolute_import, unicode_literals import ast import logging import re import salt.loader from salt.ext.six.moves import map # Import third party libs try: from pyroute2 import IPDB IP = IPDB() HAS_PYROUTE2 = True except ImportError: IP = None HAS_PYROUTE2 = False log = logging.getLogger(__name__) __virtual_name__ = "network_settings" ATTRS = [ "family", "txqlen", "ipdb_scope", "index",
class ConfigApplier(object): def __init__(self): self.ip = IPDB() def _setIpConfig(self, iface): ipconfig = iface.ipconfig ipv4 = ipconfig.ipv4 ipv6 = ipconfig.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 ipconfig.ipv6autoconf is not None: with open('/proc/sys/net/ipv6/conf/%s/autoconf' % iface.name, 'w') as ipv6_autoconf: ipv6_autoconf.write('1' if ipconfig.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.ipconfig.bootproto == 'dhcp': runDhclient(iface) if iface.ipconfig.dhcpv6: runDhclient(iface, 6) 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.ipconfig: 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=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()
def __init__(self): self.ip = IPDB()
def mocker_run(uuid1, *args, **kwargs): ''' run <image_id> <command> - создает контейнер из указанного image_id и запускает его с указанной командой ''' images = list_images() image_name = uuid1 #kwargs['<name>'] ip_last_octet = 103 # TODO : configurable match = [i[3] for i in images if i[0] == image_name][0] target_file = os.path.join(_base_dir_, match) with open(target_file) as tf: image_details = json.loads(tf.read()) # setup environment details state = json.loads(image_details['history'][0]['v1Compatibility']) # Extract information about this container env_vars = state['config']['Env'] start_cmd = subprocess.list2cmdline(state['config']['Cmd']) working_dir = state['config']['WorkingDir'] id = uuid.uuid1() # unique-ish name name = 'c_' + str(id.fields[5])[:4] # unique-ish mac mac = str(id.fields[5])[:2] layer_dir = os.path.join(_base_dir_, match.replace('.json', ''), 'layers', 'contents') with IPDB() as ipdb: veth0_name = 'veth0_' + name veth1_name = 'veth1_' + name netns_name = 'netns_' + name bridge_if_name = 'bridge0' existing_interfaces = ipdb.interfaces.keys() # Create a new virtual interface with ipdb.create(kind='veth', ifname=veth0_name, peer=veth1_name) as i1: i1.up() if bridge_if_name not in existing_interfaces: ipdb.create(kind='bridge', ifname=bridge_if_name).commit() i1.set_target('master', bridge_if_name) # Create a network namespace netns.create(netns_name) # move the bridge interface into the new namespace with ipdb.interfaces[veth1_name] as veth1: veth1.net_ns_fd = netns_name # Use this network namespace as the database ns = IPDB(nl=NetNS(netns_name)) with ns.interfaces.lo as lo: lo.up() with ns.interfaces[veth1_name] as veth1: veth1.address = "02:42:ac:11:00:{0}".format(mac) veth1.add_ip('10.0.0.{0}/24'.format(ip_last_octet)) veth1.up() ns.routes.add({'dst': 'default', 'gateway': '10.0.0.1'}).commit() try: # setup cgroup directory for this user user = os.getlogin() create_user_cgroups(user) # First we create the cgroup and we set it's cpu and memory limits cg = Cgroup(name) cg.set_cpu_limit(50) # TODO : get these as command line options cg.set_memory_limit(500) # Then we a create a function to add a process in the cgroup def in_cgroup(): try: pid = os.getpid() cg = Cgroup(name) for env in env_vars: #log.info('Setting ENV %s' % env) os.putenv(*env.split('=', 1)) # Set network namespace netns.setns(netns_name) # add process to cgroup cg.add(pid) os.chroot(layer_dir) if working_dir != '': #log.info("Setting working directory to %s" % working_dir) os.chdir(working_dir) except Exception as e: traceback.print_exc() #log.error("Failed to preexecute function") #log.error(e) cmd = start_cmd print(cmd) #log.info('Running "%s"' % cmd) process = subprocess.Popen(cmd, preexec_fn=in_cgroup, shell=True) process.wait() print(process.stdout) #log.error(process.stderr) except Exception as e: traceback.print_exc() #log.error(e) finally: #log.info('Finalizing') NetNS(netns_name).close() netns.remove(netns_name) ipdb.interfaces[veth0_name].remove()
-d run in dameon mode --scan-ip scans one ip """ import socket import Queue from pyroute2 import IPDB from pyroute2 import IPRoute import signal import threading import time import select from docopt import docopt work_queue = Queue.Queue() ip = IPDB() JUNK_DATA = "AAABBBCCC" class Worker(threading.Thread): def run(self): while True: msg = work_queue.get() if msg['event'] == 'RTM_NEWLINK': plugin(msg) #when you plug in an the ethernet adapter we get the ip of the interface def plugin(msg): interface = msg['attrs'][0][1] state = msg['attrs'][2][1]
def test_interface(config): log = logging.getLogger(__name__) assert isinstance(config, NettestConfig) ifname = config.get('network.interface') dhclient = config.get('dhclient.binary') execution_timeout = config.getint('dhclient.execution_timeout') termination_timeout = config.getint('dhclient.termination_timeout') ipdb = IPDB(mode='implicit') ip = IPRoute() if ifname not in ipdb.interfaces: raise InterfaceError('Interface %s cannot be found' % ifname) interface = ipdb.interfaces.get(ifname) log.info('Releasing IP address and stopping dhclient') start_time = time.time() try: release_process = subprocess.Popen([dhclient, '-r', '-v', ifname], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as e: log.exception() raise ExecutionError('Cannot execute %s' % dhclient) while release_process.poll() is None: time.sleep(TIME_QUANTUM) if time.time() - start_time > execution_timeout: log.error('Timeout exceeded waiting for dhclient to release ip') release_process.terminate() time.sleep(termination_timeout) if relase_process.poll() is None: release_process.kill() if release_process.poll() is None: raise TerminationError( 'Cannot kill hanged dhclient process, exiting') release_time_used = time.time() - start_time del start_time if release_process.poll() != 0: stdout, stderr = release_process.communicate() log.error('Dhclient cannot release IP address. Output was: %s %s', stdout, stderr) del release_process log.info('Time used to release IP adderess: %.2f ms', release_time_used * 1000) log.info('Deleting any left ip addresses') if interface.ipaddr: for ipaddr, prefixlen in interface.ipaddr: interface.del_ip(ipaddr, prefixlen) interface.commit() log.info('Shutting down %s', ifname) interface.down().commit() start_time = time.time() log.info('Bringing %s up', ifname) interface.up().commit() log.info('Obtaining IP address') try: acquire_process = subprocess.Popen( [dhclient, '-1', '-4', '-v', ifname], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as e: log.exception() raise ExecutionError('Cannot execute %s' % dhclient) while acquire_process.poll() is None: time.sleep(TIME_QUANTUM) if time.time() - start_time > execution_timeout: log.error('Timeout exceeded waiting for dhclient to acquire ip') acquire_process.terminate() time.sleep(termination_timeout) if acquire_process.poll() is None: acquire_process.kill() if acquire_process.poll() is None: raise TerminationError( 'Cannot kill hanged dhclient process, exiting') raise CannotAcquireIP('Dhclient timeout exceeded') acquire_time_used = time.time() - start_time del start_time if acquire_process.poll() != 0: stdout, stderr = acquire_process.communicate() raise CannotAcquireIP( 'Dhclient cannot acquire IP address. Output was: %s %s', stdout, stderr) log.info('Time used to up interface and acquire ' 'ip address: %.2f ms', acquire_time_used * 1000) return release_time_used, acquire_time_used
def test_respawn_ipdb(self): for _ in range(RESPAWNS): with IPDB(): pass
from pyroute2.common import uifname p0 = uifname() ### # # "Pre" callbacks are executed before the message # gets processed by IPDB, and in synchronous manner. # Normally, you will not need these callbacks, but # they can be useful to perform some hacks # def cb(ipdb, msg, action): if action == 'RTM_NEWLINK': msg['flags'] = 1234 # create IPDB instance ip = IPDB() # register "pre" callback ip.register_callback(cb, mode='pre') # create an interface ip.create(kind='dummy', ifname=p0).commit() # assert flags assert ip.interfaces[p0].flags == 1234 # cleanup ip.interfaces[p0].remove() ip.interfaces[p0].commit() # release Netlink socket ip.release()
def get(self): with IPDB() as ip: j = {k: v for k, v in ip.interfaces.items() if isinstance(k, str)} return jsonify(j)
def setup(self): create_link('dummyX', 'dummy') self.ip = IPDB(mode='direct')
def get(self, interface): with IPDB() as ip: j = ip.interfaces[interface] return jsonify(j)
def update_interface_cache(): print('[N] Updating interface cache.') # IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28') bridged = {} slaves = {} for interface in json.loads(sys_command('bridge -j link show').decode('UTF-8')): bridged[interface['ifname']] = interface['master'] if not interface['master'] in slaves: slaves[interface['master']] = [] slaves[interface['master']].append(interface['ifname']) with IPRoute() as ip: with IPDB() as ipdb: for link in ip.get_links(): ifname = link.get_attr('IFLA_IFNAME') #print(f'{ifname}:') #print(json.dumps(link, indent=4, default=lambda o: str(o))) #print(json.dumps(ipdb.by_name[ifname], indent=4, default=lambda o: str(o))) datastore['interfaces'][ifname] = { 'ifname' : ifname, 'ip' : list(ipdb.by_name[ifname]['ipaddr']), 'mac' : link.get_attr('IFLA_ADDRESS'), # / ipdb['address'] 'state' : link.get_attr('IFLA_OPERSTATE').lower(), # link['state'] shows an inaccurate state. 'gateway' : None, 'routes' : [], 'connected_to' : bridged[ifname] if ifname in bridged else [], 'raw_data' : { 'link' : link, 'ip' : ipdb.by_name[ifname] } } if datastore['interfaces'][ifname]['mac'][:5] == 'fe:01': _type = datastore['interfaces'][ifname]['mac'].split(':')[2] if _type == '00': datastore['switches'][ifname] = Switch(ifname=ifname, **datastore['interfaces'][ifname]) elif _type == '01': datastore['routers'][ifname] = Router(ifname=ifname, trunk=slaves[ifname][0], **{**datastore['interfaces'][ifname], 'connected_to' : slaves[ifname][0]}) # TODO: Enslave the subinterfaces to the router. #for interface in slaves[ifname][1:]: # datastore['routers'][ifname].connect(interface) #elif _type == '02': # datastore['interfaces'][ifname] = Bridge(ifname=ifname, **datastore['interfaces'][ifname]) elif _type == '03': datastore['interfaces'][ifname] = None # This is a sink to another network interface else: # TODO: FIX! datastore['nics'][ifname] = VirtualNic(**datastore['interfaces'][ifname]) del(datastore['interfaces'][ifname]) else: datastore['interfaces'][ifname] = Interface(**datastore['interfaces'][ifname]) for ip_addr in ipdb.by_name[ifname]['ipaddr']: tmp_mapper[ip_addr[0]] = ifname for route in ip.get_default_routes(): datastore['gateways'][route.get_attr('RTA_GATEWAY')] = route datastore['default_routes'][route.get_attr('RTA_GATEWAY')] = {'priority' : route.get_attr('RTA_PRIORITY'), 'raw_data' : route} for route in ip.get_routes(): route_dest = route.get_attr('RTA_DST') gateway = route.get_attr('RTA_GATEWAY') preferred_source = route.get_attr('RTA_PREFSRC') if gateway: datastore['gateways'][gateway] = route datastore['routes'][route_dest] = {'source' : preferred_source, 'raw_data' : route, 'gateway' : gateway} if gateway and not route_dest and not preferred_source: # Default route, try to find the preferred source for interface in datastore['interfaces']: for ip_info in datastore['interfaces'][interface].ip: interface_subnet = ipaddress.ip_network(f'{ip_info[0]}/{str(ip_info[1])}', strict=False) try: if ipaddress.IPv4Address(gateway) in interface_subnet: datastore['interfaces'][interface]['gateway'] = gateway break except ipaddress.AddressValueError: pass # IPv6 for interface in datastore['interfaces']: for ip_info in datastore['interfaces'][interface]['ip']: try: if ipaddress.IPv4Address(ip_info[0]) == ipaddress.IPv4Address(preferred_source): datastore['interfaces'][interface]['routes'].append(route_dest) except ipaddress.AddressValueError: continue # IPv6 address, TODO: Implement support for IPv6
def test_vrouter(self): require_user('root') nsid = str(uuid.uuid4()) ns = NetNS(nsid) ipdb = IPDB() ipns = IPDB(nl=ns) try: ipdb.create(ifname='ve0p0', peer='ve0p1', kind='veth').commit() ipdb.interfaces.ve0p1.net_ns_fd = nsid ipdb.commit() with ipns.interfaces.ve0p1 as i: i.set_ifname('eth0') i.up() except: raise finally: ipdb.interfaces.ve0p0.remove() ipdb.commit() ipdb.release() ipns.release() ns.remove()
def interface_up(ifname): with IPDB() as ipdb: for i in set(ipdb.interfaces.values()): if i.ifname == ifname and i.operstate == 'UP': return True return False
''' Example: python ./examples/create_bond.py Creates bond interface. ''' from pyroute2 import IPDB from pyroute2.common import uifname ip = IPDB() try: # create unique interface names p0 = uifname() p1 = uifname() ms = uifname() # The same scheme works for bridge interfaces too: you # can create a bridge interface and enslave some ports # to it just as below. ip.create(kind='dummy', ifname=p0).commit() ip.create(kind='dummy', ifname=p1).commit() with ip.create(kind='bond', ifname=ms) as i: # enslave two interfaces i.add_port(ip.interfaces[p0]) i.add_port(ip.interfaces[p1]) # make an example more scary: add IPs i.add_ip('10.251.0.1/24') i.add_ip('10.251.0.2/24')
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()
# | ^ | br100 |-<-<-<--| sim | | # | clsfy_neigh() | | ^ \------/ | # lan1 ----|->->->->->->->-| <--1Mb--| | | # lan2 ----|->->->->->->->-| | classify_wan() | # ^ \------------/ | # pass() | from bpf import BPF from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from simulation import Simulation import sys from time import sleep from builtins import input ipr = IPRoute() ipdb = IPDB(nl=ipr) b = BPF(src_file="tc_neighbor_sharing.c", debug=0) wan_fn = b.load_func("classify_wan", BPF.SCHED_CLS) pass_fn = b.load_func("pass", BPF.SCHED_CLS) neighbor_fn = b.load_func("classify_neighbor", BPF.SCHED_CLS) num_neighbors = 3 num_locals = 2 # class to build the simulation network class SharedNetSimulation(Simulation): def __init__(self, ipdb): super(SharedNetSimulation, self).__init__(ipdb)
def get_ipv4(iface): if not IPDB().interfaces[iface].ipaddr: None return IPDB().interfaces[iface]
def setup(self): self.ip = IPDB()
def release(self): IPDB().release()
def test_respawn_ipdb(self): for _ in range(RESPAWNS): with IPDB() as i: assert len(i.interfaces.keys()) assert len(i.routes.keys()) assert len(i.rules.keys())
# 9: # 9: OK from ctypes import c_uint from bcc import BPF from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from utils import NSPopenWithCheck, mayFail import sys from time import sleep from unittest import main, TestCase import subprocess from simulation import Simulation arg1 = sys.argv.pop(1) ipr = IPRoute() ipdb = IPDB(nl=ipr) sim = Simulation(ipdb) allocated_interfaces = set(ipdb.interfaces.keys()) def get_next_iface(prefix): i = 0 while True: iface = "{0}{1}".format(prefix, i) if iface not in allocated_interfaces: allocated_interfaces.add(iface) return iface i += 1
def watchdog_callback(ipdb: object, message: object, action: object): global oifs if action in ('RTM_NEWADDR', 'RTM_NEWLINK') \ and ipdb.interfaces[message.get_attr('RTA_OIF')].get('operstate') == 'UP': store_interfaces_oifs(ipdb) if action == 'RTM_NEWROUTE': if message.get('family') == AF_INET \ and message.get_attr('RTA_OIF') in oifs \ and 20000 < message.get_attr('RTA_PRIORITY') < 21000: if verify_valid_route(ipdb, message.get_attr('RTA_OIF'), message.get_attr('RTA_GATEWAY')): print('[watchdog]', action, 'Encontrado rota invalida: ', message) delete_invalid_route(ipdb, message.get_attr('RTA_OIF'), message.get_attr('RTA_GATEWAY')) print('Verificando rotas de rede') main_ipdb: IPDB = IPDB() store_interfaces_oifs(main_ipdb) print('Inicializando watchdog') watchdog: Watchdog = main_ipdb.watchdog() watchdog.wait() print('Registrando callback') callback: int = main_ipdb.register_callback(watchdog_callback) print('Validando rotas atuais') try: routes = get_default_routes(main_ipdb) routes = [x for x in routes if 20000 < x.get('priority') < 21000] if len(routes) != 0: for route in routes: