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 nepi.execution.ec import ExperimentController
21 from nepi.execution.runner import ExperimentRunner
22 from nepi.util.netgraph import NetGraph, TopologyType
23 import nepi.data.processing.ccn.parser as ccn_parser
29 content_name = "ccnx:/test/bunny.ts"
33 repofile = os.path.join(
34 os.path.dirname(os.path.realpath(__file__)), "repoFile1.0.8.2")
36 def get_simulator(ec):
37 simulator = ec.filter_resources("linux::ns3::Simulation")
40 node = ec.register_resource("linux::Node")
41 ec.set(node, "hostname", "localhost")
43 simu = ec.register_resource("linux::ns3::Simulation")
44 ec.set(simu, "enableDump", True)
45 ec.set(simu, "StopTime", STOP_TIME)
46 ec.register_connection(simu, node)
51 def add_collector(ec, trace_name, subdir, newname = None):
52 collector = ec.register_resource("Collector")
53 ec.set(collector, "traceName", trace_name)
54 ec.set(collector, "subDir", subdir)
56 ec.set(collector, "rename", newname)
60 def add_dce_host(ec, nid):
61 simu = get_simulator(ec)
63 host = ec.register_resource("ns3::Node")
64 ec.set(host, "enableStack", True)
65 ec.register_connection(host, simu)
68 ec.netgraph.annotate_node(nid, "host", host)
70 def add_dce_ccnd(ec, nid):
71 # Retrieve annotation from netgraph
72 host = ec.netgraph.node_annotation(nid, "host")
74 # Add dce ccnd to the dce node
75 ccnd = ec.register_resource("linux::ns3::dce::CCND")
76 ec.set (ccnd, "stackSize", 1<<20)
77 ec.set (ccnd, "debug", 7)
78 ec.set (ccnd, "capacity", 50000)
79 ec.set (ccnd, "StartTime", "1s")
80 ec.register_connection(ccnd, host)
82 # Collector to retrieve ccnd log
83 collector = add_collector(ec, "stderr", nid, "log")
84 ec.register_connection(collector, ccnd)
87 ec.netgraph.annotate_node(nid, "ccnd", ccnd)
89 def add_dce_ccnr(ec, nid):
90 # Retrieve annotation from netgraph
91 host = ec.netgraph.node_annotation(nid, "host")
93 # Add a CCN content repository to the dce node
94 ccnr = ec.register_resource("linux::ns3::dce::CCNR")
95 ec.set (ccnr, "repoFile1", repofile)
96 ec.set (ccnr, "stackSize", 1<<20)
97 ec.set (ccnr, "StartTime", "2s")
98 ec.register_connection(ccnr, host)
100 def add_dce_ccncat(ec, nid):
101 # Retrieve annotation from netgraph
102 host = ec.netgraph.node_annotation(nid, "host")
104 # Add a ccncat application to the dce host
105 ccncat = ec.register_resource("linux::ns3::dce::CCNCat")
106 ec.set (ccncat, "contentName", content_name)
107 ec.set (ccncat, "stackSize", 1<<20)
108 ec.set (ccncat, "StartTime", "8s")
109 ec.register_connection(ccncat, host)
111 def add_dce_fib_entry(ec, nid1, nid2):
112 # Retrieve annotations from netgraph
113 host1 = ec.netgraph.node_annotation(nid1, "host")
114 net = ec.netgraph.edge_net_annotation(nid1, nid2)
117 # Add FIB entry between peer hosts
118 ccndc = ec.register_resource("linux::ns3::dce::FIBEntry")
119 ec.set (ccndc, "protocol", "udp")
120 ec.set (ccndc, "uri", "ccnx:/")
121 ec.set (ccndc, "host", ip2)
122 ec.set (ccndc, "stackSize", 1<<20)
123 ec.set (ccndc, "StartTime", "4s")
124 ec.register_connection(ccndc, host1)
126 def add_dce_net_iface(ec, nid1, nid2):
127 # Retrieve annotations from netgraph
128 host = ec.netgraph.node_annotation(nid1, "host")
129 net = ec.netgraph.edge_net_annotation(nid1, nid2)
131 prefix = net["prefix"]
133 dev = ec.register_resource("ns3::PointToPointNetDevice")
134 ec.set(dev,"DataRate", "5Mbps")
135 ec.set(dev, "ip", ip1)
136 ec.set(dev, "prefix", prefix)
137 ec.register_connection(host, dev)
139 queue = ec.register_resource("ns3::DropTailQueue")
140 ec.register_connection(dev, queue)
144 def avg_interests(ec, run):
146 logs_dir = ec.run_dir
150 interest_expiry_count,
151 interest_dupnonce_count,
153 content_count) = ccn_parser.process_content_history_logs(
155 ec.netgraph.topology)
157 shortest_path = networkx.shortest_path(graph,
158 source = ec.netgraph.sources()[0],
159 target = ec.netgraph.targets()[0])
161 ### Compute metric: Avg number of Interests seen per content name
162 ### normalized by the number of nodes in the shortest path
163 content_name_count = len(content_names.values())
164 nodes_in_shortest_path = len(shortest_path) - 1
165 metric = interest_count / (float(content_name_count) * float(nodes_in_shortest_path))
167 # TODO: DUMP RESULTS TO FILE
168 # TODO: DUMP GRAPH DELAYS!
169 f = open("/tmp/metric", "a+")
170 f.write("%.2f\n" % metric)
172 print " METRIC", metric
176 def add_dce_edge(ec, nid1, nid2):
177 ### Add network interfaces to hosts
178 p2p1 = add_dce_net_iface(ec, nid1, nid2)
179 p2p2 = add_dce_net_iface(ec, nid2, nid1)
181 # Create point to point link between interfaces
182 chan = ec.register_resource("ns3::PointToPointChannel")
183 ec.set(chan, "Delay", "0ms")
185 ec.register_connection(chan, p2p1)
186 ec.register_connection(chan, p2p2)
188 #### Add routing between CCN nodes
189 add_dce_fib_entry(ec, nid1, nid2)
190 add_dce_fib_entry(ec, nid2, nid1)
192 def add_dce_node(ec, nid):
193 ### Add CCN nodes (ec.netgraph holds the topology graph)
194 add_dce_host(ec, nid)
195 add_dce_ccnd(ec, nid)
197 if nid == ec.netgraph.targets()[0]:
198 add_dce_ccnr(ec, nid)
200 if nid == ec.netgraph.sources()[0]:
201 add_dce_ccncat(ec, nid)
203 if __name__ == '__main__':
205 #### Create NEPI Experiment Description with LINEAR topology
206 ec = ExperimentController("dce_ccn",
207 topo_type = TopologyType.LINEAR,
211 add_node_callback = add_dce_node,
212 add_edge_callback = add_dce_edge)
214 print "Results stored at", ec.exp_dir
216 #### Retrieve the consumer to wait for ot to finish
217 ccncat = ec.filter_resources("linux::ns3::dce::CCNCat")
219 #### Run experiment until metric convergences
220 rnr = ExperimentRunner()
221 runs = rnr.run(ec, min_runs = 1, max_runs = 1,
222 compute_metric_callback = avg_interests,