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 = {}
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 = {}
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
def set_up_ns_ID(self): """ update the starting ID of NetworkNamespace Class According to instance_nbr """ instance_count = CFG.getint(DEFAULTSECT, 'controller_instance_number') NetworkNamespace.ID = NetworkNamespace.ID + 10 * instance_count
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, 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)
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
def start(self, phys_ports, nodecount=None): """ Start the fibbing network :param nodecount: Pre-allocate nodecount fibbing nodes """ # Create root node self.root = self.add_node(id='root', cls=RootRouter, start=False) self.root.lsdb.set_leader_watchdog(self) del self.nodes[self.root.id] # The root node should not originate LSA self.graph_thread.start() self.json_thread.start() # And map all physical ports to it ports = gen_physical_ports(phys_ports) for name, addr in ports: link = PhysicalLink(self.root, name, addr) self.root.add_physical_link(link) self.root.start() # Create additional nodes if requested if nodecount is None: nodecount = CFG.getint(DEFAULTSECT, 'initial_node_count') while nodecount > 0: self.add_node() nodecount -= 1
def __init__(self, client, *args, **kwargs): Cmd.__init__(self, *args, **kwargs) self.client = client def do_add(self, line=''): self.client.add(('192.168.14.1', '192.168.23.2', 1, '3.3.3.0/24')) self.client.add((None, '192.168.23.2', 1, '4.4.4.0/24')) self.client.add([(None, '192.168.23.2', 1, '5.5.5.0/24'), (None, '192.168.14.1', 1, '5.5.5.0/24')]) def do_remove(self, line=''): self.client.remove(('192.168.14.1', '192.168.23.2', '3.3.3.0/24')) self.client.remove((None, '192.168.23.2', '4.4.4.0/24')) self.client.remove([(None, '192.168.23.2', '5.5.5.0/24'), (None, '192.168.14.1', '5.5.5.0/24')]) def do_exit(self, line): return True if __name__ == '__main__': log.setLevel(logging.DEBUG) shapeshifter = ShapeshifterProxyTest() c = SJMPClient("localhost", CFG.getint(DEFAULTSECT, "json_port"), target=shapeshifter) fakenode = ProxyCloner(FakeNodeProxy, c) Thread(target=c.communicate, name='client').start() TestCLI(fakenode).cmdloop() c.stop()
class TestCLI(Cmd): Cmd.prompt = "> " def __init__(self, client, *args, **kwargs): Cmd.__init__(self, *args, **kwargs) self.client = client def do_add(self, line=""): self.client.add(("192.168.14.1", "192.168.23.2", 1, "3.3.3.0/24")) self.client.add((None, "192.168.23.2", 1, "4.4.4.0/24")) self.client.add([(None, "192.168.23.2", 1, "5.5.5.0/24"), (None, "192.168.14.1", 1, "5.5.5.0/24")]) def do_remove(self, line=""): self.client.remove(("192.168.14.1", "192.168.23.2", "3.3.3.0/24")) self.client.remove((None, "192.168.23.2", "4.4.4.0/24")) self.client.remove([(None, "192.168.23.2", "5.5.5.0/24"), (None, "192.168.14.1", "5.5.5.0/24")]) def do_exit(self, line): return True if __name__ == "__main__": log.setLevel(logging.DEBUG) shapeshifter = ShapeshifterProxyTest() c = SJMPClient("localhost", CFG.getint(DEFAULTSECT, "json_port"), target=shapeshifter) fakenode = ProxyCloner(FakeNodeProxy, c) Thread(target=c.communicate, name="client").start() TestCLI(fakenode).cmdloop() c.stop()