Example #1
0
 def solve(self, topo, requirement_dags):
     # a list of tuples with info on the node to be attracted,
     # the forwarding address, the cost to be set in the fake LSA,
     # and the respective destinations
     self.fake_ospf_lsas = []
     self.reqs = requirement_dags
     self.igp_graph = topo
     self.igp_paths = ShortestPath(self.igp_graph)
     # process input forwarding DAGs, one at the time
     for dest, dag in requirement_dags.iteritems():
         log.info('Solving DAG for dest %s', dest)
         self.dest, self.dag = dest, dag
         log.debug('Checking dest in dag')
         ssu.add_dest_to_graph(dest, dag)
         log.debug('Checking dest in igp graph')
         ssu.add_dest_to_graph(dest,
                               topo,
                               edges_src=dag.predecessors,
                               spt=self.igp_paths,
                               metric=self.new_edge_metric)
         ssu.complete_dag(dag,
                          topo,
                          dest,
                          self.igp_paths,
                          skip=self.reqs.keys())
         # Add temporarily the destination to the igp graph and/or req dags
         if not ssu.solvable(dag, topo):
             log.warning('Skipping requirement for dest: %s', dest)
             continue
         for node in dag:
             nhs = self.nhs_for(node, dest, dag)
             if not nhs:
                 continue
             for req_nh in nhs:
                 log.debug('Placing a fake node for %s->%s', node, req_nh)
                 for i in xrange(get_edge_multiplicity(dag, node, req_nh)):
                     self.fake_ospf_lsas.append(
                         ssu.LSA(node=node,
                                 nh=req_nh,
                                 cost=(-1 - i),
                                 dest=dest))
         # Check whether we need to include one more fake node to handle
         # the case where we create a new route from scratch.
         for p in dag.predecessors_iter(dest):
             if not is_fake(topo, p, dest):
                 continue
             log.debug(
                 '%s is a terminal node towards %s but had no prior '
                 'route to it! Adding a synthetic route', p, dest)
             self.fake_ospf_lsas.append(
                 ssu.GlobalLie(dest, self.new_edge_metric, p))
     return self.fake_ospf_lsas
Example #2
0
 def solve(self, graph, requirements):
     """Compute the augmented topology for a given graph and a set of
     requirements.
     :type graph: IGPGraph
     :type requirements: { dest: IGPGraph }
     :param requirements: the set of requirement DAG on a per dest. basis
     :return: list of fake LSAs"""
     self.reqs = requirements
     log.info('Preparing IGP graph')
     self.g = prepare_graph(graph, requirements)
     log.info('Computing SPT')
     self._p = ShortestPath(graph)
     lsa = []
     for dest, dag in requirements.iteritems():
         self.dest, self.dag = dest, dag
         self.ecmp.clear()
         log.info('Evaluating requirement %s', dest)
         log.info('Ensuring the consistency of the DAG')
         self.check_dest()
         ssu.complete_dag(self.dag,
                          self.g,
                          self.dest,
                          self._p,
                          skip=self.reqs.keys())
         log.info('Computing original and required next-hop sets')
         for n, node in self.nodes():
             node.forced_nhs = set(self.dag.successors(n))
             node.original_nhs = set(
                 [p[1] for p in self._p.default_path(n, self.dest)])
         if not ssu.solvable(self.dag, self.g):
             log.warning('Consistency check failed, skipping %s', dest)
             continue
         log.info('Placing initial fake nodes')
         self.place_fake_nodes()
         log.info('Initializing fake nodes')
         self.initialize_fake_nodes()
         log.info('Propagating initial lower bounds')
         self.propagate_lb()
         log.debug('Fake node bounds: %s',
                   [n for _, n in self.nodes() if n.has_any_fake_node()])
         log.info('Reducing the augmented topology')
         self.merge_fake_nodes()
         self.remove_redundant_fake_nodes()
         log.info('Generating LSAs')
         lsas = self.create_fake_lsa()
         log.info('Solved the DAG for destination %s with LSA set: %s',
                  self.dest, lsas)
         lsa.extend(lsas)
     return lsa
Example #3
0
 def solve(self, graph, requirements):
     """Compute the augmented topology for a given graph and a set of
     requirements.
     :type graph: IGPGraph
     :type requirements: { dest: IGPGraph }
     :param requirements: the set of requirement DAG on a per dest. basis
     :return: list of fake LSAs"""
     self.reqs = requirements
     log.info('Preparing IGP graph')
     self.g = prepare_graph(graph, requirements)
     log.info('Computing SPT')
     self._p = ShortestPath(graph)
     lsa = []
     for dest, dag in requirements.iteritems():
         self.dest, self.dag = dest, dag
         self.ecmp.clear()
         log.info('Evaluating requirement %s', dest)
         log.info('Ensuring the consistency of the DAG')
         self.check_dest()
         ssu.complete_dag(self.dag, self.g, self.dest, self._p,
                          skip=self.reqs.keys())
         log.info('Computing original and required next-hop sets')
         for n, node in self.nodes():
             node.forced_nhs = set(self.dag.successors(n))
             node.original_nhs = set([p[1] for p in
                                      self._p.default_path(n, self.dest)])
         if not ssu.solvable(self.dag, self.g):
             log.warning('Consistency check failed, skipping %s', dest)
             continue
         log.info('Placing initial fake nodes')
         self.place_fake_nodes()
         log.info('Initializing fake nodes')
         self.initialize_fake_nodes()
         log.info('Propagating initial lower bounds')
         self.propagate_lb()
         log.debug('Fake node bounds: %s',
                   [n for _, n in self.nodes() if n.has_any_fake_node()])
         log.info('Reducing the augmented topology')
         self.merge_fake_nodes()
         self.remove_redundant_fake_nodes()
         log.info('Generating LSAs')
         lsas = self.create_fake_lsa()
         log.info('Solved the DAG for destination %s with LSA set: %s',
                  self.dest, lsas)
         lsa.extend(lsas)
     return lsa
Example #4
0
 def solve(self, topo, requirement_dags):
     # a list of tuples with info on the node to be attracted,
     # the forwarding address, the cost to be set in the fake LSA,
     # and the respective destinations
     self.fake_ospf_lsas = []
     self.reqs = requirement_dags
     self.igp_graph = topo
     self.igp_paths = ShortestPath(self.igp_graph)
     # process input forwarding DAGs, one at the time
     for dest, dag in requirement_dags.iteritems():
         log.info('Solving DAG for dest %s', dest)
         self.dest, self.dag = dest, dag
         log.debug('Checking dest in dag')
         ssu.add_dest_to_graph(dest, dag)
         log.debug('Checking dest in igp graph')
         ssu.add_dest_to_graph(dest, topo,
                               edges_src=dag.predecessors,
                               spt=self.igp_paths,
                               metric=self.new_edge_metric)
         ssu.complete_dag(dag, topo, dest, self.igp_paths,
                          skip=self.reqs.keys())
         # Add temporarily the destination to the igp graph and/or req dags
         if not ssu.solvable(dag, topo):
             log.warning('Skipping requirement for dest: %s', dest)
             continue
         for node in dag:
             nhs = self.nhs_for(node, dest, dag)
             if not nhs:
                 continue
             for req_nh in nhs:
                 log.debug('Placing a fake node for %s->%s', node, req_nh)
                 for i in xrange(get_edge_multiplicity(dag, node, req_nh)):
                     self.fake_ospf_lsas.append(ssu.LSA(node=node,
                                                        nh=req_nh,
                                                        cost=(-1 - i),
                                                        dest=dest))
         # Check whether we need to include one more fake node to handle
         # the case where we create a new route from scratch.
         for p in dag.predecessors_iter(dest):
             if not is_fake(topo, p, dest):
                 continue
             log.debug('%s is a terminal node towards %s but had no prior '
                       'route to it! Adding a synthetic route', p, dest)
             self.fake_ospf_lsas.append(
                     ssu.GlobalLie(dest, self.new_edge_metric, p))
     return self.fake_ospf_lsas
Example #5
0
 def solve(self, topo, requirement_dags):
     # a list of tuples with info on the node to be attracted,
     # the forwarding address, the cost to be set in the fake LSA,
     # and the respective destinations
     self.fake_ospf_lsas = []
     self.reqs = requirement_dags
     self.igp_graph = topo
     self.igp_paths = ShortestPath(self.igp_graph)
     log.debug('Original SPT: %s', self.igp_paths)
     # process input forwarding DAGs, one at the time
     for dest, dag in requirement_dags.iteritems():
         log.debug('Solving DAG for dest %s', dest)
         self.dest, self.dag = dest, dag
         log.debug('Checking dest in dag')
         ssu.add_dest_to_graph(dest, dag)
         log.debug('Checking dest in igp graph')
         ssu.add_dest_to_graph(dest,
                               topo,
                               edges_src=dag.predecessors,
                               spt=self.igp_paths,
                               metric=self.new_edge_metric)
         ssu.complete_dag(dag,
                          topo,
                          dest,
                          self.igp_paths,
                          skip=self.reqs.keys())
         # Add temporarily the destination to the igp graph and/or req dags
         if not ssu.solvable(dag, topo):
             log.warning('Skipping requirement for dest: %s', dest)
             continue
         for node in nx.topological_sort(dag, reverse=True)[1:]:
             nhs, original_nhs = self.nhs_for(node, dag, dest)
             if not self.require_fake_node(nhs, original_nhs):
                 log.debug('%s does not require a fake node (%s - %s)',
                           node, nhs, original_nhs)
                 continue
             for req_nh in nhs:
                 log.debug('Placing a fake node for nh %s', req_nh)
                 self.fake_ospf_lsas.append(
                     ssu.LSA(node=node, nh=req_nh, cost=-1, dest=dest))
     return self.fake_ospf_lsas
Example #6
0
 def solve(self, topo, requirement_dags):
     # a list of tuples with info on the node to be attracted,
     # the forwarding address, the cost to be set in the fake LSA,
     # and the respective destinations
     self.fake_ospf_lsas = []
     self.reqs = requirement_dags
     self.igp_graph = topo
     self.igp_paths = ShortestPath(self.igp_graph)
     log.debug('Original SPT: %s', self.igp_paths)
     # process input forwarding DAGs, one at the time
     for dest, dag in requirement_dags.iteritems():
         log.debug('Solving DAG for dest %s', dest)
         self.dest, self.dag = dest, dag
         log.debug('Checking dest in dag')
         ssu.add_dest_to_graph(dest, dag)
         log.debug('Checking dest in igp graph')
         ssu.add_dest_to_graph(dest, topo,
                               edges_src=dag.predecessors,
                               spt=self.igp_paths,
                               metric=self.new_edge_metric)
         ssu.complete_dag(dag, topo, dest, self.igp_paths,
                          skip=self.reqs.keys())
         # Add temporarily the destination to the igp graph and/or req dags
         if not ssu.solvable(dag, topo):
             log.warning('Skipping requirement for dest: %s', dest)
             continue
         for node in nx.topological_sort(dag, reverse=True)[1:]:
             nhs, original_nhs = self.nhs_for(node, dag, dest)
             if not self.require_fake_node(nhs, original_nhs):
                 log.debug('%s does not require a fake node (%s - %s)',
                           node, nhs, original_nhs)
                 continue
             for req_nh in nhs:
                 log.debug('Placing a fake node for nh %s', req_nh)
                 self.fake_ospf_lsas.append(ssu.LSA(node=node,
                                                    nh=req_nh,
                                                    cost=-1,
                                                    dest=dest))
     return self.fake_ospf_lsas