def configure_EGP(cls, node): cfg = '' v6cfg = [] # find any link on which two different netid's (i.e., AS numbers) are # present and configure a bgp-session between the two corresponding nodes. for localnetif in node.netifs(): # do not include control interfaces if hasattr(localnetif, 'control') and localnetif.control == True: continue for idx, net_netif in list(localnetif.net._netif.items()): candidate_node = net_netif.node # skip our own interface if localnetif == net_netif.node: continue # found two different ASes. if not node.netid == net_netif.node.netid and \ service_flags.EGP in net_netif.node.services: for local_node_addr in localnetif.addrlist: local_node_addr_str = str(local_node_addr.split('/')[0]) if not node.enable_ipv4 and \ isIPv4Address(local_node_addr): continue if not node.enable_ipv6 and \ isIPv6Address(local_node_addr): continue for remote_node_addr in net_netif.addrlist: remote_node_addr_str = str(remote_node_addr.split('/')[0]) if not net_netif.node.enable_ipv4 and \ isIPv4Address(remote_node_addr): continue if not net_netif.node.enable_ipv6 and \ isIPv6Address(remote_node_addr): continue # for inter-AS links, use interface addresses # instead of loopback addresses if (isIPv4Address(local_node_addr) and \ isIPv4Address(remote_node_addr)): cfg += ' neighbor %s remote-as %s\n' % \ (remote_node_addr_str, \ str(net_netif.node.netid)) elif (isIPv6Address(local_node_addr) and \ isIPv6Address(remote_node_addr)): cfg += ' neighbor %s remote-as %s\n' % \ (remote_node_addr_str, str(net_netif.node.netid)) v6cfg.append((' neighbor %s activate\n' % remote_node_addr_str)) v6cfg.append((' network %s\n' % str(local_node_addr))) return cfg, v6cfg
def addaddr(self, ifindex, addr): if self.up: if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): self.cmd([IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)]) if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr): try: if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): self._netif[ifindex].deladdr(addr) except ValueError: self.warn("trying to delete unknown address: %s" % addr) if self.up: if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): self.cmd([IP_BIN, "addr", "del", str(addr), "dev", self.ifname(ifindex)])
def compileZoneFile(cls, nameservers, hosts = None): # element in nameservers: tuple(server-name, server-ipaddr, zone that server handles) # element in hosts: tuple(server-name, server-ipaddr) if nameservers is None: nameservers = [] if hosts is None: hosts = [] nameserverlist = [] tmpnameserverlist = [] forwardhostlist = [] reversehostlist = [] seen_server_names = {} for server_name, server_addr, zone in nameservers: if isIPv4Address(server_addr): recordtype = 'A' elif isIPv6Address(server_addr): recordtype = 'AAAA' else: raise ValueError if not server_name in seen_server_names: seen_server_names[server_name] = {} if not zone in seen_server_names[server_name]: seen_server_names[server_name][zone]= 1 tmpnameserverlist.extend([ server_name, ' ', recordtype, ' ', server_addr, '\n' ]) for servername, zones in seen_server_names.items(): for zone in zones.keys(): nameserverlist.extend([zone, ' IN NS ', servername, '\n']) nameserverlist.extend(tmpnameserverlist) for host_name, host_addr, zone in hosts: if isIPv4Address(host_addr): recordtype = 'A' elif isIPv6Address(host_addr): recordtype = 'AAAA' else: raise ValueError forwardhostlist.extend([host_name, ' IN ', recordtype, ' ', host_addr, '\n']) return (''.join(nameserverlist), ''.join(forwardhostlist), ''.join(reversehostlist))
def generateZebraConf(cls, node, services): ''' Returns configuration file text that defines which daemons to run. ''' cfg = [] cfg.append('log file /tmp/quagga-zebra-%s.log\n' % node.name) cfg.append('hostname %s\n' % node.name) cfg.append('agentx\n') cfg.append('interface lo\n') if node.enable_ipv4: cfg.append(' ip address %s/32\n' % node.getLoopbackIPv4()) if node.enable_ipv6: cfg.append(' ipv6 address %s/128\n' % node.getLoopbackIPv6()) for ifc in node.netifs(): # do not ever include control interfaces in anything if hasattr(ifc, 'control') and ifc.control == True: continue cfg.append('interface %s\n' % ifc.name) for a in ifc.addrlist: if isIPv4Address(a): cfg.append(' ip address %s\n' % a) if isIPv6Address(a): cfg.append(' ipv6 address %s\n' % a) cfg.append('!\n') if node.enable_ipv4: cfg.append('ip forwarding\n') if node.enable_ipv6: cfg.append('ipv6 forwarding\n') return ''.join(cfg)
def add_virtual_host(self, parent, obj): assert isinstance(obj, nodes.PyCoreNode) el = self.add_host(parent, obj.name) device = self.find_device(self.root.baseEle, obj.name) if device is None: self.session.warn('corresponding XML device not found for %s' % (obj.name)) return self.add_mapping(device, 'testHost', el.getAttribute('id')) self.add_type(el, 'virtual') for netif in obj.netifs(): for address in netif.addrlist: addr, slash, prefixlen= address.partition('/') if ipaddr.isIPv4Address(addr): addr_type = 'IPv4' elif ipaddr.isIPv6Address(addr): addr_type = 'IPv6' else: raise NotImplementedError self.add_address(el, addr_type, address, netif.name) if isinstance(netif.net, nodes.EmaneNode): nem = self.add_emane_interface(parent, el, netif) interface = self.find_interface(device, netif.name) self.add_mapping(interface, 'nem', nem.getAttribute('id')) return el
def generateconfig(cls, node, filename, services): cfg = "# auto-generated by StaticRouteToLoopback dummy service (utility.py)\n" for ifc in node.netifs(): for idx, net_netif in list(ifc.net._netif.items()): # do not include control interfaces if hasattr(ifc, 'control') and ifc.control == True: continue # skip all own interface(s) if ifc == net_netif: continue # only core routers are candidate gateways if not service_flags.Router in net_netif.node.services: continue for addr in ifc.addrlist: if node.enable_ipv4 and isIPv4Address(addr): route_target = node.getLoopbackIPv4() elif node.enable_ipv6 and isIPv6Address(addr): route_target = node.getLoopbackIPv6() else: continue print(('[%s] ip r a %s via %s' % (str(cls), str(route_target), str(addr.split('/')[0])))) net_netif.node.cmd(['ip', 'route', 'add', str(route_target), 'via', addr.split('/')[0]]) cfg += ' '.join(['#ip', 'route', 'add', str(route_target), 'via', addr.split('/')[0], '\n']) return cfg
def generatequaggaifcconfig(cls, node, ifc): if not node.enable_ipv4 and not node.enable_ipv6: return '' if hasattr(ifc, 'control') and ifc.control == True: return '' enable_ifc = False for a in ifc.addrlist: if node.enable_ipv4 and isIPv4Address(a): enable_ifc = True if node.enable_ipv6 and isIPv6Address(a): enable_ifc = True cfg = '' if enable_ifc: cfg += cls.mtucheck(ifc) for idx, net_netif in list(ifc.net._netif.items()): # skip our own interface if ifc == net_netif: continue # skip control interface if hasattr(ifc, 'control') and ifc.control == True: continue # found the same AS, enable IGP/OSPF if node.netid == net_netif.node.netid: if not service_flags.Router in net_netif.node.services: # other end of link is not router. don't send hellos cfg += ' ipv6 ospf6 passive\n' break return cfg
def generatequaggaconfig(cls, node): cfg = '' cfg += cls.generatequaggaloconfig(node) for ifc in node.netifs(): # do not ever include control interfaces in anything if hasattr(ifc, 'control') and ifc.control == True: continue tmpcfg = 'interface %s\n' % ifc.name cfgv4 = '' cfgv6 = '' cfgvall = '' want_ipv4 = False want_ipv6 = False ifccfg = cls.generatequaggaifcconfig(node, ifc) if cls._ipv4_routing and node.enable_ipv4: want_ipv4 = True if cls._ipv6_routing and node.enable_ipv6: want_ipv6 = True if want_ipv4 and not want_ipv6: cfgv4 += ifccfg elif not want_ipv4 and want_ipv6: cfgv6 += ifccfg elif want_ipv4 and want_ipv6: cfgvall += ifccfg if want_ipv4 and not want_ipv6: ipv4list = [x for x in ifc.addrlist if isIPv4Address(x)] tmpcfg += cfgv4 elif not want_ipv4 and want_ipv6: ipv6list = [x for x in ifc.addrlist if isIPv6Address(x)] tmpcfg += cfgv6 elif want_ipv4 and want_ipv6: tmpcfg += cfgv4 tmpcfg += cfgv6 tmpcfg += cfgvall tmpcfg += '!\n' if want_ipv4 or want_ipv6: cfg += tmpcfg cfg += '! ISIS configuration\n' if node.enable_ipv4 or node.enable_ipv6: cfg += 'log file /tmp/quagga-isis-%s.log\n' % node.name cfg += 'router isis 1\n' cfg += ' net %s\n' % cls.get_ISIS_ID(cls.routerid(node), str(node.netid)) cfg += ' metric-style wide\n' cfg += '!\n' return cfg
def addrstr(x): ''' helper for mapping IP addresses to zebra config statements ''' if isIPv4Address(x): return 'ip address %s' % x elif isIPv6Address(x): return 'ipv6 address %s' % x else: raise Value('invalid address: %s').with_traceback(x)
def generateQuaggaConf(cls, node, services): ''' Returns configuration file text. Other services that depend on zebra will have generatequaggaifcconfig() and generatequaggaconfig() hooks that are invoked here. ''' # we could verify here that filename == Quagga.conf cfg = "" for ifc in node.netifs(): cfg += "interface %s\n" % ifc.name # include control interfaces in addressing but not routing daemons if hasattr(ifc, 'control') and ifc.control == True: cfg += " " cfg += "\n ".join(map(cls.addrstr, ifc.addrlist)) cfg += "\n" continue cfgv4 = "" cfgv6 = "" want_ipv4 = False want_ipv6 = False for s in services: if cls._name not in s._depends: continue ifccfg = s.generatequaggaifcconfig(node, ifc) if s._ipv4_routing: want_ipv4 = True if s._ipv6_routing: want_ipv6 = True cfgv6 += ifccfg else: cfgv4 += ifccfg if want_ipv4: ipv4list = filter(lambda x: isIPv4Address(x.split('/')[0]), ifc.addrlist) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv4list)) cfg += "\n" cfg += cfgv4 if want_ipv6: ipv6list = filter(lambda x: isIPv6Address(x.split('/')[0]), ifc.addrlist) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv6list)) cfg += "\n" cfg += cfgv6 cfg += "!\n" for s in services: if cls._name not in s._depends: continue cfg += s.generatequaggaconfig(node) return cfg
def nodewalker_asroot_dns_find_hosts_in_as_callback(startnode, currentnode): """ add any host from the AS of startnode to hostlist and return it """ hosts = [] # element in hosts: tuple(server-fqdn, server-ipaddr, zone that host lives in) if hasattr(currentnode, 'netid') and not currentnode.netid is None: netid = currentnode.netid else: # TODO: netid 0 is invalid netid = 0 zone = "AS%s.virtual." % str(netid) # ignore AS authoritative servers as they are already included #if not service_flags.DNSASRootServer in currentnode.services and \ if currentnode.netid == startnode.netid: # add plain hostname server_name = currentnode.name for ipversion in currentnode.getIPversions(): if ipversion in startnode.getIPversions(): server_addr = currentnode.getLoopback(ipversion) server_addr = str(server_addr).partition('/')[0] hosts.append((server_name, server_addr, zone)) # add all interface names for intf in list(currentnode._netif.values()): server_name = '%s.%s' % (intf.name, currentnode.name) # use first v4 and first v6 address of this interface v4addr = None v6addr = None for addr in intf.addrlist: addr = addr.partition('/')[0] if not v4addr is None and not v6addr is None: break if v4addr is None and isIPv4Address(addr): v4addr = addr if v6addr is None and isIPv6Address(addr): v6addr = addr if not v4addr is None and 4 in currentnode.getIPversions() and \ 4 in startnode.getIPversions(): hosts.append((server_name, v4addr, zone)) if not v6addr is None and 6 in currentnode.getIPversions() and \ 6 in startnode.getIPversions(): hosts.append((server_name, v6addr, zone)) return hosts
def nodewalker_if_verbose_callback(startnode, currentnode): result = [] #if currentnode.enable_ipv6 and startnode.enable_ipv6: # result.append(str(currentnode.getLoopbackIPv6())) if currentnode.enable_ipv4 and startnode.enable_ipv4: for intf in currentnode._netif.values(): for addr in intf.addrlist: if isIPv4Address(addr): result.extend([addr.partition('/')[0], ' ', currentnode.name, '\n']) if currentnode.enable_ipv6 and startnode.enable_ipv6: for intf in currentnode._netif.values(): for addr in intf.addrlist: if isIPv6Address(addr): result.extend([addr.partition('/')[0], ' ', currentnode.name, '\n']) return result
def nodewalker_callback(startnode, currentnode): result = [] hostname = '%s.AS%s.virtual' % (currentnode.name, str(currentnode.netid)) if currentnode.enable_ipv6 and startnode.enable_ipv6: result.extend([hostname, ' AAAA ', str(currentnode.getLoopbackIPv6()), '\n']) # TODO: in order to check PTR records, convert IP addr to PTR-style #result.extend([str(currentnode.getLoopbackIPv6()), ' PTR ', # hostname, '\n']) if currentnode.enable_ipv4 and startnode.enable_ipv4: result.extend([hostname, ' A ', str(currentnode.getLoopbackIPv4()), '\n']) # TODO: in order to check PTR records, convert IP addr to PTR-style #result.extend([str(currentnode.getLoopbackIPv4()), ' PTR ', # hostname, '\n']) if currentnode.enable_ipv4 and startnode.enable_ipv4: for intf in currentnode._netif.values(): if hasattr(intf, 'control') and intf.control == True: continue for addr in intf.addrlist: if isIPv4Address(addr): result.extend(['%s.%s' % (intf.name, hostname), ' A ', addr.partition('/')[0], '\n']) # TODO: in order to check PTR records, convert IP addr to PTR-style #result.extend([addr.partition('/')[0], ' PTR ', # '%s.%s' % (intf.name, hostname), '\n']) if currentnode.enable_ipv6 and startnode.enable_ipv6: for intf in currentnode._netif.values(): if hasattr(intf, 'control') and intf.control == True: continue for addr in intf.addrlist: if isIPv6Address(addr): result.extend(['%s.%s' % (intf.name, hostname), ' AAAA ', addr.partition('/')[0], '\n']) # TODO: in order to check PTR records, convert IP addr to PTR-style #result.extend([addr.partition('/')[0], ' PTR ', # '%s.%s' % (intf.name, hostname), '\n']) return result
def nodewalker_if_callback(startnode, currentnode): result = [] #if currentnode.enable_ipv6 and startnode.enable_ipv6: # result.append(str(currentnode.getLoopbackIPv6())) if currentnode.enable_ipv4 and startnode.enable_ipv4: for intf in currentnode._netif.values(): if hasattr(intf, 'control') and intf.control == True: continue for addr in intf.addrlist: if isIPv4Address(addr): result.extend([addr.partition('/')[0], '\n']) if currentnode.enable_ipv6 and startnode.enable_ipv6: for intf in currentnode._netif.values(): if hasattr(intf, 'control') and intf.control == True: continue for addr in intf.addrlist: if isIPv6Address(addr): result.extend([addr.partition('/')[0], '\n']) return result
def generateDelegationRecord(cls, delegation_servers, zone): delegationitems = [] delegationitems.append('$ORIGIN %s\n' % zone) tmp_servers = [server for server, server_addr in delegation_servers] # add each server once but only once (that's why the set is there) for server in set(tmp_servers): delegationitems.append('@ IN NS %s\n' % (server)) for server, server_addr in delegation_servers: recordtype = '' if isIPv4Address(server_addr): recordtype = 'A' elif isIPv6Address(server_addr): recordtype = 'AAAA' else: raise ValueError delegationitems.append('%s %s %s\n' % (server, recordtype, server_addr)) return ''.join(delegationitems)
def generateconfig(cls, node, filename, services): cfg = "#!/bin/sh\n" cfg += "# auto-generated by DefaultRoute service (utility.py)\n" for ifc in node.netifs(): for idx, net_netif in list(ifc.net._netif.items()): # do not include control interfaces if hasattr(ifc, 'control') and ifc.control == True: continue # skip our own interface if ifc == net_netif: continue for addr in net_netif.addrlist: # only core routers are candidate gateways if not service_flags.Router in net_netif.node.services: continue if node.enable_ipv4 and isIPv4Address(addr): cfg += cls.addrstr(addr) if node.enable_ipv6 and isIPv6Address(addr): cfg += cls.addrstr(addr) return cfg
def get_ipv6_addresses(self): #print('[DEBUG] all addresses: %s' % str(self.__addresses__)) #print('[DEBUG] IPv6 addresses: %s' % str([addr for addr in self.__addresses__ if # isIPv6Address(addr)])) return [addr for addr in self.__addresses__ if isIPv6Address(addr)]
def getAndGeneratePTRZonesASAuthServer(cls, node): """ returns a list of all reverse zones a root dns server serves """ # find dns as authoritative servers # (server_name, server_addr, zone) as_auth_servers = [] service_helpers.nodewalker(node, node, as_auth_servers, cls.nodewalker_root_dns_find_all_auth_servers_callback) as_auth_servers = [('%s.%s' % (server_name, zone), server_addr, zone) \ for server_name, server_addr, zone in as_auth_servers] # zone = "AS%s.virtual." % str(netid) zonenames = [] if hasattr(node, 'netid') and not node.netid is None: netid = node.netid else: # TODO: netid 0 is invalid netid = 0 asn = netid for ipversion in node.getIPversions(): # collect loopback address space loopback_net = Loopback.getLoopbackNet_per_net(\ node.session.sessionid, netid, ipversion) print(('[DEBUG] loopback_net IPv%d: %s' % (ipversion, loopback_net))) # collect interface address space interface_net = Interface.getInterfaceNet_per_net(\ node.session.sessionid, netid, ipversion) print(('[DEBUG] interface_net IPv%d: %s' % (ipversion, interface_net))) if ipversion == 4: auth_servers = [(server_name, server_addr) \ for server_name, server_addr, zone in as_auth_servers \ if zone == "AS%s.virtual." % str(netid) and \ isIPv4Address(server_addr)] elif ipversion == 6: auth_servers = [(server_name, server_addr) \ for server_name, server_addr, zone in as_auth_servers \ if zone == "AS%s.virtual." % str(netid) and \ isIPv6Address(server_addr)] else: raise ValueError for asn_net in loopback_net, interface_net: zonename = cls.getPTRZoneNameFromPrefix(cls, asn_net) print(('[DEBUG] zonename: %s' % zonename)) ORIGINHeader = '$ORIGIN %s\n' % zonename print(('[DEBUG] ORIGINHeader: %s' % ORIGINHeader)) SOAHeader = cls.generateSOAHeader(cls, auth_servers, zonename) print(('[DEBUG] SOAHeader:\n%s' % SOAHeader)) zoneentries = [] # get host list of this AS # TODO: iterating over all nodes for interface and # loopback address space is expensive. and we are only talking # about IPv4 or IPv6 at the moment. # is there a better way of doing this? hosts = [] service_helpers.nodewalker(node, node, hosts, cls.nodewalker_asroot_dns_find_hosts_in_as_callback) for hostname, asn_addr, zone in hosts: if ipversion == 4 and not isIPv4Address(asn_addr): continue if ipversion == 6 and not isIPv6Address(asn_addr): continue if ipversion == 4: asn_addr = IPv4Addr(asn_addr) elif ipversion == 6: asn_addr = IPv6Addr(asn_addr) else: raise ValueError if asn_addr < asn_net.minaddr() or \ asn_addr > asn_net.maxaddr(): continue # set prefix length. just to be sure asn_addr.set_prefixlen(asn_net.prefixlen) asn_ptr_name = cls.getPTR_CNAME_FromAddr(cls, asn_addr) print(('[DEBUG] ASN PTR addr (IPv%d): %s' % (ipversion, str(asn_addr)))) print(('[DEBUG] adding: "%s IN PTR %s.AS%s.virtual.' % (asn_ptr_name, hostname, str(netid)))) zoneentries.append(('%s IN PTR %s.AS%s.virtual.' % (asn_ptr_name, hostname, str(netid)))) print(('[DEBUG] PTR records: %s' % (zoneentries))) zonecontents = '%s\n%s\n%s\n' % (ORIGINHeader, SOAHeader, '\n'.join(zoneentries)) cls.writeZoneFile(cls, node, zonename, zonecontents) print(('[DEBUG] adding ptrzone: %s' % zonename)) zonenames.append(zonename) return zonenames
def getAndGeneratePTRZonesRootServer(cls, node): """ returns a list of all reverse zones a root dns server serves """ # find dns root servers # (server_name, server_addr) rootservers = [] service_helpers.nodewalker(node, node, rootservers, cls.nodewalker_find_root_dns_callback) rootservers = [('%s.' % server_name, server_addr) \ for server_name, server_addr in rootservers] # find dns as authoritative servers # (server_name, server_addr, zone) as_auth_servers = [] service_helpers.nodewalker(node, node, as_auth_servers, cls.nodewalker_root_dns_find_all_auth_servers_callback) as_auth_servers = [('%s.%s' % (server_name, zone), server_addr, zone) \ for server_name, server_addr, zone in as_auth_servers] zonenames = [] SOAHeader = cls.generateSOAHeader(cls, rootservers, '.') print(('[DEBUG] SOAHeader:\n%s' % SOAHeader)) for ipversion in node.getIPversions(): # collect loopback address space loopback_net = Loopback.getLoopbackNet(ipversion) print(('[DEBUG] loopback_net IPv%d: %s' % (ipversion, loopback_net))) # collect interface address space interface_net = Interface.getInterfaceNet(ipversion) print(('[DEBUG] interface_net IPv%d: %s' % (ipversion, interface_net))) # get all deployed ASN's asns = list(NetIDNodeMap.mapping[node.session.sessionid].keys()) print(('[DEBUG] deployed ASN\'s: %s' % asns)) for net in loopback_net, interface_net: zonename = cls.getPTRZoneNameFromPrefix(cls, net) net_prefixlen = net.prefixlen print(('[DEBUG] zonename: %s' % zonename)) ORIGINHeader = '$ORIGIN %s\n' % zonename print(('[DEBUG] ORIGINHeader: %s' % ORIGINHeader)) zoneentries = [] for asn in asns: # get AS address space if net == loopback_net: asn_net = Loopback.getLoopbackNet_per_net(\ node.session.sessionid, asn, ipversion) elif net == interface_net: asn_net = Interface.getInterfaceNet_per_net(\ node.session.sessionid, asn, ipversion) # find authoritative AS dns servers # zone == "AS%s.virtual." % str(netid) for server_name, server_addr, zone in as_auth_servers: server_asn = zone.lstrip('AS') server_asn = int(server_asn[:server_asn.find('.')]) # not the correct asn if not asn == server_asn: continue # not our IP version if ipversion == 4 and not isIPv4Address(server_addr): continue if ipversion == 6 and not isIPv6Address(server_addr): continue print(('[DEBUG] server_name: %s, server_addr: %s, zone: %s' % (server_name, server_addr, zone))) if ipversion == 4: # get host list of this AS # TODO: iterating over all nodes for each AS for interface and # loopback address space is expensive. and we are only talking # about IPv4 at the moment. is there a better way of doing this? hosts = [] # TODO: tmp. setting another netid of a node is a dirty hack tmpnetid = node.netid node.netid = server_asn service_helpers.nodewalker(node, node, hosts, cls.nodewalker_asroot_dns_find_hosts_in_as_callback) node.netid = tmpnetid for hostname, asn_addr, zone in hosts: if not isIPv4Address(asn_addr): continue asn_addr = IPv4Addr(asn_addr) print(('[DEBUG] asn_addr(%s) in asn_net(%s)' % (str(asn_addr), str(asn_net)))) if asn_addr < asn_net.minaddr() or \ asn_addr > asn_net.maxaddr(): continue # set prefix length of the supernet asn_addr.set_prefixlen(net_prefixlen) asn_ptr_name = cls.getPTR_CNAME_FromAddr(cls, asn_addr) #print(('[DEBUG] deployed ASN network (IPv%d): %s' % # (ipversion, str(asn_net)))) print(('[DEBUG] ASN PTR addr (IPv%d): %s' % (ipversion, str(asn_addr)))) print(('[DEBUG] adding: "%s IN NS %s"' % (asn_ptr_name, server_name))) zoneentries.append(('%s IN NS %s' % (asn_ptr_name, server_name))) elif ipversion == 6: asn_ptr_name = cls.getPTRZoneNameFromPrefix(cls, asn_net) print(('[DEBUG] adding: "%s IN NS %s"' % (asn_ptr_name, server_name))) zoneentries.append(('%s IN NS %s' % (asn_ptr_name, server_name))) print(('[DEBUG] subnet name servers: %s' % (zoneentries))) zonecontents = '%s\n%s\n%s\n' % (ORIGINHeader, SOAHeader, '\n'.join(zoneentries)) cls.writeZoneFile(cls, node, zonename, zonecontents) print(('[DEBUG] adding ptrzone to zonenames: %s' % zonename)) zonenames.append(zonename) return zonenames
def add_link(self, link): def is_ptp(link): return (not link.get_src_node().get_type() == 'lanswitch' and \ not link.get_dst_node().get_type() == 'lanswitch') # TODO: refactor me #print('[TRACE] add_link(link=%s)' % str(link)) # TODO: raise if link_cnt > 255 / if addr > ipv4_interface_net/'ipv4_interface_net_per_netid' asn = link.get_src_node().get_asn() #print('[DEBUG] ASN of src_node: %d' % asn) ptp = is_ptp(link) #print('[DEBUG] is PTP: %s' % ptp) # generate which interfaces generate_src_if = False src_interface = link.get_src_interface() generate_dst_if = False dst_interface = link.get_dst_interface() src_if_ipv4_addr = None dst_if_ipv4_addr = None src_if_ipv6_addr = None dst_if_ipv6_addr = None # case: both interfaces of this link have no addresses set if link.get_src_interface() is None or link.get_dst_interface() is None: if ptp: link_ipv4_prefix = self.__as_get_next_link_ipv4_prefix__(asn, ptp=ptp) #print('[DEBUG] ipv4 link_prefix: %s' % str(link_ipv4_prefix)) src_if_ipv4_addr = link_ipv4_prefix.minaddr() src_if_ipv4_addr.set_prefixlen(link_ipv4_prefix.prefixlen) dst_if_ipv4_addr = link_ipv4_prefix.maxaddr() dst_if_ipv4_addr.set_prefixlen(link_ipv4_prefix.prefixlen) link_ipv6_prefix = self.__as_get_next_link_ipv6_prefix__(asn) #print('[DEBUG] ipv6 link_prefix: %s' % str(link_ipv6_prefix)) src_if_ipv6_addr = link_ipv6_prefix.minaddr() src_if_ipv6_addr.set_prefixlen(link_ipv6_prefix.prefixlen) # when using >=/64 for ptp-links, use next line if link_ipv6_prefix.prefixlen >= 64: #dst_if_ipv6_addr = link_ipv6_prefix.maxaddr() dst_if_ipv6_addr = src_if_ipv6_addr + 1 dst_if_ipv6_addr.set_prefixlen(link_ipv6_prefix.prefixlen) else: # when using </64 (63,62,..) for ptp-links, use next line dst_prefix = IPv6Prefix('%s/%s' % (str(src_if_ipv6_addr), str(link_ipv6_prefix.prefixlen + 1))) # intentionally overflow to next prefix # (skip brdcst, network, select first addr of following prefix) dst_if_ipv6_addr = dst_prefix.maxaddr() + 3 dst_if_ipv6_addr.set_prefixlen(link_ipv6_prefix.prefixlen) if link.get_src_interface() is None: generate_src_if = True if link.get_dst_interface() is None: generate_dst_if = True else: # not point-to-point-link # this means, that there is a switch between src and dst # find igp_node (router) behind the switch and use it's subnet # as address space for connected nodes switch = None if link.get_src_node().get_type() == 'lanswitch': switch = link.get_src_node() generate_dst_if = True elif link.get_dst_node().get_type() == 'lanswitch': switch = link.get_dst_node() generate_src_if = True # give me all links that this switch currently has for node_link in self.get_links_of_node(switch): for node, interface in node_link.nodes: if node is switch: continue # found the igp_node (router) behind the switch if node.get_tag() == 'igp': if len(interface.get_addresses()) == 1 and \ interface.get_addresses()[0] is None: #print('[DEBUG] igp_node does not yet have an addr on its interface') pass else: # TODO: this is kinda wrong. what happens when there are more than # one addresses assigned? for base_addr in interface.get_addresses(): ifc_key = interface.get_key() #print('[DEBUG] base addr of igp_node (if idx: %s) behind switch: %s' # % (ifc_key, base_addr)) if isIPv4Address(base_addr): # set src and dst to the same addr (we only assign one of them. see below) if not node in self.__bookkeeping__['ipv4_brdcst_max_addr']: self.__bookkeeping__['ipv4_brdcst_max_addr'][node] = {} if not ifc_key in self.__bookkeeping__['ipv4_brdcst_max_addr'][node]: self.__bookkeeping__['ipv4_brdcst_max_addr'][node][ifc_key] = base_addr self.__bookkeeping__['ipv4_brdcst_max_addr'][node][ifc_key] += 1 src_if_ipv4_addr = self.__bookkeeping__['ipv4_brdcst_max_addr'][node][ifc_key] src_if_ipv4_addr.set_prefixlen(base_addr.prefixlen) dst_if_ipv4_addr = src_if_ipv4_addr elif isIPv6Address(base_addr): # set src and dst to the same addr (we only assign one of them. see below) if not node in self.__bookkeeping__['ipv6_brdcst_max_addr']: self.__bookkeeping__['ipv6_brdcst_max_addr'][node] = {} if not ifc_key in self.__bookkeeping__['ipv6_brdcst_max_addr'][node]: self.__bookkeeping__['ipv6_brdcst_max_addr'][node][ifc_key] = base_addr self.__bookkeeping__['ipv6_brdcst_max_addr'][node][ifc_key] += 1 src_if_ipv6_addr = self.__bookkeeping__['ipv6_brdcst_max_addr'][node][ifc_key] src_if_ipv6_addr.set_prefixlen(base_addr.prefixlen) dst_if_ipv6_addr = src_if_ipv6_addr if len(self.get_links_of_node(switch)) == 0: #print('[DEBUG] switch does not yet have any registered links') link_ipv4_prefix = self.__as_get_next_link_ipv4_prefix__(asn, ptp=ptp) #print('[DEBUG] ipv4 link_prefix: %s' % str(link_ipv4_prefix)) # set src and dst to the same addr (we only assign one of them. see below) src_if_ipv4_addr = link_ipv4_prefix.minaddr() src_if_ipv4_addr.set_prefixlen(link_ipv4_prefix.prefixlen) dst_if_ipv4_addr = src_if_ipv4_addr link_ipv6_prefix = self.__as_get_next_link_ipv6_prefix__(asn, ptp=ptp) #print('[DEBUG] ipv6 link_prefix: %s' % str(link_ipv6_prefix)) src_if_ipv6_addr = link_ipv6_prefix.minaddr() src_if_ipv6_addr.set_prefixlen(link_ipv6_prefix.prefixlen) dst_if_ipv6_addr = src_if_ipv6_addr if generate_src_if: #print('[DEBUG] link: src ipv4 address: %s/%s' % (src_if_ipv4_addr, # str(src_if_ipv4_addr.get_prefixlen()))) #print('[DEBUG] link: src ipv6 address: %s/%s' % (src_if_ipv6_addr, # str(src_if_ipv6_addr.get_prefixlen()))) # don't assign an IP address to a switch interface if link.get_src_node().get_type() == 'lanswitch': #print('[DEBUG] node type is lanswitch') src_interface = link.get_src_node().create_interface([]) else: src_interface = link.get_src_node().create_interface([ src_if_ipv4_addr, src_if_ipv6_addr]) #print('[DEBUG] adding link_src: (%s, %s)' % (link.get_src_node().get_name(), src_interface)) link.set_src(link.get_src_node(), src_interface) if src_interface is None: #print('[DEBUG] src_interface is None: %s' % str(src_interface)) src_interface = link.get_src_node().create_interface([]) link.set_src(link.get_src_node(), src_interface) if generate_dst_if: #print('[DEBUG] link: dst ipv4 address: %s/%s' % (dst_if_ipv4_addr, # str(dst_if_ipv4_addr.get_prefixlen()))) #print('[DEBUG] link: dst ipv6 address: %s/%s' % (dst_if_ipv6_addr, # str(dst_if_ipv6_addr.get_prefixlen()))) # don't assign an IP address to a switch interface if link.get_dst_node().get_type() == 'lanswitch': #print('[DEBUG] node type is lanswitch') dst_interface = link.get_dst_node().create_interface([]) else: dst_interface = link.get_dst_node().create_interface([ dst_if_ipv4_addr, dst_if_ipv6_addr]) #print('[DEBUG] adding link_dst: (%s, %s)' % (link.get_dst_node().get_name(), dst_interface)) link.set_dst(link.get_dst_node(), dst_interface) if dst_interface is None: dst_interface = link.get_dst_node().create_interface([]) link.set_dst(link.get_dst_node(), dst_interface) self.__links__.append(link)
def newnetif(self, net = None, addrlist = [], hwaddr = None, ifindex = None, ifname = None): self.lock.acquire() try: if isinstance(net, EmaneNode): ifindex = self.newtuntap(ifindex = ifindex, ifname = ifname, net = net) # TUN/TAP is not ready for addressing yet; the device may # take some time to appear, and installing it into a # namespace after it has been bound removes addressing; # save addresses with the interface now self.attachnet(ifindex, net) netif = self.netif(ifindex) netif.sethwaddr(hwaddr) for addr in maketuple(addrlist): if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): netif.addaddr(addr) return ifindex else: ifindex = self.newveth(ifindex = ifindex, ifname = ifname, net = net) if net is not None: self.attachnet(ifindex, net) if hwaddr: self.sethwaddr(ifindex, hwaddr) for addr in maketuple(addrlist): if self.enable_ipv4 and isIPv4Address(addr) or \ self.enable_ipv6 and isIPv6Address(addr): self.addaddr(ifindex, addr) self.ifup(ifindex) return ifindex finally: self.lock.release()