Exemple #1
0
 def _setUpPaperGadget(self):
     # H1 -- 19 -- A1 ---------+
     #  |                      |
     #  +-- 10 ----+           2
     #             |           |
     #  H2 -- 2 -- X -- 100 -- Y
     #  |         / \          |
     #  6  H3 -- 2   \         |
     #  |   |        8         |
     #  |   6----+  /         17
     #  |        | /           |
     #  +--------A2------------+
     #
     self.paper_gadget = g = IGPGraph()
     self._add_edge(g, 'H1', 'A1', 19)
     self._add_edge(g, 'H1', 'X', 10)
     self._add_edge(g, 'A1', 'Y', 2)
     self._add_edge(g, 'X', 'Y', 100)
     self._add_edge(g, 'X', 'H2', 2)
     self._add_edge(g, 'X', 'H3', 2)
     self._add_edge(g, 'X', 'A2', 8)
     self._add_edge(g, 'H3', 'A2', 6)
     self._add_edge(g, 'H2', 'A2', 6)
     self._add_edge(g, 'Y', 'A2', 17)
     for _, data in g.nodes_iter(data=True):
         data['router'] = True
Exemple #2
0
 def _setUpDoubleDiamond(self):
     #  + --------19--------- +
     #  |                     |
     #  H1 ---10--- Y1        |
     #    \         |         |
     #    15        5         |
     #     \        |         |
     #     Y2 -10-  X --100-- D --1000-- 1/8
     #              |         |
     #     H2---2---+         |
     #     /                  |
     #    6                   |
     #   /                    |
     #  A -------- 17 --------+
     self.ddiamond = g = IGPGraph()
     self._add_edge(g, 'H1', 'D', metric=19)
     self._add_edge(g, 'H1', 'Y1', metric=10)
     self._add_edge(g, 'Y1', 'X', metric=5)
     self._add_edge(g, 'H1', 'Y2', metric=15)
     self._add_edge(g, 'Y2', 'X', metric=10)
     self._add_edge(g, 'A', 'H2', metric=6)
     self._add_edge(g, 'H2', 'X', metric=2)
     self._add_edge(g, 'A', 'D', metric=17)
     self._add_edge(g, 'X', 'D', metric=100)
     for _, data in g.nodes_iter(data=True):
         data['router'] = True
Exemple #3
0
 def testDoubleDiamond(self, expected_lsa_count=3):
     self.log_test_name()
     self._test(
         self.gadgets.ddiamond, {
             '1_8':
             IGPGraph([('H1', 'Y1'), ('H1', 'Y2'), ('Y1', 'X'), ('Y2', 'X'),
                       ('H2', 'X'), ('X', 'D')])
         }, expected_lsa_count)
Exemple #4
0
 def testPaperGadget(self):
     log.warning('Testing PaperGadget')
     self._test(
         self.gadgets.paper_gadget, {
             '3_8':
             IGPGraph([('H1', 'X'), ('H2', 'X'), ('H3', 'X'), ('X', 'Y'),
                       ('A1', 'Y'), ('A2', 'Y')])
         }, 1)
Exemple #5
0
 def testSquareWithThreeConsecutiveChanges(self):
     log.warning('Testing SquareWithThreeConsecutiveChanges')
     self._test(
         self.gadgets.square, {
             '3_8':
             IGPGraph([('D2', 'B1'), ('B1', 'T1'), ('T1', 'T2'),
                       ('T2', 'B2'), ('B2', 'D1')])
         }, 3)
Exemple #6
0
 def testDoubleDiamond(self):
     log.warning('Testing DoubleDiamond')
     self._test(
         self.gadgets.ddiamond, {
             '1_8':
             IGPGraph([('H1', 'Y1'), ('H1', 'Y2'), ('Y1', 'X'), ('Y2', 'X'),
                       ('H2', 'X'), ('X', 'D')])
         }, 3)
Exemple #7
0
 def testSquareWithThreeConsecutiveChanges(self, expected_lsa_count=3):
     self.log_test_name()
     self._test(
         self.gadgets.square, {
             '3_8':
             IGPGraph([('D2', 'B1'), ('B1', 'T1'), ('T1', 'T2'),
                       ('T2', 'B2'), ('B2', 'D1')])
         }, expected_lsa_count)
Exemple #8
0
 def testPaperGadget(self, expected_lsa_count=1):
     self.log_test_name()
     self._test(
         self.gadgets.paper_gadget, {
             '3_8':
             IGPGraph([('H1', 'X'), ('H2', 'X'), ('H3', 'X'), ('X', 'Y'),
                       ('A1', 'Y'), ('A2', 'Y')])
         }, expected_lsa_count)
Exemple #9
0
 def testDiamond(self, expected_lsa_count=2):
     self.log_test_name()
     self._test(
         self.gadgets.diamond, {
             '3_8':
             IGPGraph([('A', 'Y1'), ('A', 'Y2'), ('Y2', 'X'), ('Y1', 'X'),
                       ('X', 'D'), ('O', 'D')])
         }, expected_lsa_count)
Exemple #10
0
 def testDiamond(self):
     log.warning('Testing Diamond')
     self._test(
         self.gadgets.diamond, {
             '3_8':
             IGPGraph([('A', 'Y1'), ('A', 'Y2'), ('Y2', 'X'), ('Y1', 'X'),
                       ('X', 'D'), ('O', 'D')])
         }, 2)
    def simple_path_requirement(self, prefix, path):
        """Add a path requirement for the given prefix.

        :param path: The ordered list of routerid composing the path.
                     E.g. for path = [A, B, C], the following edges will be
                     used as requirements: [](A, B), (B, C), (C, D)]"""
        self.fwd_dags[prefix] = IGPGraph(
                [(s, d) for s, d in zip(path[:-1], path[1:])])
        self.refresh_lsas()
 def __init__(self, *args, **kwargs):
     super(SouthboundListener, self).__init__(*args, **kwargs)
     self.igp_graph = IGPGraph()
     self.dirty = False
     self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                   'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT, 'json_port'),
                                  target=self)
     self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)
Exemple #13
0
 def testParallel(self):
     log.warning('Testing Parallel')
     self._test(
         self.gadgets.parallel, {
             '3_8':
             IGPGraph([('A2', 'B2'), ('B2', 'C2'), ('C2', 'D2'),
                       ('D2', 'D1'), ('D1', 'C1'), ('C1', 'B1'),
                       ('B1', 'A1'), ('A1', 'D')])
         }, 4)
Exemple #14
0
 def testParallel(self, expected_lsa_count=4):
     self.log_test_name()
     self._test(
         self.gadgets.parallel, {
             '3_8':
             IGPGraph([('A2', 'B2'), ('B2', 'C2'), ('C2', 'D2'),
                       ('D2', 'D1'), ('D1', 'C1'), ('C1', 'B1'),
                       ('B1', 'A1'), ('A1', 'D')])
         }, expected_lsa_count)
Exemple #15
0
 def testSquareWithThreeConsecutiveChangesAndMultipleRequirements(
         self, expected_lsa_count=5):
     self.log_test_name()
     dag = IGPGraph([('D2', 'B1'), ('B1', 'T1'), ('T1', 'T2'), ('T2', 'B2'),
                     ('B2', 'D1')])
     self._test(self.gadgets.square, {
         '3_8': dag,
         '8_3': dag.reverse(copy=True)
     }, expected_lsa_count)
Exemple #16
0
 def testSquareWithThreeConsecutiveChangesAndMultipleRequirements(self):
     log.warning('Testing SquareWithThreeConsecutiveChanges'
                 'AndMultipleRequirements')
     dag = IGPGraph([('D2', 'B1'), ('B1', 'T1'), ('T1', 'T2'), ('T2', 'B2'),
                     ('B2', 'D1')])
     self._test(self.gadgets.square, {
         '3_8': dag,
         '8_3': dag.reverse(copy=True)
     }, 5)
Exemple #17
0
 def _setUpWeird(self):
     #     +-----D-----+
     #    /      |      \
     #   2       2       2
     #  /        |        \
     # A -- 4 -- B -- 2 -- C
     self.weird = g = IGPGraph()
     self._add_edge(g, 'A', 'B', 4)
     self._add_edge(g, 'B', 'C', 2)
     self._add_edge(g, 'D', 'C', 2)
     self._add_edge(g, 'D', 'B', 2)
     self._add_edge(g, 'D', 'A', 2)
Exemple #18
0
    def _setUpTrapezoid(self):
        #  R1 -- 100 -- E1 -- 10 -+
        #   |                     |
        #  100                    D
        #   |                     |
        #  R2 -- 10  -- E2 -- 10 -+

        self.trap = g = IGPGraph()
        self._add_edge(g, 'R1', 'E1', metric=100)
        self._add_edge(g, 'R1', 'R2', metric=100)
        self._add_edge(g, 'R2', 'E2', metric=10)
        self._add_edge(g, 'E1', 'D', metric=10)
        self._add_edge(g, 'E2', 'D', metric=10)
Exemple #19
0
 def _setUpWeird(self):
     #     +-----D-----+
     #    /      |      \
     #   2       2       2
     #  /        |        \
     # A -- 4 -- B -- 2 -- C
     self.weird = g = IGPGraph()
     self._add_edge(g, 'A', 'B', 4)
     self._add_edge(g, 'B', 'C', 2)
     self._add_edge(g, 'D', 'C', 2)
     self._add_edge(g, 'D', 'B', 2)
     self._add_edge(g, 'D', 'A', 2)
     for _, data in g.nodes_iter(data=True):
         data['router'] = True
Exemple #20
0
    def _setUpTrapezoid(self):
        #  R1 -- 100 -- E1 -- 10 -+
        #   |                     |
        #  100                    D
        #   |                     |
        #  R2 -- 10  -- E2 -- 10 -+

        self.trap = g = IGPGraph()
        self._add_edge(g, 'R1', 'E1', metric=100)
        self._add_edge(g, 'R1', 'R2', metric=100)
        self._add_edge(g, 'R2', 'E2', metric=10)
        self._add_edge(g, 'E1', 'D', metric=10)
        self._add_edge(g, 'E2', 'D', metric=10)
        for _, data in g.nodes_iter(data=True):
            data['router'] = True
Exemple #21
0
 def testTrapezoidWithEcmp(self, expected_lsa_count=3):
     self.log_test_name()
     self._test(
         self.gadgets.trap,
         {
             '2_8':
             IGPGraph([
                 ('R1', 'R2'),
                 ('R2', 'E2'),
                 ('E2', 'D'),
                 # ECMP on E1
                 ('E1', 'D'),
                 ('E1', 'R1')
             ])
         },
         expected_lsa_count)
Exemple #22
0
 def testTrapezoidWithEcmp(self):
     log.warning('Testing TrapezoidWithEcmp')
     self._test(
         self.gadgets.trap,
         {
             '2_8':
             IGPGraph([
                 ('R1', 'R2'),
                 ('R2', 'E2'),
                 ('E2', 'D'),
                 # ECMP on E1
                 ('E1', 'D'),
                 ('E1', 'R1')
             ])
         },
         3)
Exemple #23
0
 def _setUpParallelTracks(self):
     #    A2--B2--C2--D2
     #   /|   |   |   |
     #  D-A1--B1--C1--D1
     self.parallel = g = IGPGraph()
     self._add_edge(g, 'D', 'A1', 2)
     self._add_edge(g, 'D', 'A2', 2)
     self._add_edge(g, 'B2', 'A2', 2)
     self._add_edge(g, 'B1', 'A1', 2)
     self._add_edge(g, 'B1', 'C1', 2)
     self._add_edge(g, 'B2', 'C2', 2)
     self._add_edge(g, 'C2', 'D2', 2)
     self._add_edge(g, 'C1', 'D1', 2)
     self._add_edge(g, 'D2', 'D1', 2)
     self._add_edge(g, 'C2', 'C1', 2)
     self._add_edge(g, 'B2', 'B1', 2)
     self._add_edge(g, 'A2', 'A1', 2)
Exemple #24
0
 def _setUpSquare(self):
     self.square = g = IGPGraph()
     # T1  --10--  T2
     #  |    \       |
     #  10     5    100
     #  |        \   |
     #  B1  --3--   B2  --100--D1
     #  |
     # 100
     #  |
     #  D2
     self._add_edge(g, 'B1', 'B2', metric=3)
     self._add_edge(g, 'T1', 'B1', metric=10)
     self._add_edge(g, 'T2', 'T1', metric=10)
     self._add_edge(g, 'B2', 'T1', metric=5)
     self._add_edge(g, 'T2', 'B2', metric=100)
     self._add_edge(g, 'D1', 'B2', metric=100)
     self._add_edge(g, 'D2', 'B1', metric=100)
Exemple #25
0
 def __init__(self):
     self.BASE_NET = ip_network(CFG.get(DEFAULTSECT, 'base_net'))
     self.private_addresses = PrivateAddressStore(CFG.get(DEFAULTSECT,
                                                          'private_ips'))
     self.last_line = ''
     self.leader_watchdog = None
     self.transaction = False
     self.uncommitted_changes = 0
     self.graph = IGPGraph()
     self._lsdb = {NetworkLSA.TYPE: {},
                   RouterLSA.TYPE: {},
                   ASExtLSA.TYPE: {}}
     self.controllers = defaultdict(list)  # controller nr : ip_list
     self.listener = {}
     self.keep_running = True
     self.queue = Queue()
     self.processing_thread = start_daemon_thread(
             target=self.process_lsa, name='lsa processing thread')
Exemple #26
0
 def __init__(self):
     self.BASE_NET = ip_network(CFG.get(DEFAULTSECT, 'base_net'))
     self.private_addresses = PrivateAddressStore(
         CFG.get(DEFAULTSECT, 'private_ips'))
     self.last_line = ''
     self.leader_watchdog = None
     self.transaction = None
     self.graph = IGPGraph()
     self.routers = {}  # router-id : lsa
     self.networks = {}  # DR IP : lsa
     self.ext_networks = {}  # (router-id, dest) : lsa
     self.controllers = defaultdict(list)  # controller nr : ip_list
     self.listener = {}
     self.keep_running = True
     self.queue = Queue()
     self.processing_thread = Thread(target=self.process_lsa,
                                     name="lsa_processing_thread")
     self.processing_thread.setDaemon(True)
     self.processing_thread.start()
Exemple #27
0
    def build_graph(self):
        self.controllers.clear()
        new_graph = IGPGraph()
        # Rebuild the graph from the LSDB
        for lsa in chain(self.routers.itervalues(),
                         self.networks.itervalues(),
                         self.ext_networks.itervalues()):

            if is_expired_lsa(lsa):
                log.debug("LSA %s is too old (%d) ignoring it!",
                          lsa, lsa.age)
            else:
                lsa.apply(new_graph, self)
        # Contract all IPs to their respective router-id
        for rlsa in self.routers.itervalues():
            rlsa.contract_graph(new_graph,
                                self.private_addresses
                                .addresses_of(rlsa.routerid))
        # Figure out the controllers layout
        controller_prefix = CFG.getint(DEFAULTSECT, 'controller_prefixlen')
        # Group by controller and log them
        for ip in new_graph.nodes_iter():
            try:
                addr = ip_address(ip)
            except ValueError:
                continue  # Have a prefix
            if addr in self.BASE_NET:
                """1. Compute address diff to remove base_net
                   2. Right shift to remove host bits
                   3. Mask with controller mask"""
                cid = (((int(addr) - int(self.BASE_NET.network_address)) >>
                        self.BASE_NET.max_prefixlen - controller_prefix) &
                       ((1 << controller_prefix) - 1))
                self.controllers[cid].append(ip)
        # Contract them on the graph
        for id, ips in self.controllers.iteritems():
            cname = 'C_%s' % id
            new_graph.add_controller(cname)
            new_graph.contract(cname, ips)
        # Remove generated self loops
        new_graph.remove_edges_from(new_graph.selfloop_edges())
        self.apply_secondary_addresses(new_graph)
        return new_graph
Exemple #28
0
 def _setUpParallelTracks(self):
     #    A2--B2--C2--D2
     #   /|   |   |   |
     #  D-A1--B1--C1--D1
     self.parallel = g = IGPGraph()
     self._add_edge(g, 'D', 'A1', 2)
     self._add_edge(g, 'D', 'A2', 2)
     self._add_edge(g, 'B2', 'A2', 2)
     self._add_edge(g, 'B1', 'A1', 2)
     self._add_edge(g, 'B1', 'C1', 2)
     self._add_edge(g, 'B2', 'C2', 2)
     self._add_edge(g, 'C2', 'D2', 2)
     self._add_edge(g, 'C1', 'D1', 2)
     self._add_edge(g, 'D2', 'D1', 2)
     self._add_edge(g, 'C2', 'C1', 2)
     self._add_edge(g, 'B2', 'B1', 2)
     self._add_edge(g, 'A2', 'A1', 2)
     for _, data in g.nodes_iter(data=True):
         data['router'] = True
Exemple #29
0
 def commit_change(self):
     """
         @API
         commit the changes, and applied the requirements
         entered for the current session
     """
     for prefix in self.change_pfx:
         tmp = []
         if not self.simple_req[prefix]:
             self.remove_dag_requirement(prefix)
         else:
             for item in self.simple_req[prefix]:
                 for s, d in zip(item.path[:-1], item.path[1:]):
                     if (s, d) not in tmp:
                         tmp.append((s, d))
             LOG.debug('add_dag_requirement')
             self.add_dag_requirement(prefix, IGPGraph(tmp))
     del self.change_pfx[:]
     self.refresh_augmented_topo()
Exemple #30
0
 def _setUpDiamond(self):
     #  A  ---5---  Y1
     #  | \         |
     #  | 10        10
     #  |  \        |
     #  |  Y2 -15-- X ---50--- D
     #  |           |          |
     #  25 +--30----+          |
     #  | /                    |
     #  O -------- 10 ---------+
     self.diamond = g = IGPGraph()
     self._add_edge(g, 'A', 'Y1', metric=5)
     self._add_edge(g, 'Y1', 'X', metric=10)
     self._add_edge(g, 'A', 'Y2', metric=10)
     self._add_edge(g, 'Y2', 'X', metric=15)
     self._add_edge(g, 'X', 'D', metric=50)
     self._add_edge(g, 'A', 'O', metric=25)
     self._add_edge(g, 'X', 'O', metric=30)
     self._add_edge(g, 'D', 'O', metric=10)