def test_to_ns2_directed(self): t = fnss.DirectedTopology() t.add_path([1,2,3,4]) fnss.set_capacities_constant(t, 10, 'Gbps') fnss.set_delays_constant(t, 2, 'us') fnss.set_buffer_sizes_constant(t, 20, 'packets') fnss.to_ns2(t, path.join(TMP_DIR,'ns2-dir.tcl'), stacks=False)
def test_clear_delays(self): topo = fnss.star_topology(12) fnss.set_delays_constant(topo, 1, 'ms', None) self.assertEqual(topo.number_of_edges(), len(nx.get_edge_attributes(topo, 'delay'))) fnss.clear_delays(topo) self.assertEqual(0, len(nx.get_edge_attributes(topo, 'delay')))
def nrr_topology(cls): """Return topology for testing NRR caching strategies """ # Topology sketch # # 0 ---- 2----- 4 # | \ # | s # | / # 1 ---- 3 ---- 5 # topology = IcnTopology(fnss.Topology()) nx.add_path(topology, [0, 2, 4, "s", 5, 3, 1]) topology.add_edge(2, 3) receivers = (0, 1) source = "s" caches = (2, 3, 4, 5) contents = (1, 2, 3, 4) fnss.add_stack(topology, source, 'source', {'contents': contents}) for v in caches: fnss.add_stack(topology, v, 'router', {'cache_size': 1}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) fnss.set_delays_constant(topology, 1, 'ms') return topology
def topology_path(n, delay=1, **kwargs): """Return a path topology with a receiver on node `0` and a source at node 'n-1' Parameters ---------- n : int (>=3) The number of nodes delay : float The link delay in milliseconds Returns ------- topology : IcnTopology The topology object """ topology = fnss.line_topology(n) receivers = [0] routers = range(1, n-1) sources = [n-1] topology.graph['icr_candidates'] = set(routers) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, delay, 'ms') # label links as internal or external for u, v in topology.edges_iter(): topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def test_to_omnetpp_directed(self): t = fnss.DirectedTopology() t.add_path([1, 2, 3, 4]) fnss.set_capacities_constant(t, 10, 'Gbps') fnss.set_delays_constant(t, 2, 'us') fnss.set_buffer_sizes_constant(t, 20, 'packets') fnss.to_omnetpp(t, path.join(TMP_DIR, 'omnetpp-dir.ned'))
def test_to_mininet(self): t = fnss.Topology() t.add_path([1, 2, 3, 4]) for n in (1, 4): t.node[n]['type'] = 'host' for n in (2, 3): t.node[n]['type'] = 'switch' fnss.set_capacities_constant(t, 10, 'Mbps') fnss.set_delays_constant(t, 10, 'ms') mn_topo = fnss.to_mininet(t, relabel_nodes=False) self.assertIsNotNone(mn_topo) hosts = mn_topo.hosts() switches = mn_topo.switches() for h in '1', '4': self.assertIn(h, hosts) for s in '2', '3': self.assertIn(s, switches) mn_topo = fnss.to_mininet(t, relabel_nodes=True) # Relabeling should be: # 1 -> h1 # 2 -> s1 # 3 -> s2 # 4 -> h2 self.assertIsNotNone(mn_topo) hosts = mn_topo.hosts() switches = mn_topo.switches() for h in 'h1', 'h2': self.assertIn(h, hosts) for s in 's1', 's2': self.assertIn(s, switches)
def topology_geant2(**kwargs): """Return a scenario based on GEANT topology. Differently from plain GEANT, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 53 nodes topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates the top 50% routers for betweenness centrality icr_candidates = routers[len(routers)//2:] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_fiveNode(**kwargs): """Return a scenario based on Five_Node topology. This functions the similar as the GEANT topology but with only 5 nodes All routers are given caches Sources are added on initilization in addition to the main network to all nodes with 2 connections Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 5 nodes topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'SixNode.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates all routers icr_candidates = routers # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def test_algorithms(self): t = algorithms.IcnTopology(fnss.line_topology(6)) t.graph['icr_candidates'] = set(t.nodes()) fnss.set_delays_constant(t, 1, 'ms') fnss.set_delays_constant(t, 3, 'ms', [(1, 2), (3, 4)]) clusters = algorithms.compute_clusters(t, 3) expected_clusters = [set([0, 1]), set([2, 3]), set([4, 5])] self.assertEqual(expected_clusters, clusters)
def test_buffer_sizes_bw_delay_prod_no_return_path(self): topo = fnss.DirectedTopology() topo.add_edge(1, 2, weight=1) topo.add_edge(1, 3, weight=1) topo.add_edge(3, 2, weight=1) fnss.set_capacities_constant(topo, 10) fnss.set_delays_constant(topo, 2) self.assertRaises(ValueError, fnss.set_buffer_sizes_bw_delay_prod, topo)
def generate_topo(n): topo = nx.powerlaw_cluster_graph(n,2,0.08) # topo = fnss.waxman_1_topology(n=50,alpha=0.6,beta=0.3) # topo = fnss.fat_tree_topology(n) fnss.set_weights_constant(topo,1) fnss.set_delays_constant(topo, 1, 'ms') fnss.set_capacities_edge_betweenness(topo,[100,500,1000],'Mbps') fnss.write_topology(topo,'topo_pl_50.xml')
def test_buffer_sizes_bw_delay_prod_unused_links(self): topo = fnss.Topology() topo.add_edge(1, 2, weight=100) topo.add_edge(2, 3, weight=1) topo.add_edge(3, 1, weight=1) fnss.set_capacities_constant(topo, 10) fnss.set_delays_constant(topo, 2) fnss.set_buffer_sizes_bw_delay_prod(topo) self.assertTrue(all((topo.adj[u][v]['buffer'] is not None for (u, v) in topo.edges())))
def setUpClass(cls): cls.topo = fnss.glp_topology(n=100, m=1, m0=10, p=0.2, beta=-2, seed=1) fnss.set_capacities_random_uniform(cls.topo, [10, 20, 40]) odd_links = [(u, v) for (u, v) in cls.topo.edges() if (u + v) % 2 == 1] even_links = [(u, v) for (u, v) in cls.topo.edges() if (u + v) % 2 == 0] fnss.set_delays_constant(cls.topo, 2, 'ms', odd_links) fnss.set_delays_constant(cls.topo, 5, 'ms', even_links) cls.capacities = [12, 25, 489, 1091]
def topology_garr2(**kwargs): """Return a scenario based on GARR topology. Differently from plain GARR, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # routers are all remaining nodes --> 27 caches routers = [n for n in topology.nodes_iter() if n not in receivers + sources] artificial_receivers = list(range(1000, 1000 + len(routers))) for i in range(len(routers)): topology.add_edge(routers[i], artificial_receivers[i]) receivers += artificial_receivers # Caches to nodes with degree > 3 (after adding artificial receivers) degree = nx.degree(topology) icr_candidates = [n for n in topology.nodes_iter() if degree[n] > 3.5] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def setUpClass(cls): # set up topology used for all traffic matrix tests cls.topo = fnss.k_ary_tree_topology(3, 4) cls.capacities = [10, 20] cls.odd_links = [(u, v) for (u, v) in cls.topo.edges_iter() if (u + v) % 2 == 1] cls.even_links = [(u, v) for (u, v) in cls.topo.edges_iter() if (u + v) % 2 == 0] fnss.set_capacities_random_uniform(cls.topo, cls.capacities) fnss.set_delays_constant(cls.topo, 3, 'ms', cls.odd_links) fnss.set_delays_constant(cls.topo, 12, 'ms', cls.even_links)
def test_delays_constant(self): topo = fnss.k_ary_tree_topology(3, 4) self.assertRaises(ValueError, fnss.set_delays_constant, topo, 2, 'Km') odd_links = [(u, v) for (u, v) in topo.edges_iter() if (u + v) % 2 == 1] even_links = [(u, v) for (u, v) in topo.edges_iter() if (u + v) % 2 == 0] fnss.set_delays_constant(topo, 2, 's', odd_links) fnss.set_delays_constant(topo, 5000000, 'us', even_links) self.assertEqual('s', topo.graph['delay_unit']) self.assertTrue(all(topo.edge[u][v]['delay'] in [2, 5] for (u, v) in topo.edges_iter()))
def topology_garr(network_cache=0.05, n_contents=100000, seed=None): """ Return a scenario based on GARR topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents+1), sources, seed=seed) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' cache_placement = uniform_cache_placement(topology, network_cache*n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology
def topology_geant(**kwargs): """Return a scenario based on GEANT topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes icr_candidates = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_four_child_tree(network_cache=0.05, n_contents=100000, seed=None): """ Returns a tree topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ h = 5 # depth of the tree topology = fnss.k_ary_tree_topology(4, h) topology.add_node(1365, depth=-1) topology.add_path([0, 1365]) receivers = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == h] sources = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == -1] caches = [v for v in topology.nodes_iter() if topology.node[v]['depth'] >= 0 and topology.node[v]['depth'] < h] # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents+1), sources, seed=seed) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) cache_placement = uniform_cache_placement(topology, network_cache*n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return topology
def setUpClass(cls): # set up topology used for all traffic matrix tests cls.G = fnss.glp_topology(n=50, m=1, m0=10, p=0.2, beta=-2, seed=1) fnss.set_capacities_random(cls.G, {10: 0.5, 20: 0.3, 40: 0.2}, capacity_unit='Mbps') fnss.set_delays_constant(cls.G, 2, delay_unit='ms') fnss.set_weights_inverse_capacity(cls.G) for node in [2, 4, 6]: fnss.add_stack(cls.G, node, 'tcp', {'protocol': 'cubic', 'rcvwnd': 1024}) for node in [2, 4]: fnss.add_application(cls.G, node, 'client', {'rate': 100, 'user-agent': 'fnss'}) fnss.add_application(cls.G, 2, 'server', {'port': 80, 'active': True, 'user-agent': 'fnss'})
def setUp(self): topo = cacheplacement.IcnTopology(fnss.line_topology(7)) receivers = [0] sources = [6] icr_candidates = [1, 2, 3, 4, 5] topo.graph['icr_candidates'] = set(icr_candidates) for router in icr_candidates: fnss.add_stack(topo, router, 'router') for src in sources: fnss.add_stack(topo, src, 'source') for rcv in receivers: fnss.add_stack(topo, rcv, 'receiver') fnss.set_delays_constant(topo, 2, 'ms') fnss.set_delays_constant(topo, 20, 'ms', [(2, 3)]) self.topo = topo
def test_to_mininet(self): t = fnss.Topology() t.add_path([1, 2, 3, 4]) for n in (1, 4): t.node[n]['type'] = 'host' for n in (2, 3): t.node[n]['type'] = 'switch' fnss.set_capacities_constant(t, 10, 'Mbps') fnss.set_delays_constant(t, 10, 'ms') mn_topo = fnss.to_mininet(t) self.assertIsNotNone(mn_topo) hosts = mn_topo.hosts() switches = mn_topo.switches() for h in '1', '4': self.assertIn(h, hosts) for s in '2', '3': self.assertIn(s, switches)
def topology_tandem(n=3,nc=0.01, **kwargs): T = 'TANDEM' # name of the topology topology = fnss.line_topology(n) topology = list(nx.connected_component_subgraphs(topology))[0] receivers = [0] routers = [1, 2] #sources = [2] source_attachment = routers[1]; source = source_attachment + 1000 topology.add_edge(source_attachment, source) sources = [source] topology.graph['icr_candidates'] = set(routers) fnss.add_stack(topology, source, 'source') #for v in sources: # fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' C = str(nc) fnss.write_topology(topology, path.join(TOPOLOGY_RESOURCES_DIR, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) return IcnTopology(topology)
def topology_path(network_cache=0.05, n_contents=100000, n=3, seed=None): """ Return a scenario based on path topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.line_topology(n) receivers = [0] caches = range(1, n-1) sources = [n-1] # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents+1), sources, seed=seed) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' cache_placement = uniform_cache_placement(topology, network_cache*n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology
def topology_garr(**kwargs): """Return a scenario based on GARR topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_wide(**kwargs): """Return a scenario based on WIDE topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'WideJpn.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [9, 8, 11, 13, 12, 15, 14, 17, 16, 19, 18] # receivers are internal nodes with degree = 1 receivers = [27, 28, 3, 5, 4, 7] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] # All routers can be upgraded to ICN functionalitirs icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def test_base_topology_class(self): weight = 2 capacity = 3 delay = 4 buffer_size = 5 topology = fnss.Topology() topology.add_path([1, 2, 3]) fnss.set_weights_constant(topology, weight) fnss.set_capacities_constant(topology, capacity) fnss.set_delays_constant(topology, delay) fnss.set_buffer_sizes_constant(topology, buffer_size) weights = topology.weights() capacities = topology.capacities() delays = topology.delays() buffer_sizes = topology.buffers() for e in topology.edges_iter(): self.assertEqual(weight, weights[e]) self.assertEqual(capacity, capacities[e]) self.assertEqual(delay, delays[e]) self.assertEqual(buffer_size, buffer_sizes[e])
def topology_tree(k, h, delay=1, **kwargs): """Returns a tree topology, with a source at the root, receivers at the leafs and caches at all intermediate nodes. Parameters ---------- h : height The height of the tree k : branching factor The branching factor of the tree delay : float The link delay in milliseconds Returns ------- topology : IcnTopology The topology object """ topology = fnss.k_ary_tree_topology(k, h) receivers = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == h] sources = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == 0] routers = [v for v in topology.nodes_iter() if topology.node[v]['depth'] > 0 and topology.node[v]['depth'] < h] topology.graph['icr_candidates'] = set(routers) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, delay, 'ms') # label links as internal for u, v in topology.edges_iter(): topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_binary_tree(**kwargs): """Returns a tree topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ h = 5 # depth of the tree topology = fnss.k_ary_tree_topology(2, h) receivers = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == h] sources = [v for v in topology.nodes_iter() if topology.node[v]['depth'] == 0] routers = [v for v in topology.nodes_iter() if topology.node[v]['depth'] > 0 and topology.node[v]['depth'] < h] topology.graph['icr_candidates'] = set(routers) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_path(n=3, **kwargs): """Return a scenario based on path topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.line_topology(n) receivers = [0] routers = range(1, n-1) sources = [n-1] topology.graph['icr_candidates'] = set(routers) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def scenario_geant(net_cache=[0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GEANT' # name of the topology # 240 nodes in the main component topology = fnss.parse_topology_zoo( path.join(scenarios_dir, 'resources/Geant2012.graphml')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes caches = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [ v for v in topology.nodes() if v not in caches + sources + receivers ] # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) for v in routers: fnss.add_stack(topology, v, 'router', {}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc) * n_contents) / len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology( topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule( event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
def topology_repo_mesh(n, m, delay_int=0.02, delay_ext=1, **kwargs): """Returns a ring topology This topology is comprised of a mesh of *n* nodes. Each of these nodes is attached to a receiver. In addition *m* router are attached each to a source. Therefore, this topology has in fact 2n + m nodes. Parameters ---------- n : int The number of routers in the ring m : int The number of sources delay_int : float The internal link delay in milliseconds delay_ext : float The external link delay in milliseconds Returns ------- topology : IcnTopology The topology object """ receiver_access_delay = 0.001 if m > n: raise ValueError("m cannot be greater than n") topology = fnss.full_mesh_topology(n) topology.sources_no = m topology.routers_no = n routers = range(n) receivers = ['rec_%d' % i for i in range(n)] sources = ['src_%d' % i for i in range(m)] internal_links = zip(routers, receivers) for u in routers: for v in routers: if v != u: internal_links.append(tuple([u, v])) external_links = zip(routers[:m], sources) for u, v in internal_links: topology.add_edge(u, v, type='internal') for u, v in external_links: topology.add_edge(u, v, type='external') topology.graph['icr_candidates'] = set(routers) n_sources = m print("The number of sources: " + repr(n_sources)) print("The number of receivers: " + repr(n)) topology.graph['receiver_access_delay'] = receiver_access_delay topology.graph['link_delay'] = delay_int for v in routers: fnss.add_stack(topology, v, 'router') if 'source' not in topology.node[v]['stack']: try: try: topology.node[v]['extra_types'].append('source') topology.node[v]['extra_types'].append('router') except Exception as e: err_type = str(type(e)).split("'")[1].split(".")[1] if err_type == "KeyError": topology.node[v].update(extra_types=['source']) topology.node[v]['extra_types'].append('router') except Exception as e: err_type = str(type(e)).split("'")[1].split(".")[1] if err_type == "KeyError": continue for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, delay_int, 'ms', internal_links) fnss.set_delays_constant(topology, delay_ext, 'ms', external_links) # label links as internal topology.graph['receivers'] = receivers topology.graph['sources'] = sources topology.graph['sources'].extend(routers) topology.graph['routers'] = routers topology.graph['edge_routers'] = routers return IcnTopology(topology)
# topology has a 'type' attribute which identifies whether it a link of the # core path or it is in a bell. # Look at dumbbell_topology documentation for more details. # this return a dictionary of egdes and value of attribute type # This function is provided by the NetworkX library. # Since FNSS Topology and DirecteedTopology objects inherit from NetworkX's # Graph and DiGraph, respectively, NetworkX functions can be used in FNSS too. link_types = nx.get_edge_attributes(topology, 'type') core_links = [links for links in link_types if link_types[links] == 'core'] edge_links = [links for links in link_types if link_types[links] == 'right_bell' or link_types[links] == 'left_bell'] # set delay equal to 1 ms in edge links and equal to 2 ms in core links fnss.set_delays_constant(topology, 1, 'ms', edge_links) fnss.set_delays_constant(topology, 2, 'ms', core_links) # set capacity of 10 Mbps in edge links and 40 Mbps in core links fnss.set_capacities_constant(topology, 10, 'Mbps', edge_links) fnss.set_capacities_constant(topology, 40, 'Mbps', core_links) # Now we deploy a traffic sources on right bell and traffic receivers on left # bell node_types = nx.get_node_attributes(topology, 'type') left_nodes = [nodes for nodes in node_types if node_types[nodes] == 'left_bell'] right_nodes = [nodes for nodes in node_types if node_types[nodes] == 'right_bell'] for node in left_nodes:
def scenario_tiscali(net_cache=[0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on Tiscali topology, parsed from RocketFuel dataset Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'TISCALI' # name of the topology # 240 nodes in the main component topology = fnss.parse_rocketfuel_isp_map( path.join(scenarios_dir, 'resources/3257.r0.cch')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) onedeg = [v for v in topology.nodes() if deg[v] == 1] # they are 80 # we select as caches nodes with highest degrees # we use as min degree 6 --> 36 nodes # If we changed min degrees, that would be the number of caches we would have: # Min degree N caches # 2 160 # 3 102 # 4 75 # 5 50 # 6 36 # 7 30 # 8 26 # 9 19 # 10 16 # 11 12 # 12 11 # 13 7 # 14 3 # 15 3 # 16 2 caches = [v for v in topology.nodes() if deg[v] >= 6] # 36 nodes # sources are node with degree 1 whose neighbor has degree at least equal to 5 # we assume that sources are nodes connected to a hub # they are 44 sources = [ v for v in onedeg if deg[list(topology.edge[v].keys())[0]] > 4.5 ] # they are # receivers are node with degree 1 whose neighbor has degree at most equal to 4 # we assume that receivers are nodes not well connected to the network # they are 36 receivers = [ v for v in onedeg if deg[list(topology.edge[v].keys())[0]] < 4.5 ] # we set router stacks because some strategies will fail if no stacks # are deployed routers = [ v for v in topology.nodes() if v not in caches + sources + receivers ] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) for v in routers: fnss.add_stack(topology, v, 'router', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc) * n_contents) / len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology( topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule( event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
# core path or it is in a bell. # Look at dumbbell_topology documentation for more details. # this return a dictionary of egdes and value of attribute type # This function is provided by the NetworkX library. # Since FNSS Topology and DirecteedTopology objects inherit from NetworkX's # Graph and DiGraph, respectively, NetworkX functions can be used in FNSS too. link_types = nx.get_edge_attributes(fnss_topo, 'type') core_links = [links for links in link_types if link_types[links] == 'core'] edge_links = [ links for links in link_types if link_types[links] == 'right_bell' or link_types[links] == 'left_bell' ] # set delay equal to 1 ms in edge links and equal to 2 ms in core links fnss.set_delays_constant(fnss_topo, 1, 'ms', edge_links) fnss.set_delays_constant(fnss_topo, 2, 'ms', core_links) # set capacity of 10 Mbps in edge links and 40 Mbps in core links fnss.set_capacities_constant(fnss_topo, 10, 'Mbps', edge_links) fnss.set_capacities_constant(fnss_topo, 40, 'Mbps', core_links) # Set buffer size constant to all interfaces fnss.set_buffer_sizes_constant(fnss_topo, 50, 'packets') # Now we deploy a traffic sources on right bell and traffic receivers on left # bell node_types = nx.get_node_attributes(fnss_topo, 'type') core_nodes = [nodes for nodes in node_types if node_types[nodes] == 'core'] left_nodes = [ nodes for nodes in node_types if node_types[nodes] == 'left_bell'
def scenario_garr(net_cache=[0.01, 0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GARR' # name of the topology topology = fnss.parse_topology_zoo( path.join(scenarios_dir, 'resources/Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [ 1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60 ] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc) * n_contents) / len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology( topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule( event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
# Import RocketFuel topology # Replace the filename with the actual location of the file you want to parse topology = fnss.parse_rocketfuel_isp_map("rocket-fuel-topo-file.cch") # add capacities capacities = [1, 10, 40] capacity_unit = 'Gbps' fnss.set_capacities_edge_betweenness(topology, capacities, capacity_unit, weighted=False) # add weights proportional to inverse of capacity fnss.set_weights_inverse_capacity(topology) # add constant link delays of 2 ms fnss.set_delays_constant(topology, 2, delay_unit='ms') # generate cyclostationary traffic matrix (period 7 days, 24 samples per day) tmc = fnss.sin_cyclostationary_traffic_matrix( topology, mean=0.5, # average flow in TM is 0,5 Gbps stddev=0.05, # this is the std among average flows of different OD pairs gamma=0.8, # gamma and log_psi are parameters for fitting the std of log_psi=-0.33, # volume fluctuations over time. Look at Nucci et al. paper delta=0.2, # traffic variation from period max and avg as fraction of average n=24, # number of samples per each period periods=7, # number of periods max_u=0.9, # max link utilization desired origin_nodes=None, # Specify origin and destination nodes. If None, destination_nodes=None # all nodes of the topology are both ) # origin and destination nodes of traffic
def topology_garr2(**kwargs): """Return a scenario based on GARR topology. Differently from plain GARR, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [ 1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60 ] # routers are all remaining nodes --> 27 caches routers = [ n for n in topology.nodes_iter() if n not in receivers + sources ] artificial_receivers = list(range(1000, 1000 + len(routers))) for i in range(len(routers)): topology.add_edge(routers[i], artificial_receivers[i]) receivers += artificial_receivers # Caches to nodes with degree > 3 (after adding artificial receivers) degree = nx.degree(topology) icr_candidates = [n for n in topology.nodes_iter() if degree[n] > 3.5] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_geant2(**kwargs): """Return a scenario based on GEANT topology. Differently from plain GEANT, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 53 nodes topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates the top 50% routers for betweenness centrality icr_candidates = routers[len(routers) // 2:] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
from mininet.link import TCLink from mininet.util import dumpNodeConnections from mininet.log import setLogLevel from mininet.node import RemoteController from mininet.cli import CLI # Create FNSS topology. Let's create a simple datacenter topology # This topology does not contain loops. If you want to use a topology with # loops or multiple paths in Mininet you need to use a custom controller. # More info here: # https://github.com/mininet/mininet/wiki/Introduction-to-Mininet#multipath-routing fnss_topo = fnss.two_tier_topology(n_core=1, n_edge=2, n_hosts=2) # Set link attributes fnss.set_capacities_constant(fnss_topo, 10, 'Mbps') fnss.set_delays_constant(fnss_topo, 2, 'ms') fnss.set_buffer_sizes_constant(fnss_topo, 50, 'packets') # Convert FNSS topology to Mininet # If argument relabel_nodes is set to False, node labels are not changed when # converting an FNSS topology to a Mininet one, except converting the type to # string (e.g. 1 -> '1'). If relabel_nodes is set to True (default option) # then nodes are label according to Mininet conventions, e.g. hosts are # prepended an h (e.g. 1 -> 'h1') and switches are prepended an s # (e.g. 2 -> 's2') mn_topo = fnss.to_mininet(fnss_topo, relabel_nodes=True) # Create a Mininet instance and start it # Use TCLink to implement links enables Linux Traffic Container (TC) for rate # limitation net = Mininet(topo=mn_topo, link=TCLink, controller=RemoteController)
def topology_tiscali2(**kwargs): """Return a scenario based on Tiscali topology, parsed from RocketFuel dataset Differently from plain Tiscali, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.parse_rocketfuel_isp_map(path.join(TOPOLOGY_RESOURCES_DIR, '3257.r0.cch') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] # degree of nodes deg = nx.degree(topology) # nodes with degree = 1 onedeg = [v for v in topology.nodes() if deg[v] == 1] # they are 80 # we select as caches nodes with highest degrees # we use as min degree 6 --> 36 nodes # If we changed min degrees, that would be the number of caches we would have: # Min degree N caches # 2 160 # 3 102 # 4 75 # 5 50 # 6 36 # 7 30 # 8 26 # 9 19 # 10 16 # 11 12 # 12 11 # 13 7 # 14 3 # 15 3 # 16 2 icr_candidates = [v for v in topology.nodes() if deg[v] >= 6] # 36 nodes # Add remove caches to adapt betweenness centrality of caches for i in [181, 208, 211, 220, 222, 250, 257]: icr_candidates.remove(i) icr_candidates.extend([232, 303, 326, 363, 378]) # sources are node with degree 1 whose neighbor has degree at least equal to 5 # we assume that sources are nodes connected to a hub # they are 44 sources = [v for v in onedeg if deg[list(topology.edge[v].keys())[0]] > 4.5] # they are # receivers are node with degree 1 whose neighbor has degree at most equal to 4 # we assume that receivers are nodes not well connected to the network # they are 36 receivers = [v for v in onedeg if deg[list(topology.edge[v].keys())[0]] < 4.5] # we set router stacks because some strategies will fail if no stacks # are deployed routers = [v for v in topology.nodes() if v not in sources + receivers] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)