def ebgp_net(): graph = NetworkGraph() r1, r2 = 'R1', 'R2' graph.add_router(r1) graph.add_router(r2) graph.add_router_edge(r1, r2) graph.add_router_edge(r2, r1) # BGP configs graph.set_bgp_asnum(r1, 100) graph.set_bgp_asnum(r2, 200) graph.add_bgp_neighbor(r1, r2) # Some internal to be announced network net = ip_network(u'128.0.0.0/24') prefix = '128_0_0_0' lo0 = 'lo10' prefix_map = {prefix: net} loaddr = ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen)) graph.set_loopback_addr(r1, lo0, loaddr) graph.add_bgp_announces(r1, lo0) # Synthesize all the interfaces and link configurations connecte_syn = ConnectedSyn(graph, full=True) assert connecte_syn.synthesize() graph.set_iface_names() gns3 = GNS3Topo(graph=graph, prefix_map=prefix_map) gns3.write_configs('out-configs/ebgp-simple')
def get_ebgp_linear_topo(N=2): """Return N routers configured in a linear topology""" net = NetworkGraph() for i in range(1, N + 1): name = "R%d" % i net.add_router(name) net.set_bgp_asnum(name, i * 100) for i in range(1, N): r1 = "R%d" % i r2 = "R%d" % (i + 1) net.add_router_edge(r1, r2) net.add_router_edge(r2, r1) net.add_bgp_neighbor(r1, r2, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) return net
def gen_mesh(mesh_size, asnum=None): """Generate a full mesh topology""" g_phy = NetworkGraph() for num in range(mesh_size): node = 'R%d' % (num + 1) g_phy.add_router(node) if asnum: g_phy.set_bgp_asnum(node, asnum) for src in g_phy.nodes(): for dst in g_phy.nodes(): if src == dst: continue g_phy.add_router_edge(src, dst) if asnum: if dst not in g_phy.get_bgp_neighbors(src): g_phy.add_bgp_neighbor(router_a=src, router_b=dst, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) return g_phy
def two_ebgp_nodes(export_path): """ Two routers connected via eBGP Very simple once router announces a single prefix and the other selects it """ graph = NetworkGraph() r1, r2 = 'R1', 'R2' graph.add_router(r1) graph.add_router(r2) graph.add_router_edge(r1, r2) graph.add_router_edge(r2, r1) # BGP configs graph.set_bgp_asnum(r1, 100) graph.set_bgp_asnum(r2, 200) # Establish peering # The actual network interfaces used for peering will be synthesized graph.add_bgp_neighbor(r1, r2, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) # Some internal network net = ip_network(u'128.0.0.0/24') prefix = '128_0_0_0' prefix_map = {prefix: net} lo0 = 'lo0' graph.set_loopback_addr( r1, lo0, ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen))) # Announce the internal network graph.add_bgp_announces(r1, lo0) # The communities recognized by us comms = [Community("100:10"), Community("100:20")] # The announcement that will be propagated by R1 ann = Announcement(prefix=prefix, peer=r1, origin=BGP_ATTRS_ORIGIN.EBGP, next_hop='R1Hop', as_path=[100], as_path_len=1, local_pref=100, med=100, communities=dict([(c, False) for c in comms]), permitted=True) path = PathReq(Protocols.BGP, prefix, ['R2', 'R1'], False) reqs = [path] # Get SMT Context ctx = create_context(reqs, graph, [ann]) propagation = EBGPPropagation(reqs, graph, ctx) propagation.compute_dags() propagation.synthesize() # Synthesize all the interfaces and link configurations connecte_syn = ConnectedSyn([], graph, full=True) connecte_syn.synthesize() # SMT Solving solver = z3.Solver(ctx=ctx.z3_ctx) assert ctx.check(solver) == z3.sat, solver.unsat_core() # Update graph with the concrete values after solver propagation.update_network_graph() gns3 = GNS3Topo(graph=graph, prefix_map=prefix_map) gns3.write_configs('%s/ibgp-simple' % export_path)
def test_double_import(): """Unit test of Route maps""" graph = NetworkGraph() r1, r2 = 'R1', 'R2' graph.add_router(r1) graph.add_router(r2) graph.add_router_edge(r1, r2) graph.add_router_edge(r2, r1) # BGP configs graph.set_bgp_asnum(r1, 100) graph.set_bgp_asnum(r2, 200) # Establish peering # The actual network interfaces used for peering will be synthesized graph.add_bgp_neighbor(r1, r2, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) # Some internal network net = ip_network(u'128.0.0.0/24') prefix = '128_0_0_0' prefix_map = {prefix: net} lo0 = 'lo0' graph.set_loopback_addr( r1, lo0, ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen))) # Announce the internal network graph.add_bgp_announces(r1, lo0) # The communities recognized by us comms = [Community("100:10"), Community("100:20")] # The announcement that will be propagated by R1 ann = Announcement(prefix=prefix, peer=r1, origin=BGP_ATTRS_ORIGIN.EBGP, next_hop='R1Hop', as_path=[100], as_path_len=1, local_pref=100, med=100, communities=dict([(c, False) for c in comms]), permitted=True) path = PathReq(Protocols.BGP, prefix, ['R2', 'R1'], False) reqs = [path] ctx = create_context(reqs, graph, [ann], create_as_paths=True) from synet.utils.fnfree_policy import SMTRouteMap rline1 = RouteMapLine(matches=None, actions=None, access=VALUENOTSET, lineno=10) deny_line1 = RouteMapLine(matches=None, actions=None, access=Access.deny, lineno=100) rmap1 = RouteMap(name='Rmap1', lines=[rline1, deny_line1]) rline2 = RouteMapLine(matches=None, actions=None, access=VALUENOTSET, lineno=10) deny_line2 = RouteMapLine(matches=None, actions=None, access=Access.deny, lineno=100) rmap2 = RouteMap(name='Rmap1', lines=[rline2, deny_line2]) sym = get_sym([ann], ctx) smt1 = SMTRouteMap(rmap1, sym, ctx) smt2 = SMTRouteMap(rmap2, smt1.announcements, ctx) print "Original permitted", sym.announcements[0].permitted print "SMT 1 permitted", smt1.announcements[0].permitted print "SMT 2 permitted", smt2.announcements[0].permitted ctx.register_constraint(smt1.announcements[0].permitted.var == True) ctx.register_constraint(smt2.announcements[0].permitted.var == False) solver = z3.Solver(ctx=ctx.z3_ctx) ret = ctx.check(solver) #print solver.to_smt2() assert ret == z3.sat, solver.unsat_core() #print solver.model() print "Original permitted", sym.announcements[0].permitted print "SMT 1 permitted", smt1.announcements[0].permitted print "SMT 2 permitted", smt2.announcements[0].permitted
def two_ebgp_nodes_route_map(export_path): """ Two routers connected via eBGP with route maps Very simple one router announces a single prefix and the other selects it """ graph = NetworkGraph() r1, r2 = 'R1', 'R2' graph.add_router(r1) graph.add_router(r2) graph.add_router_edge(r1, r2) graph.add_router_edge(r2, r1) # BGP configs graph.set_bgp_asnum(r1, 100) graph.set_bgp_asnum(r2, 200) # Establish peering # The actual network interfaces used for peering will be synthesized graph.add_bgp_neighbor(r1, r2, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) # Some internal network net = ip_network(u'128.0.0.0/24') prefix = '128_0_0_0' prefix_map = {prefix: net} lo0 = 'lo0' graph.set_loopback_addr( r1, lo0, ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen))) # Announce the internal network graph.add_bgp_announces(r1, lo0) # The communities recognized by us comms = [Community("100:10"), Community("100:20")] # The announcement that will be propagated by R1 ann = Announcement(prefix=prefix, peer=r1, origin=BGP_ATTRS_ORIGIN.EBGP, next_hop='R1Hop', as_path=[100], as_path_len=1, local_pref=100, med=100, communities=dict([(c, False) for c in comms]), permitted=True) path = PathReq(Protocols.BGP, prefix, ['R2', 'R1'], False) reqs = [path] # Create a route map to export from R1 to R2 iplist = IpPrefixList(name='IpList1', access=Access.permit, networks=[prefix]) graph.add_ip_prefix_list(r1, iplist) ip_match = MatchIpPrefixListList(iplist) set_community = ActionSetCommunity([comms[0]]) rline = RouteMapLine(matches=[ip_match], actions=[set_community], access=Access.permit, lineno=10) export_map = RouteMap(name="Export_R1_to_R2", lines=[rline]) # Register the route map graph.add_route_map(r1, export_map) # Set the route map as an export route map graph.add_bgp_export_route_map(r1, r2, export_map.name) # Create a route map to import at R2 to from R1 comm_list = CommunityList(list_id=1, access=Access.permit, communities=[comms[0]]) graph.add_bgp_community_list(r2, comm_list) comm_match = MatchCommunitiesList(comm_list) set_local_pref = ActionSetLocalPref(200) rline = RouteMapLine(matches=[MatchNextHop(VALUENOTSET)], actions=[set_local_pref], access=Access.permit, lineno=10) import_map = RouteMap(name="Import_R2_from_R1", lines=[rline]) # Register the route map graph.add_route_map(r2, import_map) # Set the route map as an import route map graph.add_bgp_import_route_map(r2, r1, import_map.name) # Get SMT Context ctx = create_context(reqs, graph, [ann]) propagation = EBGPPropagation(reqs, graph, ctx) propagation.compute_dags() propagation.synthesize() # Synthesize all the interfaces and link configurations connecte_syn = ConnectedSyn([], graph, full=True) connecte_syn.synthesize() # SMT Solving solver = z3.Solver(ctx=ctx.z3_ctx) assert ctx.check(solver) == z3.sat, solver.unsat_core() # Update graph with the concrete values after solver propagation.update_network_graph() gns3 = GNS3Topo(graph=graph, prefix_map=prefix_map) gns3.write_configs('%s/ebgp-route-map' % export_path) graph.write_graphml('%s/ebgp-route-map/topology.graphml' % export_path)
def get_griffin_ibgp_graph(): """ Returns the eBGP topology Griffin's, however R2 is now a mesh of iBGP routers R2_0, R2_1, R2_2, R2_3 and R5 is now a mesh of iBGP routers R5_0, R5_1, R5_2, R5_3 :return: NetworkGraph """ net = NetworkGraph() for i in range(1, 6): if i in [2, 5]: continue name = "R%d" % i net.add_router(name) net.set_bgp_asnum(name, i * 100) for i in range(4): r2 = 'R2_%d' % i r5 = 'R5_%d' % i net.add_router(r2) net.set_bgp_asnum(r2, 200) net.add_router(r5) net.set_bgp_asnum(r5, 500) # Connect R2, R5 ibgp routers for i in range(4): for j in range(4): if i == j: continue net.add_router_edge('R2_%d' % i, 'R2_%d' % j) if set([i, j]) not in [set([0, 3]), set([1, 2])]: net.add_router_edge('R5_%d' % i, 'R5_%d' % j) if 'R2_%d' % i in net.get_bgp_neighbors('R2_%d' % j): continue net.add_bgp_neighbor('R2_%d' % i, 'R2_%d' % j, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R5_%d' % i, 'R5_%d' % j, router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_router_edge('R1', 'R2_2') net.add_router_edge('R2_2', 'R1') net.add_router_edge('R1', 'R2_3') net.add_router_edge('R2_3', 'R1') net.add_router_edge('R1', 'R3') net.add_router_edge('R3', 'R1') net.add_router_edge('R1', 'R4') net.add_router_edge('R4', 'R1') net.add_router_edge('R2_1', 'R3') net.add_router_edge('R3', 'R2_1') net.add_router_edge('R2_3', 'R3') net.add_router_edge('R3', 'R2_3') net.add_router_edge('R2_0', 'R4') net.add_router_edge('R4', 'R2_0') net.add_router_edge('R3', 'R5_1') net.add_router_edge('R5_1', 'R3') net.add_router_edge('R4', 'R5_0') net.add_router_edge('R5_0', 'R4') net.add_bgp_neighbor('R1', 'R2_2', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R1', 'R2_3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R1', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R1', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R2_1', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R2_3', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R2_0', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R5_1', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R5_0', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.set_iface_names() return net
def get_griffin_graph(): """ Return the eBGP topology used in Griffin's papaers :return: NetworkGraph """ net = NetworkGraph() for i in range(1, 6): name = "R%d" % i net.add_router(name) net.set_bgp_asnum(name, i * 100) net.add_router_edge('R1', 'R2') net.add_router_edge('R2', 'R1') net.add_router_edge('R1', 'R3') net.add_router_edge('R3', 'R1') net.add_router_edge('R1', 'R4') net.add_router_edge('R4', 'R1') net.add_router_edge('R2', 'R3') net.add_router_edge('R3', 'R2') net.add_router_edge('R2', 'R4') net.add_router_edge('R4', 'R2') net.add_router_edge('R3', 'R5') net.add_router_edge('R5', 'R3') net.add_router_edge('R4', 'R5') net.add_router_edge('R5', 'R4') net.add_bgp_neighbor('R1', 'R2', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R1', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R1', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R2', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R2', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R5', 'R3', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.add_bgp_neighbor('R5', 'R4', router_a_iface=VALUENOTSET, router_b_iface=VALUENOTSET) net.set_iface_names() return net
def ibgp_net(): graph = NetworkGraph() peer, r1, r2, r3, r4 = 'Ext', 'R1', 'R2', 'R3', 'R4' # Add routers graph.add_peer(peer) graph.add_router(r1) graph.add_router(r2) graph.add_router(r3) graph.add_router(r4) # Connect routers graph.add_peer_edge(peer, r1) graph.add_peer_edge(r1, peer) graph.add_router_edge(r1, r2) graph.add_router_edge(r2, r1) graph.add_router_edge(r1, r3) graph.add_router_edge(r3, r1) graph.add_router_edge(r4, r2) graph.add_router_edge(r2, r4) graph.add_router_edge(r4, r3) graph.add_router_edge(r3, r4) # Enable OSPF graph.enable_ospf(r1, 100) graph.enable_ospf(r2, 100) graph.enable_ospf(r3, 100) graph.enable_ospf(r4, 100) # Set BGP ASN graph.set_bgp_asnum(peer, 200) graph.set_bgp_asnum(r1, 100) graph.set_bgp_asnum(r2, 100) graph.set_bgp_asnum(r3, 100) graph.set_bgp_asnum(r4, 100) # Establish BGP peering graph.add_bgp_neighbor(peer, r1) graph.add_bgp_neighbor(r1, r2) graph.add_bgp_neighbor(r1, r3) graph.add_bgp_neighbor(r1, r4) graph.add_bgp_neighbor(r2, r3) graph.add_bgp_neighbor(r2, r4) graph.add_bgp_neighbor(r3, r4) # Assign interfaces graph.set_iface_names() # Some internal to be announced network net = ip_network(u'128.0.0.0/24') prefix = '128_0_0_0' lo0 = 'lo0' prefix_map = {prefix: net} loaddr = ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen)) graph.set_loopback_addr(peer, lo0, loaddr) graph.add_bgp_announces(peer, lo0) # Synthesize connectivity syn = ConnectedSyn(graph, full=True, default_ibgp_lo='lo10') assert syn.synthesize() # Some route map actions = [ActionSetLocalPref(200)] line = RouteMapLine(matches=None, actions=actions, access=Access.permit, lineno=100) route_map = RouteMap(name="ImpPolicy", lines=[line]) graph.add_route_map(r1, route_map) graph.add_bgp_import_route_map(r1, peer, route_map.name) # Add networks # Note, some of the loop back interfaces where generated due to # ibgp peering in ConnectedSyn for router in graph.local_routers_iter(): for iface in graph.get_ifaces(router): graph.add_ospf_network(router, iface, 0) for lo in graph.get_loopback_interfaces(router): graph.add_ospf_network(router, lo, 0) # Write the configs gns3 = GNS3Topo(graph, prefix_map=prefix_map) gns3.write_configs('out-configs/ibgp')