dos2unix'es all files- only one affected : topology.py in the ns3 examples area
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Wed, 4 Nov 2015 15:36:58 +0000 (16:36 +0100)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Wed, 4 Nov 2015 15:36:58 +0000 (16:36 +0100)
examples/ns3/multi_host/topology.py

index f4d6504..a1ba1f9 100644 (file)
-#!/usr/bin/env python\r
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2015 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-#\r
-\r
-from six import PY2, next\r
-if PY2:\r
-    import ipaddr\r
-else:\r
-    import ipaddress\r
-from optparse import OptionParser\r
-import os\r
-from random import randint\r
-\r
-# list of hosts for running the experiment on\r
-hostname1 = "onelab4.warsaw.rd.tp.pl"\r
-hostname2 = "planet2.servers.ua.pt"\r
-\r
-def get_options():\r
-    # PlanetLab credentials\r
-    pl_slice = os.environ.get("PL_SLICE")\r
-    pl_user = os.environ.get("PL_USER")\r
-    pl_password = os.environ.get("PL_PASS")\r
-    pl_ssh_key = os.environ.get("PL_SSHKEY")\r
-\r
-    usage = ("usage: %prog -s <pl-slice> -u <pl-user> -p <pl-password> "\r
-                "-k <pl-ssh-key> -n <node-count> ")\r
-\r
-    parser = OptionParser(usage = usage)\r
-    parser.add_option("-s", "--pl-slice", dest="pl_slice",\r
-            help="PlanetLab slicename", default=pl_slice, type="str")\r
-    parser.add_option("-u", "--pl-user", dest="pl_user",\r
-            help="PlanetLab web username", default=pl_user, type="str")\r
-    parser.add_option("-p", "--pl-password", dest="pl_password",\r
-            help="PlanetLab web password", default=pl_password, type="str")\r
-    parser.add_option("-k", "--pl-ssh-key", dest="pl_ssh_key",\r
-            help="Path to private SSH key associated with the PL account",\r
-            default=pl_ssh_key, type="str")\r
-    parser.add_option("-n", "--node-count", dest="node_count",\r
-            help="Number of nodes in the wireless network",\r
-            default = 4, type="int")\r
-\r
-    (options, args) = parser.parse_args()\r
-\r
-    return (options.pl_slice, options.pl_user, options.pl_password, \r
-            options.pl_ssh_key, options.node_count)\r
-\r
-# == add host and simu =======================================================\r
-def add_host_simu(ec, hostname, username, pl_user, pl_password, ssh_key):\r
-    host = ec.register_resource("planetlab::Node")\r
-    ec.set(host, "hostname", hostname)\r
-\r
-    if username:\r
-        ec.set(host, "username", username)\r
-\r
-    if pl_user:\r
-        ec.set(host, "pluser", pl_user)\r
-\r
-    if pl_password:\r
-        ec.set(host, "plpassword", pl_password)\r
-\r
-    if ssh_key:\r
-        ec.set(host, "identity", ssh_key)\r
-\r
-    ec.set(host, "cleanProcesses", True)\r
-    ec.set(host, "cleanExperiment", True)\r
-\r
-    simu = ec.register_resource("linux::ns3::Simulation")\r
-    ec.set(simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")\r
-    ec.set(simu, "checksumEnabled", True)\r
-    ec.set(simu, "verbose", True)\r
-    ec.set(simu, "enableDump", True)\r
-    ec.set (simu, "StopTime", "200s")\r
-    ec.register_connection(simu, host)\r
-\r
-    return host, simu\r
-\r
-# == build topology  =========================================================\r
-\r
-def add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode):\r
-    # create the WiFi network interface\r
-    dev = ec.register_resource("ns3::WifiNetDevice")\r
-\r
-    # specify the network layer parameters\r
-    ec.set(dev, "ip", ip)\r
-    ec.set(dev, "prefix", prefixlen)\r
-    ec.register_connection(ns3_node, dev)\r
-\r
-    # specify the MAC layer parameters\r
-    #\r
-    # can be in access point mode or not\r
-    if ap_mode:\r
-        mac = ec.register_resource("ns3::ApWifiMac")\r
-    else:\r
-        mac = ec.register_resource("ns3::StaWifiMac")\r
-\r
-    # the MAC is IEEE 802.11a\r
-    ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")\r
-    ec.register_connection(dev, mac)\r
-\r
-    # specify the physical layer parameters\r
-    phy = ec.register_resource("ns3::YansWifiPhy")\r
-    #\r
-    # it physical layer is IEEE802.11a\r
-    ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")\r
-    ec.register_connection(dev, phy)\r
-    #\r
-    # specify an error model for transmissions\r
-    error = ec.register_resource("ns3::NistErrorRateModel")\r
-    ec.register_connection(phy, error)\r
-\r
-    # specify the Wifi manager to be assocated with the interface\r
-    manager = ec.register_resource("ns3::ArfWifiManager")\r
-    ec.register_connection(dev, manager)\r
-\r
-    return dev, phy\r
-\r
-def add_ns3_wifi_channel(ec):\r
-    channel = ec.register_resource("ns3::YansWifiChannel")\r
-\r
-    delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")\r
-    ec.register_connection(channel, delay)\r
-\r
-    loss  = ec.register_resource("ns3::LogDistancePropagationLossModel")\r
-    ec.register_connection(channel, loss)\r
-\r
-    return channel\r
-\r
-# == Add random mobility\r
-def add_ns3_random_mobility(ec, ns3_node):\r
-    speed =  1\r
-    bounds_width = 100\r
-    bounds_height = 100\r
-    x = randint(0, bounds_width)\r
-    y = randint(0, bounds_height)\r
-    z = 0\r
-\r
-    position = "%d:%d:%d" % (x, y, z)\r
-    bounds = "0|%d|0|%d" % (bounds_width, bounds_height)\r
-    speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)\r
-    pause = "ns3::ConstantRandomVariable[Constant=1.0]"\r
-\r
-    mobility = ec.register_resource("ns3::RandomDirection2dMobilityModel")\r
-    ec.set(mobility, "Position", position)\r
-    ec.set(mobility, "Bounds", bounds)\r
-    ec.set(mobility, "Speed", speed)\r
-    ec.set(mobility, "Pause",  pause)\r
-    ec.register_connection(ns3_node, mobility)\r
-\r
-    return mobility\r
-\r
-# == Add constant mobility\r
-def add_ns3_constant_mobility(ec, ns3_node):\r
-    mobility = ec.register_resource("ns3::ConstantPositionMobilityModel")\r
-    position = "%d:%d:%d" % (0, 50, 0)\r
-    ec.set(mobility, "Position", position)\r
-    ec.register_connection(ns3_node, mobility)\r
-\r
-    return mobility\r
-\r
-# == add ns-3 node\r
-def add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False):\r
-    ns3_node = ec.register_resource("ns3::Node")\r
-    ec.set(ns3_node, "enableStack", True)\r
-    ec.register_connection(ns3_node, simu)\r
-\r
-    dev, phy = add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode)\r
-    ec.register_connection(channel, phy)\r
-\r
-    if not ap_mode:\r
-        add_ns3_random_mobility(ec, ns3_node)\r
-    else:\r
-        add_ns3_constant_mobility(ec, ns3_node)\r
-\r
-    return ns3_node\r
-\r
-# == add DCE agent\r
-def add_dce_agent(ec, ns3_node):\r
-    agent = ec.register_resource("linux::ns3::dce::Application")\r
-    ec.set(agent, "sources", "code/agent.c")\r
-    ec.set(agent, "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")\r
-    ec.set(agent, "binary", "agent")\r
-    ec.set(agent, "stackSize", 1<<20)\r
-    ec.set(agent, "StartTime", "10s")\r
-    ec.set(agent, "StopTime", "200s")\r
-\r
-    ec.register_connection(agent, ns3_node)\r
-\r
-    return agent\r
-\r
-# == add DCE transmitter\r
-def add_dce_transmitter(ec, ns3_node, target):\r
-    transmitter = ec.register_resource("linux::ns3::dce::Application")\r
-    ec.set(transmitter, "sources", "code/transmitter.c")\r
-    ec.set(transmitter, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")\r
-    ec.set(transmitter, "binary", "transmitter")\r
-    ec.set(transmitter, "arguments", target)\r
-    ec.set(transmitter, "stackSize", 1<<20)\r
-    ec.set(transmitter, "StartTime", "10s")\r
-    ec.set(transmitter, "StopTime", "200s")\r
-    \r
-    ec.register_connection(transmitter, ns3_node)\r
-\r
-    return transmitter\r
-\r
-# == Add ns-3 route\r
-def add_ns3_route(ec, ns3_node, network, prefixlen, nexthop):\r
-    route = ec.register_resource("ns3::Route")\r
-    ec.set(route, "network", network)\r
-    ec.set(route, "prefix", prefixlen)\r
-    ec.set(route, "nexthop", nexthop)\r
-    ec.register_connection(route, ns3_node)\r
-\r
-    return route\r
-\r
-# = build ns3 topology =======================================================\r
-def build_ns3_topology(ec, simu, node_count, network, prefixlen, agent_ip):\r
-    channel = add_ns3_wifi_channel(ec)\r
-\r
-    if PY2:\r
-        net = ipaddr.IPv4Network("%s/%s" % (network, prefixlen)) \r
-        itr = net.iterhosts()\r
-    else:\r
-        net = ipaddress.IPv4Network("%s/%s" % (network, prefixlen)) \r
-        itr = net.hosts()\r
-\r
-    ap_ip = next(itr).exploded\r
-    ap = add_ns3_node(ec, simu, ap_ip, prefixlen, channel, ap_mode=True)\r
-\r
-    agent = None\r
-    if ap_ip == agent_ip:\r
-        agent = add_dce_agent(ec, ap)\r
-\r
-    for i in range(0, node_count):\r
-        ip = itr.next().exploded\r
-        sensor = add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False)\r
-        transmitter = add_dce_transmitter(ec, sensor, ap_ip)\r
-        add_ns3_route(ec, sensor, network="0.0.0.0", prefixlen="0", nexthop=ap_ip)\r
-\r
-    return ap, agent\r
-\r
-\r
-# == add FdNetDevice =========================================================\r
-def add_fdnet_device(ec, ap, ip, prefixlen):\r
-    fddev = ec.register_resource("ns3::FdNetDevice")\r
-    ec.set(fddev, "ip", ip)\r
-    ec.set(fddev, "prefix", prefixlen)\r
-    ec.register_connection(ap, fddev)\r
-\r
-    return fddev\r
-\r
-# == connect with UDP tunnel =================================================\r
-def connect_with_udp_tunnel(ec, fddev1, fddev2):                                                             \r
-    tunnel = ec.register_resource("planetlab::ns3::FdUdpTunnel")\r
-    ec.register_connection(tunnel, fddev1)\r
-    ec.register_connection(tunnel, fddev2)\r
-\r
-    return tunnel\r
-\r
-# == connect with virtual link ===============================================\r
-def connect_with_virtual_link(ec, tap, fddev):                                                                   \r
-    link = ec.register_resource("planetlab::ns3::TunTapFdLink")                          \r
-    ec.register_connection(link, tap)\r
-    ec.register_connection(link, fddev)\r
-\r
-    return link\r
-\r
-# == Add planet lab route ====================================================\r
-\r
-def add_planetlab_route(ec, dev, network, prefixlen, nexthop):\r
-    route = ec.register_resource("planetlab::Vroute")\r
-    ec.set(route, "network", network)\r
-    ec.set(route, "prefix", prefixlen)\r
-    ec.set(route, "nexthop", nexthop)\r
-    ec.register_connection(route, dev)\r
-\r
-    return route\r
-\r
+#!/usr/bin/env python
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2015 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License version 2 as
+#    published by the Free Software Foundation;
+#
+#    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: Damien Saucez <damien.saucez@inria.fr>
+#         Alina Quereilhac <alina.quereilhac@inria.fr>
+#
+
+from six import PY2, next
+if PY2:
+    import ipaddr
+else:
+    import ipaddress
+from optparse import OptionParser
+import os
+from random import randint
+
+# list of hosts for running the experiment on
+hostname1 = "onelab4.warsaw.rd.tp.pl"
+hostname2 = "planet2.servers.ua.pt"
+
+def get_options():
+    # PlanetLab credentials
+    pl_slice = os.environ.get("PL_SLICE")
+    pl_user = os.environ.get("PL_USER")
+    pl_password = os.environ.get("PL_PASS")
+    pl_ssh_key = os.environ.get("PL_SSHKEY")
+
+    usage = ("usage: %prog -s <pl-slice> -u <pl-user> -p <pl-password> "
+                "-k <pl-ssh-key> -n <node-count> ")
+
+    parser = OptionParser(usage = usage)
+    parser.add_option("-s", "--pl-slice", dest="pl_slice",
+            help="PlanetLab slicename", default=pl_slice, type="str")
+    parser.add_option("-u", "--pl-user", dest="pl_user",
+            help="PlanetLab web username", default=pl_user, type="str")
+    parser.add_option("-p", "--pl-password", dest="pl_password",
+            help="PlanetLab web password", default=pl_password, type="str")
+    parser.add_option("-k", "--pl-ssh-key", dest="pl_ssh_key",
+            help="Path to private SSH key associated with the PL account",
+            default=pl_ssh_key, type="str")
+    parser.add_option("-n", "--node-count", dest="node_count",
+            help="Number of nodes in the wireless network",
+            default = 4, type="int")
+
+    (options, args) = parser.parse_args()
+
+    return (options.pl_slice, options.pl_user, options.pl_password, 
+            options.pl_ssh_key, options.node_count)
+
+# == add host and simu =======================================================
+def add_host_simu(ec, hostname, username, pl_user, pl_password, ssh_key):
+    host = ec.register_resource("planetlab::Node")
+    ec.set(host, "hostname", hostname)
+
+    if username:
+        ec.set(host, "username", username)
+
+    if pl_user:
+        ec.set(host, "pluser", pl_user)
+
+    if pl_password:
+        ec.set(host, "plpassword", pl_password)
+
+    if ssh_key:
+        ec.set(host, "identity", ssh_key)
+
+    ec.set(host, "cleanProcesses", True)
+    ec.set(host, "cleanExperiment", True)
+
+    simu = ec.register_resource("linux::ns3::Simulation")
+    ec.set(simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")
+    ec.set(simu, "checksumEnabled", True)
+    ec.set(simu, "verbose", True)
+    ec.set(simu, "enableDump", True)
+    ec.set (simu, "StopTime", "200s")
+    ec.register_connection(simu, host)
+
+    return host, simu
+
+# == build topology  =========================================================
+
+def add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode):
+    # create the WiFi network interface
+    dev = ec.register_resource("ns3::WifiNetDevice")
+
+    # specify the network layer parameters
+    ec.set(dev, "ip", ip)
+    ec.set(dev, "prefix", prefixlen)
+    ec.register_connection(ns3_node, dev)
+
+    # specify the MAC layer parameters
+    #
+    # can be in access point mode or not
+    if ap_mode:
+        mac = ec.register_resource("ns3::ApWifiMac")
+    else:
+        mac = ec.register_resource("ns3::StaWifiMac")
+
+    # the MAC is IEEE 802.11a
+    ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")
+    ec.register_connection(dev, mac)
+
+    # specify the physical layer parameters
+    phy = ec.register_resource("ns3::YansWifiPhy")
+    #
+    # it physical layer is IEEE802.11a
+    ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")
+    ec.register_connection(dev, phy)
+    #
+    # specify an error model for transmissions
+    error = ec.register_resource("ns3::NistErrorRateModel")
+    ec.register_connection(phy, error)
+
+    # specify the Wifi manager to be assocated with the interface
+    manager = ec.register_resource("ns3::ArfWifiManager")
+    ec.register_connection(dev, manager)
+
+    return dev, phy
+
+def add_ns3_wifi_channel(ec):
+    channel = ec.register_resource("ns3::YansWifiChannel")
+
+    delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")
+    ec.register_connection(channel, delay)
+
+    loss  = ec.register_resource("ns3::LogDistancePropagationLossModel")
+    ec.register_connection(channel, loss)
+
+    return channel
+
+# == Add random mobility
+def add_ns3_random_mobility(ec, ns3_node):
+    speed =  1
+    bounds_width = 100
+    bounds_height = 100
+    x = randint(0, bounds_width)
+    y = randint(0, bounds_height)
+    z = 0
+
+    position = "%d:%d:%d" % (x, y, z)
+    bounds = "0|%d|0|%d" % (bounds_width, bounds_height)
+    speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)
+    pause = "ns3::ConstantRandomVariable[Constant=1.0]"
+
+    mobility = ec.register_resource("ns3::RandomDirection2dMobilityModel")
+    ec.set(mobility, "Position", position)
+    ec.set(mobility, "Bounds", bounds)
+    ec.set(mobility, "Speed", speed)
+    ec.set(mobility, "Pause",  pause)
+    ec.register_connection(ns3_node, mobility)
+
+    return mobility
+
+# == Add constant mobility
+def add_ns3_constant_mobility(ec, ns3_node):
+    mobility = ec.register_resource("ns3::ConstantPositionMobilityModel")
+    position = "%d:%d:%d" % (0, 50, 0)
+    ec.set(mobility, "Position", position)
+    ec.register_connection(ns3_node, mobility)
+
+    return mobility
+
+# == add ns-3 node
+def add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False):
+    ns3_node = ec.register_resource("ns3::Node")
+    ec.set(ns3_node, "enableStack", True)
+    ec.register_connection(ns3_node, simu)
+
+    dev, phy = add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode)
+    ec.register_connection(channel, phy)
+
+    if not ap_mode:
+        add_ns3_random_mobility(ec, ns3_node)
+    else:
+        add_ns3_constant_mobility(ec, ns3_node)
+
+    return ns3_node
+
+# == add DCE agent
+def add_dce_agent(ec, ns3_node):
+    agent = ec.register_resource("linux::ns3::dce::Application")
+    ec.set(agent, "sources", "code/agent.c")
+    ec.set(agent, "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")
+    ec.set(agent, "binary", "agent")
+    ec.set(agent, "stackSize", 1<<20)
+    ec.set(agent, "StartTime", "10s")
+    ec.set(agent, "StopTime", "200s")
+
+    ec.register_connection(agent, ns3_node)
+
+    return agent
+
+# == add DCE transmitter
+def add_dce_transmitter(ec, ns3_node, target):
+    transmitter = ec.register_resource("linux::ns3::dce::Application")
+    ec.set(transmitter, "sources", "code/transmitter.c")
+    ec.set(transmitter, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")
+    ec.set(transmitter, "binary", "transmitter")
+    ec.set(transmitter, "arguments", target)
+    ec.set(transmitter, "stackSize", 1<<20)
+    ec.set(transmitter, "StartTime", "10s")
+    ec.set(transmitter, "StopTime", "200s")
+    
+    ec.register_connection(transmitter, ns3_node)
+
+    return transmitter
+
+# == Add ns-3 route
+def add_ns3_route(ec, ns3_node, network, prefixlen, nexthop):
+    route = ec.register_resource("ns3::Route")
+    ec.set(route, "network", network)
+    ec.set(route, "prefix", prefixlen)
+    ec.set(route, "nexthop", nexthop)
+    ec.register_connection(route, ns3_node)
+
+    return route
+
+# = build ns3 topology =======================================================
+def build_ns3_topology(ec, simu, node_count, network, prefixlen, agent_ip):
+    channel = add_ns3_wifi_channel(ec)
+
+    if PY2:
+        net = ipaddr.IPv4Network("%s/%s" % (network, prefixlen)) 
+        itr = net.iterhosts()
+    else:
+        net = ipaddress.IPv4Network("%s/%s" % (network, prefixlen)) 
+        itr = net.hosts()
+
+    ap_ip = next(itr).exploded
+    ap = add_ns3_node(ec, simu, ap_ip, prefixlen, channel, ap_mode=True)
+
+    agent = None
+    if ap_ip == agent_ip:
+        agent = add_dce_agent(ec, ap)
+
+    for i in range(0, node_count):
+        ip = itr.next().exploded
+        sensor = add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False)
+        transmitter = add_dce_transmitter(ec, sensor, ap_ip)
+        add_ns3_route(ec, sensor, network="0.0.0.0", prefixlen="0", nexthop=ap_ip)
+
+    return ap, agent
+
+
+# == add FdNetDevice =========================================================
+def add_fdnet_device(ec, ap, ip, prefixlen):
+    fddev = ec.register_resource("ns3::FdNetDevice")
+    ec.set(fddev, "ip", ip)
+    ec.set(fddev, "prefix", prefixlen)
+    ec.register_connection(ap, fddev)
+
+    return fddev
+
+# == connect with UDP tunnel =================================================
+def connect_with_udp_tunnel(ec, fddev1, fddev2):                                                             
+    tunnel = ec.register_resource("planetlab::ns3::FdUdpTunnel")
+    ec.register_connection(tunnel, fddev1)
+    ec.register_connection(tunnel, fddev2)
+
+    return tunnel
+
+# == connect with virtual link ===============================================
+def connect_with_virtual_link(ec, tap, fddev):                                                                   
+    link = ec.register_resource("planetlab::ns3::TunTapFdLink")                          
+    ec.register_connection(link, tap)
+    ec.register_connection(link, fddev)
+
+    return link
+
+# == Add planet lab route ====================================================
+
+def add_planetlab_route(ec, dev, network, prefixlen, nexthop):
+    route = ec.register_resource("planetlab::Vroute")
+    ec.set(route, "network", network)
+    ec.set(route, "prefix", prefixlen)
+    ec.set(route, "nexthop", nexthop)
+    ec.register_connection(route, dev)
+
+    return route
+