Beispiel #1
0
 def routerid(node):
     ''' Helper to return the first IPv4 address of a node as its router ID.
     '''
     # Use IPv4 loopback address of this node as the routerID.
     # Don't get v4-loopback-addr directly from node as the node might has
     # IPv4 disabled. Instead, directly query the central 'database' for the
     # IPv4 address that would be the nodes IPv4 loopback.
     return str(Loopback.getLoopbackIPv4(node))
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    def generatequaggaconfig(cls, node):
        v6cfg = []
        v6prefixes = []

        if not node.enable_ipv4 and not node.enable_ipv6:
            return ''

        cfg = '!\n! BGP configuration\n!\n'
        cfg += 'log file /tmp/quagga-bgp-%s.log\n' % node.name
        cfg += 'router bgp %s\n' % node.netid
        cfg += '  bgp router-id %s\n' % cls.routerid(node)
        cfg += '  redistribute kernel\n'
        cfg += '  redistribute static\n'

        cfg += '!\n'

        if hasattr(node, 'netid') and not node.netid is None:
            netid = node.netid
        else:
            # TODO: netid 0 is invalid
            netid = 0

        # configure EBGP connections:
        if service_flags.EGP in node.services:
            tmpcfg, tmpv6cfg = cls.configure_EGP(node)
            cfg += tmpcfg
            v6cfg.extend(tmpv6cfg)

        # configure IBGP connections
        confstr_list = [cfg]
        # full mesh
        service_helpers.nodewalker(node, node, confstr_list,
                cls.nodewalker_ibgp_find_neighbors_callback)
        cfg = ''.join(confstr_list)

        if node.enable_ipv4 and service_flags.EGP in node.services:
            interface_net = Interface.getInterfaceNet_per_net(\
                    node.session.sessionid, netid, 4)
            loopback_net = Loopback.getLoopbackNet_per_net(\
                    node.session.sessionid, netid, 4)
            cfg += '  network %s\n' % str(loopback_net)
            cfg += '  network %s\n' % str(interface_net)
            cfg += '  aggregate-address %s summary-only\n' % str(loopback_net)
            cfg += '  aggregate-address %s summary-only\n' % str(interface_net)

        if node.enable_ipv6:
            v6_ibgp_neighbor_list = []
            service_helpers.nodewalker(node, node, v6_ibgp_neighbor_list,
                    cls.nodewalker_ibgp_find_neighbor_addrs_v6_callback)
            cfg += '  address-family ipv6\n'
            # activate IBGP neighbors
            cfg += ''.join([('    neighbor %s activate\n') % \
                    (str(remote_addr).split('/')[0]) \
                    for local_addr, remote_addr in v6_ibgp_neighbor_list])
            # activate EBGP neighbors
            cfg += ''.join(v6cfg)
            if service_flags.EGP in node.services:
                # announce networks
                interface_net = Interface.getInterfaceNet_per_net(\
                        node.session.sessionid, netid, 6)
                loopback_net = Loopback.getLoopbackNet_per_net(\
                        node.session.sessionid, netid, 6)
                cfg += '    network %s\n' % str(loopback_net)
                cfg += '    network %s\n' % str(interface_net)
                cfg += '    aggregate-address %s summary-only\n' % str(loopback_net)
                cfg += '    aggregate-address %s summary-only\n' % str(interface_net)
            adj_addrs = cls.collect_adjacent_loopback_addrs_v6(cls, node)
            for adj_addr in adj_addrs:
                cfg += '    network %s/128\n' % str(adj_addr)
            cfg += '\n  exit-address-family\n'

        return cfg
Beispiel #5
0
 def routerid(node):
     ''' Helper to return the first IPv4 address of a node as its router ID.
     '''
     return str(Loopback.getLoopbackIPv4(node))