Added routes to OMF nodes
[nepi.git] / src / nepi / testbeds / netns / metadata.py
index 7c46f7a..36e914a 100644 (file)
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
 from constants import TESTBED_ID, TESTBED_VERSION
@@ -6,11 +5,11 @@ from nepi.core import metadata
 from nepi.core.attributes import Attribute
 from nepi.util import tags, validation
 from nepi.util.constants import ApplicationStatus as AS, \
-        FactoryCategories as FC
+        FactoryCategories as FC, DeploymentConfiguration as DC
 
 from nepi.util.tunchannel_impl import \
     preconfigure_tunchannel, postconfigure_tunchannel, \
-    wait_tunchannel, create_tunchannel, \
+    prestart_tunchannel, create_tunchannel, \
     crossconnect_tunchannel_peer_init, \
     crossconnect_tunchannel_peer_compl
 
@@ -20,13 +19,14 @@ import functools
 NODE = "Node"
 P2PIFACE = "P2PNodeInterface"
 TAPIFACE = "TapNodeInterface"
+TUNIFACE = "TunNodeInterface"
 NODEIFACE = "NodeInterface"
 SWITCH = "Switch"
 APPLICATION = "Application"
 TUNCHANNEL = "TunChannel"
 
 NS3_TESTBED_ID = "ns3"
-FDNETDEV = "ns3::FileDescriptorNetDevice"
+FDNETDEV = "ns3::FdNetDevice"
 
 def _follow_trace(testbed_instance, guid, trace_id, filename):
     filepath = testbed_instance.trace_filepath(guid, trace_id, filename)
@@ -51,7 +51,10 @@ def connect_fd(testbed_instance, tap_guid, cross_data):
     passfd.sendfd(sock, tap.fd, '0')
     # TODO: after succesful transfer, the tap device should close the fd
 
-def connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid):
+def connect_tunchannel_tun(testbed_instance, chan_guid, tap_guid):
+    connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid, ethernet_mode=False)
+
+def connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid, ethernet_mode=True):
     tap = testbed_instance._elements[tap_guid]
     chan = testbed_instance._elements[chan_guid]
 
@@ -62,7 +65,7 @@ def connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid):
     chan.tun_socket = os.fdopen(tap.fd)
     
     # Set the channel to ethernet mode (it's a tap)
-    chan.ethernet_mode = True
+    chan.ethernet_mode = ethernet_mode
     
     # Check to see if the device uses PI headers
     # It's normally so
@@ -74,7 +77,7 @@ def connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid):
         IFF_NO_PI = 0x00001000
         struct_ifreq = "x"*16+"H"+"x"*22
         flags = struct.unpack(struct_ifreq,
-            fcntl.ioctl(tap.fd, TUNGETIFF, struct.pack(struct_ifreq,0)) )
+            fcntl.ioctl(tap.fd, TUNGETIFF, struct.pack(struct_ifreq,0)) )[0]
         with_pi = (0 == (flags & IFF_NO_PI))
     except:
         # maybe the kernel doesn't support the IOCTL,
@@ -149,6 +152,15 @@ def create_tapiface(testbed_instance, guid):
     element = node.add_tap()
     testbed_instance.elements[guid] = element
 
+def create_tuniface(testbed_instance, guid):
+    node_guid = testbed_instance.get_connected(guid, "node", "devs")
+    if len(node_guid) == 0:
+        raise RuntimeError("Can't instantiate interface %d outside netns \
+                node" % guid)
+    node = testbed_instance.elements[node_guid[0]]
+    element = node.add_tun()
+    testbed_instance.elements[guid] = element
+
 def create_nodeiface(testbed_instance, guid):
     node_guid = testbed_instance.get_connected(guid, "node", "devs")
     if len(node_guid) == 0:
@@ -233,7 +245,7 @@ def configure_node(testbed_instance, guid):
         return
     routes = testbed_instance._add_route[guid]
     for route in routes:
-        (destination, netprefix, nexthop, metric) = route
+        (destination, netprefix, nexthop, metric, device) = route
         element.add_route(prefix = destination, prefix_len = netprefix,
             nexthop = nexthop, metric = metric)
 
@@ -307,6 +319,11 @@ connections = [
         "to":   (TESTBED_ID, TAPIFACE, "node"),
         "can_cross": False
     }),
+    dict({
+        "from": (TESTBED_ID, NODE, "devs"),
+        "to":   (TESTBED_ID, TUNIFACE, "node"),
+        "can_cross": False
+    }),
     dict({
         "from": (TESTBED_ID, NODE, "devs"),
         "to":   (TESTBED_ID, NODEIFACE, "node"),
@@ -322,6 +339,12 @@ connections = [
         "to":   (None, None, "->fd"),
         "compl_code": connect_fd,
         "can_cross": True
+    }),
+    dict({
+        "from": (TESTBED_ID, TUNIFACE, "fd->"),
+        "to":   (None, None, "->fd"),
+        "compl_code": connect_fd,
+        "can_cross": True
     }),
      dict({
         "from": (TESTBED_ID, SWITCH, "devs"),
@@ -340,6 +363,12 @@ connections = [
         "init_code": connect_tunchannel_tap,
         "can_cross": False
     }),
+    dict({
+        "from": (TESTBED_ID, TUNCHANNEL, "->fd" ),
+        "to":   (TESTBED_ID, TUNIFACE, "fd->" ),
+        "init_code": connect_tunchannel_tun,
+        "can_cross": False
+    }),
     dict({
         "from": (TESTBED_ID, TUNCHANNEL, "tcp"),
         "to":   (None, None, "tcp"),
@@ -376,7 +405,8 @@ attributes = dict({
                 "name": "up",
                 "help": "Link up",
                 "type": Attribute.BOOL,
-                "value": False,
+                "value": True,
+                "flags": Attribute.NoDefaultValue, 
                 "validation_function": validation.is_bool
             }),
     "device_name": dict({
@@ -451,11 +481,11 @@ traces = dict({
     })
 
 create_order = [ NODE, P2PIFACE, NODEIFACE, TAPIFACE, 
-        TUNCHANNEL, SWITCH,
+        TUNIFACE, TUNCHANNEL, SWITCH,
         APPLICATION ]
 
 configure_order = [ P2PIFACE, NODEIFACE, TAPIFACE, 
-        TUNCHANNEL, SWITCH, 
+        TUNIFACE, TUNCHANNEL, SWITCH, 
         NODE, APPLICATION ]
 
 factories_info = dict({
@@ -489,6 +519,16 @@ factories_info = dict({
             "connector_types": ["node", "fd->"],
             "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
         }),
+    TUNIFACE: dict({
+            "help": "Tun device network interface",
+            "category": FC.CATEGORY_DEVICES,
+            "create_function": create_tuniface,
+            "configure_function": configure_device,
+            "box_attributes": ["lladdr", "up", "device_name", "mtu", 
+                "multicast", "broadcast", "arp"],
+            "connector_types": ["node", "fd->"],
+            "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
+        }),
     NODEIFACE: dict({
             "help": "Node network interface",
             "category": FC.CATEGORY_DEVICES,
@@ -530,12 +570,12 @@ factories_info = dict({
             "create_function": create_tunchannel,
             "preconfigure_function": preconfigure_tunchannel,
             "configure_function": postconfigure_tunchannel,
-            "prestart_function": wait_tunchannel,
+            "prestart_function": prestart_tunchannel,
             "help": "Channel to forward "+TAPIFACE+" data to "
                 "other TAP interfaces supporting the NEPI tunneling protocol.",
             "connector_types": ["->fd", "udp", "tcp"],
             "allow_addresses": False,
-            "box_attributes": ["tun_proto", "tun_addr", "tun_port", "tun_key"],
+            "box_attributes": ["tun_proto", "tun_addr", "tun_port", "tun_key", "tun_cipher"],
             "tags": [tags.TUNNEL],
     }),
 })
@@ -550,6 +590,10 @@ testbed_attributes = dict({
             }),
     })
 
+supported_recovery_policies = [
+        DC.POLICY_FAIL,
+    ]
+
 class MetadataInfo(metadata.MetadataInfo):
     @property
     def connector_types(self):
@@ -590,4 +634,8 @@ class MetadataInfo(metadata.MetadataInfo):
     @property
     def testbed_version(self):
         return TESTBED_VERSION
+    
+    @property
+    def supported_recover_policies(self):
+        return supported_recovery_policies