Added routes to OMF nodes
[nepi.git] / src / nepi / testbeds / planetlab / interfaces.py
index c853a37..f4df82f 100644 (file)
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
 from constants import TESTBED_ID
@@ -61,9 +60,16 @@ class NodeIface(object):
         
         if self.node is None or self.node._node_id is None:
             raise RuntimeError, "Cannot pick interface without an assigned node"
-        
+      
+        # HACK: SFA doesnt give the node_id!!
+        if not isinstance(self.node._node_id, int):
+            node_data = self._api.GetNodes(filters={'hostname':self.node.hostname}, fields=('node_id',))[0]
+            node_id = node_data['node_id']
+        else:
+            node_id = self.node._node_id
+
         avail = self._api.GetInterfaces(
-            node_id=self.node._node_id, 
+            node_id=node_id, 
             is_primary=self.primary,
             fields=('interface_id','mac','netmask','ip') )
         
@@ -94,7 +100,12 @@ class _CrossIface(object):
         self.tun_addr = addr
         self.tun_port = port
         self.tun_cipher = cipher
-        
+
+        # Attributes
+        self.address = None
+        self.netprefix = None
+        self.netmask = None
         # Cannot access cross peers
         self.peer_proto_impl = None
     
@@ -126,7 +137,7 @@ class TunIface(object):
         self.up = None
         self.mtu = None
         self.snat = False
-        self.txqueuelen = None
+        self.txqueuelen = 1000
         self.pointopoint = None
         self.multicast = False
         self.bwlimit = None
@@ -139,6 +150,7 @@ class TunIface(object):
         
         # These get initialized when the iface is connected to any filter
         self.filter_module = None
+        self.multicast_forwarder = None
         
         # These get initialized when the iface is configured
         self.external_iface = None
@@ -187,6 +199,14 @@ class TunIface(object):
         if self.peer_proto_impl:
             return self.peer_proto_impl.if_name
 
+    def if_up(self):
+        if self.peer_proto_impl:
+            return self.peer_proto_impl.if_up()
+
+    def if_down(self):
+        if self.peer_proto_impl:
+            return self.peer_proto_impl.if_down()
+
     def routes_here(self, route):
         """
         Returns True if the route should be attached to this interface
@@ -195,19 +215,19 @@ class TunIface(object):
         if self.address and self.netprefix:
             addr, prefix = self.address, self.netprefix
             pointopoint = self.pointopoint
-            if not pointopoint:
+            if not pointopoint and self.peer_iface:
                 pointopoint = self.peer_iface.address
             
             if pointopoint:
                 prefix = 32
                 
-            dest, destprefix, nexthop, metric = route
+            dest, destprefix, nexthop, metric, device = route
             
-            myNet = ipaddr.IPNetwork("%s/%d" % (addr, prefix))
-            gwIp = ipaddr.IPNetwork(nexthop)
+            myNet = ipaddr.IPv4Network("%s/%d" % (addr, prefix))
+            gwIp = ipaddr.IPv4Network(nexthop)
             
             if pointopoint:
-                peerIp = ipaddr.IPNetwork(pointopoint)
+                peerIp = ipaddr.IPv4Network(pointopoint)
                 
                 if gwIp == peerIp:
                     return True
@@ -238,23 +258,23 @@ class TunIface(object):
         if self.tun_cipher != 'PLAIN' and self.peer_proto not in ('udp','tcp',None):
             raise RuntimeError, "Miscofnigured TUN: %s - ciphered tunnels only work with udp or tcp links" % (self,)
     
-    def _impl_instance(self, home_path, listening):
+    def _impl_instance(self, home_path):
         impl = self._PROTO_MAP[self.peer_proto](
-            self, self.peer_iface, home_path, self.tun_key, listening)
+            self, self.peer_iface, home_path, self.tun_key)
         impl.port = self.tun_port
+        impl.cross_slice = not self.peer_iface or isinstance(self.peer_iface, _CrossIface)
         return impl
     
     def recover(self):
         if self.peer_proto:
             self.peer_proto_impl = self._impl_instance(
-                self._home_path,
-                False) # no way to know, no need to know
+                self._home_path)
             self.peer_proto_impl.recover()
         else:
             self._delay_recover = True
     
-    def prepare(self, home_path, listening):
-        if not self.peer_iface and (self.peer_proto and (listening or (self.peer_addr and self.peer_port))):
+    def prepare(self, home_path):
+        if not self.peer_iface and (self.peer_proto and self.peer_addr):
             # Ad-hoc peer_iface
             self.peer_iface = _CrossIface(
                 self.peer_proto,
@@ -263,15 +283,13 @@ class TunIface(object):
                 self.peer_cipher)
         if self.peer_iface:
             if not self.peer_proto_impl:
-                self.peer_proto_impl = self._impl_instance(home_path, listening)
+                self.peer_proto_impl = self._impl_instance(home_path)
             if self._delay_recover:
                 self.peer_proto_impl.recover()
-            else:
-                self.peer_proto_impl.prepare()
     
-    def setup(self):
+    def launch(self):
         if self.peer_proto_impl:
-            self.peer_proto_impl.setup()
+            self.peer_proto_impl.launch()
     
     def cleanup(self):
         if self.peer_proto_impl:
@@ -282,9 +300,9 @@ class TunIface(object):
             self.peer_proto_impl.destroy()
             self.peer_proto_impl = None
 
-    def async_launch_wait(self):
+    def wait(self):
         if self.peer_proto_impl:
-            self.peer_proto_impl.async_launch_wait()
+            self.peer_proto_impl.wait()
 
     def sync_trace(self, local_dir, whichtrace, tracemap = None):
         if self.peer_proto_impl:
@@ -560,6 +578,28 @@ class ClassQueueFilter(TunFilter):
         # Attributes
         self.module = "classqueue.py"
 
+class LoggingClassQueueFilter(ClassQueueFilter):
+    _TRACEMAP = ClassQueueFilter._TRACEMAP.copy()
+    _TRACEMAP.update({
+        # tracename : (remotename, localname)
+        'queue_stats_f'   : ('queue_stats_f', 'queue_stats_f'),
+        'queue_stats_b'   : ('queue_stats_b', 'queue_stats_b'),
+    })
+    
+    def __init__(self, api=None):
+        super(LoggingClassQueueFilter, self).__init__(api)
+        # Attributes
+        self.module = "loggingclassqueue.py classqueue.py"
+        
+    def _args_get(self):
+        # Inject outpath
+        args = dict(filter(lambda x:len(x)>1, map(lambda x:x.split('=',1),(self._args or "").split(','))))
+        args["outpath"] = "queue_stats"
+        return ",".join(map("=".join, args.iteritems()))
+    def _args_set(self, value):
+        self._args = value
+    args = property(_args_get, _args_set)
+
 class ToSQueueFilter(TunFilter):
     def __init__(self, api=None):
         super(ToSQueueFilter, self).__init__(api)