From 2886e68a48b44b82c1c554f52dfa5b580288893a Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Mon, 26 May 2014 18:52:41 +0200 Subject: [PATCH] NEPI DCE integration with CCN example --- src/nepi/resources/linux/ns3/ns3client.py | 3 +- .../resources/linux/ns3/ns3dceapplication.py | 2 +- src/nepi/resources/linux/ns3/ns3simulation.py | 23 +----- .../resources/ns3/ns3ccndceapplication.py | 71 +++++++++-------- src/nepi/resources/ns3/ns3dceapplication.py | 58 ++++++++++---- src/nepi/resources/ns3/ns3node.py | 30 +++---- test/resources/linux/ns3/ns3dceapplication.py | 79 +++++++------------ test/resources/linux/ns3/ns3simulation.py | 2 - 8 files changed, 130 insertions(+), 138 deletions(-) diff --git a/src/nepi/resources/linux/ns3/ns3client.py b/src/nepi/resources/linux/ns3/ns3client.py index 2d98a1ba..43dd7d7b 100644 --- a/src/nepi/resources/linux/ns3/ns3client.py +++ b/src/nepi/resources/linux/ns3/ns3client.py @@ -70,7 +70,8 @@ class LinuxNS3Client(NS3Client): "socket_addr": self.simulation.remote_socket, } - (reply, err), proc = self.simulation.node.execute(command) + (reply, err), proc = self.simulation.node.execute(command, + with_lock = True) if (err and proc.poll()) or reply.strip() == "": msg = (" Couldn't connect to remote socket %s - REPLY: %s " diff --git a/src/nepi/resources/linux/ns3/ns3dceapplication.py b/src/nepi/resources/linux/ns3/ns3dceapplication.py index 8d197b9a..df24dbdb 100644 --- a/src/nepi/resources/linux/ns3/ns3dceapplication.py +++ b/src/nepi/resources/linux/ns3/ns3dceapplication.py @@ -22,7 +22,7 @@ from nepi.execution.resource import clsinit_copy, ResourceState, reschedule_dela from nepi.resources.ns3.ns3dceapplication import NS3BaseDceApplication @clsinit_copy -class NS3LinuxDceApplication(NS3BaseDceApplication): +class LinuxNS3DceApplication(NS3BaseDceApplication): _rtype = "ns3::LinuxDceApplication" @classmethod diff --git a/src/nepi/resources/linux/ns3/ns3simulation.py b/src/nepi/resources/linux/ns3/ns3simulation.py index e026bb81..308b7775 100644 --- a/src/nepi/resources/linux/ns3/ns3simulation.py +++ b/src/nepi/resources/linux/ns3/ns3simulation.py @@ -126,11 +126,6 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): self._socket_name = "ns3-%s.sock" % os.urandom(4).encode('hex') self._dce_manager_helper_uuid = None self._dce_application_helper_uuid = None - - # Lock used to synchronize usage of DceManagerHelper - self.dce_manager_lock = threading.Lock() - # Lock used to synchronize usage of DceApplicationHelper - self.dce_application_lock = threading.Lock() @property def socket_name(self): @@ -140,14 +135,6 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): def remote_socket(self): return os.path.join(self.run_home, self.socket_name) - @property - def dce_manager_helper_uuid(self): - return self._dce_manager_helper_uuid - - @property - def dce_application_helper_uuid(self): - return self._dce_application_helper_uuid - @property def ns3_build_home(self): return os.path.join(self.node.bin_dir, "ns-3", self.get("ns3Version"), @@ -233,10 +220,6 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): stype = self.create("StringValue", sched_type) self.invoke(GLOBAL_VALUE_UUID, "Bind", "SchedulerType", btrue) - if self.get("enableDCE"): - self._dce_manager_helper_uuid = self.create("DceManagerHelper") - self._dce_application_helper_uuid = self.create("DceApplicationHelper") - def do_deploy(self): if not self.node or self.node.state < ResourceState.READY: self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state ) @@ -357,8 +340,8 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): @property def dce_repo(self): - #return "http://code.nsnam.org/ns-3-dce" - return "http://code.nsnam.org/epmancini/ns-3-dce" + return "http://code.nsnam.org/ns-3-dce" + #eturn "http://code.nsnam.org/epmancini/ns-3-dce" @property def _build(self): @@ -581,7 +564,7 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation): .replace("${HOME}", self.node.home_dir) # If NS3LIBRARIES is defined and not empty, use that value, # if not use ns3_build_home/lib/ - .replace("${BIN_DCE}", "${NS3LIBRARIES-%s/lib/}../bin_dce" % \ + .replace("${BIN_DCE}", "${NS3LIBRARIES-%s/lib}/../bin_dce" % \ self.ns3_build_home) ) diff --git a/src/nepi/resources/ns3/ns3ccndceapplication.py b/src/nepi/resources/ns3/ns3ccndceapplication.py index 232ac714..bbf5832c 100644 --- a/src/nepi/resources/ns3/ns3ccndceapplication.py +++ b/src/nepi/resources/ns3/ns3ccndceapplication.py @@ -22,26 +22,21 @@ from nepi.execution.resource import clsinit_copy, ResourceState, reschedule_dela from nepi.resources.ns3.ns3dceapplication import NS3BaseDceApplication import os +import threading @clsinit_copy class NS3BaseCCNDceApplication(NS3BaseDceApplication): _rtype = "abstract::ns3::CCNDceApplication" - @classmethod - def _register_attributes(cls): - files = Attribute("files", - "Semi-colon separated list of 'key=value' pairs to set as " - "DCE files (AddFile). The key should be a path to a local file " - "and the key is the path to be set in DCE for that file" , - flags = Flags.Design) + # Lock used to synchronize usage of CcnClientHelper + ccn_client_lock = threading.Lock() + _ccn_client_helper_uuid = None - stdinfile = Attribute("stdinFile", - "File to set as StdinFile. The value shoudl be either an empty " - "or a path to a local file ", - flags = Flags.Design) - - cls._register_attribute(files) - cls._register_attribute(stdinfile) + @property + def ccn_client_helper_uuid(self): + if not self._ccn_client_helper_uuid: + self._ccn_client_helper_uuid = self.simulation.create("CcnClientHelper") + return self._ccn_client_helper_uuid def _instantiate_object(self): pass @@ -53,62 +48,74 @@ class NS3BaseCCNDceApplication(NS3BaseDceApplication): # Preventing concurrent access to the DceApplicationHelper # from different DceApplication RMs - with self.simulation.dce_application_lock: + with self.ccn_client_lock: self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "ResetArguments") self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "ResetEnvironment") self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "SetBinary", self.get("binary")) self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "SetStackSize", self.get("stackSize")) arguments = self.get("arguments") if arguments: for arg in map(str.strip, arguments.split(";")): self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, - "AddArgument", arg) + self.ccn_client_helper_uuid, + "AddArgument", arg) environment = self.get("environment") if environment: for env in map(str.strip, environment.split(";")): key, val = env.split("=") self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, - "AddEnvironment", key, val) + self.ccn_client_helper_uuid, + "AddEnvironment", key, val) if self.has_attribute("files"): files = self.get("files") if files: - for files in map(str.strip, files.split(";")): - remotepath, dcepath = files.split("=") - localpath = "${SHARE}/" + os.path.basename(remotepath) + for file in map(str.strip, files.split(";")): + remotepath, dcepath = file.split("=") + localpath = os.path.join(self.simulation.app_home, + os.path.basename(remotepath)) self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, - "AddFile", localpath, dcepath) + self.ccn_client_helper_uuid, + "AddFile", localpath, dcepath) if self.has_attribute("stdinFile"): stdinfile = self.get("stdinFile") if stdinfile: + # stdinfile might be an empty text that should be set as + # stdin if stdinfile != "": - stdinfile = "${SHARE}/" + os.path.basename(stdinfile) - + stdinfile = os.path.join(self.simulation.app_home, + os.path.basename(stdinfile)) + self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "SetStdinFile", stdinfile) apps_uuid = self.simulation.invoke( - self.simulation.ccn_client_helper_uuid, + self.ccn_client_helper_uuid, "InstallInNode", self.node.uuid) + """ + container_uuid = self.simulation.create("NodeContainer") + self.simulation.invoke(container_uuid, "Add", self.node.uuid) + apps_uuid = self.simulation.invoke( + self.ccn_client_helper_uuid, + "Install", container_uuid) + """ + self._uuid = self.simulation.invoke(apps_uuid, "Get", 0) if self.has_changed("StartTime"): diff --git a/src/nepi/resources/ns3/ns3dceapplication.py b/src/nepi/resources/ns3/ns3dceapplication.py index 7d26fbda..a3e97fae 100644 --- a/src/nepi/resources/ns3/ns3dceapplication.py +++ b/src/nepi/resources/ns3/ns3dceapplication.py @@ -22,11 +22,20 @@ from nepi.execution.resource import clsinit_copy, ResourceState, reschedule_dela from nepi.resources.ns3.ns3application import NS3BaseApplication import os - +import threading + @clsinit_copy class NS3BaseDceApplication(NS3BaseApplication): _rtype = "abstract::ns3::DceApplication" + # Lock used to synchronize usage of DceManagerHelper + dce_manager_lock = threading.Lock() + # Lock used to synchronize usage of DceApplicationHelper + dce_application_lock = threading.Lock() + + _dce_manager_helper_uuid = None + _dce_application_helper_uuid = None + @classmethod def _register_attributes(cls): binary = Attribute("binary", @@ -75,11 +84,20 @@ class NS3BaseDceApplication(NS3BaseApplication): self.error(msg) raise RuntimeError, msg - if nodes[0].get("enableDCE") == False: - raise RuntimeError("DceApplication not connected to DCE enabled node") - return nodes[0] - + + @property + def dce_manager_helper_uuid(self): + if not self._dce_manager_helper_uuid: + self._dce_manager_helper_uuid = self.simulation.create("DceManagerHelper") + return self._dce_manager_helper_uuid + + @property + def dce_application_helper_uuid(self): + if not self._dce_application_helper_uuid: + self._dce_application_helper_uuid = self.simulation.create("DceApplicationHelper") + return self._dce_application_helper_uuid + def _instantiate_object(self): pass @@ -90,28 +108,28 @@ class NS3BaseDceApplication(NS3BaseApplication): # Preventing concurrent access to the DceApplicationHelper # from different DceApplication RMs - with self.simulation.dce_application_lock: + with self.dce_application_lock: self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "ResetArguments") self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "ResetEnvironment") self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "SetBinary", self.get("binary")) self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "SetStackSize", self.get("stackSize")) arguments = self.get("arguments") if arguments: for arg in map(str.strip, arguments.split(";")): self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "AddArgument", arg) environment = self.get("environment") @@ -119,13 +137,21 @@ class NS3BaseDceApplication(NS3BaseApplication): for env in map(str.strip, environment.split(";")): key, val = env.split("=") self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "AddEnvironment", key, val) apps_uuid = self.simulation.invoke( - self.simulation.dce_application_helper_uuid, + self.dce_application_helper_uuid, "InstallInNode", self.node.uuid) + """ + container_uuid = self.simulation.create("NodeContainer") + self.simulation.invoke(container_uuid, "Add", self.node.uuid) + apps_uuid = self.simulation.invoke( + self.dce_application_helper_uuid, + "Install", container_uuid) + """ + self._uuid = self.simulation.invoke(apps_uuid, "Get", 0) if self.has_changed("StartTime"): @@ -153,9 +179,9 @@ class NS3BaseDceApplication(NS3BaseApplication): def _configure_traces(self): # Preventing concurrent access to the DceApplicationHelper # from different DceApplication RMs - with self.simulation.dce_application_lock: - pid = self.simulation.invoke(self.simulation.dce_application_helper_uuid, - "GetPid", self._uuid) + with self.dce_application_lock: + pid = self.simulation.invoke(self.dce_application_helper_uuid, + "GetPid", self.uuid) node_id = self.simulation.invoke(self.node.uuid, "GetId") self._trace_filename["stdout"] = "files-%s/var/log/%s/stdout" % (node_id, pid) self._trace_filename["stderr"] = "files-%s/var/log/%s/stderr" % (node_id, pid) diff --git a/src/nepi/resources/ns3/ns3node.py b/src/nepi/resources/ns3/ns3node.py index b6188e36..0c0d8766 100644 --- a/src/nepi/resources/ns3/ns3node.py +++ b/src/nepi/resources/ns3/ns3node.py @@ -25,16 +25,6 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseNode(NS3Base): _rtype = "abstract::ns3::Node" - @classmethod - def _register_attributes(cls): - enable_dce = Attribute("enableDCE", - "This node will run in DCE emulation mode ", - default = False, - type = Types.Bool, - flags = Flags.Design) - - cls._register_attribute(enable_dce) - @property def simulation(self): from nepi.resources.ns3.ns3simulation import NS3Simulation @@ -73,6 +63,13 @@ class NS3BaseNode(NS3Base): return devices + @property + def dceapplications(self): + from nepi.resources.ns3.ns3dceapplication import NS3BaseDceApplication + dceapplications = self.get_connected(NS3BaseDceApplication.get_rtype()) + + return dceapplications + @property def _rms_to_wait(self): rms = set() @@ -93,8 +90,9 @@ class NS3BaseNode(NS3Base): uuid_packet_socket_factory = self.simulation.create("PacketSocketFactory") self.simulation.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory) - if self.get("enableDCE") == True: - self._add_dce() + dceapplications = self.dceapplications + if dceapplications: + self._add_dce(dceapplications) def _connect_object(self): ipv4 = self.ipv4 @@ -105,10 +103,12 @@ class NS3BaseNode(NS3Base): if mobility: self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid) - def _add_dce(self): + def _add_dce(self, dceapplications): + dceapp = dceapplications[0] + container_uuid = self.simulation.create("NodeContainer") self.simulation.invoke(container_uuid, "Add", self.uuid) - with self.simulation.dce_manager_lock: - self.simulation.invoke(self.simulation.dce_manager_helper_uuid, + with dceapp.dce_manager_lock: + self.simulation.invoke(dceapp.dce_manager_helper_uuid, "Install", container_uuid) diff --git a/test/resources/linux/ns3/ns3dceapplication.py b/test/resources/linux/ns3/ns3dceapplication.py index e75e8a5f..b3f21cac 100644 --- a/test/resources/linux/ns3/ns3dceapplication.py +++ b/test/resources/linux/ns3/ns3dceapplication.py @@ -42,6 +42,10 @@ def add_ns3_node(ec, simu): udp = ec.register_resource("ns3::UdpL4Protocol") ec.register_connection(node, udp) + tcp = ec.register_resource("ns3::TcpL4Protocol") + ec.register_connection(node, tcp) + + return node def add_point2point_device(ec, node, address = None, prefix = None): @@ -133,10 +137,13 @@ def add_wifi_channel(ec): class LinuxNS3DceApplicationTest(unittest.TestCase): def setUp(self): - self.fedora_host = "nepi2.pl.sophia.inria.fr" + #self.fedora_host = "nepi2.pl.sophia.inria.fr" #self.fedora_host = "planetlabpc1.upf.edu" - self.fedora_user = "inria_nepi" - self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME']) + #self.fedora_user = "inria_nepi" + #self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME']) + self.fedora_host = "mimas.inria.fr" + self.fedora_user = "aquereil" + self.fedora_identity = "%s/.ssh/id_rsa" % (os.environ['HOME']) def test_dce_ping(self): ec = ExperimentController(exp_id = "test-dce-ping") @@ -145,7 +152,7 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.set(node, "hostname", self.fedora_host) ec.set(node, "username", self.fedora_user) ec.set(node, "identity", self.fedora_identity) - ec.set(node, "cleanProcesses", True) + #ec.set(node, "cleanProcesses", True) #ec.set(node, "cleanHome", True) simu = ec.register_resource("LinuxNS3Simulation") @@ -156,12 +163,10 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.register_connection(simu, node) nsnode1 = add_ns3_node(ec, simu) - ec.set(nsnode1, "enableDCE", True) p2p1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30") ec.set(p2p1, "DataRate", "5Mbps") nsnode2 = add_ns3_node(ec, simu) - ec.set(nsnode2, "enableDCE", True) p2p2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30") ec.set(p2p2, "DataRate", "5Mbps") @@ -216,7 +221,7 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.set(node, "hostname", self.fedora_host) ec.set(node, "username", self.fedora_user) ec.set(node, "identity", self.fedora_identity) - ec.set(node, "cleanProcesses", True) + #ec.set(node, "cleanProcesses", True) #ec.set(node, "cleanHome", True) simu = ec.register_resource("LinuxNS3Simulation") @@ -227,12 +232,10 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.register_connection(simu, node) nsnode1 = add_ns3_node(ec, simu) - ec.set(nsnode1, "enableDCE", True) p2p1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30") ec.set(p2p1, "DataRate", "5Mbps") nsnode2 = add_ns3_node(ec, simu) - ec.set(nsnode2, "enableDCE", True) p2p2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30") ec.set(p2p2, "DataRate", "5Mbps") @@ -245,6 +248,7 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ### create applications ccnd1 = ec.register_resource("ns3::LinuxCCNDceApplication") + ec.set(ccnd1, "depends", "libpcap0.8-dev openjdk-6-jdk ant1.8 autoconf " "libssl-dev libexpat-dev libpcap-dev libecryptfs0 libxml2-utils auto" "make gawk gcc g++ git-core pkg-config libpcre3-dev openjdk-6-jre-lib") @@ -253,22 +257,16 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): "cd ccnx-0.7.2 && " " INSTALL_BASE=${BIN_DCE}/.. ./configure && " " make MORE_LDLIBS=-pie && " - " make install && cd -") - ec.set (ccnd1, "binary", "ccndstart") + " make install && " + " cp ${BIN_DCE}/../bin/ccn* ${BIN_DCE} && " + " cd -") + ec.set (ccnd1, "binary", "ccnd") ec.set (ccnd1, "stackSize", 1<<20) + ec.set (ccnd1, "environment", "CCND_CAP=50000; CCND_DEBUG=7") ec.set (ccnd1, "StartTime", "1s") ec.set (ccnd1, "StopTime", "20s") ec.register_connection(ccnd1, nsnode1) - ccnkill1 = ec.register_resource("ns3::LinuxCCNDceApplication") - ec.set (ccnkill1, "binary", "ccnsmoketest") - ec.set (ccnkill1, "arguments", "kill") - ec.set (ccnkill1, "stdinFile", "") - ec.set (ccnkill1, "stackSize", 1<<20) - ec.set (ccnkill1, "StartTime", "110s") - ec.set (ccnkill1, "StopTime", "120s") - ec.register_connection(ccnkill1, nsnode1) - repofile = os.path.join( os.path.dirname(os.path.realpath(__file__)), "repoFile1") @@ -291,8 +289,9 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.register_connection(ccndc1, nsnode1) ccnd2 = ec.register_resource("ns3::LinuxCCNDceApplication") - ec.set (ccnd2, "binary", "ccndstart") + ec.set (ccnd2, "binary", "ccnd") ec.set (ccnd2, "stackSize", 1<<20) + ec.set (ccnd2, "environment", "CCND_CAP=50000; CCND_DEBUG=7") ec.set (ccnd2, "StartTime", "1s") ec.set (ccnd2, "StopTime", "120s") ec.register_connection(ccnd2, nsnode2) @@ -323,43 +322,21 @@ class LinuxNS3DceApplicationTest(unittest.TestCase): ec.set (ccncat, "StopTime", "120s") ec.register_connection(ccncat, nsnode2) - ccnkill2 = ec.register_resource("ns3::LinuxCCNDceApplication") - ec.set (ccnkill2, "binary", "ccnsmoketest") - ec.set (ccnkill2, "arguments", "kill") - ec.set (ccnkill2, "stdinFile", "") - ec.set (ccnkill2, "stackSize", 1<<20) - ec.set (ccnkill2, "StartTime", "110s") - ec.set (ccnkill2, "StopTime", "120s") - ec.register_connection(ccnkill2, nsnode2) - ec.deploy() - ec.wait_finished([ccncat, ccnkill1, ccnkill2]) + ec.wait_finished([ccncat]) - print ec.trace(ccncat, "cmdline") - """ - expected = "ping -c 10 -s 1000 10.0.0.2" - cmdline = ec.trace(ping, "cmdline") + expected = "ccncat ccnx:/test/bunny.ts" + cmdline = ec.trace(ccncat, "cmdline") self.assertTrue(cmdline.find(expected) > -1, cmdline) - """ - print ec.trace(ccncat, "status") - """ - expected = "Start Time: NS3 Time: 1s (" - status = ec.trace(ping, "status") + expected = "Start Time: NS3 Time: 4s (" + status = ec.trace(ccncat, "status") self.assertTrue(status.find(expected) > -1, status) - """ - - print len(ec.trace(ccncat, "stdout")) - """ - expected = "10 packets transmitted, 10 received, 0% packet loss, time 9002ms" - stdout = ec.trace(ping, "stdout") - self.assertTrue(stdout.find(expected) > -1, stdout) - """ - stderr = ec.trace(simu, "stderr") - expected = "DceApplication:StartApplication" - self.assertTrue(stderr.find(expected) > -1, stderr) + expected = 2873956 + stdout = ec.trace(ccncat, "stdout") + self.assertTrue(len(stdout) == expected , stdout) ec.shutdown() diff --git a/test/resources/linux/ns3/ns3simulation.py b/test/resources/linux/ns3/ns3simulation.py index d46e586c..292b1c02 100644 --- a/test/resources/linux/ns3/ns3simulation.py +++ b/test/resources/linux/ns3/ns3simulation.py @@ -771,12 +771,10 @@ class LinuxNS3SimulationTest(unittest.TestCase): ec.register_connection(simu, node) nsnode1 = add_ns3_node(ec, simu) - ec.set(nsnode1, "enableDCE", True) p2p1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30") ec.set(p2p1, "DataRate", "5Mbps") nsnode2 = add_ns3_node(ec, simu) - ec.set(nsnode2, "enableDCE", True) p2p2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30") ec.set(p2p2, "DataRate", "5Mbps") -- 2.43.0