Beispiel #1
0
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
Beispiel #2
0
    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
Beispiel #3
0
 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)
Beispiel #4
0
 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"
Beispiel #5
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
Beispiel #6
0
 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
Beispiel #7
0
 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
Beispiel #8
0
 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
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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