def test_move_ns_fd(self): foo = str(uuid4()) bar = str(uuid4()) ifA = uifname() ifB = uifname() netnsmod.create(foo) netnsmod.create(bar) with IPDB(nl=NetNS(foo)) as ip: ip.create(ifname=ifA, kind='veth', peer=ifB).commit() assert ifA in ip.interfaces.keys() assert ifB in ip.interfaces.keys() with ip.interfaces[ifB] as intf: intf.net_ns_fd = bar assert ifA in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() with IPDB(nl=NetNS(bar)) as ip: assert ifA not in ip.interfaces.keys() assert ifB in ip.interfaces.keys() ip.interfaces[ifB].remove().commit() assert ifA not in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() with IPDB(nl=NetNS(foo)) as ip: assert ifA not in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() netnsmod.remove(foo) netnsmod.remove(bar)
def test_create_peer_attrs(self): foo = str(uuid4()) bar = str(uuid4()) ifA = uifname() ifB = uifname() netnsmod.create(foo) netnsmod.create(bar) with IPDB(nl=NetNS(foo)) as ip: ip.create(ifname=ifA, kind='veth', peer={ 'ifname': ifB, 'net_ns_fd': bar }).commit() assert ifA in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() with IPDB(nl=NetNS(bar)) as ip: assert ifA not in ip.interfaces.keys() assert ifB in ip.interfaces.keys() ip.interfaces[ifB].remove().commit() assert ifA not in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() with IPDB(nl=NetNS(foo)) as ip: assert ifA not in ip.interfaces.keys() assert ifB not in ip.interfaces.keys() netnsmod.remove(foo) netnsmod.remove(bar)
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 addporns(): with NetNS(netns=netns) as ipr: inet = ipr.link_lookup(ifname=master)[0] for i in slaves: slave = ipr.link_lookup(ifname=i)[0] ipr.link("set", index=slave, master=inet)
def _create_endpoint(self, request, response): logger.debug('endpoint.create') network_id = request['NetworkID'] # if no CreateNetwork request received namespace = 'sdns' + network_id[:6] if namespace not in netns.listnetns(): self._create_namespace(namespace) endpoint_id = request['EndpointID'] address = request['Interface']['Address'] ip = IPRoute() veth0_name = 'veth%s0' % endpoint_id[:6] veth1_name = 'veth%s1' % endpoint_id[:6] ip.link('add', ifname=veth0_name, kind='veth', peer=veth1_name) veth0 = ip.link_lookup(ifname=veth0_name)[0] veth1 = ip.link_lookup(ifname=veth1_name)[0] ip.link('set', index=veth0, mtu=1450) ip.link('set', index=veth1, mtu=1450) ip_addr, mask = address.split('/') ip.addr('add', index=veth1, address=ip_addr, mask=int(mask)) ip.link('set', index=veth0, net_ns_fd=namespace) ns = NetNS(namespace) ns.link('set', index=veth0, state='up') bridge = ns.link_lookup(ifname='shoutbr0')[0] ns.link('set', index=veth0, master=bridge) ip.close() ns.close() return {'Interface': {}}
def _create_tunnel(self, namespace, peer): ip = IPRoute() ns = NetNS(namespace) conn_id = self._connection_identifier(peer) conn_hash = hashlib.md5( (conn_id + namespace).encode('utf-8')).hexdigest() vxlan_name = 'sdvx' + conn_hash[:6] vni = int(conn_hash[:6], 16) ip.link('add', ifname=vxlan_name, kind='vxlan', vxlan_id=vni, vxlan_local=self._local_address, vxlan_group=peer, vxlan_port=4789) vxlan = ip.link_lookup(ifname=vxlan_name)[0] ip.link('set', index=vxlan, net_ns_fd=namespace) vxlan = ns.link_lookup(ifname=vxlan_name)[0] ns.link('set', index=vxlan, mtu=1500) ns.link('set', index=vxlan, state='up') bridge = ns.link_lookup(ifname='shoutbr0')[0] ns.link('set', index=vxlan, master=bridge) ip.close() ns.close()
def configipns(): with NetNS(netns=netns) as ipr: inet = ipr.link_lookup(ifname=ifname)[0] ipr.addr("add", index=inet, address=ip_addr, mask=int(mask)) if gateway is not None: ipr.route("add", dst="default", gateway=gateway)
def address_exists(netns=None, **kwarg): ret = 0 ipr = None if netns is None: ipr = IPRoute() else: ipr = NetNS(netns) if 'match' in kwarg: nkw = kwarg['match'] else: nkw = dict(kwarg) for key in ('address', 'local'): if key in nkw: nkw[key] = nkw[key].split('/')[0] if 'ifname' in kwarg: links = list(ipr.link_lookup(ifname=kwarg['ifname'])) if links: nkw['index'] = links[0] nkw.pop('ifname') else: ipr.close() return 0 ret = list(ipr.addr('dump', match=nkw)) ipr.close() return len(ret) == 1
def _add_namespace(self, name, address, netmaskLength): """ Creates a namespace with the given name, and creates a veth interface with one endpoint inside the namespace which has the given address and netmask length. The peer end of veth interface can be used to connect the namespace to a bridge. """ self._remove_namespace_if_exists(name) netns.create(name) veth_name = "veth0" _remove_interface_if_exists(self.vethPeer) # Create the veth pair and set one endpoint to the namespace. with IPRoute() as ipr: ipr.link('add', ifname=veth_name, kind='veth', peer=self.vethPeer) idx = ipr.link_lookup(ifname=veth_name)[0] ipr.link('set', index=idx, net_ns_fd=name) # Assign address to the veth interface and bring it up. with IPDB(nl=NetNS(name)) as ipdb: with ipdb.interfaces[veth_name] as veth: veth.add_ip('%s/%d' % ( address, netmaskLength, )) veth.up() # Bring the loopback interface up. with ipdb.interfaces['lo'] as lo: lo.up()
def exec_add(self): #logging.info("add") #logging.info(self.params.cni_args_dict) ep = endpoint(self.params, self.core_api, self.obj_api) mizarnetns = ep.get_mizarnetns(self.iproute) self.iproute_ns = NetNS(mizarnetns) ep.prepare_veth_pair(self.iproute, self.iproute_ns) ep.create_endpoint_obj() if ep.watch_endpoint_obj(): ep.provision_endpoint(self.iproute, self.iproute_ns) else: #TODO error handling pass ep.finalize_provisioning() logging.info("provisioned {}".format(ep.name)) result = { "cniVersion": self.params.cni_version, "interfaces": [{ "name": ep.interface, "mac": ep.mac, "sandbox": ep.netns }], "ips": [{ "version": "4", "address": "{}/{}".format(ep.ip, ep.prefix), "gateway": ep.gw, "interface": 0 }] } return json.dumps(result)
def test_connect_netns(self): nsname = str(uuid.uuid4()) with self.ndb.schema.db_lock: s = len(self.ndb.interfaces.summary()) - 1 assert self.count_interfaces(nsname) == 0 assert self.count_interfaces('localhost') == s # connect RTNL source event = threading.Event() self.ndb.connect_source(nsname, NetNS(nsname), event) assert event.wait(5) with self.ndb.schema.db_lock: s = len(self.ndb.interfaces.summary()) - 1 assert self.count_interfaces(nsname) > 0 assert self.count_interfaces('localhost') < s # disconnect the source self.ndb.disconnect_source(nsname) with self.ndb.schema.db_lock: s = len(self.ndb.interfaces.summary()) - 1 assert self.count_interfaces(nsname) == 0 assert self.count_interfaces('localhost') == s netns.remove(nsname)
def wrapper(*args, **kwargs): main_shim_file = None if parent_tag: main_shim_file = kwargs[parent_tag].cpserver.shim_file.name cpserver = CPServer(main_shim_file=main_shim_file, extra_opts=cpserver_extra_opts()) cp = cpserver.getClient() d = None try: with NetNS(cpserver.getNetNsPath()) as netns: d = dict(cpserver=cpserver, netns=netns, cp=cp) if tag: d = {tag: type('cp_wrapper', (object, ), d)} kwargs.update(d) func(*args, **kwargs) except: if tag and d: # in case class restarted cpserver get new object cpserver = d[tag].cpserver cpsystem(cpserver, 'ip -d addr show', ignore_status=True) cpsystem(cpserver, 'ip -d route show table all', ignore_status=True) cpserver.mibdump('all') raise finally: # make sure cp server goes away if tag and d: # in case class restarted cpserver get new object cpserver = d[tag].cpserver d, cp = None, None cpserver.cleanup()
def test_multithread(self): require_user('root') parallel_count = 5 test_count = 10 ns_names = ['testns%i' % i for i in range(parallel_count)] success = [True] for ns_name in ns_names: NetNS(ns_name) for _t in range(test_count): threads = [ Thread(target=_ns_worker, args=(netnsmod._get_netnspath(ns_name), i, success)) for i, ns_name in enumerate(ns_names) ] for thread in threads: thread.start() for thread in threads: thread.join() for ns_name in ns_names: netnsmod.remove(ns_name) assert success[0]
def post(self, nspath): if nspath in netns.listnetns(): abort(500, "Namespace already exists") else: mynet = NetNS(nspath) mynet.close() return("Namespace successfully created")
def delete(self, nspath): if nspath not in netns.listnetns(): abort(404, "Namespace not found") else: with NetNS(nspath) as n: n.remove() n.close() return("Namespace successfully removed")
def test_fd_leaks_nonexistent_ns(self): for i in range(RESPAWNS): nsid = 'non_existent_leak_%i' % i try: with NetNS(nsid, flags=0): pass except OSError as e: assert e.errno in (errno.ENOENT, errno.EPIPE)
def test_fd_leaks(self): for i in range(RESPAWNS): nsid = 'leak_%i' % i ns = NetNS(nsid) ns.close() ns.remove() if hasattr(atexit, '_exithandlers'): assert ns.close not in atexit._exithandlers
def test_netns(self): ns = NetNS(str(uuid.uuid4())) try: assert len(ns.get_links()) > 1 except: raise finally: ns.close() ns.remove()
def _delete_namespace(self, namespace): ns = NetNS(namespace) bridge = ns.link_lookup(ifname='shoutbr0')[0] ns.link('set', index=bridge, state='down') ns.link('del', index=bridge) ns.close() netns.remove(namespace)
def setUpClass(cls): super().setUpClass() cls.ns = None while cls.ns is None: try: cls.name = "".join( random.choice(string.ascii_letters) for _ in range(16)) cls.ns = NetNS(cls.name, flags=os.O_CREAT | os.O_EXCL) except FileExistsError: pass
def create_mizarnetns(self, params, ep): os.makedirs('/var/run/netns/', exist_ok=True) f = os.listdir('/var/run/netns/') logging.debug("files ns {}".format(f)) src = params.netns dst = '/var/run/netns/{}'.format(ep.netns) os.symlink(src, dst) logging.debug("Created namespace {} from {}".format( ep.netns, params.netns)) return NetNS(ep.netns)
def __init__(self, routePolicy=None, netns=None): if routePolicy is None: self.routePolicy = DEFAULT_ROUTE_POLICY else: self.routePolicy = routePolicy if netns is None: netns = 'global-vrf' self.ipdb = IPDB(nl=NetNS(netns)) self.route_events = ROUTE_EVENTS
def create(self): iface = self.containerName + 'veth0' ifacePeer = self.containerName + 'veth1' ip_main = IPDB() ip_sub = IPDB(nl=NetNS(self.containerName)) ip_main.create(ifname=iface, kind='veth', peer=ifacePeer).commit() with ip_main.interfaces[ifacePeer] as veth: veth.net_ns_fd = self.containerName with ip_main.interfaces[iface] as veth: veth.up() ip_main.release() with ip_sub.interfaces[ifacePeer] as veth: #if not self.containerDhcp: if not hasattr(self, 'containerDhcp'): veth.add_ip(self.containerIp) if hasattr(self, 'containerMac'): veth.address = self.containerMac ip_sub.release() ns = NetNS(self.containerName) idx = ns.link_lookup(ifname=ifacePeer)[0] ns.link('set', index=idx, net_ns_fs=self.containerName, ifname='eth0') ns.link('set', index=idx, net_ns_fs=self.containerName, state='up') if hasattr(self, 'containerGateway'): request = {"dst": "0.0.0.0/0", "gateway": self.containerGateway} ns.route("add", **IPRouteRequest(request)) ns.close() subprocess.call(["ovs-vsctl", "add-port", "br0", iface]) dockerControl = DockerControl(self.containerObject) if hasattr(self, 'containerDhcp'): dhcpCmd = 'dhclient eth0' dockerControl.runCmd(dhcpCmd) addressCmd = 'ip address show dev eth0' addressInfo = dockerControl.runCmd(addressCmd) addressInfoList = addressInfo.splitlines() macAddressInfo = addressInfoList[1].split()[1] ipAddressInfo = addressInfoList[2].split()[1] ipAddressInfoDict = dict({ 'containerName': self.containerName, 'macAddress': macAddressInfo, 'ipAddress': ipAddressInfo }) return json.dumps(ipAddressInfoDict)
def create_ns(): with NetNS(netns=netns) as ipr: ipr.link("add", ifname=ifname, kind="veth", peer=peer) ifnet = ipr.link_lookup(ifname=ifname)[0] ifpeer = ipr.link_lookup(ifname=peer)[0] ipr.link("set", index=ifnet, mtu=mtu) ipr.link("set", index=ifnet, state="up") ipr.link("set", index=ifpeer, mtu=mtu) ipr.link("set", index=ifpeer, state="up")
def route_exists(netns=None, **kwarg): ret = 0 ipr = None if netns is not None: ipr = NetNS(netns) else: ipr = IPRoute() ret = list(ipr.route('dump', **kwarg)) ipr.close() return len(ret) >= 1
def test_create_veth_attrs(self): require_user('root') nsname = str(uuid.uuid4()) netns = NetNS(nsname) try: peer = {'ifname': self.uifname(), 'net_ns_fd': nsname} self._create_veth(peer) assert len(self.ip.link_lookup(ifname=peer['ifname'])) == 0 assert len(netns.link_lookup(ifname=peer['ifname'])) > 0 finally: netns.close() netns.remove()
def test_fd_leaks(self): namespaces = [] for i in range(RESPAWNS): nsid = 'leak_%i' % i ns = NetNS(nsid) ns.close() ns.remove() namespaces.append(ns) if sys.version_info > (3, 2) and sys.version_info < (3, 6): for n in namespaces: assert_raises(OSError, fcntl.fcntl, n.server.sentinel, fcntl.F_GETFD)
def createEndpoint(name, svcName, endpointtype): if endpointtype == 'ns': ip_host = IPDB() ip_host.create(ifname=name, kind='veth', peer=name + '_' + svcName).commit() ip_ns = IPDB(nl=NetNS(name)) with ip_host.interfaces[name] as veth: veth.net_ns_fd = name veth.up() with ip_host.interfaces[name + '_' + svcName] as veth: veth.up() subprocess.call( ["ovs-vsctl", "add-port", "vs-" + svcName, name + '_' + svcName]) ip_host.release() ip_ns.release() nsp = NSPopen(name, ['dhclient', '-lf', '/tmp/' + name + '.lease', name], stdout=subprocess.PIPE) nsp.wait() nsp.release() if endpointtype == 'lxc': subprocess.call(['/usr/bin/lxc-clone', 'template', name]) lxcUpOvsScript = '#!/bin/bash\n' lxcUpOvsScript += 'BRIDGE="vs-' + svcName + '"\n' lxcUpOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n' lxcUpOvsScript += 'ovs-vsctl add-port $BRIDGE $5\n' f = open('/var/lib/lxc/' + name + '/ovsup.sh', 'w+') f.write(lxcUpOvsScript) f.close() lxcDownOvsScript = '#!/bin/bash\n' lxcDownOvsScript += 'BRIDGE="vs-' + svcName + '"\n' lxcDownOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n' f = open('/var/lib/lxc/' + name + '/ovsdown.sh', 'w+') f.write(lxcDownOvsScript) f.close() os.chmod('/var/lib/lxc/' + name + '/ovsup.sh', stat.S_IRWXU) os.chmod('/var/lib/lxc/' + name + '/ovsdown.sh', stat.S_IRWXU) lxcConfig = 'lxc.include = /usr/share/lxc/config/ubuntu.common.conf\n' lxcConfig += 'lxc.arch = x86_64\n' lxcConfig += 'lxc.rootfs = /var/lib/lxc/' + name + '/rootfs\n' lxcConfig += 'lxc.utsname = ' + name + '\n' lxcConfig += 'lxc.network.type = veth\n' lxcConfig += 'lxc.network.veth.pair = ' + name + '\n' lxcConfig += 'lxc.network.script.up = /var/lib/lxc/' + name + '/ovsup.sh\n' lxcConfig += 'lxc.network.script.down = /var/lib/lxc/' + name + '/ovsdown.sh\n' lxcConfig += 'lxc.network.flags = up\n' f = open('/var/lib/lxc/' + name + '/config', 'w+') f.write(lxcConfig) f.close() subprocess.call(['/usr/bin/lxc-start', '-d', '-n', name]) pass return json.dumps({'status': 'created endpoint'})
def get_interfaces(self): ''' This method retrieves the list of interfaces for the network namespace. :returns: list of interfaces in the namespace :rtype: list ''' interfaces = [] with IPDB(nl=NetNS(self.name)) as ipdb: for i in ipdb.interfaces: if type(i) is str: interfaces.append(i) return interfaces
def test_create_from_path(self): ns_dir = tempfile.mkdtemp() # Create namespace ns_name = str(uuid4()) nspath = '%s/%s' % (ns_dir, ns_name) temp_ns = NetNS(nspath) temp_ns.close() fd = open(nspath) self._test_create(nspath, fd.fileno()) fd.close() netnsmod.remove(nspath) assert ns_name not in netnsmod.listnetns() assert ns_name not in netnsmod.listnetns(ns_dir)