def test_expand_single(self): # Arrange N = 4 g = get_ibgp_linear_topo(N=N) req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R1'], strict=False) ctx = self.create_context([req], g) propagation = EBGPPropagation([req], g, ctx) # Act # Case 1 p1 = propagation.expand_as_path((100, ), ['R1']) print "P1", p1 expected = set([ ('R1', ), ('R1', 'R2'), ('R1', 'R3'), ('R1', 'R4'), ]) self.assertEquals(p1, expected)
def test_ebgp_linear(self): # Arrange N = 4 g = get_ebgp_linear_topo(N) net = "Prefix0" prefix_map = {net: ip_network(u'128.0.0.0/24')} addr = (prefix_map[net].hosts().next(), prefix_map[net].prefixlen) g.set_loopback_addr('R1', 'lo0', ip_interface("%s/%d" % addr)) for i in range(1, N + 1): first = 'R%d' % (i - 1) if i > 1 else None middle = 'R%d' % i last = 'R%d' % (i + 1) if i < N else None if last: #if middle == 'R1': # continue rline = RouteMapLine(None, None, VALUENOTSET, 10) rmap = RouteMap('Exp_%s' % last, [rline]) g.add_route_map(middle, rmap) g.add_bgp_export_route_map(middle, last, rmap.name) print "ADD EXPORT ROUTE MAP AT", middle, rmap.name if first: rmap = RouteMap('Imp_%s' % first, [rline]) g.add_route_map(middle, rmap) g.add_bgp_import_route_map(middle, first, rmap.name) print "ADD IMPORT ROUTE MAP AT", middle, rmap.name #nx.nx_pydot.write_dot(g, '/tmp/linear.xdot') req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R1'], strict=False) ctx = self.create_context([req], g) # Act propagation = EBGPPropagation([req], g, ctx) propagation.compute_dags() # Assert ebgp = propagation.ebgp_graphs['Prefix0'] ibgp = propagation.ibgp_graphs['Prefix0'] nx.nx_pydot.write_dot(ebgp, '/tmp/ebgp_linear.xdot') nx.nx_pydot.write_dot(ibgp, '/tmp/ibgp_linear.xdot') propagation.synthesize() solver = z3.Solver(ctx=ctx.z3_ctx) ret = ctx.check(solver) assert ret == z3.sat, solver.unsat_core() propagation.update_network_graph() gns3 = GNS3Topo(g, prefix_map) gns3.write_configs('./out-configs/ebgp-linear-%s' % N)
def synthesize_bgp(self): self._bgp_ctx = self._create_context(create_as_paths=False) self._bgp_synthesizer = EBGPPropagation(self.bgp_reqs, self.topo, self._bgp_ctx) # Compute BGP Propagation unmatching_order = self.bgp_synthesizer.compute_dags() if unmatching_order: msg = "Unimplementable BGP requirements; " \ "the following BGP selection order cannot be met: " \ "{}".format(unmatching_order) raise UnImplementableRequirements(msg) self.bgp_synthesizer.synthesize() #SMT Solving self._bgp_solver = z3.Solver(ctx=self._bgp_ctx.z3_ctx) if self.bgp_ctx.check(self.bgp_solver, track=True, out_smt=self.configs.bgp_smt) != z3.sat: msg = "Unimplementable BGP requirements;" \ "Possibly change the requirements or loosen the sketch." \ "The following constraints couldn't be satisfied:" \ "{}".format(self.bgp_solver.unsat_core()) raise UnImplementableRequirements(msg) self.bgp_synthesizer.update_network_graph() return True
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 linear_ebgp(N, export_path): """ Routers connected in a line and each eBGP pair with it's direct neighbors """ # Topology g = get_ebgp_linear_topo(N) # Announce locally prefix = "Prefix0" net = ip_network(u'128.0.0.0/24') prefix_map = {prefix: net} g.set_loopback_addr( 'R1', 'lo0', ip_interface("%s/%d" % (net.hosts().next(), net.prefixlen))) g.add_bgp_announces('R1', 'lo0') # Announcement comms = [Community("100:10"), Community("100:20")] cs = dict([(c, False) for c in comms]) # The announcement that will be propagated by R1 ann = get_announcement(prefix=prefix, peer='R1', comms=cs) # Set up route maps for i in range(1, N + 1): first = 'R%d' % (i - 1) if i > 1 else None middle = 'R%d' % i last = 'R%d' % (i + 1) if i < N else None if last: matches = [MatchAsPath(VALUENOTSET)] #matches = None rline = RouteMapLine(matches, None, VALUENOTSET, 10) deny_line = RouteMapLine(None, None, Access.deny, 100) rmap = RouteMap('Exp_%s' % last, [rline, deny_line]) g.add_route_map(middle, rmap) g.add_bgp_export_route_map(middle, last, rmap.name) if first: matches = [MatchAsPath(VALUENOTSET)] #matches = None rline = RouteMapLine(matches, None, VALUENOTSET, 10) deny_line = RouteMapLine(None, None, Access.deny, 100) rmap = RouteMap('Imp_%s' % first, [rline, deny_line]) g.add_route_map(middle, rmap) g.add_bgp_import_route_map(middle, first, rmap.name) # nx.nx_pydot.write_dot(g, '/tmp/linear.xdot') req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R1'], strict=False) ctx = create_context([req], g, [ann]) propagation = EBGPPropagation([req], g, ctx) propagation.compute_dags() propagation.synthesize() solver = z3.Solver(ctx=ctx.z3_ctx) ret = ctx.check(solver) assert ret == z3.sat, solver.unsat_core() propagation.update_network_graph() gns3 = GNS3Topo(g, prefix_map) gns3.write_configs('%s/linear-ebgp-%d' % (export_path, N))
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 test_expand(self): # Arrange g = get_griffin_ibgp_graph() p0 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2_2', 'R2_0', 'R4', 'R1'], strict=False) p1 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2_2', 'R1'], strict=False) r2_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p0, p1], strict=False) p2 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R2_3', 'R1'], strict=False) p3 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R1'], strict=False) r3_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p2, p3], strict=False) r4_req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R4', 'R1'], strict=False) p6 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5_3', 'R5_2', 'R5_0', 'R4', 'R1'], strict=False) p7 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5_3', 'R5_1', 'R3', 'R1'], strict=False) r5_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p6, p7], strict=False) reqs = [r2_req, r3_req, r4_req, r5_req] ctx = self.create_context(reqs, g) propagation = EBGPPropagation(reqs, g, ctx) # Act # Case 1: Direct eBGP p1 = propagation.expand_as_path((100, ), ['R1']) p2 = propagation.expand_as_path((100, 400), ['R1']) self.assertEquals(p1, set([ ('R1', ), ])) self.assertEquals(p2, set([('R1', 'R4')])) # Case 2: Direct eBGP->iBGP p3 = propagation.expand_as_path((100, 200), ['R1']) paths_to_r2 = set([ ('R1', 'R2_2'), ('R1', 'R2_2', 'R2_0'), ('R1', 'R2_2', 'R2_1'), ('R1', 'R2_2', 'R2_3'), ('R1', 'R2_3'), ('R1', 'R2_3', 'R2_0'), ('R1', 'R2_3', 'R2_1'), ('R1', 'R2_3', 'R2_2'), ]) self.assertEquals(p3, paths_to_r2) ## Case 3: eBGP-> iBGP -> eBGP p4 = propagation.expand_as_path((100, 200, 300), ['R1']) paths_to_r3 = set([ ('R1', 'R2_2', 'R2_1', 'R3'), ('R1', 'R2_2', 'R2_3', 'R3'), ('R1', 'R2_3', 'R3'), ('R1', 'R2_3', 'R2_1', 'R3'), ]) self.assertEquals(p4, paths_to_r3)
def test_ibgp_linear(self): # Arrange N = 4 g = get_ibgp_linear_topo(N=N) net = "Prefix0" prefix_map = {net: ip_network(u'128.0.0.0/24')} ifaddr = ip_interface( "%s/%d" % (prefix_map[net].hosts().next(), prefix_map[net].prefixlen)) g.set_loopback_addr('R1', 'lo0', ifaddr) for i, node in enumerate(sorted(g.routers_iter())): g.set_loopback_addr('R%d' % (i + 1), 'lo100', ip_interface(u'192.168.0.%d/32' % i)) #for i in range(1, N): # r1 = 'R1' # r2 = "R%d" % (i + 1) # g.set_bgp_neighbor_iface(r1, r2, 'lo100') for i in range(2, N + 1): r1 = 'R1' node = 'R%s' % i rline = RouteMapLine(None, None, VALUENOTSET, 10) #rmap = RouteMap('Exp_%s' % node, [rline]) #g.add_route_map(r1, rmap) #g.add_bgp_export_route_map('R1', 'R%d' % i, rmap.name) rmap = RouteMap('Imp_%s' % r1, [rline]) g.add_route_map(node, rmap) g.add_bgp_import_route_map(node, r1, rmap.name) #nx.nx_pydot.write_dot(g, '/tmp/linear.dot') req1 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R1'], strict=False) req2 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R1'], strict=False) reqs = [req1, req2] ctx = self.create_context(reqs, g) # Act propagation = EBGPPropagation(reqs, g, ctx) propagation.compute_dags() # Assert #ebgp = propagation.ebgp_graphs['Prefix0'] #ibgp = propagation.ibgp_graphs['Prefix0'] #nx.nx_pydot.write_dot(ebgp, '/tmp/ebgp_linear.dot') #nx.nx_pydot.write_dot(ibgp, '/tmp/ibgp_linear.dot') propagation.synthesize() solver = z3.Solver(ctx=ctx.z3_ctx) ret = ctx.check(solver) assert ret == z3.sat, solver.unsat_core() propagation.update_network_graph() for router in g.routers_iter(): g.enable_ospf(router, 100) for iface in g.get_ifaces(router): g.add_ospf_network(router, iface, 0) if router != 'R1': g.add_ospf_network( router, g.get_loopback_addr(router, 'lo100').network, 0) g.add_ospf_network('R1', g.get_loopback_addr('R1', 'lo0').network, 0) gns3 = GNS3Topo(g, prefix_map) gns3.write_configs('./out-configs/ibgp-linear-%d' % N)
def test_good_gadget_ibgp(self): # Arrange g = get_griffin_ibgp_graph() for src in g.routers_iter(): for dst in g.get_bgp_neighbors(src): if src == dst: continue # Export matches1 = [MatchAsPath(VALUENOTSET)] matches2 = [MatchAsPath(VALUENOTSET)] rline1 = RouteMapLine(matches1, [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 10) rline2 = RouteMapLine(matches2, [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 20) rmap = RouteMap('Exp_%s' % dst, [rline1, rline2]) g.add_route_map(src, rmap) g.add_bgp_export_route_map(src, dst, rmap.name) # Import matches1 = [MatchAsPath(VALUENOTSET)] matches2 = [MatchAsPath(VALUENOTSET)] rline1 = RouteMapLine(matches1, [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 10) rline2 = RouteMapLine(matches2, [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 20) rmap = RouteMap('Imp_%s' % dst, [rline1, rline2]) g.add_route_map(src, rmap) g.add_bgp_import_route_map(src, dst, rmap.name) p0 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2_2', 'R2_0', 'R4', 'R1'], strict=False) p1 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2_2', 'R1'], strict=False) r2_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p0, p1], strict=False) p2 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R2_3', 'R1'], strict=False) p3 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R1'], strict=False) r3_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p2, p3], strict=False) r4_req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R4', 'R1'], strict=False) p6 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5_3', 'R5_2', 'R5_0', 'R4', 'R1'], strict=False) p7 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5_3', 'R5_1', 'R3', 'R1'], strict=False) r5_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p6, p7], strict=False) reqs = [r2_req, r3_req, r4_req, r5_req] ctx = self.create_context(reqs, g) # Act propagation = EBGPPropagation(reqs, g, ctx) unmatching_order = propagation.compute_dags() ebgp = propagation.ebgp_graphs['Prefix0'] ibgp = propagation.ibgp_graphs['Prefix0'] #nx.nx_pydot.write_dot(ibgp, '/tmp/ibgp_good.xdot') #nx.nx_pydot.write_dot(ebgp, '/tmp/ebgp_good.xdot') # Assert assert not unmatching_order # Assert eBGP propagation self.assertEqual(ebgp.node[100]['order'], [set([(100, )])]) self.assertEqual( ebgp.node[200]['order'], [set([(100, 400, 200)]), set([(100, 200)])]) self.assertEqual( ebgp.node[300]['order'], [set([(100, 200, 300)]), set([(100, 300)])]) self.assertEqual(ebgp.node[400]['order'], [set([(100, 400)])]) self.assertEqual(ebgp.node[500]['order'], [set([(100, 400, 500)]), set([(100, 300, 500)])]) # Assert iBGP propagation self.assertEqual(ibgp.node['R1']['order'], [set([('R1', )])]) self.assertEqual(ibgp.node['R2_0']['order'], [set([('R1', 'R4', 'R2_0')])]) self.assertEqual(ibgp.node['R2_1']['order'], []) self.assertEqual( ibgp.node['R2_2']['order'], [set([('R1', 'R4', 'R2_0', 'R2_2')]), set([('R1', 'R2_2')])]) self.assertEqual(ibgp.node['R2_3']['order'], [set([('R1', 'R2_3')])]) self.assertEqual(ibgp.node['R3']['order'], [set([('R1', 'R2_3', 'R3')]), set([('R1', 'R3')])]) self.assertEqual(ibgp.node['R4']['order'], [set([('R1', 'R4')])]) self.assertEqual(ibgp.node['R5_0']['order'], [set([('R1', 'R4', 'R5_0')])]) self.assertEqual(ibgp.node['R5_1']['order'], [set([('R1', 'R3', 'R5_1')])]) self.assertEqual(ibgp.node['R5_2']['order'], [set([('R1', 'R4', 'R5_0', 'R5_2')])]) self.assertEqual(ibgp.node['R5_3']['order'], [ set([('R1', 'R4', 'R5_0', 'R5_2', 'R5_3')]), set([('R1', 'R3', 'R5_1', 'R5_3')]) ]) propagation.synthesize()
def test_bad_gadget(self): # Arrange g = get_griffin_graph() p0 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R4', 'R1'], strict=False) p1 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R1'], strict=False) r2_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p0, p1], strict=False) p2 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R2', 'R1'], strict=False) p3 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R1'], strict=False) r3_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p2, p3], strict=False) p4 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R4', 'R5', 'R3', 'R1'], strict=False) p5 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R4', 'R1'], strict=False) r4_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p4, p5], strict=False) p6 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5', 'R3', 'R1'], strict=False) p7 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5', 'R4', 'R1'], strict=False) r5_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p6, p7], strict=False) reqs = [r2_req, r3_req, r4_req, r5_req] # Action ctx = self.create_context(reqs, g) propagation = EBGPPropagation(reqs, g, ctx) unmatching_order = propagation.compute_dags() dag = propagation.ebgp_graphs['Prefix0'] # Assert assert unmatching_order
def test_good_gadget(self): # Arrange g = get_griffin_graph() net = "Prefix0" prefix_map = {net: ip_network(u'128.0.0.0/24')} addr = (prefix_map[net].hosts().next(), prefix_map[net].prefixlen) g.set_loopback_addr('R1', 'lo0', ip_interface("%s/%d" % addr)) for src in g.routers_iter(): for dst in g.get_bgp_neighbors(src): if src == dst: continue # Export ip_list = IpPrefixList(name="L_%s-to_%s" % (src, dst), access=Access.permit, networks=[VALUENOTSET]) g.add_ip_prefix_list(src, ip_list) rline = RouteMapLine([MatchIpPrefixListList(ip_list)], [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 10) rmap = RouteMap('Exp_%s' % dst, [rline]) g.add_route_map(src, rmap) g.add_bgp_export_route_map(src, dst, rmap.name) # Import #rline = RouteMapLine(None, [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 10) #rmap = RouteMap('Imp_%s' % dst, [rline]) #g.add_route_map(src, rmap) #g.add_bgp_import_route_map(src, dst, rmap.name) rline1 = RouteMapLine([MatchAsPath(VALUENOTSET)], [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 10) rline2 = RouteMapLine([MatchAsPath(VALUENOTSET)], [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 20) rline3 = RouteMapLine([MatchAsPath(VALUENOTSET)], [ActionSetLocalPref(VALUENOTSET)], VALUENOTSET, 30) rmap = RouteMap('Imp_%s' % dst, [rline1, rline2, rline3]) g.add_route_map(src, rmap) g.add_bgp_import_route_map(src, dst, rmap.name) p0 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R4', 'R1'], strict=False) p1 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R2', 'R1'], strict=False) r2_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p0, p1], strict=False) p2 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R2', 'R1'], strict=False) p3 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R3', 'R1'], strict=False) r3_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p2, p3], strict=False) r4_req = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R4', 'R1'], strict=False) p6 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5', 'R4', 'R1'], strict=False) p7 = PathReq(Protocols.BGP, dst_net='Prefix0', path=['R5', 'R3', 'R1'], strict=False) r5_req = PathOrderReq(Protocols.BGP, dst_net='Prefix0', paths=[p6, p7], strict=False) # Action reqs = [r2_req, r3_req, r4_req, r5_req] ctx = self.create_context(reqs, g) propagation = EBGPPropagation(reqs, g, ctx) unmatching_order = propagation.compute_dags() assert not unmatching_order propagation.synthesize() solver = z3.Solver(ctx=ctx.z3_ctx) ret = ctx.check(solver) assert ret == z3.sat, solver.unsat_core() print solver.model() propagation.update_network_graph() gns3 = GNS3Topo(g, prefix_map) gns3.write_configs('./out-configs/good_gadget')
def bgp(n, nreqs=10): req_file = './topos/cav/gridrand%d-bgp-%d-req.logic' % (n, nreqs) topo = gen_grid_topology(n, n, 0) static_reqs, ospf_reqs, bgp_reqs = read_reqs(req_file) seed = 159734782 path_gen = 200 ospfRand = random.Random(seed) for node in topo.routers_iter(): topo.enable_ospf(node, 100) topo.set_bgp_asnum(node, 100) # Initially all costs are empty topo.set_static_routes_empty(node) for src, dst in topo.edges(): topo.set_edge_ospf_cost(src, dst, VALUENOTSET) peer = 'ATT' egresses = set([p.path[-2] for p in bgp_reqs]) topo.add_peer(peer) topo.set_bgp_asnum(peer, 5000) for req in bgp_reqs: req.path.append(peer) for egress in egresses: topo.add_peer_edge(peer, egress) topo.add_peer_edge(egress, peer) topo.add_bgp_neighbor(peer, egress, VALUENOTSET, VALUENOTSET) for src in topo.local_routers_iter(): for dst in topo.local_routers_iter(): if src == dst or dst in topo.get_bgp_neighbors(src): continue topo.add_bgp_neighbor(src, dst, VALUENOTSET, VALUENOTSET) prefix = 'GOOGLE' communities = [Community("100:%d" % i) for i in range(5)] ann = Announcement(prefix=prefix, peer=peer, origin=BGP_ATTRS_ORIGIN.EBGP, as_path=[1, 2, 5000], as_path_len=3, next_hop='%sHop' % peer, local_pref=100, med=10, communities=dict([(c, False) for c in communities]), permitted=True) topo.add_bgp_advertise(peer, ann) conn = ConnectedSyn([], topo, full=True) conn.synthesize() static_syn = StaticSyn(static_reqs, topo) static_syn.synthesize() ospf = OSPFCEGIS(topo, gen_paths=path_gen, random_obj=ospfRand) for req in ospf_reqs: ospf.add_req(req) assert ospf.synthesize(allow_ecmp=True) assert not ospf.removed_reqs for router in topo.local_routers_iter(): count = itertools.count(1) for neighbor in topo.get_bgp_neighbors(router): if router == neighbor: continue comm_list = CommunityList( list_id=count.next(), access=Access.permit, communities=[VALUENOTSET, VALUENOTSET, VALUENOTSET]) topo.add_bgp_community_list(router, comm_list) match_comm = MatchCommunitiesList(comm_list) iplist = IpPrefixList(name='ip%s' % count.next(), access=Access.permit, networks=[VALUENOTSET]) topo.add_ip_prefix_list(router, iplist) match_ip = MatchIpPrefixListList(iplist) match_next_hop = MatchNextHop(VALUENOTSET) match_sel = MatchSelectOne([match_comm, match_next_hop, match_ip]) actions = [ ActionSetLocalPref(VALUENOTSET), ActionSetCommunity([VALUENOTSET], True) ] rline = RouteMapLine([match_sel], actions, VALUENOTSET, 10) dline = RouteMapLine(None, None, Access.deny, 100) rmap = RouteMap("Rimp_%s_from_%s" % (router, neighbor), lines=[rline, dline]) topo.add_route_map(router, rmap) topo.add_bgp_import_route_map(router, neighbor, rmap.name) ctx = create_context(bgp_reqs, topo, [ann]) p = EBGPPropagation(bgp_reqs, topo, ctx) p.compute_dags() p.synthesize() solver = z3.Solver() ret = ctx.check(solver) assert ret == z3.sat, solver.unsat_core() p.update_network_graph()