예제 #1
0
 def test_ordered_notvalid(self):
     fan_out = 4
     network_graph = self.get_triangles(fan_out)
     source = 'source'
     sink = 'sink'
     p1 = [source, 'R1', sink]
     p2 = [source, 'R2', sink]
     p3 = [source, 'R3', sink]
     path1 = PathReq(Protocols.OSPF, 'Google', p1, False)
     path2 = PathReq(Protocols.OSPF, 'Google', p2, False)
     path3 = PathReq(Protocols.OSPF, 'Google', p3, False)
     paths = [path1, path2, path3]
     order_req1 = PathOrderReq(Protocols.OSPF, 'Google', paths, False)
     order_req2 = PathOrderReq(Protocols.OSPF, 'Google',
                               [path3, path2, path1], False)
     ospf = synet.synthesis.ospf_heuristic.OSPFSyn(network_graph,
                                                   gen_paths=10)
     ospf.add_req(order_req1)
     ospf.add_req(order_req2)
     ret = ospf.synthesize()
     self.assertFalse(ret)
예제 #2
0
def generate_ordered_reqs(topo, reqsize, ordered, rand):
    """Generate reqsize of PathOrderReq each has ordered paths"""
    graph = nx.DiGraph()
    for src, dst in topo.edges():
        graph.add_edge(src, dst)

    computed_paths = {}
    tmp_cost = 'tmp-cost'
    for src, dst in graph.edges():
        graph[src][dst][tmp_cost] = rand.randint(1, sys.maxint)

    for src in graph.nodes():
        for dst in graph.nodes():
            if src == dst:
                continue
            if (src, dst) not in computed_paths:
                shortest = nx.shortest_path(graph, src, dst, weight=tmp_cost)
                computed_paths[(src, dst)] = [shortest]

    edges = list(graph.edges())
    for src, dst in edges:
        cost = graph[src][dst][tmp_cost]
        graph.remove_edge(src, dst)
        if nx.has_path(graph, src, dst):
            shortest = nx.shortest_path(graph, src, dst, weight=tmp_cost)
            if shortest not in computed_paths[(src, dst)]:
                computed_paths[(src, dst)].append(shortest)
        graph.add_edge(src, dst, **{tmp_cost: cost})

    valid = []
    for (src, dst) in computed_paths:
        k = len(computed_paths[(src, dst)])
        if k == ordered:
            valid.append(computed_paths[(src, dst)])

    if len(valid) >= reqsize:
        sampled = random.sample(valid, reqsize)
        reqs = []
        for plist in sampled:
            req = PathOrderReq(Protocols.OSPF, plist[0][-1], [
                PathReq(Protocols.OSPF, path[-1], path, False)
                for path in plist
            ], False)
            reqs.append(req)
        return reqs
    else:
        print "Regenerating random ordered paths"
        return generate_ordered_reqs(topo, reqsize, ordered, rand)
예제 #3
0
 def test_ordered_correct(self):
     fan_out = 4
     network_graph = self.get_triangles(fan_out)
     source = 'source'
     sink = 'sink'
     p1 = [source, 'R1', sink]
     p2 = [source, 'R2', sink]
     p3 = [source, 'R3', sink]
     p4 = [source, 'R4', sink]
     path1 = PathReq(Protocols.OSPF, 'Google', p1, False)
     path2 = PathReq(Protocols.OSPF, 'Google', p2, False)
     path3 = PathReq(Protocols.OSPF, 'Google', p3, False)
     paths = [path1, path2, path3]
     order_req = PathOrderReq(Protocols.OSPF, 'Google', paths, False)
     ospf = synet.synthesis.ospf_heuristic.OSPFSyn(network_graph,
                                                   gen_paths=10)
     ospf.add_req(order_req)
     ret = ospf.synthesize()
     self.assertTrue(ret)
     ospf.update_network_graph()
     p1_cost = [
         network_graph.get_edge_ospf_cost(src, dst)
         for src, dst in zip(p1[0::1], p1[1::1])
     ]
     p2_cost = [
         network_graph.get_edge_ospf_cost(src, dst)
         for src, dst in zip(p2[0::1], p2[1::1])
     ]
     p3_cost = [
         network_graph.get_edge_ospf_cost(src, dst)
         for src, dst in zip(p3[0::1], p3[1::1])
     ]
     p4_cost = [
         network_graph.get_edge_ospf_cost(src, dst)
         for src, dst in zip(p4[0::1], p4[1::1])
     ]
     p1_cost = sum(p1_cost)
     p2_cost = sum(p2_cost)
     p3_cost = sum(p3_cost)
     p4_cost = sum(p4_cost)
     self.assertLessEqual(p1_cost, p2_cost)
     self.assertLessEqual(p2_cost, p3_cost)
     self.assertLessEqual(p3_cost, p4_cost)
예제 #4
0
    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)
예제 #5
0
    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()
예제 #6
0
    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
예제 #7
0
    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')
예제 #8
0
    def test_next_hop_mixed_route_map(self):
        # Arrange
        graph, (ann1, ann2, ann3) = self.get_cust_peer_linear_topo()
        r1, r2, provider1, provider2,  customer = 'R1', 'R2', 'Provider1', 'Provider2', 'Customer'
        prefix1 = ann1.prefix
        prefix2 = ann3.prefix
        graph.add_bgp_advertise(node=provider1, announcement=ann1, loopback='lo10')
        graph.add_bgp_advertise(node=provider2, announcement=ann2, loopback='lo10')
        #graph.add_bgp_advertise(node=customer, announcement=ann3, loopback='lo10')

        clist = CommunityList(list_id=1, access=Access.permit, communities=[VALUENOTSET])
        match = MatchCommunitiesList(clist)
        graph.add_bgp_community_list(r1, clist)
        rline1 = RouteMapLine(matches=[match], actions=[], access=VALUENOTSET, lineno=10)
        rline2 = RouteMapLine(matches=[], actions=[], access=Access.permit, lineno=100)
        rmap_export = RouteMap(name='DenyExport', lines=[rline1, rline2])
        graph.add_route_map(r1, rmap_export)
        graph.add_bgp_export_route_map(r1, provider1, rmap_export.name)
        graph.add_bgp_export_route_map(r1, provider2, rmap_export.name)

        # Custom match
        iplist = IpPrefixList(name='L1', access=Access.permit, networks=[VALUENOTSET])
        graph.add_ip_prefix_list(r1, iplist)
        match = MatchIpPrefixListList(iplist)
        actions = [ActionSetLocalPref(VALUENOTSET), ActionSetCommunity(communities=[VALUENOTSET])]
        rline1 = RouteMapLine(matches=[match], actions=actions, access=VALUENOTSET, lineno=10)
        rline2 = RouteMapLine(matches=[], actions=[], access=Access.deny, lineno=100)
        rmap_import = RouteMap(name='Import', lines=[rline1, rline2])
        graph.add_route_map(r1, rmap_import)
        graph.add_bgp_import_route_map(r1, provider1, rmap_import.name)
        graph.add_bgp_import_route_map(r1, provider2, rmap_import.name)

        p1 = PathReq(Protocols.BGP, dst_net=prefix1, path=[customer, r2, r1, provider1], strict=False)
        p2 = PathReq(Protocols.BGP, dst_net=prefix1, path=[customer, r2, r1, provider1], strict=False)
        req1 = PathOrderReq(Protocols.BGP, prefix1, [p2, p1], strict=False)
        netcomplete = NetComplete([req1], graph, [ann1, ann2])
        next_hop_vals = {
            'R1': 'Provider1-Fa0-0',
            'R2': 'Provider1-Fa0-0',
            'Customer': 'R2-Fa0-0',
            'Provider1': '0.0.0.0',
            'Provider2': '0.0.0.0',
        }
        provider1_as = [graph.get_bgp_asnum(provider1)] + ann1.as_path
        provider2_as = [graph.get_bgp_asnum(provider2)] + ann2.as_path
        r1_as = [graph.get_bgp_asnum(r1)] + provider1_as
        customer_as = [graph.get_bgp_asnum(customer)] + r1_as
        as_path_vals = {
            'R1': 'as_path_{}'.format('_'.join([str(x) for x in r1_as])),
            'R2': 'as_path_{}'.format('_'.join([str(x) for x in r1_as])),
            'Customer': 'as_path_{}'.format('_'.join([str(x) for x in customer_as])),
            'Provider1': 'as_path_{}'.format('_'.join([str(x) for x in provider1_as])),
            'Provider2': 'as_path_{}'.format('_'.join([str(x) for x in provider2_as])),
        }
        as_path_len_vals = {
            'R1': len(r1_as) - 1,
            'R2': len(r1_as) - 1,
            'Customer': len(customer_as) - 1,
            'Provider1': len(provider1_as) - 1,
            'Provider2': len(provider2_as) - 1,
        }
        # Act
        ret = netcomplete.synthesize()
        netcomplete.write_configs('out-configs/ibgp')
        # Assert
        self.assertTrue(ret)
        for node, attrs in netcomplete.bgp_synthesizer.ibgp_propagation.nodes(data=True):
            for ann in attrs['box'].selected_sham:
                self.assertTrue(ann.permitted.is_concrete)
                self.assertTrue(ann.permitted.get_value())

                self.assertTrue(ann.prefix.is_concrete)
                self.assertEquals(desanitize_smt_name(ann.prefix.get_value()), prefix1)

                self.assertTrue(ann.next_hop.is_concrete)
                self.assertEquals(desanitize_smt_name(ann.next_hop.get_value()), next_hop_vals[node])

                self.assertTrue(ann.as_path.is_concrete)
                self.assertEquals(ann.as_path.get_value(), as_path_vals[node])

                self.assertTrue(ann.as_path_len.is_concrete)
                self.assertEquals(ann.as_path_len.get_value(), as_path_len_vals[node])

                self.assertTrue(ann.med.is_concrete)
                self.assertEquals(ann.med.get_value(), DEFAULT_MED)

                self.assertTrue(ann.local_pref.is_concrete)
                #self.assertEquals(ann.local_pref.get_value(), DEFAULT_LOCAL_PREF)

                for comm, val in ann.communities.iteritems():
                    self.assertTrue(val.is_concrete)
예제 #9
0
def bgp_example(output_dir):
    # Generate the basic network of three routers
    graph = gen_mesh(3, 100)
    r1, r2, r3, r4 = 'R1', 'R2', 'R3', 'R4'

    # Enable OSPF in the sketch
    for node in graph.local_routers_iter():
        graph.enable_ospf(node, 100)
    # Edge weights are symbolic
    for src, dst in graph.edges():
        graph.set_edge_ospf_cost(src, dst, VALUENOTSET)
    graph.set_loopback_addr(r3, 'lo100', VALUENOTSET)
    graph.set_loopback_addr(r2, 'lo100', VALUENOTSET)
    graph.add_ospf_network(r1, 'lo100', '0.0.0.0')
    graph.add_ospf_network(r2, 'lo100', '0.0.0.0')
    graph.add_ospf_network(r3, 'lo100', '0.0.0.0')
    graph.add_ospf_network(r1, 'Fa0/0', '0.0.0.0')
    graph.add_ospf_network(r2, 'Fa0/0', '0.0.0.0')
    graph.add_ospf_network(r3, 'Fa0/0', '0.0.0.0')

    # Add two providers and one customer
    provider1 = 'Provider1'
    provider2 = 'Provider2'
    customer = 'Customer'
    graph.add_peer(provider1)
    graph.add_peer(provider2)
    graph.add_peer(customer)
    graph.set_bgp_asnum(provider1, 400)
    graph.set_bgp_asnum(provider2, 500)
    graph.set_bgp_asnum(customer, 600)
    graph.add_peer_edge(r2, provider1)
    graph.add_peer_edge(provider1, r2)
    graph.add_peer_edge(r3, provider2)
    graph.add_peer_edge(provider2, r3)
    graph.add_peer_edge(r1, customer)
    graph.add_peer_edge(customer, r1)

    # Establish BGP peering
    graph.add_bgp_neighbor(provider1, r2)
    graph.add_bgp_neighbor(provider2, r3)
    graph.add_bgp_neighbor(customer, r1)

    # The traffic class announced by the two providers
    net1 = ip_network(u'128.0.0.0/24')
    # The traffic class announced by the customer
    net2 = ip_network(u'128.0.1.0/24')

    prefix1 = str(net1)
    prefix2 = str(net2)
    # Known communities
    comms = [Community("100:{}".format(c)) for c in range(1, 4)]
    # The symbolic announcement injected by provider1
    ann1 = Announcement(
        prefix1,
        peer=provider1,
        origin=BGP_ATTRS_ORIGIN.INCOMPLETE,
        as_path=[5000],  # We assume it learned from other upstream ASes
        as_path_len=1,
        #next_hop='0.0.0.0',
        next_hop='{}Hop'.format(provider1),
        local_pref=100,
        med=100,
        communities=dict([(c, False) for c in comms]),
        permitted=True)
    # The symbolic announcement injected by provider1
    # Note it has a shorter AS Path
    ann2 = Announcement(
        prefix1,
        peer=provider2,
        origin=BGP_ATTRS_ORIGIN.INCOMPLETE,
        as_path=[3000, 5000],  # We assume it learned from other upstream ASes
        as_path_len=2,
        next_hop='0.0.0.0',
        local_pref=100,
        med=100,
        communities=dict([(c, False) for c in comms]),
        permitted=True)
    # The symbolic announcement injected by customer
    ann3 = Announcement(prefix2,
                        peer=customer,
                        origin=BGP_ATTRS_ORIGIN.INCOMPLETE,
                        as_path=[],
                        as_path_len=0,
                        next_hop='0.0.0.0',
                        local_pref=100,
                        med=100,
                        communities=dict([(c, False) for c in comms]),
                        permitted=True)

    graph.add_bgp_advertise(provider1, ann1, loopback='lo100')
    graph.set_loopback_addr(provider1, 'lo100',
                            ip_interface(net1.hosts().next()))

    graph.add_bgp_advertise(provider2, ann2, loopback='lo100')
    graph.set_loopback_addr(provider2, 'lo100',
                            ip_interface(net1.hosts().next()))

    graph.add_bgp_advertise(customer, ann3, loopback='lo100')
    graph.set_loopback_addr(customer, 'lo100',
                            ip_interface(net2.hosts().next()))

    ########################## Configuration sketch ###############################

    for local, peer in [(r2, provider1), (r3, provider2)]:
        imp_name = "{}_import_from_{}".format(local, peer)
        exp_name = "{}_export_to_{}".format(local, peer)
        imp = RouteMap.generate_symbolic(name=imp_name,
                                         graph=graph,
                                         router=local)
        exp = RouteMap.generate_symbolic(name=exp_name,
                                         graph=graph,
                                         router=local)
        graph.add_bgp_import_route_map(local, peer, imp.name)
        graph.add_bgp_export_route_map(local, peer, exp.name)

    for local, peer in [(r2, r3), (r3, r2)]:
        # In Cisco the last line is a drop by default
        rline1 = RouteMapLine(matches=[],
                              actions=[],
                              access=VALUENOTSET,
                              lineno=10)
        from tekton.bgp import Access
        rline2 = RouteMapLine(matches=[],
                              actions=[],
                              access=Access.deny,
                              lineno=100)
        rmap_export = RouteMap(name='{}_export_{}'.format(local, peer),
                               lines=[rline1, rline2])
        graph.add_route_map(local, rmap_export)
        graph.add_bgp_export_route_map(local, peer, rmap_export.name)

    # Requirements
    path1 = PathReq(Protocols.BGP, prefix1, [customer, r1, r2, provider1],
                    False)
    path2 = PathReq(Protocols.BGP, prefix1, [customer, r1, r3, r2, provider1],
                    False)
    path3 = PathReq(Protocols.BGP, prefix1, [r3, r1, r2, provider1], False)

    path4 = PathReq(Protocols.BGP, prefix1, [customer, r1, r3, provider2],
                    False)
    path5 = PathReq(Protocols.BGP, prefix1, [customer, r1, r2, r3, provider2],
                    False)
    path6 = PathReq(Protocols.BGP, prefix1, [r2, r1, r3, provider2], False)

    reqs = [
        PathOrderReq(Protocols.BGP, prefix1, [
            KConnectedPathsReq(Protocols.BGP, prefix1, [path1, path2, path3],
                               False),
            KConnectedPathsReq(Protocols.BGP, prefix1, [path4, path5, path6],
                               False),
        ], False),
        PathOrderReq(Protocols.OSPF, "dummy", [
            PathReq(Protocols.OSPF, "dummy", [r1, r2], False),
            PathReq(Protocols.OSPF, "dummy", [r1, r3, r2], False),
        ], False),
        PathOrderReq(Protocols.OSPF, "dummy", [
            PathReq(Protocols.OSPF, "dummy", [r1, r3], False),
            PathReq(Protocols.OSPF, "dummy", [r1, r2, r3], False),
        ], False),
    ]
    external_anns = [ann1, ann2, ann3]
    netcomplete = NetComplete(reqs=reqs,
                              topo=graph,
                              external_announcements=external_anns)
    netcomplete.synthesize()
    netcomplete.write_configs(output_dir=output_dir)