Exemple #1
0
def build_ebgp(anm):
    g_in = anm['input']
    g_phy = anm['phy']
    g_ebgp = anm.add_overlay("ebgp", directed=True)
    g_ebgp.add_nodes_from(g_in.routers())
    ebgp_edges = [e for e in g_in.edges() if not e.attr_equal("asn")]
    g_ebgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [n for n in g_in.switches()
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_ebgp.add_nodes_from(ebgp_switches, retain=['asn'])
    g_ebgp.log.debug("eBGP switches are %s" % ebgp_switches)
    g_ebgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches),
    bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_ebgp, ebgp_switches)
    # need to recalculate as may have aggregated
    ebgp_switches = list(g_ebgp.switches())
    g_ebgp.log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_ebgp, ebgp_switches)
    same_asn_edges = []
    for edge in exploded_edges:
        if edge.src.asn == edge.dst.asn:
            same_asn_edges.append(edge)
        else:
            edge.multipoint = True
    """TODO: remove up to here once compiler updated"""

    g_ebgp.remove_edges_from(same_asn_edges)
Exemple #2
0
def build_layer3(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    gl2_conn = anm['layer2_conn']
    g_l3 = anm.add_overlay("layer3")
    g_l3.add_nodes_from(gl2_conn, retain=['label'])
    g_l3.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3.add_edges_from(gl2_conn.edges())

    switches = g_l3.switches()

    ank_utils.aggregate_nodes(g_l3, switches)
    exploded_edges = ank_utils.explode_nodes(g_l3, switches)

    # also explode virtual switches
    vswitches = [
        n for n in g_l3.nodes() if n['layer2'].device_type == "switch"
        and n['layer2'].device_subtype == "virtual"
    ]

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #3
0
def build_ebgp(anm):
    g_in = anm['input']
    g_phy = anm['phy']
    g_ebgp = anm.add_overlay("ebgp", directed=True)
    g_ebgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [e for e in g_in.edges() if not e.attr_equal("asn")]
    g_ebgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [
        n for n in g_in.nodes("is_switch")
        if not ank_utils.neigh_equal(g_phy, n, "asn")
    ]
    g_ebgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_ebgp.add_edges_from(
        (e for e in g_in.edges()
         if e.src in ebgp_switches or e.dst in ebgp_switches),
        bidirectional=True,
        type='ebgp')
    ank_utils.aggregate_nodes(g_ebgp, ebgp_switches, retain="edge_id")
    ebgp_switches = list(g_ebgp.nodes(
        "is_switch"))  # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_ebgp,
                                             ebgp_switches,
                                             retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True
Exemple #4
0
def build_ebgp(anm):
    g_in = anm['input']
    g_phy = anm['phy']
    g_ebgp = anm.add_overlay("ebgp", directed=True)
    g_ebgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [e for e in g_in.edges() if not e.attr_equal("asn")]
    g_ebgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [n for n in g_in.nodes("is_switch")
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_ebgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_ebgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches),
    bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_ebgp, ebgp_switches, retain="edge_id")
    # need to recalculate as may have aggregated
    ebgp_switches = list(g_ebgp.nodes("is_switch"))
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_ebgp, ebgp_switches,
            retain="edge_id")
    same_asn_edges = []
    for edge in exploded_edges:
        if edge.src.asn == edge.dst.asn:
            same_asn_edges.append(edge)
        else:
            edge.multipoint = True
    """TODO: remove up to here once compiler updated"""

    g_ebgp.remove_edges_from(same_asn_edges)
def build_l3_connectivity(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm["input"]
    g_l3conn = anm.add_overlay("layer3")
    g_l3conn.add_nodes_from(
        g_in,
        retain=[
            "label",
            "update",
            "device_type",
            "asn",
            "specified_int_names",
            "device_subtype",
            "platform",
            "host",
            "syntax",
        ],
    )
    g_l3conn.add_nodes_from(g_in.switches(), retain=["asn"])
    g_l3conn.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3conn, g_l3conn.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3conn, g_l3conn.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #6
0
def build_layer3(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    g_l2 = anm['layer2']
    g_l3 = anm.add_overlay("layer3")
    g_l3.add_nodes_from(g_l2, retain=['label'])
    g_l3.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3.add_edges_from(g_l2.edges())

    switches = g_l3.switches()

    ank_utils.aggregate_nodes(g_l3, switches)
    exploded_edges = ank_utils.explode_nodes(g_l3,
                                             switches)

    # also explode virtual switches
    vswitches = [n for n in g_l3.nodes()
                 if n['layer2'].device_type == "switch"
                 and n['layer2'].device_subtype == "virtual"]

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #7
0
def build_layer3(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    gl2_conn = anm['layer2_conn']
    g_l3 = anm.add_overlay("layer3")
    g_l3.add_nodes_from(gl2_conn, retain=['label', 'devsubtype'])
    ank_utils.copy_attr_from(g_in, g_l3, "multicast")
    g_l3.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3.add_edges_from(gl2_conn.edges(), retain=['link_type'])

    edges_to_remove = [
        edge for edge in gl2_conn.edges() if edge.link_type == 'is_not_l3'
    ]

    g_l3.remove_edges_from(edges_to_remove)
    edges_to_remove = []

    switches = g_l3.switches()

    ank_utils.aggregate_nodes(g_l3, switches)
    exploded_edges = ank_utils.explode_nodes(g_l3,
                                             switches,
                                             retain=['link_type'])

    # also explode virtual switches
    vswitches = [
        n for n in g_l3.nodes() if n['layer2'].device_type == "switch"
        and n['layer2'].device_subtype == "virtual"
    ]

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #8
0
def build_isis(anm):
    """Build isis overlay"""
    g_in = anm["input"]
    if not any(n.igp == "isis" for n in g_in):
        log.debug("No ISIS nodes")
        return
    g_ipv4 = anm["ipv4"]
    g_isis = anm.add_overlay("isis")
    g_isis.add_nodes_from(g_in.nodes("is_router", igp="isis"), retain=["asn"])
    g_isis.add_nodes_from(g_in.nodes("is_switch"), retain=["asn"])
    g_isis.add_edges_from(g_in.edges(), retain=["edge_id"])
    # Merge and explode switches
    ank_utils.aggregate_nodes(g_isis, g_isis.nodes("is_switch"), retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_isis, g_isis.nodes("is_switch"), retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    g_isis.remove_edges_from([link for link in g_isis.edges() if link.src.asn != link.dst.asn])

    for node in g_isis:
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1  # default

    for link in g_isis.edges():
        link.metric = 1  # default
        # link.hello = 5 # for debugging, TODO: read from graph

    for edge in g_isis.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #9
0
def build_isis(anm):
    G_in = anm['input']
    G_ip = anm['ip']
    G_isis = anm.add_overlay("isis")
    #G_isis.add_nodes_from(G_in.nodes("is_router", igp = "isis"), retain=['asn'])
#TODO: filter only igp=isis nodes, set the igp as a default in build_network
    G_isis.add_nodes_from(G_in.nodes("is_router"), retain=['asn'])
    G_isis.add_nodes_from(G_in.nodes("is_switch"), retain=['asn'])
    G_isis.add_edges_from(G_in.edges(), retain = ['edge_id'])
# Merge and explode switches
    ank.aggregate_nodes(G_isis, G_isis.nodes("is_switch"), retain = "edge_id")
    ank.explode_nodes(G_isis, G_isis.nodes("is_switch"), retain = "edge_id")

    G_isis.remove_edges_from([link for link in G_isis.edges() if link.src.asn != link.dst.asn])

    for node in G_isis:
        ip_node = G_ip.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1 # default

    for link in G_isis.edges():
        link.metric = 1 # default
Exemple #10
0
def build_layer1_conn(anm):
    g_l1 = anm['layer1']
    g_l1_conn = anm.add_overlay('layer1_conn')
    g_l1_conn.add_nodes_from(g_l1, retain="collision_domain")
    g_l1_conn.add_edges_from(g_l1.edges())

    collision_domains = g_l1_conn.nodes(collision_domain=True)
    exploded_edges = ank_utils.explode_nodes(g_l1_conn, collision_domains)

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #11
0
def build_layer1_conn(anm):
    g_l1 = anm['layer1']
    g_l1_conn = anm.add_overlay('layer1_conn')
    g_l1_conn.add_nodes_from(g_l1, retain="collision_domain")
    g_l1_conn.add_edges_from(g_l1.edges(), retain=['link_type'])

    collision_domains = g_l1_conn.nodes(collision_domain=True)
    exploded_edges = ank_utils.explode_nodes(g_l1_conn, collision_domains, retain=['link_type'])

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #12
0
def build_layer2_conn(anm):
    g_l2 = anm['layer2']
    g_l2_conn = anm.add_overlay('layer2_conn')
    g_l2_conn.add_nodes_from(g_l2, retain="broadcast_domain")
    g_l2_conn.add_edges_from(g_l2.edges())

    broadcast_domains = g_l2_conn.nodes(broadcast_domain=True)
    exploded_edges = ank_utils.explode_nodes(g_l2_conn, broadcast_domains)

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #13
0
def build_layer2_conn(anm):
    g_l2 = anm['layer2']
    g_l2_conn = anm.add_overlay('layer2_conn')
    g_l2_conn.add_nodes_from(g_l2, retain=["broadcast_domain", "devsubtype"])
    g_l2_conn.add_edges_from(g_l2.edges(), retain=['link_type'])

    broadcast_domains = g_l2_conn.nodes(broadcast_domain=True)
    exploded_edges = ank_utils.explode_nodes(g_l2_conn, broadcast_domains, retain=['link_type'])

    # explode each seperately?
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #14
0
def build_isis(anm):
    """Build isis overlay"""
    g_in = anm['input']
    g_ipv4 = anm['ipv4']
    g_isis = anm.add_overlay("isis")
    g_isis.add_nodes_from(g_in.nodes("is_router", igp = "isis"), retain=['asn'])
    g_isis.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
    g_isis.add_edges_from(g_in.edges(), retain=['edge_id'])
# Merge and explode switches
    ank_utils.aggregate_nodes(g_isis, g_isis.nodes("is_switch"),
                              retain="edge_id")
    ank_utils.explode_nodes(g_isis, g_isis.nodes("is_switch"),
                            retain="edge_id")

    g_isis.remove_edges_from(
        [link for link in g_isis.edges() if link.src.asn != link.dst.asn])

    for node in g_isis:
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1  # default

    for link in g_isis.edges():
        link.metric = 1  # default
Exemple #15
0
def build_layer3(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    g_l2 = anm['layer2']
    g_l3 = anm.add_overlay("layer3")
    g_l3.add_nodes_from(g_l2, retain=['label'])
    g_l3.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3, g_l3.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3, g_l3.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #16
0
def build_layer3(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    g_l2 = anm['layer2']
    g_l3 = anm.add_overlay("layer3")
    g_l3.add_nodes_from(g_l2 , retain=['label'])
    g_l3.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3, g_l3.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3,
                                             g_l3.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #17
0
def build_l3_connectivity(anm):
    """ creates l3_connectivity graph, which is switch nodes aggregated and exploded"""
    #TODO: use this as base for ospf, ebgp, ip, etc rather than exploding in each
    g_in = anm['input']
    g_l3conn = anm.add_overlay("l3_conn")
    g_l3conn.add_nodes_from(g_in, retain=['label', 'update', 'device_type', 'asn',
        'specified_int_names',
        'device_subtype', 'platform', 'host', 'syntax'])
    g_l3conn.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
#TODO: check if edge_id needs to be still retained
    g_l3conn.add_edges_from(g_in.edges(), retain=['edge_id'])

    ank_utils.aggregate_nodes(g_l3conn, g_l3conn.nodes("is_switch"),
                              retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_l3conn, g_l3conn.nodes("is_switch"),
                            retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True
Exemple #18
0
def build_l3_connectivity(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    g_l3conn = anm.add_overlay("l3_conn")
    g_l3conn.add_nodes_from(
        g_in, retain=['label', 'update', 'device_type', 'asn',
                      'specified_int_names',
                      'device_subtype', 'platform', 'host', 'syntax'])
    g_l3conn.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3conn.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3conn, g_l3conn.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3conn,
                                             g_l3conn.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #19
0
def build_eigrp(anm):
    """Build eigrp overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_eigrp = anm.add_overlay("eigrp")

    if not anm['phy'].data.enable_routing:
        log.info("Routing disabled, not configuring EIGRP")
        return

    if not any(n.igp == "eigrp" for n in g_in):
        log.debug("No EIGRP nodes")
        return
    g_ipv4 = anm['ipv4']
    g_eigrp.add_nodes_from(g_in.nodes("is_router",
        igp = "eigrp"), retain=['asn'])
    g_eigrp.add_nodes_from(g_in.nodes("is_server",
        igp = "eigrp"), retain=['asn'])
    g_eigrp.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
    g_eigrp.add_edges_from(g_in.edges(), retain=['edge_id'])
# Merge and explode switches
    ank_utils.aggregate_nodes(g_eigrp, g_eigrp.nodes("is_switch"),
                              retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_eigrp,
        g_eigrp.nodes("is_switch"),
                            retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    g_eigrp.remove_edges_from(
        [link for link in g_eigrp.edges() if link.src.asn != link.dst.asn])

    for node in g_eigrp:
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.name = "one"  # default

    for link in g_eigrp.edges():
        link.metric = 1  # default

    for edge in g_eigrp.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #20
0
def build_eigrp(anm):
    """Build eigrp overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_l3 = anm['layer3']
    g_eigrp = anm.add_overlay("eigrp")
    g_phy = anm['phy']

    if not anm['phy'].data.enable_routing:
        g_eigrp.log.info("Routing disabled, not configuring EIGRP")
        return

    if not any(n.igp == "eigrp" for n in g_phy):
        log.debug("No EIGRP nodes")
        return
    eigrp_nodes = [n for n in g_l3 if n['phy'].igp == "eigrp"]
    g_eigrp.add_nodes_from(eigrp_nodes)
    g_eigrp.add_edges_from(g_l3.edges(), warn=False)
    ank_utils.copy_int_attr_from(g_l3, g_eigrp, "multipoint")

    ank_utils.copy_attr_from(g_in,
                             g_eigrp,
                             "custom_config_eigrp",
                             dst_attr="custom_config")

    # Merge and explode switches
    ank_utils.aggregate_nodes(g_eigrp, g_eigrp.switches())
    exploded_edges = ank_utils.explode_nodes(g_eigrp, g_eigrp.switches())
    for edge in exploded_edges:
        edge.multipoint = True

    g_eigrp.remove_edges_from(
        [link for link in g_eigrp.edges() if link.src.asn != link.dst.asn])

    for node in g_eigrp:
        node.process_id = node.asn

    for link in g_eigrp.edges():
        link.metric = 1  # default

    for edge in g_eigrp.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #21
0
def build_l3_connectivity(anm):
    """ l3_connectivity graph: switch nodes aggregated and exploded"""
    g_in = anm['input']
    g_l3conn = anm.add_overlay("layer3")
    g_l3conn.add_nodes_from(g_in,
                            retain=[
                                'label', 'update', 'device_type', 'asn',
                                'specified_int_names', 'device_subtype',
                                'platform', 'host', 'syntax'
                            ])
    g_l3conn.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3conn.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3conn, g_l3conn.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3conn, g_l3conn.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #22
0
def build_eigrp(anm):
    """Build eigrp overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_l3 = anm['layer3']
    g_eigrp = anm.add_overlay("eigrp")
    g_phy = anm['phy']

    if not anm['phy'].data.enable_routing:
        g_eigrp.log.info("Routing disabled, not configuring EIGRP")
        return

    if not any(n.igp == "eigrp" for n in g_phy):
        log.debug("No EIGRP nodes")
        return
    eigrp_nodes = [n for n in g_l3 if n['phy'].igp == "eigrp"]
    g_eigrp.add_nodes_from(eigrp_nodes)
    g_eigrp.add_edges_from(g_l3.edges(), warn=False)
    ank_utils.copy_int_attr_from(g_l3, g_eigrp, "multipoint")

    ank_utils.copy_attr_from(
        g_in, g_eigrp, "custom_config_eigrp", dst_attr="custom_config")

# Merge and explode switches
    ank_utils.aggregate_nodes(g_eigrp, g_eigrp.switches())
    exploded_edges = ank_utils.explode_nodes(g_eigrp,
                                             g_eigrp.switches())
    for edge in exploded_edges:
        edge.multipoint = True

    g_eigrp.remove_edges_from(
        [link for link in g_eigrp.edges() if link.src.asn != link.dst.asn])

    for node in g_eigrp:
        node.process_id = node.asn

    for link in g_eigrp.edges():
        link.metric = 1  # default

    for edge in g_eigrp.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #23
0
def build_l3_connectivity(anm):
    """ creates l3_connectivity graph, which is switch nodes aggregated and exploded"""
    #TODO: use this as base for ospf, ebgp, ip, etc rather than exploding in each
    g_in = anm['input']
    g_l3conn = anm.add_overlay("l3_conn")
    g_l3conn.add_nodes_from(g_in,
                            retain=[
                                'label', 'update', 'device_type', 'asn',
                                'specified_int_names', 'device_subtype',
                                'platform', 'host', 'syntax'
                            ])
    g_l3conn.add_nodes_from(g_in.switches(), retain=['asn'])
    g_l3conn.add_edges_from(g_in.edges())

    ank_utils.aggregate_nodes(g_l3conn, g_l3conn.switches())
    exploded_edges = ank_utils.explode_nodes(g_l3conn, g_l3conn.switches())
    for edge in exploded_edges:
        edge.multipoint = True
        edge.src_int.multipoint = True
        edge.dst_int.multipoint = True
Exemple #24
0
def build_ebgp(anm):
    g_in = anm['input']
    g_phy = anm['phy']
    g_ebgp = anm.add_overlay("ebgp", directed=True)
    g_ebgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [e for e in g_in.edges() if not e.attr_equal("asn")]
    g_ebgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [n for n in g_in.nodes("is_switch")
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_ebgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_ebgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches), bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_ebgp, ebgp_switches, retain="edge_id")
    ebgp_switches = list(g_ebgp.nodes("is_switch")) # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_ebgp, ebgp_switches,
            retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True
Exemple #25
0
def build_isis(anm):
    """Build isis overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_isis = anm.add_overlay("isis")

    if not any(n.igp == "isis" for n in g_in):
        log.debug("No ISIS nodes")
        return
    g_ipv4 = anm['ipv4']
    g_isis.add_nodes_from(g_in.nodes("is_router", igp="isis"), retain=['asn'])
    g_isis.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
    g_isis.add_edges_from(g_in.edges(), retain=['edge_id'])
    # Merge and explode switches
    ank_utils.aggregate_nodes(g_isis,
                              g_isis.nodes("is_switch"),
                              retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_isis,
                                             g_isis.nodes("is_switch"),
                                             retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    g_isis.remove_edges_from(
        [link for link in g_isis.edges() if link.src.asn != link.dst.asn])

    for node in g_isis:
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1  # default

    for link in g_isis.edges():
        link.metric = 1  # default
        # link.hello = 5 # for debugging, TODO: read from graph

    for edge in g_isis.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #26
0
def build_isis(anm):
    """Build isis overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_isis = anm.add_overlay("isis")

    if not anm['phy'].data.enable_routing:
        g_isis.log.info("Routing disabled, not configuring ISIS")
        return

    if not any(n.igp == "isis" for n in g_in):
        g_isis.log.debug("No ISIS nodes")
        return
    g_ipv4 = anm['ipv4']
    g_isis.add_nodes_from(g_in.l3devices(igp="isis"), retain=['asn'])
    g_isis.add_nodes_from(g_in.switches(), retain=['asn'])
    g_isis.add_edges_from(g_in.edges())
    # Merge and explode switches
    ank_utils.aggregate_nodes(g_isis, g_isis.switches())
    exploded_edges = ank_utils.explode_nodes(g_isis, g_isis.switches())
    for edge in exploded_edges:
        edge.multipoint = True

    g_isis.remove_edges_from(
        [link for link in g_isis.edges() if link.src.asn != link.dst.asn])

    for node in g_isis.routers():
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1  # default

    for link in g_isis.edges():
        link.metric = 1  # default

    for edge in g_isis.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #27
0
def build_isis(anm):
    """Build isis overlay"""
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['isis'] in compilers
    g_isis = anm.add_overlay("isis")

    if not anm['phy'].data.enable_routing:
        g_isis.log.info("Routing disabled, not configuring ISIS")
        return

    if not any(n.igp == "isis" for n in g_in):
        g_isis.log.debug("No ISIS nodes")
        return
    g_ipv4 = anm['ipv4']
    g_isis.add_nodes_from(g_in.l3devices(igp = "isis"), retain=['asn'])
    g_isis.add_nodes_from(g_in.switches(), retain=['asn'])
    g_isis.add_edges_from(g_in.edges())
# Merge and explode switches
    ank_utils.aggregate_nodes(g_isis, g_isis.switches())
    exploded_edges = ank_utils.explode_nodes(g_isis, g_isis.switches())
    for edge in exploded_edges:
        edge.multipoint = True

    g_isis.remove_edges_from(
        [link for link in g_isis.edges() if link.src.asn != link.dst.asn])

    for node in g_isis.routers():
        ip_node = g_ipv4.node(node)
        node.net = ip_to_net_ent_title_ios(ip_node.loopback)
        node.process_id = 1  # default

    for link in g_isis.edges():
        link.metric = 1  # default

    for edge in g_isis.edges():
        for interface in edge.interfaces():
            interface.metric = edge.metric
            interface.multipoint = edge.multipoint
Exemple #28
0
def build_bgp(anm):
    """Build iBGP end eBGP overlays"""
    # eBGP
    g_in = anm['input']
    g_phy = anm['phy']

    if not anm['phy'].data.enable_routing:
        log.info("Routing disabled, not configuring BGP")
        return

    build_ebgp(anm)
    build_ebgp_v4(anm)
    build_ebgp_v6(anm)

    """TODO: remove from here once compiler updated"""
    g_bgp = anm.add_overlay("bgp", directed=True)
    g_bgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [edge for edge in g_in.edges() if not edge.attr_equal("asn")]
    g_bgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')
#TODO: why don't we include edge_id here

    ebgp_switches = [n for n in g_in.nodes("is_switch")
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_bgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_bgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches), bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_bgp, ebgp_switches, retain="edge_id")
    ebgp_switches = list(g_bgp.nodes("is_switch")) # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_bgp, ebgp_switches,
            retain="edge_id")

    same_asn_edges = []
    for edge in exploded_edges:
        if edge.src.asn == edge.dst.asn:
            same_asn_edges.append(edge)
        else:
            edge.multipoint = True
    """TODO: remove up to here once compiler updated"""

    g_bgp.remove_edges_from(same_asn_edges)

# now iBGP
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_level")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l2_cluster")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l3_cluster")
    for node in g_bgp:
        # set defaults
        if node.ibgp_level is None:
            node.ibgp_level = 1

        if node.ibgp_level == "None":  # if unicode string from yEd
            node.ibgp_level = 1

#TODO CHECK FOR IBGP NONE

        node.ibgp_level = int(node.ibgp_level)  # ensure is numeric

        if not node.ibgp_l2_cluster or node.ibgp_l2_cluster == "None":
            # ibgp_l2_cluster defaults to region
            node.ibgp_l2_cluster = node.region or "default_l2_cluster"
        if not node.ibgp_l3_cluster or node.ibgp_l3_cluster == "None":
            # ibgp_l3_cluster defaults to ASN
            node.ibgp_l3_cluster = node.asn

    for asn, devices in ank_utils.groupby("asn", g_bgp):
        # group by nodes in phy graph
        routers = list(g_bgp.node(n) for n in devices if n.is_router)
        # list of nodes from bgp graph
        ibgp_levels = {int(r.ibgp_level) for r in routers}
        max_level = max(ibgp_levels)
        # all possible edge src/dst pairs
        ibgp_routers = [r for r in routers if r.ibgp_level > 0]
        all_pairs = [(s, t) for s in ibgp_routers for t in ibgp_routers if s != t]
        if max_level == 3:
            up_links, down_links, over_links = three_tier_ibgp_edges(ibgp_routers)

        elif max_level == 2:
            #TODO: check when this is reached - as RR is not HRR.... due to naming/levels mapping
            up_links, down_links, over_links = build_two_tier_ibgp(ibgp_routers)

        elif max_level == 1:
            up_links = []
            down_links = []
            over_links = [(s, t) for (s, t) in all_pairs
                             if s.ibgp_l3_cluster == t.ibgp_l3_cluster
                             and s.ibgp_l2_cluster == t.ibgp_l2_cluster
                             ]
        else:
            # no iBGP
            up_links = []
            down_links = []
            over_links = []

        if max_level > 0:
            g_bgp.add_edges_from(up_links, type='ibgp', direction='up')
            g_bgp.add_edges_from(down_links, type='ibgp', direction='down')
            g_bgp.add_edges_from(over_links, type='ibgp', direction='over')

        else:
            log.debug("No iBGP routers in %s" % asn)

# and set label back
    ibgp_label_to_level = {
        0: "None",  # Explicitly set role to "None" -> Not in iBGP
        3: "RR",
        1: "RRC",
        2: "HRR",
    }
    for node in g_bgp:
        node.ibgp_role = ibgp_label_to_level[node.ibgp_level]

    ebgp_nodes = [d for d in g_bgp if any(
        edge.type == 'ebgp' for edge in d.edges())]
    g_bgp.update(ebgp_nodes, ebgp=True)

    for ebgp_edge in g_bgp.edges(type = "ebgp"):
        for interface in ebgp_edge.interfaces():
            interface.ebgp = True

    for edge in g_bgp.edges(type='ibgp'):
        # TODO: need interface querying/selection. rather than hard-coded ids
        edge.bind_interface(edge.src, 0)

    #TODO: need to initialise interface zero to be a loopback rather than physical type
    for node in g_bgp:
        for interface in node.interfaces():
            interface.multipoint = any(e.multipoint for e in interface.edges())

    build_ibgp_v4(anm)
    build_ibgp_v6(anm)
Exemple #29
0
def build_ospf(anm):
    """
    Build OSPF graph.

    Allowable area combinations:
    0 -> 0
    0 -> x (x!= 0)
    x -> 0 (x!= 0)
    x -> x (x != 0)

    Not-allowed:
    x -> x (x != y != 0)

    #TODO: build check that verifies these rules
    """
    import netaddr
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['ospf'] in compilers
    g_ospf = anm.add_overlay("ospf")

    if not any(n.igp == "ospf" for n in g_in):
        log.debug("No OSPF nodes")
        return

    g_ospf.add_nodes_from(g_in.nodes("is_router", igp="ospf"), retain=['asn'])
    g_ospf.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
    g_ospf.add_edges_from(g_in.edges(), retain=['edge_id'])

    ank_utils.copy_attr_from(g_in, g_ospf, "ospf_area", dst_attr="area")
    ank_utils.copy_edge_attr_from(g_in,
                                  g_ospf,
                                  "ospf_cost",
                                  dst_attr="cost",
                                  type=float)

    ank_utils.aggregate_nodes(g_ospf,
                              g_ospf.nodes("is_switch"),
                              retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_ospf,
                                             g_ospf.nodes("is_switch"),
                                             retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    g_ospf.remove_edges_from([
        link for link in g_ospf.edges() if link.src.asn != link.dst.asn
    ])  # remove inter-AS links

    area_zero_ip = netaddr.IPAddress("0.0.0.0")
    area_zero_int = 0
    area_zero_ids = {area_zero_ip, area_zero_int}
    default_area = area_zero_int
    if any(router.area == "0.0.0.0" for router in g_ospf):
        # string comparison as hasn't yet been cast to IPAddress
        default_area = area_zero_ip

    for router in g_ospf:
        if not router.area or router.area == "None":
            router.area = default_area
            # check if 0.0.0.0 used anywhere, if so then use 0.0.0.0 as format
        else:
            try:
                router.area = int(router.area)
            except ValueError:
                try:
                    router.area = netaddr.IPAddress(router.area)
                except netaddr.core.AddrFormatError:
                    log.warning("Invalid OSPF area %s for %s. Using default"
                                " of %s" % (router.area, router, default_area))
                    router.area = default_area

    for router in g_ospf:
        # and set area on interface
        for edge in router.edges():
            if edge.area:
                continue  # allocated (from other "direction", as undirected)
            if router.area == edge.dst.area:
                edge.area = router.area  # intra-area
                continue

            if router.area in area_zero_ids or edge.dst.area in area_zero_ids:
                # backbone to other area
                if router.area in area_zero_ids:
                    # router in backbone, use other area
                    edge.area = edge.dst.area
                else:
                    # router not in backbone, use its area
                    edge.area = router.area

    for router in g_ospf:
        areas = {edge.area for edge in router.edges()}
        router.areas = list(areas)  # edges router participates in

        if len(areas) in area_zero_ids:
            router.type = "backbone"  # no ospf edges (eg single node in AS)
        elif len(areas) == 1:
            # single area: either backbone (all 0) or internal (all nonzero)
            if len(areas & area_zero_ids):
                # intersection has at least one element -> router has area zero
                router.type = "backbone"
            else:
                router.type = "internal"

        else:
            # multiple areas
            if len(areas & area_zero_ids):
                # intersection has at least one element -> router has area zero
                router.type = "backbone ABR"
            else:
                log.warning(
                    "%s spans multiple areas but is not a member of area 0" %
                    router)
                router.type = "INVALID"

    if (any(area_zero_int in router.areas for router in g_ospf)
            and any(area_zero_ip in router.areas for router in g_ospf)):
        log.warning("Using both area 0 and area 0.0.0.0")

    for link in g_ospf.edges():
        if not link.cost:
            link.cost = 1

    # map areas and costs onto interfaces
    #TODO: later map them directly rather than with edges - this is part of the transition
    for edge in g_ospf.edges():
        for interface in edge.interfaces():
            interface.cost = edge.cost
            interface.area = edge.area
            interface.multipoint = edge.multipoint

    for router in g_ospf:
        router.loopback_zero.area = router.area
        router.loopback_zero.cost = 0
Exemple #30
0
def build_bgp(anm):
    """Build iBGP end eBGP overlays"""
    # eBGP
    g_in = anm['input']
    g_phy = anm['phy']

    build_ebgp(anm)
    build_ebgp_v4(anm)
    build_ebgp_v6(anm)
    """TODO: remove from here once compiler updated"""
    g_bgp = anm.add_overlay("bgp", directed=True)
    g_bgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [edge for edge in g_in.edges() if not edge.attr_equal("asn")]
    g_bgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')
    #TODO: why don't we include edge_id here

    ebgp_switches = [
        n for n in g_in.nodes("is_switch")
        if not ank_utils.neigh_equal(g_phy, n, "asn")
    ]
    g_bgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_bgp.add_edges_from((e for e in g_in.edges()
                          if e.src in ebgp_switches or e.dst in ebgp_switches),
                         bidirectional=True,
                         type='ebgp')
    ank_utils.aggregate_nodes(g_bgp, ebgp_switches, retain="edge_id")
    ebgp_switches = list(
        g_bgp.nodes("is_switch"))  # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_bgp,
                                             ebgp_switches,
                                             retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True
    """TODO: remove up to here once compiler updated"""

    # now iBGP
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_level")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l2_cluster")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l3_cluster")
    for node in g_bgp:
        # set defaults
        if node.ibgp_level is None:
            node.ibgp_level = 1

        if node.ibgp_level == "None":  # if unicode string from yEd
            node.ibgp_level = 1

#TODO CHECK FOR IBGP NONE

        node.ibgp_level = int(node.ibgp_level)  # ensure is numeric

        if not node.ibgp_l2_cluster or node.ibgp_l2_cluster == "None":
            # ibgp_l2_cluster defaults to region
            node.ibgp_l2_cluster = node.region or "default_l2_cluster"
        if not node.ibgp_l3_cluster or node.ibgp_l3_cluster == "None":
            # ibgp_l3_cluster defaults to ASN
            node.ibgp_l3_cluster = node.asn

    for asn, devices in ank_utils.groupby("asn", g_bgp):
        # group by nodes in phy graph
        routers = list(g_bgp.node(n) for n in devices if n.is_router)
        # list of nodes from bgp graph
        ibgp_levels = {int(r.ibgp_level) for r in routers}
        max_level = max(ibgp_levels)
        # all possible edge src/dst pairs
        ibgp_routers = [r for r in routers if r.ibgp_level > 0]
        all_pairs = [(s, t) for s in ibgp_routers for t in ibgp_routers
                     if s != t]
        if max_level == 3:
            up_links, down_links, over_links = three_tier_ibgp_edges(
                ibgp_routers)

        elif max_level == 2:
            up_links, down_links, over_links = build_two_tier_ibgp(
                ibgp_routers)

        elif max_level == 1:
            up_links = []
            down_links = []
            over_links = [(s, t) for (s, t) in all_pairs
                          if s.ibgp_l3_cluster == t.ibgp_l3_cluster
                          and s.ibgp_l2_cluster == t.ibgp_l2_cluster]
        else:
            # no iBGP
            up_links = []
            down_links = []
            over_links = []

        if max_level > 0:
            g_bgp.add_edges_from(up_links, type='ibgp', direction='up')
            g_bgp.add_edges_from(down_links, type='ibgp', direction='down')
            g_bgp.add_edges_from(over_links, type='ibgp', direction='over')

        else:
            log.debug("No iBGP routers in %s" % asn)


# and set label back
    ibgp_label_to_level = {
        0: "None",  # Explicitly set role to "None" -> Not in iBGP
        3: "RR",
        1: "RRC",
        2: "HRR",
    }
    for node in g_bgp:
        node.ibgp_role = ibgp_label_to_level[node.ibgp_level]

    ebgp_nodes = [
        d for d in g_bgp if any(edge.type == 'ebgp' for edge in d.edges())
    ]
    g_bgp.update(ebgp_nodes, ebgp=True)

    for ebgp_edge in g_bgp.edges(type="ebgp"):
        for interface in ebgp_edge.interfaces():
            interface.ebgp = True

    for edge in g_bgp.edges(type='ibgp'):
        # TODO: need interface querying/selection. rather than hard-coded ids
        edge.bind_interface(edge.src, 0)

    #TODO: need to initialise interface zero to be a loopback rather than physical type
    for node in g_bgp:
        for interface in node.interfaces():
            interface.multipoint = any(e.multipoint for e in interface.edges())

    build_ibgp_v4(anm)
    build_ibgp_v6(anm)
Exemple #31
0
def build_bgp(anm):
    """Build iBGP end eBGP overlays"""
    # eBGP
    g_in = anm['input']
    g_phy = anm['phy']

    if not anm['phy'].data.enable_routing:
        log.info("Routing disabled, not configuring BGP")
        return

    build_ebgp(anm)
    build_ebgp_v4(anm)
    build_ebgp_v6(anm)

    """TODO: remove from here once compiler updated"""
    g_bgp = anm.add_overlay("bgp", directed=True)
    g_bgp.add_nodes_from(g_in.routers())
    ebgp_edges = [edge for edge in g_in.edges() if not edge.attr_equal("asn")]
    g_bgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [n for n in g_in.switches()
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_bgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_bgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches), bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_bgp, ebgp_switches)
    ebgp_switches = list(g_bgp.switches()) # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_bgp, ebgp_switches)

    same_asn_edges = []
    for edge in exploded_edges:
        if edge.src.asn == edge.dst.asn:
            same_asn_edges.append(edge)
        else:
            edge.multipoint = True
    """TODO: remove up to here once compiler updated"""

    g_bgp.remove_edges_from(same_asn_edges)


    build_ibgp(anm)

    ebgp_nodes = [d for d in g_bgp if any(
        edge.type == 'ebgp' for edge in d.edges())]
    g_bgp.update(ebgp_nodes, ebgp=True)

    for ebgp_edge in g_bgp.edges(type = "ebgp"):
        for interface in ebgp_edge.interfaces():
            interface.ebgp = True

    for edge in g_bgp.edges(type='ibgp'):
        # TODO: need interface querying/selection. rather than hard-coded ids
        edge.bind_interface(edge.src, 0)

    #TODO: need to initialise interface zero to be a loopback rather than physical type
    for node in g_bgp:
        for interface in node.interfaces():
            interface.multipoint = any(e.multipoint for e in interface.edges())

    build_ibgp_v4(anm)
    build_ibgp_v6(anm)
Exemple #32
0
def build_ospf(anm):
    """
    Build OSPF graph.

    Allowable area combinations:
    0 -> 0
    0 -> x (x!= 0)
    x -> 0 (x!= 0)
    x -> x (x != 0)

    Not-allowed:
    x -> x (x != y != 0)

    #TODO: build check that verifies these rules
    """
    import netaddr
    g_in = anm['input']
    # add regardless, so allows quick check of node in anm['ospf'] in compilers
    g_ospf = anm.add_overlay("ospf")

    if not any(n.igp == "ospf" for n in g_in):
        log.debug("No OSPF nodes")
        return

    g_ospf.add_nodes_from(g_in.nodes("is_router", igp = "ospf"), retain=['asn'])
    g_ospf.add_nodes_from(g_in.nodes("is_server", igp = "ospf"), retain=['asn'])
    g_ospf.add_nodes_from(g_in.nodes("is_switch"), retain=['asn'])
    g_ospf.add_edges_from(g_in.edges(), retain=['edge_id'])

    ank_utils.copy_attr_from(g_in, g_ospf, "ospf_area", dst_attr="area")
    ank_utils.copy_edge_attr_from(g_in, g_ospf, "ospf_cost", dst_attr="cost",  type=float)

    ank_utils.aggregate_nodes(g_ospf, g_ospf.nodes("is_switch"),
                              retain="edge_id")
    exploded_edges = ank_utils.explode_nodes(g_ospf, g_ospf.nodes("is_switch"),
                            retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    g_ospf.remove_edges_from([link for link in g_ospf.edges(
    ) if link.src.asn != link.dst.asn])  # remove inter-AS links

    area_zero_ip = netaddr.IPAddress("0.0.0.0")
    area_zero_int = 0
    area_zero_ids = {area_zero_ip, area_zero_int}
    default_area = area_zero_int
    if any(router.area == "0.0.0.0" for router in g_ospf):
        # string comparison as hasn't yet been cast to IPAddress
        default_area = area_zero_ip

    #TODO: use interfaces throughout, rather than edges

    for router in g_ospf:
        if not router.area or router.area == "None":
            router.area = default_area
            # check if 0.0.0.0 used anywhere, if so then use 0.0.0.0 as format
        else:
            try:
                router.area = int(router.area)
            except ValueError:
                try:
                    router.area = netaddr.IPAddress(router.area)
                except netaddr.core.AddrFormatError:
                    log.warning("Invalid OSPF area %s for %s. Using default"
                                " of %s" % (router.area, router, default_area))
                    router.area = default_area

    for router in g_ospf:
# and set area on interface
        for edge in router.edges():
            if edge.area:
                continue  # allocated (from other "direction", as undirected)
            if router.area == edge.dst.area:
                edge.area = router.area  # intra-area
                continue

            if router.area in area_zero_ids or edge.dst.area in area_zero_ids:
# backbone to other area
                if router.area in area_zero_ids:
                    # router in backbone, use other area
                    edge.area = edge.dst.area
                else:
                    # router not in backbone, use its area
                    edge.area = router.area

    for router in g_ospf:
        areas = {edge.area for edge in router.edges()}
        router.areas = list(areas)  # edges router participates in

        if len(areas) in area_zero_ids:
            router.type = "backbone"  # no ospf edges (eg single node in AS)
        elif len(areas) == 1:
            # single area: either backbone (all 0) or internal (all nonzero)
            if len(areas & area_zero_ids):
                # intersection has at least one element -> router has area zero
                router.type = "backbone"
            else:
                router.type = "internal"

        else:
            # multiple areas
            if len(areas & area_zero_ids):
                # intersection has at least one element -> router has area zero
                router.type = "backbone ABR"
            else:
                log.warning(
                    "%s spans multiple areas but is not a member of area 0"
                    % router)
                router.type = "INVALID"

    if (any(area_zero_int in router.areas for router in g_ospf) and
            any(area_zero_ip in router.areas for router in g_ospf)):
        log.warning("Using both area 0 and area 0.0.0.0")

    for link in g_ospf.edges():
        if not link.cost:
            link.cost = 1

    # map areas and costs onto interfaces
    #TODO: later map them directly rather than with edges - this is part of the transition
    for edge in g_ospf.edges():
        for interface in edge.interfaces():
            interface.cost = edge.cost
            interface.area = edge.area
            interface.multipoint = edge.multipoint

    for router in g_ospf:
        router.loopback_zero.area = router.area
        router.loopback_zero.cost = 0
Exemple #33
0
def build_ospf(anm):
    """
    Build OSPF graph.
    
    Allowable area combinations:
    0 -> 0
    0 -> x (x!= 0)
    x -> 0 (x!= 0)
    x -> x (x != 0)

    Not-allowed:
    x -> x (x != y != 0)
    """
    import netaddr
    G_in = anm['input']
    G_ospf = anm.add_overlay("ospf")
    G_ospf.add_nodes_from(G_in.nodes("is_router"), retain=['asn'])
    G_ospf.add_nodes_from(G_in.nodes("is_switch"), retain=['asn'])
    G_ospf.add_edges_from(G_in.edges(), retain = ['edge_id'])

    ank.copy_attr_from(G_in, G_ospf, "ospf_area", dst_attr = "area") #TODO: move this into graphml (and later gml) reader

    ank.aggregate_nodes(G_ospf, G_ospf.nodes("is_switch"), retain = "edge_id")
    ank.explode_nodes(G_ospf, G_ospf.nodes("is_switch"), retain= "edge_id")

    G_ospf.remove_edges_from([link for link in G_ospf.edges() if link.src.asn != link.dst.asn]) # remove inter-AS links

    area_zero_ip = netaddr.IPAddress("0.0.0.0")
    area_zero_int = 0
    area_zero_ids = set([area_zero_ip, area_zero_int])
    default_area = area_zero_int
    if any(router.area == "0.0.0.0"  for router in G_ospf): # string comparison as hasn't yet been cast to IPAddress
        default_area = area_zero_ip

    for router in G_ospf:
        if not router.area or router.area == "None":
            #TODO: tidy up this default of None being a string
            router.area = default_area #TODO: could check if 0.0.0.0 used anywhere, if so then use 0.0.0.0 as base format
        else:
            try:
                router.area = int(router.area)
            except ValueError:
                try:
                    router.area = netaddr.IPAddress(router.area) 
                except netaddr.core.AddrFormatError:
                    log.warning("Invalid OSPF area %s for %s. Using default of %s" %
                            (router.area, router, default_area))
                    router.area = default_area


    for router in G_ospf:
# and set area on interface
        for edge in router.edges():
            if edge.area:
                continue # already allocated (from other "direction", as undirected)
            if router.area == edge.dst.area:
                edge.area = router.area # intra-area
            else:
                if router.area in area_zero_ids or edge.dst.area in area_zero_ids:
# backbone to other area
                    if router.area in area_zero_ids:
                        edge.area = edge.dst.area # router in backbone, use other area
                    else:
                        edge.area = router.area # router not in backbone, use its area

    for router in G_ospf:
        areas = set(edge.area for edge in router.edges())

        router.areas = list(areas) # store all the edges a router participates in

        if len(areas) in area_zero_ids:
            router.type = "backbone" # no ospf edges (such as single node in AS)
        elif len(areas) == 1:
            # single area: either backbone (all 0) or internal (all nonzero)
            if len(areas & area_zero_ids): # intersection has at least one element -> router has area zero 
                router.type = "backbone"
            else:
                router.type = "internal"

        else:
            # multiple areas
            if len(areas & area_zero_ids): # intersection has at least one element -> router has area zero 
                router.type = "backbone ABR"
            else:
                log.warning("%s spans multiple areas but is not a member of area 0" % router)
                router.type = "INVALID"


    if (any(area_zero_int in router.areas for router in G_ospf) and 
            any(area_zero_ip in router.areas for router in G_ospf)): 
        log.warning("Using both area 0 and area 0.0.0.0")


#TODO: do we want to allocate non-symmetric OSPF costs? do we need a directed OSPF graph?
# (note this will all change once have proper interface nodes)
    for link in G_ospf.edges():
        link.cost = 1
Exemple #34
0
def build_bgp(anm):
    """Build iBGP end eBGP overlays"""
    # eBGP
    g_in = anm['input']
    g_phy = anm['phy']

    if not anm['phy'].data.enable_routing:
        log.info("Routing disabled, not configuring BGP")
        return

    build_ebgp(anm)
    build_ebgp_v4(anm)
    build_ebgp_v6(anm)

    """TODO: remove from here once compiler updated"""
    g_bgp = anm.add_overlay("bgp", directed=True)
    g_bgp.add_nodes_from(g_in.routers())
    ebgp_edges = [edge for edge in g_in.edges()
        if edge.src.asn != edge.dst.asn]
    g_bgp.add_edges_from(ebgp_edges, bidirectional=True, type='ebgp')

    ebgp_switches = [n for n in g_in.switches()
            if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_bgp.add_nodes_from(ebgp_switches, retain=['asn'])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_bgp.add_edges_from((e for e in g_in.edges()
            if e.src in ebgp_switches or e.dst in ebgp_switches), bidirectional=True, type='ebgp')
    ank_utils.aggregate_nodes(g_bgp, ebgp_switches)
    ebgp_switches = list(g_bgp.switches()) # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_bgp, ebgp_switches)

    same_asn_edges = []
    for edge in exploded_edges:
        if edge.src.asn == edge.dst.asn:
            same_asn_edges.append(edge)
        else:
            edge.multipoint = True
    """TODO: remove up to here once compiler updated"""
    ank_utils.copy_attr_from(g_in, g_bgp, "custom_config_bgp", dst_attr="custom_config")

    g_bgp.remove_edges_from(same_asn_edges)


    build_ibgp(anm)

    ebgp_nodes = [d for d in g_bgp if any(
        edge.type == 'ebgp' for edge in d.edges())]
    g_bgp.update(ebgp_nodes, ebgp=True)

    for ebgp_edge in g_bgp.edges(type = "ebgp"):
        for interface in ebgp_edge.interfaces():
            interface.ebgp = True

    for edge in g_bgp.edges(type='ibgp'):
        # TODO: need interface querying/selection. rather than hard-coded ids
        edge.bind_interface(edge.src, 0)

    #TODO: need to initialise interface zero to be a loopback rather than physical type
    for node in g_bgp:
        for interface in node.interfaces():
            interface.multipoint = any(e.multipoint for e in interface.edges())

    build_ibgp_v4(anm)
    build_ibgp_v6(anm)
Exemple #35
0
def build_bgp(anm):
    """Build iBGP end eBGP overlays"""
    # eBGP
    g_in = anm["input"]
    g_phy = anm["phy"]
    g_bgp = anm.add_overlay("bgp", directed=True)
    g_bgp.add_nodes_from(g_in.nodes("is_router"))
    ebgp_edges = [edge for edge in g_in.edges() if not edge.attr_equal("asn")]
    g_bgp.add_edges_from(ebgp_edges, bidirectional=True, type="ebgp")
    # TODO: why don't we include edge_id here

    ebgp_switches = [n for n in g_in.nodes("is_switch") if not ank_utils.neigh_equal(g_phy, n, "asn")]
    g_bgp.add_nodes_from(ebgp_switches, retain=["asn"])
    log.debug("eBGP switches are %s" % ebgp_switches)
    g_bgp.add_edges_from(
        (e for e in g_in.edges() if e.src in ebgp_switches or e.dst in ebgp_switches), bidirectional=True, type="ebgp"
    )
    ank_utils.aggregate_nodes(g_bgp, ebgp_switches, retain="edge_id")
    ebgp_switches = list(g_bgp.nodes("is_switch"))  # need to recalculate as may have aggregated
    log.debug("aggregated eBGP switches are %s" % ebgp_switches)
    exploded_edges = ank_utils.explode_nodes(g_bgp, ebgp_switches, retain="edge_id")
    for edge in exploded_edges:
        edge.multipoint = True

    # now iBGP
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_level")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l2_cluster")
    ank_utils.copy_attr_from(g_in, g_bgp, "ibgp_l3_cluster")
    for node in g_bgp:
        # set defaults
        if node.ibgp_level is None:
            node.ibgp_level = 1

        if node.ibgp_level == "None":  # if unicode string from yEd
            node.ibgp_level = 1

        # TODO CHECK FOR IBGP NONE

        node.ibgp_level = int(node.ibgp_level)  # ensure is numeric

        if not node.ibgp_l2_cluster or node.ibgp_l2_cluster == "None":
            # ibgp_l2_cluster defaults to region
            node.ibgp_l2_cluster = node.region or "default_l2_cluster"
        if not node.ibgp_l3_cluster or node.ibgp_l3_cluster == "None":
            # ibgp_l3_cluster defaults to ASN
            node.ibgp_l3_cluster = node.asn

    for asn, devices in ank_utils.groupby("asn", g_bgp):
        # group by nodes in phy graph
        routers = list(g_bgp.node(n) for n in devices if n.is_router)
        # list of nodes from bgp graph
        ibgp_levels = {int(r.ibgp_level) for r in routers}
        max_level = max(ibgp_levels)
        # all possible edge src/dst pairs
        ibgp_routers = [r for r in routers if r.ibgp_level > 0]
        all_pairs = [(s, t) for s in ibgp_routers for t in ibgp_routers if s != t]
        if max_level == 3:
            up_links, down_links, over_links = three_tier_ibgp_edges(ibgp_routers)

        elif max_level == 2:
            up_links, down_links, over_links = build_two_tier_ibgp(ibgp_routers)

        elif max_level == 1:
            up_links = []
            down_links = []
            over_links = [
                (s, t)
                for (s, t) in all_pairs
                if s.ibgp_l3_cluster == t.ibgp_l3_cluster and s.ibgp_l2_cluster == t.ibgp_l2_cluster
            ]
        else:
            # no iBGP
            up_links = []
            down_links = []
            over_links = []

        if max_level > 0:
            g_bgp.add_edges_from(up_links, type="ibgp", direction="up")
            g_bgp.add_edges_from(down_links, type="ibgp", direction="down")
            g_bgp.add_edges_from(over_links, type="ibgp", direction="over")

        else:
            log.debug("No iBGP routers in %s" % asn)

    # and set label back
    ibgp_label_to_level = {0: "None", 3: "RR", 1: "RRC", 2: "HRR"}  # Explicitly set role to "None" -> Not in iBGP
    for node in g_bgp:
        node.ibgp_role = ibgp_label_to_level[node.ibgp_level]

    ebgp_nodes = [d for d in g_bgp if any(edge.type == "ebgp" for edge in d.edges())]
    g_bgp.update(ebgp_nodes, ebgp=True)

    for ebgp_edge in g_bgp.edges(type="ebgp"):
        for interface in ebgp_edge.interfaces():
            interface.ebgp = True

    for edge in g_bgp.edges(type="ibgp"):
        # TODO: need interface querying/selection. rather than hard-coded ids
        edge.bind_interface(edge.src, 0)

    # TODO: need to initialise interface zero to be a loopback rather than physical type
    for node in g_bgp:
        for interface in node.interfaces():
            interface.multipoint = any(e.multipoint for e in interface.edges())