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 post(self, nspath): if nspath in netns.listnetns(): abort(500, "Namespace already exists") else: mynet = NetNS(nspath) mynet.close() return("Namespace successfully created")
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 _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 test_netns(self): ns = NetNS(str(uuid.uuid4())) try: assert len(ns.get_links()) > 1 except: raise finally: ns.close() ns.remove()
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_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 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 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)
def _delete_endpoint(self, request, response): logger.debug('endpoint.delete') network_id = request['NetworkID'] endpoint_id = request['EndpointID'] veth0_name = 'veth%s0' % endpoint_id[:6] namespace = 'sdns' + network_id[:6] ns = NetNS(namespace) veth0 = ns.link_lookup(ifname=veth0_name)[0] ns.link('set', index=veth0, router=0) ns.link('set', index=veth0, state='down') ns.link('del', index=veth0) ns.close() return {}
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_namespace(self, namespace): ip = IPRoute() ns = NetNS(namespace) ns.link('add', ifname='shoutbr0', kind='bridge') bridge = ns.link_lookup(ifname='shoutbr0')[0] ns.link('set', index=bridge, mtu=1450) ns.link('set', index=bridge, state='up') if self._raft.is_leader: for peer in self._peers: self._create_tunnel(namespace, peer) else: while self._relay_ip is None: logger.warning('waiting') time.sleep(0.5) self._create_tunnel(namespace, self._relay_ip) ip.close() ns.close()
def test_get_netns_info(self): require_user('root') nsname = str(uuid.uuid4()) netns = NetNS(nsname) try: peer = {'ifname': self.uifname(), 'net_ns_fd': nsname} ifname = self._create_veth(peer) # get veth veth = self.ip.link('get', ifname=ifname)[0] target = veth.get_attr('IFLA_LINK_NETNSID') for info in self.ip.get_netns_info(): path = info.get_attr('NSINFO_PATH') assert path.endswith(nsname) netnsid = info['netnsid'] if target == netnsid: break else: raise KeyError('peer netns not found') finally: netns.close() netns.remove()
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 teardown(self): ''' 1. close the test NDB 2. remove the registered interfaces, ignore not existing ''' self.ndb.close() self.ipr.close() for (ifname, nsname) in self.interfaces.items(): try: ipr = None # # spawn ipr to remove the interface if nsname is not None: ipr = NetNS(nsname) else: ipr = IPRoute() # # lookup the interface index index = list(ipr.link_lookup(ifname=ifname)) if len(index): index = index[0] else: # # ignore not existing interfaces continue # # try to remove it ipr.link('del', index=index) except NetlinkError as e: # # ignore if removed (t.ex. by another process) if e.code != errno.ENODEV: raise finally: if ipr is not None: ipr.close() for nsname in self.namespaces: netns.remove(nsname) for net in self.ipnets: free_network(net)
def get_ipaddr_data(response_type): if response_type == 'real': ip = NetNS('dp', flags=os.O_CREAT) physical = ip.link("get", index=ip.link_lookup(ifname="eth0")[0]) mac_address = physical[0].get_attr('IFLA_ADDRESS') try: interface = ip.get_addr(label='eth0', family=AF_INET) ip_address = interface[0].get_attr('IFA_ADDRESS') cidr = interface[0]['prefixlen'] gateway = ip.get_default_routes( family=AF_INET)[0].get_attr('RTA_GATEWAY') except IndexError as idxerror: print("Not finding an interface yet") ip_address = 'N/A' cidr = 0 gateway = 'N/A' except Exception as e: raise e finally: print("closing socket") ip.close() elif response_type == 'mock': ip_address = '192.168.0.5' cidr = 24 gateway = '192.168.0.1' else: ip_address = 'N/A' cidr = 0 gateway = 'N/A' j = { 'mac_address': mac_address, 'ip_address': ip_address, 'subnet_mask': cidr_to_netmask(cidr), 'gateway': gateway } return j
if args.remove: # cleanup interfaces for ifn in range(args.ifnum): iface = args.ifname+str(ifn) if iface in ip.interfaces: with ip.interfaces[iface] as i: i.remove() if 'tap'+args.ifname in ip.interfaces: with ip.interfaces['tap'+args.ifname] as i: i.remove() if brige_name in ip.interfaces: with ip.interfaces[brige_name] as i: i.remove() for ifn in range(args.ifnum): netns = NetNS('node'+str(ifn)) netns.close() netns.remove() else: for ifn in range(args.ifnum): iface = args.ifname+str(ifn) if not iface in ip.interfaces: ip.create(kind='veth', ifname=iface, peer=iface+'.1').commit() ip.create(kind='tuntap', ifname='tap'+args.ifname, mode='tap').commit() with ip.create(kind='bridge', ifname=brige_name) as i: for ifn in range(args.ifnum): iface = args.ifname+str(ifn) i.add_port(ip.interfaces[iface]) i.add_port(ip.interfaces['tap'+args.ifname]) if args.ipv4:
def test_fd_leaks(self): for i in range(RESPAWNS): nsid = 'leak_%i' % i ns = NetNS(nsid) ns.close() ns.remove()
print("Custom socket wrapper init done") def _forward(name, self, *args, **kwargs): print("Forward <%s> method" % name) return getattr(self._sock, name)(*args, **kwargs) for name in _socketmethods: f = partial(_forward, name) f.__name__ = name setattr(SocketWrapper, name, types.MethodType(f, self)) def fileno(self): # for some obscure reason, we can not implement `fileno()` # proxying as above, so just make a hardcore version return self._sock.fileno() def dup(self): return self.__class__(_sock=self._sock.dup()) config.SocketBase = SocketWrapper print(netns.listnetns()) ### # # Being run via the root module, real IPRoute import is postponed, # to inspect the code, refer to `pyroute2/__init__.py` # ns = NetNS('test') print(ns.get_addr()) ns.close()
if args.remove: # cleanup interfaces for ifn in range(args.ifnum): iface = args.ifname + str(ifn) if iface in ip.interfaces: with ip.interfaces[iface] as i: i.remove() if 'tap' + args.ifname in ip.interfaces: with ip.interfaces['tap' + args.ifname] as i: i.remove() if brige_name in ip.interfaces: with ip.interfaces[brige_name] as i: i.remove() for ifn in range(args.ifnum): netns = NetNS('node' + str(ifn)) netns.close() netns.remove() else: for ifn in range(args.ifnum): iface = args.ifname + str(ifn) if not iface in ip.interfaces: ip.create(kind='veth', ifname=iface, peer=iface + '.1').commit() ip.create(kind='tuntap', ifname='tap' + args.ifname, mode='tap').commit() with ip.create(kind='bridge', ifname=brige_name) as i: for ifn in range(args.ifnum): iface = args.ifname + str(ifn) i.add_port(ip.interfaces[iface])
def _forward(name, self, *args, **kwargs): print("Forward <%s> method" % name) return getattr(self._sock, name)(*args, **kwargs) for name in _socketmethods: f = partial(_forward, name) f.__name__ = name setattr(SocketWrapper, name, types.MethodType(f, self)) def fileno(self): # for some obscure reason, we can not implement `fileno()` # proxying as above, so just make a hardcore version return self._sock.fileno() def dup(self): return self.__class__(_sock=self._sock.dup()) config.SocketBase = SocketWrapper print(netns.listnetns()) ### # # Being run via the root module, real IPRoute import is postponed, # to inspect the code, refer to `pyroute2/__init__.py` # ns = NetNS('test') print(ns.get_addr()) ns.close()
class NetworkNamespace: def __init__(self): self.nsname = '' self.service = '' self.veth0 = '' self.veth1 = '' self.bridge_iface = '' self.ns = None def create(self, nsname = 'ns', service = 'ZV'): signal.signal(signal.SIGINT, self.kill) signal.signal(signal.SIGTERM, self.kill) if self.is_exist(nsname): logging.info("[NS:%s] Namespace is exist" % (nsname)) return self.nsname = nsname self.service = service self.ns = NetNS(self.nsname) self.veth0 = 'veth0' + self.nsname self.veth1 = 'veth1' + self.nsname self.bridge_iface = self.service + '-BR' self.createInterface() logging.info("[NS:%s] Create namespace" % (self.nsname)) def destroy(self, nsname = 'ns', service = 'ZV'): if self.nsname == '': self.nsname = nsname if not self.is_exist(self.nsname): logging.info("[NS:%s] Namespace is not exist" % (self.nsname)) return if self.service == '': self.service = service if self.ns == None: self.ns = NetNS(self.nsname) if self.veth0 == '': self.veth0 = 'veth0' + self.nsname if self.veth1 == '': self.veth1 = 'veth1' + self.nsname if self.bridge_iface == '': self.bridge_iface = self.service + '-BR' self.destroyInterface() self.ns.close() self.ns.remove() logging.info("[NS:%s] Destroy namespace" % (self.nsname)) def is_exist(self, nsname = 'ns'): if nsname in netns.listnetns(): return True else: return False 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 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 kill(self, sig, frame): os._exit(0)