Exemplo n.º 1
0
    def test_next_hop_ibgp(self):
        # Arrange
        graph, origin_ann = self.get_ibgp_topo()
        r1, r2, r3, r4 = 'R1', 'R2', 'R3', 'R4'
        prefix = origin_ann.prefix
        req1 = PathReq(Protocols.BGP, dst_net=prefix, path=[r2, r1], strict=False)
        req2 = PathReq(Protocols.BGP, dst_net=prefix, path=[r3, r1], strict=False)
        req3 = PathReq(Protocols.BGP, dst_net=prefix, path=[r4, r1], strict=False)
        netcomplete = NetComplete([req1, req2, req3], graph, [origin_ann])
        next_hop_vals = {
            'R1': '0.0.0.0',
            'R2': 'R1-lo100',
            'R3': 'R1-lo100',
            'R4': 'R1-lo100',
        }
        as_path_vals = {
            'R1': 'as_path_100_100',
            'R2': 'as_path_100_100',
            'R3': 'as_path_100_100',
            'R4': 'as_path_100_100',
        }
        as_path_len_vals = {
            'R1': 1,
            'R2': 1,
            'R3': 1,
            'R4': 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()), prefix)

                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(), origin_ann.med)

                self.assertTrue(ann.local_pref.is_concrete)
                self.assertEquals(ann.local_pref.get_value(), origin_ann.local_pref)

                for comm, val in ann.communities.iteritems():
                    self.assertTrue(val.is_concrete)
                    self.assertEquals(val.get_value(), origin_ann.communities[comm])
Exemplo n.º 2
0
 def test_not_empty(self):
     g = self.get_two_nodes()
     prefix = 'P0'
     reqs = [PathReq(Protocols.BGP, prefix, ['R1', 'R2'], False)]
     static_syn = StaticSyn(reqs, g)
     with self.assertRaises(CannotSynthesizeStaticRoute):
         static_syn.synthesize()
Exemplo n.º 3
0
 def test_two_existing(self):
     g = self.get_two_nodes()
     prefix = 'P0'
     reqs = [PathReq(Protocols.BGP, prefix, ['R1', 'R2'], False)]
     g.add_static_route('R1', prefix, 'R2')
     static_syn = StaticSyn(reqs, g)
     static_syn.synthesize()
     self.assertEquals(g.get_static_routes('R1')[prefix], 'R2')
Exemplo n.º 4
0
def read_reqs(req_file):
    with open(req_file) as f:
        s = f.read()
    parsed = parse_inputs(s)
    nets = {}
    for line in parsed:
        op, predicate, values = line
        assert op == '+', op
        assert predicate == 'Fwd', predicate
        net = values[0]
        protocol = values[-1]
        src, dst = values[1:-1]
        if net not in nets:
            nets[net] = {}
        if protocol not in nets[net]:
            nets[net][protocol] = []
        paths = nets[net][protocol]
        appened = False
        for path in paths:
            assert isinstance(path, list)
            if path[-1] == src:
                path.append(dst)
                appened = True
            elif path[0] == dst:
                path.insert(0, src)
                appened = True
        if not appened:
            paths.append([src, dst])

    proto_map = {
        'ospf': Protocols.OSPF,
        'static': Protocols.Static,
        'bgp': Protocols.BGP
    }
    ospf_reqs = []
    static_reqs = []
    bgp_reqs = []
    for net in nets:
        for protocol in nets[net]:
            paths = nets[net][protocol]
            proto = proto_map[protocol]
            for path in paths:
                req = PathReq(protocol=proto,
                              dst_net=net,
                              path=path,
                              strict=False)
                if proto == Protocols.OSPF:
                    ospf_reqs.append(req)
                elif proto == Protocols.Static:
                    static_reqs.append(req)
                elif proto == Protocols.BGP:
                    bgp_reqs.append(req)
                else:
                    raise ValueError("Unknown protocol")

    return static_reqs, ospf_reqs, bgp_reqs
Exemplo n.º 5
0
 def get_3path_req():
     p1 = ['R1', 'R4']
     p2 = ['R1', 'R2', 'R3', 'R4']
     p3 = ['R1', 'R3', 'R4']
     paths = [p1, p2, p3]
     reqs = []
     for path in paths:
         req = PathReq(Protocols.OSPF, path[-1], path, False)
         reqs.append(req)
     return reqs
Exemplo n.º 6
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)
Exemplo n.º 7
0
def generate_simple_reqs(topo, reqsize, rand):
    """Generate reqsize of PathReq"""
    paths = get_reqs(graph=topo, reqsize=reqsize, k=1, rand=rand)
    reqs = []
    for plist in paths.values():
        assert len(plist) >= 1
        path = plist[0]
        req = PathReq(Protocols.OSPF, path[-1], path, False)
        reqs.append(req)
    return reqs
Exemplo n.º 8
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)
Exemplo n.º 9
0
def generate_ecmp_reqs(topo, reqsize, ecmp, rand):
    """Generate reqsize of ECMPPathsReq each has ecmp paths"""
    paths = get_reqs(graph=topo, reqsize=reqsize, k=ecmp, rand=rand)
    reqs = []
    for plist in paths.values():
        assert len(plist) >= ecmp
        req = ECMPPathsReq(Protocols.OSPF, plist[0][-1], [
            PathReq(Protocols.OSPF, path[-1], path, False)
            for path in plist[:ecmp]
        ], False)
        reqs.append(req)
    return reqs
Exemplo n.º 10
0
    def test_grid_one_peer(self):
        anns = self.get_announcements(1, 1)
        g = gen_mesh(4, 100)
        self.get_add_one_peer(g, ['R2'], anns.values())

        ann = anns.values()[0]
        reqs = [
            PathReq(Protocols.BGP, ann.prefix, ['ATT', 'R2'], False),
            PathReq(Protocols.BGP, ann.prefix, ['ATT', 'R2', 'R1'], False),
            PathReq(Protocols.BGP, ann.prefix, ['ATT', 'R2', 'R3'], False),
            PathReq(Protocols.BGP, ann.prefix, ['ATT', 'R2', 'R4'], False),
        ]

        # Set Iface for R2 to ATT
        iface = 'Fa0/0'
        g.add_iface('R2', iface, is_shutdown=False)
        g.set_iface_addr('R2', iface, VALUENOTSET)
        g.set_edge_iface('R2', 'ATT', iface)
        g.set_iface_description('R2', iface, '' "To {}" ''.format('ATT'))

        p = ConnectedSyn(reqs, g)
        p.synthesize()
Exemplo n.º 11
0
 def test_ecmp_full(self):
     fan_out = 4
     network_graph = self.get_triangles(fan_out)
     source = 'source'
     sink = 'sink'
     p1 = [source, 'R1', sink]
     p2 = [source, 'R2', sink]
     path1 = PathReq(Protocols.OSPF, 'Google', p1, False)
     path2 = PathReq(Protocols.OSPF, 'Google', p2, False)
     ecmp_req = ECMPPathsReq(Protocols.OSPF, 'Google', [path1, path2],
                             False)
     ospf = synet.synthesis.ospf.OSPFSyn(network_graph)
     ospf.add_req(ecmp_req)
     ret = ospf.solve()
     self.assertTrue(ret)
     ospf.update_network_graph()
     ecmp = [
         tuple(p) for p in nx.all_shortest_paths(network_graph, source,
                                                 sink, 'ospf_cost')
     ]
     ecmp = set(ecmp)
     self.assertEquals(ecmp, set([tuple(p1), tuple(p2)]))
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    def test_one_extra(self):
        g = self.get_two_nodes()
        g.add_router('R3')
        g.add_router_edge('R1', 'R3')
        g.add_router_edge('R2', 'R3')
        g.add_router_edge('R3', 'R1')
        g.add_router_edge('R3', 'R2')

        reqs = [PathReq(Protocols.BGP, 'Prefix', ['R1', 'R2'], False)]

        # Set Iface for R1 to R3
        iface1 = 'Fa0/0'
        addr1 = ip_interface(u"192.168.0.1/24")
        g.add_iface('R1', iface1, is_shutdown=False)
        g.set_iface_addr('R1', iface1, addr1)
        g.set_edge_iface('R1', 'R3', iface1)
        g.set_iface_description('R1', iface1, '' "To {}" ''.format('R3'))

        # Set Iface for R3 to R1
        iface2 = 'Fa0/0'
        addr2 = ip_interface(u"192.168.0.2/24")
        g.add_iface('R3', iface2, is_shutdown=False)
        g.set_iface_addr('R3', iface2, addr2)
        g.set_edge_iface('R3', 'R1', iface2)
        g.set_iface_description('R3', iface2, '' "To {}" ''.format('R1'))

        # Set Iface for R2 to R3
        iface3 = 'Fa0/0'
        addr3 = ip_interface(u"192.168.1.1/24")
        g.add_iface('R2', iface3, is_shutdown=True)
        g.set_iface_addr('R2', iface3, addr3)
        g.set_edge_iface('R2', 'R3', iface3)
        g.set_iface_description('R2', iface3, '' "To {}" ''.format('R3'))

        # Set Iface for R3 to R2
        iface4 = 'Fa0/1'
        addr4 = ip_interface(u"192.168.2.2/24")
        g.add_iface('R3', iface4, is_shutdown=True)
        g.set_iface_addr('R3', iface4, addr4)
        g.set_edge_iface('R3', 'R2', iface4)
        g.set_iface_description('R3', iface4, '' "To {}" ''.format('R1'))

        p = ConnectedSyn(reqs, g)
        p.synthesize()
        self.assertTrue(g.has_edge('R1', 'R2'))
        self.assertTrue(g.has_edge('R1', 'R3'))
        self.assertTrue(g.has_edge('R2', 'R1'))
        self.assertFalse(g.has_edge('R2', 'R3'))
        self.assertTrue(g.has_edge('R3', 'R1'))
        self.assertFalse(g.has_edge('R3', 'R2'))
Exemplo n.º 14
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)
Exemplo n.º 15
0
 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)
Exemplo n.º 16
0
    def test_one_side_concrete(self):
        g = self.get_two_nodes()
        reqs = [PathReq(Protocols.BGP, 'Prefix', ['R1', 'R2'], False)]

        addr1 = ip_interface(u"192.168.0.1/24")
        # Set Iface for R1 to R2
        iface = 'Fa0/0'
        g.add_iface('R1', iface, is_shutdown=False)
        g.set_iface_addr('R1', iface, addr1)
        g.set_edge_iface('R1', 'R2', iface)
        g.set_iface_description('R1', iface, '' "To {}" ''.format('R2'))

        # Set Iface for R2 to R1
        iface = 'Fa0/0'
        g.add_iface('R2', iface, is_shutdown=False)
        g.set_iface_addr('R2', iface, VALUENOTSET)
        g.set_edge_iface('R2', 'R1', iface)
        g.set_iface_description('R2', iface, '' "To {}" ''.format('R1'))

        p = ConnectedSyn(reqs, g)
        p.synthesize()
        self.assertNotEqual(g.get_iface_addr('R2', iface), VALUENOTSET)
Exemplo n.º 17
0
 def test_ospf_enabled(self):
     # Arrange
     configs1 = NetCompleteConfigs(auto_enable_ospf_process=False)
     configs2 = NetCompleteConfigs(auto_enable_ospf_process=True)
     graph1 = get_ibgp_linear_topo(2)
     graph2 = get_ibgp_linear_topo(2)
     graph2.enable_ospf('R1', 100)
     # graph2.enable_ospf('R2', 100)
     graph2.add_ospf_network('R1', 'prefix', 0)
     reqs = [PathReq(Protocols.OSPF, 'prefix', ['R2', 'R1'], False)]
     # Act
     synthesizer1 = NetComplete(reqs=reqs,
                                topo=graph1,
                                external_announcements=[],
                                netcompplete_config=configs1)
     synthesizer2 = NetComplete(reqs=reqs,
                                topo=graph2,
                                external_announcements=[],
                                netcompplete_config=configs2)
     ret2 = synthesizer2.synthesize()
     # Assert
     self.assertRaises(SketchError, synthesizer1.synthesize)
     self.assertTrue(ret2)
Exemplo n.º 18
0
 def generate_paths(self, g, reqsize):
     """
     Generate a random set of path requirements that are guaranteed
     to be satisfiable
     :param g: Network topology
     :param reqsize: the number of required path
     :return: list of PathReq
     """
     routers = [n for n in g.local_routers_iter()]
     paths = []
     # Generate the required paths
     for i in range(0, reqsize):
         src, dst = self.random.sample(routers, 2)
         assert src != dst
         path = random_requirement_path(g,
                                        src,
                                        dst,
                                        random_obj=self.random,
                                        tmp_weight_name='test-weight')
         paths.append(path)
     reqs = []
     for path in paths:
         reqs.append(PathReq(Protocols.OSPF, path[-1], path, False))
     return reqs
Exemplo n.º 19
0
    def test_wrong_subnets(self):
        g = self.get_two_nodes()
        reqs = [PathReq(Protocols.BGP, 'Prefix', ['R1', 'R2'], False)]

        addr1 = ip_interface(u"192.168.0.1/24")
        addr2 = ip_interface(u"192.168.0.2/25")

        # Set Iface for R1 to R2
        iface = 'Fa0/0'
        g.add_iface('R1', iface, is_shutdown=False)
        g.set_iface_addr('R1', iface, addr1)
        g.set_edge_iface('R1', 'R2', iface)
        g.set_iface_description('R1', iface, '' "To {}" ''.format('R2'))

        # Set Iface for R2 to R1
        iface = 'Fa0/0'
        g.add_iface('R2', iface, is_shutdown=False)
        g.set_iface_addr('R2', iface, addr2)
        g.set_edge_iface('R2', 'R1', iface)
        g.set_iface_description('R2', iface, '' "To {}" ''.format('R1'))

        p = ConnectedSyn(reqs, g)
        with self.assertRaises(NotValidSubnetsError):
            p.synthesize()
Exemplo n.º 20
0
    def test_kconnected_ebgp(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
        graph.add_bgp_advertise(node=provider1, announcement=ann1, loopback='lo10')
        graph.add_bgp_advertise(node=provider2, announcement=ann2, loopback='lo10')

        rline = RouteMapLine(matches=[], actions=[], access=Access.deny, lineno=100)
        rmap_export = RouteMap(name='DenyExport', lines=[rline])
        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)

        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 = KConnectedPathsReq(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)
                    self.assertFalse(val.get_value())
Exemplo n.º 21
0
 def get_1path_req():
     p1 = ['R1', 'R2', 'R3', 'R4']
     req = PathReq(Protocols.OSPF, p1[-1], p1, False)
     return [req]
Exemplo n.º 22
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')
Exemplo n.º 23
0
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)
Exemplo n.º 24
0
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
Exemplo n.º 25
0
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))
Exemplo n.º 26
0
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)
Exemplo n.º 27
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
Exemplo n.º 28
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()
Exemplo n.º 29
0
    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)
Exemplo n.º 30
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)