Exemple #1
0
 def __init__(self):
     self.private_address_network = ip_network(CFG.get(DEFAULTSECT,
                                               'private_net'))
     try:
         with open(CFG.get(DEFAULTSECT, 'private_ips'), 'r') as f:
             self.private_address_binding = json.load(f)
             self.router_private_address = {}
             for subnets in self.private_address_binding.itervalues():
                 for rid, ip in subnets.iteritems():
                     try:
                         iplist = self.router_private_address[rid]
                     except KeyError:
                         iplist = self.router_private_address[rid] = []
                     iplist.append(ip)
     except Exception as e:
         log.error('Incorrect private IP addresses binding file')
         log.error(str(e))
         self.private_address_binding = {}
         self.router_private_address = {}
     self.last_line = ''
     self.transaction = None
     self.graph = DiGraph()
     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.start()
Exemple #2
0
 def __init__(self, instance_number):
     """
     :param instance_number: the controller instance number
     :param net: the subnet allocated for the fibbing nodes
     """
     self.leader = False
     self.instance = instance_number
     self.name = 'c%s' % instance_number
     self.nodes = {}
     self.bridge = Bridge('br0', self.name)
     self.root = None
     net = ip_network(CFG.get(DEFAULTSECT, 'base_net'))
     controller_prefix = CFG.getint(DEFAULTSECT, 'controller_prefixlen')
     host_prefix = net.max_prefixlen - controller_prefix
     controller_base = (int(net.network_address) +
                        (instance_number << host_prefix))
     controller_net = ip_address(controller_base)
     self.net = ip_network('%s/%s' % (controller_net, controller_prefix))
     self.graph_thread = Thread(target=self.infer_graph, name="Graph inference thread")
     self.json_proxy = SJMPServer(hostname=CFG.get(DEFAULTSECT, 'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT, 'json_port'),
                                  invoke=self.proxy_connected,
                                  target=FakeNodeProxyImplem(self))
     self.json_thread = Thread(target=self.json_proxy.communicate)
     # Used to assign unique router-id to each node
     self.next_id = 1
     self.links = []
     # The fibbing routes
     self.routes = {}
     self.route_mappings = {}
Exemple #3
0
 def __init__(self, instance_number):
     """
     :param instance_number: the controller instance number
     :param net: the subnet allocated for the fibbing nodes
     """
     self.leader = False
     self.instance = instance_number
     self.name = 'c%s' % instance_number
     self.nodes = {}
     self.bridge = Bridge('br0', self.name)
     self.root = None
     net = ip_network(CFG.get(DEFAULTSECT, 'base_net'))
     controller_prefix = CFG.getint(DEFAULTSECT, 'controller_prefixlen')
     host_prefix = net.max_prefixlen - controller_prefix
     controller_base = (int(net.network_address) +
                        (instance_number << host_prefix))
     controller_net = ip_address(controller_base)
     self.net = ip_network('%s/%s' % (controller_net, controller_prefix))
     self.graph_thread = daemon_thread(target=self.infer_graph,
                                       name="Graph inference thread")
     self.json_proxy = SJMPServer(hostname=CFG.get(DEFAULTSECT,
                                                   'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT,
                                                  'json_port'),
                                  invoke=self.proxy_connected,
                                  target=FakeNodeProxyImplem(self))
     self.json_thread = daemon_thread(target=self.json_proxy.communicate,
                                      name="JSON proxy thread")
     # Used to assign unique router-id to each node
     self.next_id = 1
     self.links = []
     # The fibbing routes
     self.routes = {}
     self.route_mappings = {}
Exemple #4
0
 def __init__(self, node, port_name, port_ip):
     """
     :param node: The node owning this link
     :param port_name: The name of the only port visible on this link
     :param port_ip: The IPV4Address of that link
     """
     section = port_name if CFG.has_section(port_name) else 'physical'
     self.src = Port(node, self, port_name, hello_int=CFG.get(section, 'hello_interval'),
                     dead_int=CFG.get(section, 'dead_interval'), area=CFG.get(section, 'area'),
                     cost=CFG.get(section, 'cost'))
     self.src.move_in_namespace()
     self.src.set_ip(port_ip)
Exemple #5
0
 def __init__(self, node, port_name, port_ip):
     """
     :param node: The node owning this link
     :param port_name: The name of the only port visible on this link
     :param port_ip: The IPV4Address of that link
     """
     section = port_name if CFG.has_section(port_name) else 'physical'
     self.src = Port(node, self, port_name, hello_int=CFG.get(section, 'hello_interval'),
                     dead_int=CFG.get(section, 'dead_interval'), area=CFG.get(section, 'area'),
                     cost=CFG.get(section, 'cost'))
     self.src.move_in_namespace()
     self.src.set_ip(port_ip)
     self.node = node
     self.name = port_name
Exemple #6
0
 def update_graph(self, new_graph):
     self.leader_watchdog.check_leader(self.get_leader())
     added_edges = new_graph.difference(self.graph)
     removed_edges = self.graph.difference(new_graph)
     node_prop_diff = {n: data
                       for n, data in new_graph.nodes_iter(data=True)
                       if n not in self.graph or
                       (data.viewitems() - self.graph.node[n].viewitems())}
     # Propagate differences
     if added_edges or removed_edges or node_prop_diff:
         log.debug('Pushing changes')
         for u, v in added_edges:
             self.for_all_listeners('add_edge', u, v,
                                    new_graph.export_edge_data(u, v))
         for u, v in removed_edges:
             self.for_all_listeners('remove_edge', u, v)
         if node_prop_diff:
             self.for_all_listeners('update_node_properties',
                                    **node_prop_diff)
         if CFG.getboolean(DEFAULTSECT, 'draw_graph'):
             new_graph.draw(CFG.get(DEFAULTSECT, 'graph_loc'))
         self.graph = new_graph
         log.info('LSA update yielded +%d -%d edges changes, '
                   '%d node property changes', len(added_edges),
                   len(removed_edges), len(node_prop_diff))
         self.for_all_listeners('commit')
Exemple #7
0
def gen_physical_ports(port_list):
    """
    Find all enabled physical interfaces of this
    :param port_list: The list of all physical ports that should be analyzed
    :return: A list of Tuple (interface name, ip address)
            for each active physical interface
    """
    ports = []
    for port_name in port_list:
        try:
            ip = ip_interface(CFG.get(port_name, 'ip'))
            ports.append((port_name, ip))
        except ConfigError:
            try:
                out = subprocess.check_output(['ip', 'a', 'show', port_name])
                for line in out.splitlines():
                    if 'inet ' in line:
                        line = line.strip(' \t\n')
                        port_addr = ip_interface(line.split(' ')[1])
                        log.debug('Added physical port %s@%s',
                                  port_name, port_addr)
                        ports.append((port_name, port_addr))
                        break
                        # TODO support multiple IP/interface?
            except subprocess.CalledProcessError as e:
                log.exception(e)
    return ports
Exemple #8
0
 def build_graph(self):
     new_graph = DiGraph()
     # Rebuild the graph from the LSDB
     for lsa in chain(self.routers.values(),
                      self.networks.values(),
                      self.ext_networks.values()):
         lsa.apply(new_graph, self)
     # Contract all IPs to their respective router-id
     for lsa in self.routers.values():
         lsa.contract_graph(new_graph, self.router_private_address.get(
             lsa.routerid, []))
     # Figure out the controllers layout
     base_net = ip_network(CFG.get(DEFAULTSECT, 'base_net'))
     controller_prefix = CFG.getint(DEFAULTSECT, 'controller_prefixlen')
     # Group by controller and log them
     for ip in new_graph.nodes_iter():
         addr = ip_address(ip)
         if addr in base_net:
             """1. Compute address diff to remove base_net
                2. Right shift to remove host bits
                3. Mask with controller mask
             """
             id = (((int(addr) - int(base_net.network_address)) >>
                    base_net.max_prefixlen - controller_prefix) &
                   ((1 << controller_prefix) - 1))
             self.controllers[id].append(ip)
     # Contract them on the graph
     for id, ips in self.controllers.iteritems():
         contract_graph(new_graph, ips, 'C_%s' % id)
     # Remove generated self loops
     new_graph.remove_edges_from(new_graph.selfloop_edges())
     self.apply_secondary_addresses(new_graph)
     return new_graph
Exemple #9
0
 def __init__(self, node, link, id=None, cost=CFG.get('fake', 'cost'), dead_int=CFG.get('fake', 'dead_interval'),
              hello_int=CFG.get('fake', 'hello_interval'), area=CFG.get('fake', 'area')):
     """
     :param node: The node owning this port
     :param link: The link in which this port belongs
     :param id: The id of this port, otherwise infer it from the node next available port number
     :param cost: The OSPF cost of that interface
     :param dead_int: The OSPF dead interval for that interface
     :param hello_int: The OSPF Hello interval
     """
     self.node = node
     self.link = link
     self.id = '%s-eth%s' % (node.id, node.get_next_port()) if not id else id
     self.ip_interface = None
     self.ospf_area = area
     self.ospf_cost = cost
     self.ospf_dead_int = dead_int
     self.ospf_hello_int = hello_int
Exemple #10
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 #11
0
 def __init__(self, node, link, id=None, cost=CFG.get('fake', 'cost'), dead_int=CFG.get('fake', 'dead_interval'),
              hello_int=CFG.get('fake', 'hello_interval'), area=CFG.get('fake', 'area')):
     """
     :param node: The node owning this port
     :param link: The link in which this port belongs
     :param id: The id of this port, otherwise infer it from the node next available port number
     :param cost: The OSPF cost of that interface
     :param dead_int: The OSPF dead interval for that interface
     :param hello_int: The OSPF Hello interval
     """
     self.node = node
     self.link = link
     self.id = '%s-eth%s' % (node.id, node.get_next_port()) if not id else id
     self.ip_interface = None
     self.ospf_area = area
     self.ospf_cost = cost
     self.ospf_dead_int = dead_int
     self.ospf_hello_int = hello_int
 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)
 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 #14
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 #15
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 #16
0
    def __init__(self, router, *args, **kwargs):
        super(MininetRouterConfig, self).__init__(router, *args, **kwargs)
        self.ospf.redistribute.connected = 1000
        self.ospf.redistribute.static = 1000
        self.ospf.router_id = router.id

        # Parse LSA throttling parameters
        delay = CFG.get("DEFAULT", 'delay')
        initial_holdtime = CFG.get("DEFAULT", 'initial_holdtime')
        max_holdtime = CFG.get("DEFAULT", 'max_holdtime')

        # Parse minimum LS intervals
        min_ls_interval = CFG.get("DEFAULT", 'min_ls_interval')
        min_ls_arrival = CFG.get("DEFAULT", 'min_ls_arrival')

        self.ospf.throttling = ConfigDict(spf=ConfigDict(delay=delay,
                                                         initial_holdtime=initial_holdtime,
                                                         max_holdtime=max_holdtime),
                                          lsa_all=ConfigDict(min_ls_interval=min_ls_interval))

        self.ospf.lsa = ConfigDict(min_ls_arrival=min_ls_arrival)
 def __init__(self, fwd_dags, optimizer, additional_routes=None):
     self.igp_graph = nx.DiGraph()
     self.dirty = False
     self.additional_routes = additional_routes
     self.optimizer = optimizer
     self.fwd_dags = fwd_dags
     self.current_lsas = set([])
     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 #18
0
 def __init__(self, address, metric, node):
     """
     :param address: The forwarding address to specify
                     for this attraction point
     :param metric: The metric of this attraction point
     :param node: The node advertizing this
     :return:
     """
     self._address = address
     self.metric = metric
     self.node = node
     self.advertized = False
     self.ttl = CFG.get(DEFAULTSECT, 'fake_lsa_ttl')
Exemple #19
0
def draw_graph(graph):
    try:
        layout = spring_layout(graph)
        metrics = {
            (src, dst): data['metric']
            for src, dst, data in graph.edges_iter(data=True)
        }
        draw_networkx_edge_labels(graph, layout, edge_labels=metrics)
        draw(graph, layout, node_size=20)
        draw_networkx_labels(graph, layout, labels={n: n for n in graph})
        output = CFG.get(DEFAULTSECT, 'graph_loc')
        if os.path.exists(output):
            os.unlink(output)
        plt.savefig(output)
        plt.close()
        log.debug('Graph of %d nodes saved in %s', len(graph), output)
    except:
        pass