3 # NEPI, a framework to manage network experiments
4 # Copyright (C) 2013 INRIA
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 as
8 # published by the Free Software Foundation;
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20 from __future__ import print_function
22 from nepi.execution.ec import ExperimentController
23 from nepi.execution.runner import ExperimentRunner
24 from nepi.util.netgraph import NetGraph, TopologyType
25 import nepi.data.processing.ccn.parser as ccn_parser
31 content_name = "ccnx:/test/bunny.ts"
35 repofile = os.path.join(
36 os.path.dirname(os.path.realpath(__file__)), "repoFile1.0.8.2")
38 def get_simulator(ec):
39 simulator = ec.filter_resources("linux::ns3::Simulation")
42 node = ec.register_resource("linux::Node")
43 ec.set(node, "hostname", "localhost")
45 simu = ec.register_resource("linux::ns3::Simulation")
46 ec.set(simu, "enableDump", True)
47 ec.set(simu, "StopTime", STOP_TIME)
48 ec.register_connection(simu, node)
53 def add_collector(ec, trace_name, subdir, newname = None):
54 collector = ec.register_resource("Collector")
55 ec.set(collector, "traceName", trace_name)
56 ec.set(collector, "subDir", subdir)
58 ec.set(collector, "rename", newname)
62 def add_dce_host(ec, nid):
63 simu = get_simulator(ec)
65 host = ec.register_resource("ns3::Node")
66 ec.set(host, "enableStack", True)
67 ec.register_connection(host, simu)
70 ec.netgraph.annotate_node(nid, "host", host)
72 def add_dce_ccnd(ec, nid):
73 # Retrieve annotation from netgraph
74 host = ec.netgraph.node_annotation(nid, "host")
76 # Add dce ccnd to the dce node
77 ccnd = ec.register_resource("linux::ns3::dce::CCND")
78 ec.set (ccnd, "stackSize", 1<<20)
79 ec.set (ccnd, "debug", 7)
80 ec.set (ccnd, "capacity", 50000)
81 ec.set (ccnd, "StartTime", "1s")
82 ec.register_connection(ccnd, host)
84 # Collector to retrieve ccnd log
85 collector = add_collector(ec, "stderr", nid, "log")
86 ec.register_connection(collector, ccnd)
89 ec.netgraph.annotate_node(nid, "ccnd", ccnd)
91 def add_dce_ccnr(ec, nid):
92 # Retrieve annotation from netgraph
93 host = ec.netgraph.node_annotation(nid, "host")
95 # Add a CCN content repository to the dce node
96 ccnr = ec.register_resource("linux::ns3::dce::CCNR")
97 ec.set (ccnr, "repoFile1", repofile)
98 ec.set (ccnr, "stackSize", 1<<20)
99 ec.set (ccnr, "StartTime", "2s")
100 ec.register_connection(ccnr, host)
102 def add_dce_ccncat(ec, nid):
103 # Retrieve annotation from netgraph
104 host = ec.netgraph.node_annotation(nid, "host")
106 # Add a ccncat application to the dce host
107 ccncat = ec.register_resource("linux::ns3::dce::CCNCat")
108 ec.set (ccncat, "contentName", content_name)
109 ec.set (ccncat, "stackSize", 1<<20)
110 ec.set (ccncat, "StartTime", "8s")
111 ec.register_connection(ccncat, host)
113 def add_dce_fib_entry(ec, nid1, nid2):
114 # Retrieve annotations from netgraph
115 host1 = ec.netgraph.node_annotation(nid1, "host")
116 net = ec.netgraph.edge_net_annotation(nid1, nid2)
119 # Add FIB entry between peer hosts
120 ccndc = ec.register_resource("linux::ns3::dce::FIBEntry")
121 ec.set (ccndc, "protocol", "udp")
122 ec.set (ccndc, "uri", "ccnx:/")
123 ec.set (ccndc, "host", ip2)
124 ec.set (ccndc, "stackSize", 1<<20)
125 ec.set (ccndc, "StartTime", "4s")
126 ec.register_connection(ccndc, host1)
128 def add_dce_net_iface(ec, nid1, nid2):
129 # Retrieve annotations from netgraph
130 host = ec.netgraph.node_annotation(nid1, "host")
131 net = ec.netgraph.edge_net_annotation(nid1, nid2)
133 prefix = net["prefix"]
135 dev = ec.register_resource("ns3::PointToPointNetDevice")
136 ec.set(dev,"DataRate", "5Mbps")
137 ec.set(dev, "ip", ip1)
138 ec.set(dev, "prefix", prefix)
139 ec.register_connection(host, dev)
141 queue = ec.register_resource("ns3::DropTailQueue")
142 ec.register_connection(dev, queue)
146 def avg_interests(ec, run):
148 logs_dir = ec.run_dir
152 interest_expiry_count,
153 interest_dupnonce_count,
155 content_count) = ccn_parser.process_content_history_logs(
157 ec.netgraph.topology)
159 shortest_path = networkx.shortest_path(graph,
160 source = ec.netgraph.sources()[0],
161 target = ec.netgraph.targets()[0])
163 ### Compute metric: Avg number of Interests seen per content name
164 ### normalized by the number of nodes in the shortest path
165 content_name_count = len(content_names)
166 nodes_in_shortest_path = len(shortest_path) - 1
167 metric = interest_count / (float(content_name_count) * float(nodes_in_shortest_path))
169 # TODO: DUMP RESULTS TO FILE
170 # TODO: DUMP GRAPH DELAYS!
171 with open("/tmp/metric", "a+") as f:
172 f.write("%.2f\n" % metric)
173 print(" METRIC", metric)
177 def add_dce_edge(ec, nid1, nid2):
178 ### Add network interfaces to hosts
179 p2p1 = add_dce_net_iface(ec, nid1, nid2)
180 p2p2 = add_dce_net_iface(ec, nid2, nid1)
182 # Create point to point link between interfaces
183 chan = ec.register_resource("ns3::PointToPointChannel")
184 ec.set(chan, "Delay", "0ms")
186 ec.register_connection(chan, p2p1)
187 ec.register_connection(chan, p2p2)
189 #### Add routing between CCN nodes
190 add_dce_fib_entry(ec, nid1, nid2)
191 add_dce_fib_entry(ec, nid2, nid1)
193 def add_dce_node(ec, nid):
194 ### Add CCN nodes (ec.netgraph holds the topology graph)
195 add_dce_host(ec, nid)
196 add_dce_ccnd(ec, nid)
198 if nid == ec.netgraph.targets()[0]:
199 add_dce_ccnr(ec, nid)
201 if nid == ec.netgraph.sources()[0]:
202 add_dce_ccncat(ec, nid)
204 if __name__ == '__main__':
206 #### Create NEPI Experiment Description with LINEAR topology
207 ec = ExperimentController("dce_ccn",
208 topo_type = TopologyType.LINEAR,
212 add_node_callback = add_dce_node,
213 add_edge_callback = add_dce_edge)
215 print("Results stored at", ec.exp_dir)
217 #### Retrieve the consumer to wait for ot to finish
218 ccncat = ec.filter_resources("linux::ns3::dce::CCNCat")
220 #### Run experiment until metric convergences
221 rnr = ExperimentRunner()
222 runs = rnr.run(ec, min_runs = 1, max_runs = 1,
223 compute_metric_callback = avg_interests,