Beispiel #1
0
def assign_asn_to_interasn_cds(g_ip, address_block = None):
    G_phy = g_ip.overlay("phy")
    for collision_domain in g_ip.nodes("collision_domain"):
        neigh_asn = list(ank_utils.neigh_attr(g_ip, collision_domain, "asn", G_phy)) #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop() # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn) # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    return
Beispiel #2
0
def assign_asn_to_interasn_cds(g_ip, address_block=None):
    G_phy = g_ip.overlay('phy')
    for broadcast_domain in g_ip.nodes('broadcast_domain'):
        neigh_asn = list(ank_utils.neigh_attr(g_ip, broadcast_domain,
                         'asn', G_phy))  # asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn)  # allocate cd to asn with most neighbors in it
        broadcast_domain.asn = asn

    return
Beispiel #3
0
def assign_asn_to_interasn_cds(g_ip, address_block=None):
    G_phy = g_ip.overlay('phy')
    for broadcast_domain in g_ip.nodes('broadcast_domain'):
        neigh_asn = list(ank_utils.neigh_attr(g_ip, broadcast_domain,
                         'asn', G_phy))  # asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn)  # allocate cd to asn with most neighbors in it
        broadcast_domain.asn = asn

    return
Beispiel #4
0
def assign_asn_to_interasn_cds(G_ip):
    #TODO: rename to assign_asn_to_cds as also does intra-asn cds
    #TODO: make this a common function to ip4 and ip6
    G_phy = G_ip.overlay("phy")
    for collision_domain in G_ip.nodes("collision_domain"):
        neigh_asn = list(ank_utils.neigh_attr(G_ip, collision_domain, "asn", G_phy)) #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop() # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn) # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    return
Beispiel #5
0
def assign_asn_to_interasn_cds(G_ip):
    #TODO: rename to assign_asn_to_cds as also does intra-asn cds
    #TODO: make this a common function to ip4 and ip6
    G_phy = G_ip.overlay("phy")
    for collision_domain in G_ip.nodes("collision_domain"):
        neigh_asn = list(ank_utils.neigh_attr(G_ip, collision_domain, "asn", G_phy)) #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop() # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn) # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    return
Beispiel #6
0
def assign_asn_to_interasn_cds(g_ip, address_block=None):
    G_phy = g_ip.overlay("phy")
    for collision_domain in g_ip.nodes("collision_domain"):
        neigh_asn = list(
            ank_utils.neigh_attr(g_ip, collision_domain, "asn",
                                 G_phy))  #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(
                neigh_asn)  # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    return
Beispiel #7
0
def assign_asn_to_interasn_cds(G_ip):
    #TODO: remove this if no longer needed

    # TODO: rename to assign_asn_to_cds as also does intra-asn cds
    # TODO: make this a common function to ip4 and ip6

    G_phy = G_ip.overlay('phy')
    for broadcast_domain in G_ip.nodes('broadcast_domain'):
        neigh_asn = list(ank_utils.neigh_attr(G_ip, broadcast_domain,
                         'asn', G_phy))  # asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn)  # allocate bc to asn with most neighbors in it
        broadcast_domain.asn = asn

    return
Beispiel #8
0
def assign_asn_to_interasn_cds(G_ip):
    #TODO: remove this if no longer needed

    # TODO: rename to assign_asn_to_cds as also does intra-asn cds
    # TODO: make this a common function to ip4 and ip6

    G_phy = G_ip.overlay('phy')
    for broadcast_domain in G_ip.nodes('broadcast_domain'):
        neigh_asn = list(
            ank_utils.neigh_attr(G_ip, broadcast_domain, 'asn',
                                 G_phy))  # asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(
                neigh_asn)  # allocate bc to asn with most neighbors in it
        broadcast_domain.asn = asn

    return
Beispiel #9
0
def build_layer2_broadcast(anm):
    g_l2 = anm['layer2']
    g_phy = anm['phy']
    g_graphics = anm['graphics']
    g_l2_bc = anm.add_overlay('layer2_bc')
    g_l2_bc.add_nodes_from(g_l2.l3devices())
    g_l2_bc.add_nodes_from(g_l2.switches())
    g_l2_bc.add_edges_from(g_l2.edges(), retain=['link_type'])

    # remove external connectors

    edges_to_split = [edge for edge in g_l2_bc.edges()
                      if edge.src.is_l3device() and edge.dst.is_l3device()]
    # TODO: debug the edges to split
    for edge in edges_to_split:
        edge.split = True  # mark as split for use in building nidb

    split_created_nodes = list(ank_utils.split(g_l2_bc, edges_to_split,
                                               retain=['split'],
                                               id_prepend='cd_'))

    # TODO: if parallel nodes, offset
    # TODO: remove graphics, assign directly
    if len(g_graphics):
        co_ords_overlay = g_graphics  # source from graphics overlay
    else:
        co_ords_overlay = g_phy  # source from phy overlay

    for node in split_created_nodes:
        node['graphics'].x = ank_utils.neigh_average(g_l2_bc, node, 'x',
                                                     co_ords_overlay) + 0.1

        # temporary fix for gh-90

        node['graphics'].y = ank_utils.neigh_average(g_l2_bc, node, 'y',
                                                     co_ords_overlay) + 0.1

        # temporary fix for gh-90

        asn = ank_utils.neigh_most_frequent(
            g_l2_bc, node, 'asn', g_phy)  # arbitrary choice
        node['graphics'].asn = asn
        node.asn = asn  # need to use asn in IP overlay for aggregating subnets

    # also allocate an ASN for virtual switches
    vswitches = [n for n in g_l2_bc.nodes()
                 if n['layer2'].device_type == "switch"
                 and n['layer2'].device_subtype == "virtual"]
    for node in vswitches:
        # TODO: refactor neigh_most_frequent to allow fallthrough attributes
        # asn = ank_utils.neigh_most_frequent(g_l2_bc, node, 'asn', g_l2)  #
        # arbitrary choice
        asns = [n['layer2'].asn for n in node.neighbors()]
        asns = [x for x in asns if x is not None]
        asn = ank_utils.most_frequent(asns)
        node.asn = asn  # need to use asn in IP overlay for aggregating subnets
        # also mark as broadcast domain

    from collections import defaultdict
    coincident_nodes = defaultdict(list)
    for node in split_created_nodes:
        coincident_nodes[(node['graphics'].x, node['graphics'].y)].append(node)

    coincident_nodes = {k: v for k, v in coincident_nodes.items()
                        if len(v) > 1}  # trim out single node co-ordinates
    import math
    for _, val in coincident_nodes.items():
        for index, item in enumerate(val):
            index = index + 1
            x_offset = 25 * math.floor(index / 2) * math.pow(-1, index)
            y_offset = -1 * 25 * math.floor(index / 2) * math.pow(-1, index)
            item['graphics'].x = item['graphics'].x + x_offset
            item['graphics'].y = item['graphics'].y + y_offset

    switch_nodes = g_l2_bc.switches()  # regenerate due to aggregated
    g_l2_bc.update(switch_nodes, broadcast_domain=True)

    # switches are part of collision domain
    g_l2_bc.update(split_created_nodes, broadcast_domain=True)

    # Assign collision domain to a host if all neighbours from same host

    for node in split_created_nodes:
        if ank_utils.neigh_equal(g_l2_bc, node, 'host', g_phy):
            node.host = ank_utils.neigh_attr(g_l2_bc, node, 'host',
                                             g_phy).next()  # first attribute

    # set collision domain IPs
    # TODO; work out why this throws a json exception
    #autonetkit.ank.set_node_default(g_l2_bc,  broadcast_domain=False)

    for node in g_l2_bc.nodes('broadcast_domain'):
        graphics_node = g_graphics.node(node)
        #graphics_node.device_type = 'broadcast_domain'
        if node.is_switch():
            # TODO: check not virtual
            node['phy'].broadcast_domain = True
        if not node.is_switch():
            # use node sorting, as accomodates for numeric/string names
            graphics_node.device_type = 'broadcast_domain'
            neighbors = sorted(neigh for neigh in node.neighbors())
            label = '_'.join(neigh.label for neigh in neighbors)
            cd_label = 'cd_%s' % label  # switches keep their names
            node.label = cd_label
            graphics_node.label = cd_label
            node.device_type = "broadcast_domain"
            node.label = node.id
            graphics_node.label = node.id

    for node in vswitches:
        node.broadcast_domain = True
Beispiel #10
0
Datei: ip.py Projekt: sk2/ANK-NG
def allocate_ips(G_ip):
    log.info("Allocating IP addresses")
    from netaddr import IPNetwork
    address_block = IPNetwork("10.0.0.0/8")
    subnet_address_blocks = address_block.subnet(16)
#TODO: need to divide this up per AS

    G_ip.data.asn_blocks = defaultdict(list)
    #print G_ip._graph
    
    G_phy = G_ip.overlay.phy
    collision_domains = list(G_ip.nodes("collision_domain"))

    routers_by_asn = G_phy.groupby("asn", G_phy.nodes(device_type="router"))

    for collision_domain in collision_domains:
        neigh_asn = list(ank_utils.neigh_attr(G_ip, collision_domain, "asn", G_phy)) #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop() # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(neigh_asn) # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    cds_by_asn = G_ip.groupby("asn", G_ip.nodes("collision_domain"))

# if node or subnet has IP already allocated, then skip from this tree

    for asn in routers_by_asn:
        log.info("Allocating IPs for ASN %s" % asn)
# Need to iterate by asn with routers, as single router AS may not have a cd
        asn_cds = cds_by_asn.get(asn) or []
        asn_cds = sorted(asn_cds)
#tree by ASN
#TODO: Add in loopbacks as a subnet also
        asn_address_block = subnet_address_blocks.next()
        #print "ips for asn", asn
        G_ip.data.asn_blocks[asn].append(asn_address_block)
#TODO: record this in G_ip graph data not node/edge data

        # Build list of collision domains sorted by size
        size_list = defaultdict(list)
        for cd in asn_cds:
            sn_size = subnet_size(cd.degree()) # Size of this collision domain
            size_list[sn_size].append(cd)

        loopback_size = subnet_size(len(routers_by_asn[asn])) # calculate from number of routers in asn

        ip_tree = defaultdict(list) # index by level to simplify creation of tree
        try:
            current_level = min(size_list) # start at base
        except ValueError:
            current_level = loopback_size # no cds, start at loopback
        
        asn_loopback_tree_node = None #keep track of to allocate loopbacks at end
        while True:
            cds = size_list[current_level]
            cds = sorted(cds, key = lambda x: x.node_id)
# initialse with leaves
#TODO: see if can get loopback on leftmost of tree -> then can have allocated with .1 .2 etc rather than .19 .20 etc
            ip_tree[current_level] += list(TreeNode(cd=cd) for cd in sorted(cds))
            if current_level == loopback_size:
                asn_loopback_tree_node = TreeNode(cd = "loopback")
                ip_tree[current_level].append(asn_loopback_tree_node)

            # now connect up at parent level
            tree_nodes = sorted(ip_tree[current_level]) # both leaves and parents of lower level
            pairs = list(itertools.izip(tree_nodes[::2], tree_nodes[1::2]))
            for left, right in pairs:
                ip_tree[current_level+1].append(TreeNode(left, right))
            if len(tree_nodes) % 2 == 1:
# odd number of tree nodes, add 
                final_tree_node = tree_nodes[-1]
                ip_tree[current_level+1].append(TreeNode(final_tree_node, None))

            current_level += 1
            if asn_loopback_tree_node and len(ip_tree[current_level]) < 2:
                # loopback has been allocated, and reached top of tree
                break

            #if leaf, assign back to collision domain

        # allocate to tree
        subnet_bits = 32 - max(ip_tree)
        tree_subnet = asn_address_block.subnet(subnet_bits)
        tree_root = ip_tree[max(ip_tree)].pop() # only one node at highest level (root)
        tree_root.subnet = tree_subnet.next()
        allocate_to_tree_node(tree_root)
        #walk_tree(tree_root)
        allocate_ips_to_cds(tree_root)

        my_tree = Tree(tree_root, asn)
        my_tree.save()

        # Get loopback from loopback tree node
        loopback_hosts = asn_loopback_tree_node.subnet.iter_hosts()
        #router.loopback = loopback_hosts.next()
        for router in sorted(routers_by_asn[asn], key = lambda x: x.label):
            router.overlay.ip.loopback = loopback_hosts.next()

        # now allocate to the links of each cd
        for cd in asn_cds:
            hosts = cd.subnet.iter_hosts()
            for edge in sorted(cd.edges()):
                edge.ip_address = hosts.next()
Beispiel #11
0
Datei: ip.py Projekt: sk2/ANK-NG
def allocate_ips(G_ip):
    log.info("Allocating IP addresses")
    from netaddr import IPNetwork
    address_block = IPNetwork("10.0.0.0/8")
    subnet_address_blocks = address_block.subnet(16)
    #TODO: need to divide this up per AS

    G_ip.data.asn_blocks = defaultdict(list)
    #print G_ip._graph

    G_phy = G_ip.overlay.phy
    collision_domains = list(G_ip.nodes("collision_domain"))

    routers_by_asn = G_phy.groupby("asn", G_phy.nodes(device_type="router"))

    for collision_domain in collision_domains:
        neigh_asn = list(
            ank_utils.neigh_attr(G_ip, collision_domain, "asn",
                                 G_phy))  #asn of neighbors
        if len(set(neigh_asn)) == 1:
            asn = set(neigh_asn).pop()  # asn of any neigh, as all same
        else:
            asn = ank_utils.most_frequent(
                neigh_asn)  # allocate cd to asn with most neighbors in it
        collision_domain.asn = asn

    cds_by_asn = G_ip.groupby("asn", G_ip.nodes("collision_domain"))

    # if node or subnet has IP already allocated, then skip from this tree

    for asn in routers_by_asn:
        log.info("Allocating IPs for ASN %s" % asn)
        # Need to iterate by asn with routers, as single router AS may not have a cd
        asn_cds = cds_by_asn.get(asn) or []
        asn_cds = sorted(asn_cds)
        #tree by ASN
        #TODO: Add in loopbacks as a subnet also
        asn_address_block = subnet_address_blocks.next()
        #print "ips for asn", asn
        G_ip.data.asn_blocks[asn].append(asn_address_block)
        #TODO: record this in G_ip graph data not node/edge data

        # Build list of collision domains sorted by size
        size_list = defaultdict(list)
        for cd in asn_cds:
            sn_size = subnet_size(cd.degree())  # Size of this collision domain
            size_list[sn_size].append(cd)

        loopback_size = subnet_size(len(
            routers_by_asn[asn]))  # calculate from number of routers in asn

        ip_tree = defaultdict(
            list)  # index by level to simplify creation of tree
        try:
            current_level = min(size_list)  # start at base
        except ValueError:
            current_level = loopback_size  # no cds, start at loopback

        asn_loopback_tree_node = None  #keep track of to allocate loopbacks at end
        while True:
            cds = size_list[current_level]
            cds = sorted(cds, key=lambda x: x.node_id)
            # initialse with leaves
            #TODO: see if can get loopback on leftmost of tree -> then can have allocated with .1 .2 etc rather than .19 .20 etc
            ip_tree[current_level] += list(
                TreeNode(cd=cd) for cd in sorted(cds))
            if current_level == loopback_size:
                asn_loopback_tree_node = TreeNode(cd="loopback")
                ip_tree[current_level].append(asn_loopback_tree_node)

            # now connect up at parent level
            tree_nodes = sorted(ip_tree[current_level]
                                )  # both leaves and parents of lower level
            pairs = list(itertools.izip(tree_nodes[::2], tree_nodes[1::2]))
            for left, right in pairs:
                ip_tree[current_level + 1].append(TreeNode(left, right))
            if len(tree_nodes) % 2 == 1:
                # odd number of tree nodes, add
                final_tree_node = tree_nodes[-1]
                ip_tree[current_level + 1].append(
                    TreeNode(final_tree_node, None))

            current_level += 1
            if asn_loopback_tree_node and len(ip_tree[current_level]) < 2:
                # loopback has been allocated, and reached top of tree
                break

            #if leaf, assign back to collision domain

        # allocate to tree
        subnet_bits = 32 - max(ip_tree)
        tree_subnet = asn_address_block.subnet(subnet_bits)
        tree_root = ip_tree[max(
            ip_tree)].pop()  # only one node at highest level (root)
        tree_root.subnet = tree_subnet.next()
        allocate_to_tree_node(tree_root)
        #walk_tree(tree_root)
        allocate_ips_to_cds(tree_root)

        my_tree = Tree(tree_root, asn)
        my_tree.save()

        # Get loopback from loopback tree node
        loopback_hosts = asn_loopback_tree_node.subnet.iter_hosts()
        #router.loopback = loopback_hosts.next()
        for router in sorted(routers_by_asn[asn], key=lambda x: x.label):
            router.overlay.ip.loopback = loopback_hosts.next()

        # now allocate to the links of each cd
        for cd in asn_cds:
            hosts = cd.subnet.iter_hosts()
            for edge in sorted(cd.edges()):
                edge.ip_address = hosts.next()
Beispiel #12
0
def build_layer2_broadcast(anm):
    g_l2 = anm['layer2']
    g_phy = anm['phy']
    g_graphics = anm['graphics']
    g_l2_bc = anm.add_overlay('layer2_bc')
    g_l2_bc.add_nodes_from(g_l2.l3devices())
    g_l2_bc.add_nodes_from(g_l2.switches())
    g_l2_bc.add_edges_from(g_l2.edges(), retain=['link_type'])

    # remove external connectors

    edges_to_split = [
        edge for edge in g_l2_bc.edges()
        if edge.src.is_l3device() and edge.dst.is_l3device()
    ]
    # TODO: debug the edges to split
    for edge in edges_to_split:
        edge.split = True  # mark as split for use in building nidb

    split_created_nodes = list(
        ank_utils.split(g_l2_bc,
                        edges_to_split,
                        retain=['split'],
                        id_prepend='cd_'))

    # TODO: if parallel nodes, offset
    # TODO: remove graphics, assign directly
    if len(g_graphics):
        co_ords_overlay = g_graphics  # source from graphics overlay
    else:
        co_ords_overlay = g_phy  # source from phy overlay

    for node in split_created_nodes:
        node['graphics'].x = ank_utils.neigh_average(g_l2_bc, node, 'x',
                                                     co_ords_overlay) + 0.1

        # temporary fix for gh-90

        node['graphics'].y = ank_utils.neigh_average(g_l2_bc, node, 'y',
                                                     co_ords_overlay) + 0.1

        # temporary fix for gh-90

        asn = ank_utils.neigh_most_frequent(g_l2_bc, node, 'asn',
                                            g_phy)  # arbitrary choice
        node['graphics'].asn = asn
        node.asn = asn  # need to use asn in IP overlay for aggregating subnets

    # also allocate an ASN for virtual switches
    vswitches = [
        n for n in g_l2_bc.nodes() if n['layer2'].device_type == "switch"
        and n['layer2'].device_subtype == "virtual"
    ]
    for node in vswitches:
        # TODO: refactor neigh_most_frequent to allow fallthrough attributes
        # asn = ank_utils.neigh_most_frequent(g_l2_bc, node, 'asn', g_l2)  #
        # arbitrary choice
        asns = [n['layer2'].asn for n in node.neighbors()]
        asns = [x for x in asns if x is not None]
        asn = ank_utils.most_frequent(asns)
        node.asn = asn  # need to use asn in IP overlay for aggregating subnets
        # also mark as broadcast domain

    from collections import defaultdict
    coincident_nodes = defaultdict(list)
    for node in split_created_nodes:
        coincident_nodes[(node['graphics'].x, node['graphics'].y)].append(node)

    coincident_nodes = {
        k: v
        for k, v in coincident_nodes.items() if len(v) > 1
    }  # trim out single node co-ordinates
    import math
    for _, val in coincident_nodes.items():
        for index, item in enumerate(val):
            index = index + 1
            x_offset = 25 * math.floor(index / 2) * math.pow(-1, index)
            y_offset = -1 * 25 * math.floor(index / 2) * math.pow(-1, index)
            item['graphics'].x = item['graphics'].x + x_offset
            item['graphics'].y = item['graphics'].y + y_offset

    switch_nodes = g_l2_bc.switches()  # regenerate due to aggregated
    g_l2_bc.update(switch_nodes, broadcast_domain=True)

    # switches are part of collision domain
    g_l2_bc.update(split_created_nodes, broadcast_domain=True)

    # Assign collision domain to a host if all neighbours from same host

    for node in split_created_nodes:
        if ank_utils.neigh_equal(g_l2_bc, node, 'host', g_phy):
            node.host = ank_utils.neigh_attr(g_l2_bc, node, 'host',
                                             g_phy).next()  # first attribute

    # set collision domain IPs
    # TODO; work out why this throws a json exception
    #autonetkit.ank.set_node_default(g_l2_bc,  broadcast_domain=False)

    for node in g_l2_bc.nodes('broadcast_domain'):
        graphics_node = g_graphics.node(node)
        #graphics_node.device_type = 'broadcast_domain'
        if node.is_switch():
            # TODO: check not virtual
            node['phy'].broadcast_domain = True
        if not node.is_switch():
            # use node sorting, as accomodates for numeric/string names
            graphics_node.device_type = 'broadcast_domain'
            neighbors = sorted(neigh for neigh in node.neighbors())
            label = '_'.join(neigh.label for neigh in neighbors)
            cd_label = 'cd_%s' % label  # switches keep their names
            node.label = cd_label
            graphics_node.label = cd_label
            node.device_type = "broadcast_domain"
            node.label = node.id
            graphics_node.label = node.id

    for node in vswitches:
        node.broadcast_domain = True