def get_address_type(address): addr, _slash, _prefixlen = address.partition("/") if ipaddress.is_ipv4_address(addr): address_type = "IPv4" elif ipaddress.is_ipv6_address(addr): address_type = "IPv6" else: raise NotImplementedError return address_type
def generateFrrConf(cls, node): """ Returns configuration file text. Other services that depend on zebra will have generatefrrifcconfig() and generatefrrconfig() hooks that are invoked here. """ # we could verify here that filename == frr.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 is True: cfg += " " cfg += "\n ".join(map(cls.addrstr, ifc.addrlist)) cfg += "\n" continue cfgv4 = "" cfgv6 = "" want_ipv4 = False want_ipv6 = False for s in node.services: if cls.name not in s.dependencies: continue ifccfg = s.generatefrrifcconfig(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: ipaddress.is_ipv4_address(x.split("/")[0]), ifc.addrlist) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv4list)) cfg += "\n" cfg += cfgv4 if want_ipv6: ipv6list = filter( lambda x: ipaddress.is_ipv6_address(x.split("/")[0]), ifc.addrlist) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv6list)) cfg += "\n" cfg += cfgv6 cfg += "!\n" for s in node.services: if cls.name not in s.dependencies: continue cfg += s.generatefrrconfig(node) return cfg
def addrstr(x): """ helper for mapping IP addresses to zebra config statements """ addr = x.split("/")[0] if ipaddress.is_ipv4_address(addr): return "ip address %s" % x elif ipaddress.is_ipv6_address(addr): return "ipv6 address %s" % x else: raise ValueError("invalid address: %s", x)
def routerid(node): """ Helper to return the first IPv4 address of a node as its router ID. """ for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue for a in ifc.addrlist: a = a.split("/")[0] if ipaddress.is_ipv4_address(a): return a # raise ValueError, "no IPv4 address found for router ID" return "0.0.0.0"
def generatequaggaconfig(cls, node): cfg = "router ospf\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid # network 10.0.0.0/24 area 0 for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue for a in ifc.addrlist: addr = a.split("/")[0] if ipaddress.is_ipv4_address(addr): net = ipaddress.Ipv4Prefix(a) cfg += " network %s area 0\n" % net cfg += "!\n" return cfg
def firstipv4prefix(node, prefixlen=24): """ Similar to QuaggaService.routerid(). Helper to return the first IPv4 prefix of a node, using the supplied prefix length. This ignores the interface's prefix length, so e.g. '/32' can turn into '/24'. """ for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue for a in ifc.addrlist: a = a.split("/")[0] if ipaddress.is_ipv4_address(a): pre = Ipv4Prefix("%s/%s" % (a, prefixlen)) return str(pre) # raise ValueError, "no IPv4 address found" return "0.0.0.0/%s" % prefixlen
def generatexorpconfig(cls, node): cfg = cls.fea("unicast-forwarding4") rtrid = cls.routerid(node) cfg += "\nprotocols {\n" cfg += " olsr4 {\n" cfg += "\tmain-address: %s\n" % rtrid for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue cfg += "\tinterface %s {\n" % ifc.name cfg += "\t vif %s {\n" % ifc.name for a in ifc.addrlist: addr = a.split("/")[0] if not ipaddress.is_ipv4_address(addr): continue cfg += "\t\taddress %s {\n" % addr cfg += "\t\t}\n" cfg += "\t }\n" cfg += "\t}\n" cfg += " }\n" cfg += "}\n" return cfg
def generatexorpconfig(cls, node): cfg = cls.fea("unicast-forwarding4") cfg += cls.policyexportconnected() cfg += "\nprotocols {\n" cfg += " rip {\n" cfg += '\texport: "export-connected"\n' for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue cfg += "\tinterface %s {\n" % ifc.name cfg += "\t vif %s {\n" % ifc.name for a in ifc.addrlist: addr = a.split("/")[0] if not ipaddress.is_ipv4_address(addr): continue cfg += "\t\taddress %s {\n" % addr cfg += "\t\t disable: false\n" cfg += "\t\t}\n" cfg += "\t }\n" cfg += "\t}\n" cfg += " }\n" cfg += "}\n" return cfg
def all_link_data(self, flags): """ Build link data objects for this network. Each link object describes a link between this network and a node. """ all_links = [] # build a link message from this network node to each node having a # connected interface for netif in self.netifs(sort=True): if not hasattr(netif, "node"): continue linked_node = netif.node uni = False if linked_node is None: # two layer-2 switches/hubs linked together via linknet() if not hasattr(netif, "othernet"): continue linked_node = netif.othernet if linked_node.id == self.id: continue netif.swapparams('_params_up') upstream_params = netif.getparams() netif.swapparams('_params_up') if netif.getparams() != upstream_params: uni = True unidirectional = 0 if uni: unidirectional = 1 interface2_ip4 = None interface2_ip4_mask = None interface2_ip6 = None interface2_ip6_mask = None for address in netif.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if ipaddress.is_ipv4_address(ip): family = AF_INET ipl = socket.inet_pton(family, ip) interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl) interface2_ip4_mask = mask else: family = AF_INET6 ipl = socket.inet_pton(family, ip) interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl) interface2_ip6_mask = mask link_data = LinkData(message_type=flags, node1_id=self.id, node2_id=linked_node.id, link_type=self.linktype, unidirectional=unidirectional, interface2_id=linked_node.getifindex(netif), interface2_mac=netif.hwaddr, interface2_ip4=interface2_ip4, interface2_ip4_mask=interface2_ip4_mask, interface2_ip6=interface2_ip6, interface2_ip6_mask=interface2_ip6_mask, delay=netif.getparam("delay"), bandwidth=netif.getparam("bw"), dup=netif.getparam("duplicate"), jitter=netif.getparam("jitter"), per=netif.getparam("loss")) all_links.append(link_data) if not uni: continue netif.swapparams('_params_up') link_data = LinkData(message_type=0, node1_id=linked_node.id, node2_id=self.id, unidirectional=1, delay=netif.getparam("delay"), bandwidth=netif.getparam("bw"), dup=netif.getparam("duplicate"), jitter=netif.getparam("jitter"), per=netif.getparam("loss")) netif.swapparams('_params_up') all_links.append(link_data) return all_links
def all_link_data(self, flags): """ Build CORE API TLVs for a point-to-point link. One Link message describes this network. :param flags: message flags :return: list of link data :rtype: list[core.emulator.data.LinkData] """ all_links = [] if len(self._netif) != 2: return all_links if1, if2 = self._netif.values() unidirectional = 0 if if1.getparams() != if2.getparams(): unidirectional = 1 interface1_ip4 = None interface1_ip4_mask = None interface1_ip6 = None interface1_ip6_mask = None for address in if1.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if ipaddress.is_ipv4_address(ip): family = AF_INET ipl = socket.inet_pton(family, ip) interface1_ip4 = ipaddress.IpAddress(af=family, address=ipl) interface1_ip4_mask = mask else: family = AF_INET6 ipl = socket.inet_pton(family, ip) interface1_ip6 = ipaddress.IpAddress(af=family, address=ipl) interface1_ip6_mask = mask interface2_ip4 = None interface2_ip4_mask = None interface2_ip6 = None interface2_ip6_mask = None for address in if2.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if ipaddress.is_ipv4_address(ip): family = AF_INET ipl = socket.inet_pton(family, ip) interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl) interface2_ip4_mask = mask else: family = AF_INET6 ipl = socket.inet_pton(family, ip) interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl) interface2_ip6_mask = mask link_data = LinkData( message_type=flags, node1_id=if1.node.id, node2_id=if2.node.id, link_type=self.linktype, unidirectional=unidirectional, delay=if1.getparam("delay"), bandwidth=if1.getparam("bw"), per=if1.getparam("loss"), dup=if1.getparam("duplicate"), jitter=if1.getparam("jitter"), interface1_id=if1.node.getifindex(if1), interface1_mac=if1.hwaddr, interface1_ip4=interface1_ip4, interface1_ip4_mask=interface1_ip4_mask, interface1_ip6=interface1_ip6, interface1_ip6_mask=interface1_ip6_mask, interface2_id=if2.node.getifindex(if2), interface2_mac=if2.hwaddr, interface2_ip4=interface2_ip4, interface2_ip4_mask=interface2_ip4_mask, interface2_ip6=interface2_ip6, interface2_ip6_mask=interface2_ip6_mask, ) all_links.append(link_data) # build a 2nd link message for the upstream link parameters # (swap if1 and if2) if unidirectional: link_data = LinkData( message_type=0, node1_id=if2.node.id, node2_id=if1.node.id, delay=if2.getparam("delay"), bandwidth=if2.getparam("bw"), per=if2.getparam("loss"), dup=if2.getparam("duplicate"), jitter=if2.getparam("jitter"), unidirectional=1, interface1_id=if2.node.getifindex(if2), interface2_id=if1.node.getifindex(if1), ) all_links.append(link_data) return all_links
def generate_config(cls, node, filename): # Check whether the node is running zebra has_zebra = 0 for s in node.services: if s.name == "zebra": has_zebra = 1 cfg = "#!/bin/sh\n" cfg += "# auto-generated by OvsService (OvsService.py)\n" cfg += "/etc/init.d/openvswitch-switch start < /dev/null\n" cfg += "ovs-vsctl add-br ovsbr0 -- set Bridge ovsbr0 fail-mode=secure\n" cfg += "ifconfig ovsbr0 up\n" for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue ifnumstr = re.findall(r"\d+", ifc.name) ifnum = ifnumstr[0] # create virtual interfaces cfg += "ip link add rtr%s type veth peer name sw%s\n" % (ifnum, ifnum) cfg += "ifconfig rtr%s up\n" % ifnum cfg += "ifconfig sw%s up\n" % ifnum # remove ip address of eths because quagga/zebra will assign same IPs to rtr interfaces # or assign them manually to rtr interfaces if zebra is not running for ifcaddr in ifc.addrlist: addr = ifcaddr.split("/")[0] if ipaddress.is_ipv4_address(addr): cfg += "ip addr del %s dev %s\n" % (ifcaddr, ifc.name) if has_zebra == 0: cfg += "ip addr add %s dev rtr%s\n" % (ifcaddr, ifnum) elif ipaddress.is_ipv6_address(addr): cfg += "ip -6 addr del %s dev %s\n" % (ifcaddr, ifc.name) if has_zebra == 0: cfg += "ip -6 addr add %s dev rtr%s\n" % (ifcaddr, ifnum) else: raise ValueError("invalid address: %s" % ifcaddr) # add interfaces to bridge cfg += "ovs-vsctl add-port ovsbr0 eth%s\n" % ifnum cfg += "ovs-vsctl add-port ovsbr0 sw%s\n" % ifnum # Add rule for default controller if there is one local (even if the controller is not local, it finds it) cfg += "ovs-vsctl set-controller ovsbr0 tcp:127.0.0.1:6633\n" # Setup default flows portnum = 1 for ifc in node.netifs(): if hasattr(ifc, "control") and ifc.control is True: continue cfg += ( "ovs-ofctl add-flow ovsbr0 priority=1000,in_port=%d,action=output:%d\n" % (portnum, portnum + 1) ) cfg += ( "ovs-ofctl add-flow ovsbr0 priority=1000,in_port=%d,action=output:%d\n" % (portnum + 1, portnum) ) portnum += 2 return cfg