Adding dce ccn example with topology generator
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 10 Aug 2014 22:43:47 +0000 (00:43 +0200)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 10 Aug 2014 22:43:47 +0000 (00:43 +0200)
examples/ccn_flooding/dce.py [new file with mode: 0644]
src/nepi/util/netgraph.py
src/nepi/util/parsers/xml_parser.py

diff --git a/examples/ccn_flooding/dce.py b/examples/ccn_flooding/dce.py
new file mode 100644 (file)
index 0000000..40c9150
--- /dev/null
@@ -0,0 +1,243 @@
+#!/usr/bin/env python
+
+###############################################################################
+#
+#    NEPI, a framework to manage network experiments
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+#
+###############################################################################
+
+from nepi.execution.ec import ExperimentController 
+from nepi.execution.runner import ExperimentRunner
+from nepi.util.netgraph import NetGraph, TopologyType
+import nepi.data.processing.ccn.parser as ccn_parser
+
+import networkx
+import socket
+import os
+
+content_name = "ccnx:/test/bunny.ts"
+
+STOP_TIME = "5000s"
+
+operating_system = "f14"
+
+repofile = os.path.join(
+        os.path.dirname(os.path.realpath(__file__)), "repoFile1.0.8.2")
+
+def get_simulator(ec):
+    simulator = ec.filter_resources("LinuxNS3Simulation")
+
+    if not simulator:
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", "localhost")
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.register_connection(simu, node)
+        return simu
+
+    return simulator[0]
+
+def add_collector(ec, trace_name, subdir, newname = None):
+    collector = ec.register_resource("Collector")
+    ec.set(collector, "traceName", trace_name)
+    ec.set(collector, "subDir", subdir)
+    if newname:
+        ec.set(collector, "rename", newname)
+
+    return collector
+
+def add_dce_host(ec, nid):
+    simu = get_simulator(ec)
+    
+    host = ec.register_resource("ns3::Node")
+    ec.set(host, "enableStack", True)
+    ec.register_connection(host, simu)
+
+    # Annotate the graph
+    ec.netgraph.annotate_node(nid, "host", host)
+    
+def add_dce_ccnd(ec, nid):
+    # Retrieve annotation from netgraph
+    host = ec.netgraph.node_annotation(nid, "host")
+    
+    # Add dce ccnd to the dce node
+    ccnd = ec.register_resource("ns3::LinuxDceCCND")
+    ec.set (ccnd, "stackSize", 1<<20)
+    ec.set (ccnd, "debug", 7)
+    ec.set (ccnd, "capacity", 50000)
+    ec.set (ccnd, "StartTime", "1s")
+    ec.set (ccnd, "StopTime", STOP_TIME)
+    ec.register_connection(ccnd, host)
+
+    # Collector to retrieve ccnd log
+    collector = add_collector(ec, "stderr", nid, "log")
+    ec.register_connection(collector, ccnd)
+
+    # Annotate the graph
+    ec.netgraph.annotate_node(nid, "ccnd", ccnd)
+
+def add_dce_ccnr(ec, nid):
+    # Retrieve annotation from netgraph
+    host = ec.netgraph.node_annotation(nid, "host")
+    
+    # Add a CCN content repository to the dce node
+    ccnr = ec.register_resource("ns3::LinuxDceCCNR")
+    ec.set (ccnr, "repoFile1", repofile) 
+    ec.set (ccnr, "stackSize", 1<<20)
+    ec.set (ccnr, "StartTime", "2s")
+    ec.set (ccnr, "StopTime", STOP_TIME)
+    ec.register_connection(ccnr, host)
+
+def add_dce_ccncat(ec, nid):
+    # Retrieve annotation from netgraph
+    host = ec.netgraph.node_annotation(nid, "host")
+   
+    ccnpeek = ec.register_resource("ns3::LinuxDceCCNPeek")
+    #ec.set (ccnpeek, "contentName", "ccnx:/chunk0")
+    ec.set (ccnpeek, "contentName", content_name)
+    ec.set (ccnpeek, "stackSize", 1<<20)
+    ec.set (ccnpeek, "StartTime", "5s")
+    ec.set (ccnpeek, "StopTime", STOP_TIME)
+    ec.register_connection(ccnpeek, host)
+
+    collector = add_collector(ec, "stdout", nid, "peek")
+    ec.register_connection(collector, ccnpeek)
+
+    # Add a ccncat application to the dce host
+    ccncat = ec.register_resource("ns3::LinuxDceCCNCat")
+    ec.set (ccncat, "contentName", content_name)
+    ec.set (ccncat, "stackSize", 1<<20)
+    ec.set (ccncat, "StartTime", "8s")
+    ec.set (ccncat, "StopTime", STOP_TIME)
+    ec.register_connection(ccncat, host)
+
+def add_dce_fib_entry(ec, nid1, nid2):
+    # Retrieve annotations from netgraph
+    host1 = ec.netgraph.node_annotation(nid1, "host")
+    net = ec.netgraph.edge_net_annotation(nid1, nid2)
+    ip2 = net[nid2]
+
+    # Add FIB entry between peer hosts
+    ccndc = ec.register_resource("ns3::LinuxDceFIBEntry")
+    ec.set (ccndc, "protocol", "udp") 
+    ec.set (ccndc, "uri", "ccnx:/") 
+    ec.set (ccndc, "host", ip2)
+    ec.set (ccndc, "stackSize", 1<<20)
+    ec.set (ccndc, "StartTime", "2s")
+    ec.set (ccndc, "StopTime", STOP_TIME)
+    ec.register_connection(ccndc, host1)
+
+def add_dce_net_iface(ec, nid1, nid2):
+    # Retrieve annotations from netgraph
+    host = ec.netgraph.node_annotation(nid1, "host")
+    net = ec.netgraph.edge_net_annotation(nid1, nid2)
+    ip1 = net[nid1]
+    prefix = net["prefix"]
+
+    dev = ec.register_resource("ns3::PointToPointNetDevice")
+    ec.set(dev, "ip", ip1)
+    ec.set(dev, "prefix", prefix)
+    ec.register_connection(host, dev)
+
+    queue = ec.register_resource("ns3::DropTailQueue")
+    ec.register_connection(dev, queue)
+
+    return dev
+
+def avg_interests(ec, run):
+    ## Process logs
+    logs_dir = ec.run_dir
+
+    (graph,
+        content_names,
+        interest_expiry_count,
+        interest_dupnonce_count,
+        interest_count,
+        content_count) = ccn_parser.process_content_history_logs(
+                logs_dir, 
+                ec.netgraph.topology)
+
+    shortest_path = networkx.shortest_path(graph, 
+            source = ec.netgraph.sources()[0], 
+            target = ec.netgraph.targets()[0])
+
+    ### Compute metric: Avg number of Interests seen per content name
+    ###                 normalized by the number of nodes in the shortest path
+    content_name_count = len(content_names.values())
+    nodes_in_shortest_path = len(shortest_path) - 1
+    metric = interest_count / (float(content_name_count) * float(nodes_in_shortest_path))
+
+    # TODO: DUMP RESULTS TO FILE
+    # TODO: DUMP GRAPH DELAYS!
+    f = open("/tmp/metric", "w+")
+    f.write("%.2f\n" % metric)
+    f.close()
+    print " METRIC", metric
+
+    return metric
+
+def add_dce_edge(ec, nid1, nid2):
+    ### Add network interfaces to hosts
+    p2p1 = add_dce_net_iface(ec, nid1, nid2)
+    p2p2 = add_dce_net_iface(ec, nid2, nid1)
+
+    # Create point to poing link between interfaces
+    chan = ec.register_resource("ns3::PointToPointChannel")
+    ec.set(chan, "Delay", "0ms")
+
+    ec.register_connection(chan, p2p1)
+    ec.register_connection(chan, p2p2)
+
+    #### Add routing between CCN nodes
+    add_dce_fib_entry(ec, nid1, nid2)
+    add_dce_fib_entry(ec, nid2, nid1)
+
+def add_dce_node(ec, nid):
+    ### Add CCN nodes (ec.netgraph holds the topology graph)
+    add_dce_host(ec, nid)
+    add_dce_ccnd(ec, nid)
+        
+    if nid == ec.netgraph.targets()[0]:
+        add_dce_ccnr(ec, nid)
+
+    if nid == ec.netgraph.sources()[0]:
+        add_dce_ccncat(ec, nid)
+
+if __name__ == '__main__':
+
+    #### Create NEPI Experiment Description with LINEAR topology 
+    ec = ExperimentController("dce_ccn", 
+            topo_type = TopologyType.LINEAR, 
+            node_count = 4,
+            assign_st = True,
+            assign_ips = True,
+            add_node_callback = add_dce_node, 
+            add_edge_callback = add_dce_edge)
+    
+    print "Results stored at", ec.exp_dir
+
+    #### Retrieve the consumer to wait for ot to finish
+    ccncat = ec.filter_resources("ns3::LinuxDceCCNCat")
+   
+    #### Run experiment until metric convergences
+    rnr = ExperimentRunner()
+    runs = rnr.run(ec, min_runs = 1, max_runs = 1, 
+            compute_metric_callback = avg_interests,
+            wait_guids = ccncat,
+            wait_time = 0)
+
index 07da169..6d68622 100644 (file)
@@ -220,7 +220,7 @@ class NetGraph(object):
         return self.topology.edge[nid1][nid2].get("net", dict())
  
     def edge_annotation(self, nid1, nid2, name):
-        return self.topoplogy.edge[nid1][nid2].get(name)
+        return self.topology.edge[nid1][nid2].get(name)
  
     def edge_annotations(self, nid1, nid2):
         return self.topology.edge[nid1][nid2].keys()
@@ -250,10 +250,10 @@ class NetGraph(object):
         netblock = "%s/%d" % (network, prefix)
         if version == 4:
             net = ipaddr.IPv4Network(netblock)
-            new_prefix = 31
+            new_prefix = 30
         elif version == 6:
             net = ipaddr.IPv6Network(netblock)
-            new_prefix = 31
+            new_prefix = 30
         else:
             raise RuntimeError, "Invalid IP version %d" % version
         
index af57cf1..ca68be1 100644 (file)
@@ -345,8 +345,8 @@ class ECXMLParser(object):
 
                             if name == "net":
                                 net = xmldecode(annonode.getAttribute("value"), eval) # dict
-                                netgraph.annotate_edge_net(net[nid1], net[nid2], net["ip1"],
-                                        net["ip2"], net["mask"], net["network"], net["prefix"])
+                                netgraph.annotate_edge_net(nid1, nid2, net[nid1], net[nid2], 
+                                        net["mask"], net["network"], net["prefix"])
                             else:
                                 value = xmldecode(annonode.getAttribute("value"))
                                 tipe = xmldecode(annonode.getAttribute("type"))