added metric to routes
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 4 Jul 2011 13:29:31 +0000 (15:29 +0200)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 4 Jul 2011 13:29:31 +0000 (15:29 +0200)
src/nepi/core/design.py
src/nepi/core/execute.py
src/nepi/core/testbed_impl.py
src/nepi/testbeds/netns/metadata_v01.py
src/nepi/testbeds/ns3/factories_metadata_v3_9.py
src/nepi/testbeds/planetlab/interfaces.py
src/nepi/testbeds/planetlab/node.py
src/nepi/util/parser/_xml.py
src/nepi/util/parser/base.py
src/nepi/util/validation.py

index 6347510..9a23ad2 100644 (file)
@@ -139,12 +139,6 @@ class Trace(AttributesMap):
 class Address(AttributesMap):
     def __init__(self):
         super(Address, self).__init__()
-        self.add_attribute(name = "AutoConfigure", 
-                help = "If set, this address will automatically be assigned", 
-                type = Attribute.BOOL,
-                value = False,
-                flags = Attribute.DesignOnly,
-                validation_function = validation.is_bool)
         self.add_attribute(name = "Address",
                 help = "Address number", 
                 type = Attribute.STRING,
@@ -168,7 +162,7 @@ class Route(AttributesMap):
         self.add_attribute(name = "Destination", 
                 help = "Network destintation",
                 type = Attribute.STRING, 
-                validation_function = validation.is_ip_address)
+                validation_function = validation.is_ref_address)
         self.add_attribute(name = "NetPrefix",
                 help = "Network destination prefix", 
                 type = Attribute.INTEGER, 
@@ -180,7 +174,13 @@ class Route(AttributesMap):
                 help = "Address for the next hop", 
                 type = Attribute.STRING,
                 flags = Attribute.HasNoDefaultValue,
-                validation_function = validation.is_ip_address)
+                validation_function = validation.is_ref_address)
+        self.add_attribute(name = "Metric",
+                help = "Routing metric", 
+                type = Attribute.INTEGER,
+                value = 0,
+                flags = Attribute.HasNoDefaultValue,
+                validation_function = validation.is_integer)
 
 class Box(AttributesMap):
     def __init__(self, guid, factory, testbed_guid, container = None):
index f8d1a9a..398a718 100644 (file)
@@ -235,7 +235,7 @@ class TestbedController(object):
         """Instructs the addition of an address"""
         raise NotImplementedError
 
-    def defer_add_route(self, guid, destination, netprefix, nexthop):
+    def defer_add_route(self, guid, destination, netprefix, nexthop, metric = 0):
         """Instructs the addition of a route"""
         raise NotImplementedError
 
@@ -880,13 +880,13 @@ class ExperimentController(object):
                                 cross_guid, cross_connector_type_name)
                 for trace_id in data.get_trace_data(guid):
                     testbed.defer_add_trace(guid, trace_id)
-                for (autoconf, address, netprefix, broadcast) in \
+                for (address, netprefix, broadcast) in \
                         data.get_address_data(guid):
                     if address != None:
                         testbed.defer_add_address(guid, address, netprefix, 
                                 broadcast)
-                for (destination, netprefix, nexthop) in data.get_route_data(guid):
-                    testbed.defer_add_route(guid, destination, netprefix, nexthop)
+                for (destination, netprefix, nexthop, metric) in data.get_route_data(guid):
+                    testbed.defer_add_route(guid, destination, netprefix, nexthop, metric)
     
     def _program_testbed_cross_connections(self, data):
         data_guids = data.guids
index cf1f9c1..ec324b1 100644 (file)
@@ -177,7 +177,7 @@ class TestbedController(execute.TestbedController):
             self._add_address[guid] = list()
         self._add_address[guid].append((address, netprefix, broadcast))
 
-    def defer_add_route(self, guid, destination, netprefix, nexthop):
+    def defer_add_route(self, guid, destination, netprefix, nexthop, metric = 0):
         if not guid in self._create:
             raise RuntimeError("Element guid %d doesn't exist" % guid)
         factory = self._get_factory(guid)
@@ -186,7 +186,7 @@ class TestbedController(execute.TestbedController):
                     factory.factory_id)
         if not guid in self._add_route:
             self._add_route[guid] = list()
-        self._add_route[guid].append((destination, netprefix, nexthop)) 
+        self._add_route[guid].append((destination, netprefix, nexthop, metric)) 
 
     def do_setup(self):
         self._root_directory = self._attributes.\
index 240f504..aa3a805 100644 (file)
@@ -232,9 +232,9 @@ def configure_node(testbed_instance, guid):
         return
     routes = testbed_instance._add_route[guid]
     for route in routes:
-        (destination, netprefix, nexthop) = route
+        (destination, netprefix, nexthop, metric) = route
         element.add_route(prefix = destination, prefix_len = netprefix,
-            nexthop = nexthop)
+            nexthop = nexthop, metric = metric)
 
 ### Factory information ###
 
index 8c43a96..cddabc2 100644 (file)
@@ -469,7 +469,7 @@ def configure_node(testbed_instance, guid):
     ns3 = testbed_instance.ns3
     routes = testbed_instance._add_route[guid]
     for route in routes:
-        (destination, netprefix, nexthop) = route
+        (destination, netprefix, nexthop, metric) = route
         address = ns3.Ipv4Address(destination)
         if nexthop:
             nexthop_address = ns3.Ipv4Address(nexthop)
index 088127e..57c3736 100644 (file)
@@ -192,7 +192,7 @@ class TunIface(object):
             if pointopoint:
                 prefix = 32
                 
-            dest, destprefix, nexthop = route
+            dest, destprefix, nexthop, metric = route
             
             myNet = ipaddr.IPNetwork("%s/%d" % (addr, prefix))
             gwIp = ipaddr.IPNetwork(nexthop)
index 2afdd47..f04c811 100644 (file)
@@ -459,7 +459,7 @@ class Node(object):
             for dev in devs:
                 if dev.routes_here(route):
                     # Schedule rule
-                    dest, prefix, nexthop = route
+                    dest, prefix, nexthop, metric = route
                     rules.append(
                         "add %s%s gw %s %s" % (
                             dest,
index 8eb3f07..5f67cab 100644 (file)
@@ -104,12 +104,9 @@ class XmlExperimentParser(ExperimentParser):
 
     def addresses_data_to_xml(self, doc, parent_tag, guid, data):
         addresses_tag = doc.createElement("addresses") 
-        for (autoconfigure, address, netprefix, broadcast) \
-                in data.get_address_data(guid):
+        for (address, netprefix, broadcast) in data.get_address_data(guid):
             address_tag = doc.createElement("address") 
             addresses_tag.appendChild(address_tag)
-            if autoconfigure:
-                address_tag.setAttribute("AutoConfigure", str(autoconf))
             if address:
                 address_tag.setAttribute("Address", str(address))
             address_tag.setAttribute("NetPrefix", str(netprefix))
@@ -120,13 +117,14 @@ class XmlExperimentParser(ExperimentParser):
 
     def routes_data_to_xml(self, doc, parent_tag, guid, data):
         routes_tag = doc.createElement("routes") 
-        for (destination, netprefix, nexthop) \
+        for (destination, netprefix, nexthop, metric) \
                 in data.get_route_data(guid):
             route_tag = doc.createElement("route") 
             routes_tag.appendChild(route_tag)
             route_tag.setAttribute("Destination", str(destination))
             route_tag.setAttribute("NetPrefix", str(netprefix))
             route_tag.setAttribute("NextHop", str(nexthop))
+            route_tag.setAttribute("Metric", str(metric))
         if routes_tag.hasChildNodes():
             parent_tag.appendChild(routes_tag)
 
@@ -250,16 +248,13 @@ class XmlExperimentParser(ExperimentParser):
                 getElementsByTagName("address")
         for address_tag in address_tag_list:
             if address_tag.nodeType == tag.ELEMENT_NODE:
-                autoconf = address_tag.getAttribute("AutoConfigure") == "True" \
-                       if address_tag.hasAttribute("AutoConfigure") else None
                 address = str(address_tag.getAttribute("Address")) \
                        if address_tag.hasAttribute("Address") else None
                 netprefix = int(address_tag.getAttribute("NetPrefix")) \
                        if address_tag.hasAttribute("NetPrefix") else None
                 broadcast = str(address_tag.getAttribute("Broadcast")) \
                        if address_tag.hasAttribute("Broadcast") else None
-                data.add_address_data(guid, autoconf, address, netprefix, 
-                        broadcast)
+                data.add_address_data(guid, address, netprefix, broadcast)
 
     def routes_data_from_xml(self, tag, guid, data):
         routes_tag_list = tag.getElementsByTagName("routes")
@@ -272,8 +267,10 @@ class XmlExperimentParser(ExperimentParser):
                 destination = str(route_tag.getAttribute("Destination"))
                 netprefix = int(route_tag.getAttribute("NetPrefix"))
                 nexthop = str(route_tag.getAttribute("NextHop"))
+                metric = int(route_tag.getAttribute("Metric")) \
+                        if route_tag.hasAttribute("Metric") else 0
                 data.add_route_data(guid, destination, netprefix, 
-                        nexthop)
+                        nexthop, metric)
 
     def connections_data_from_xml(self, tag, guid, data):
         connections_tag_list = tag.getElementsByTagName("connections")
index c06dabc..5bdbcde 100644 (file)
@@ -72,15 +72,13 @@ class ExperimentData(object):
         connection_data = connections_data[connector_type_name]
         connection_data[other_guid] = other_connector_type_name
 
-    def add_address_data(self, guid, autoconf, address, netprefix, 
+    def add_address_data(self, guid, address, netprefix, 
             broadcast):
         data = self.data[guid]
         if not "addresses" in data:
             data["addresses"] = list()
         addresses_data = data["addresses"]
         address_data = dict()
-        if autoconf:
-            address_data["AutoConfigure"] = autoconf
         if address:
             address_data["Address"] = address
         address_data["NetPrefix"] = netprefix
@@ -88,7 +86,7 @@ class ExperimentData(object):
             address_data["Broadcast"] = broadcast
         addresses_data.append(address_data)
 
-    def add_route_data(self, guid, destination, netprefix, nexthop): 
+    def add_route_data(self, guid, destination, netprefix, nexthop, metric):
         data = self.data[guid]
         if not "routes" in data:
             data["routes"] = list()
@@ -96,7 +94,8 @@ class ExperimentData(object):
         route_data = dict({
             "Destination": destination,
             "NetPrefix": netprefix, 
-            "NextHop": nexthop 
+            "NextHop": nexthop, 
+            "Metric": metric
             })
         routes_data.append(route_data)
 
@@ -172,8 +171,7 @@ class ExperimentData(object):
         if not "addresses" in data:
             return []
         addresses_data = data["addresses"]
-        return [(data["AutoConfigure"] if "AutoConfigure" in data else None,
-                 data["Address"] if "Address" in data else None,
+        return [(data["Address"] if "Address" in data else None,
                  data["NetPrefix"] if "NetPrefix" in data else None,
                  data["Broadcast"] if "Broadcast" in data else None) \
                  for data in addresses_data]
@@ -185,7 +183,8 @@ class ExperimentData(object):
         routes_data = data["routes"]
         return [(data["Destination"],
                  data["NetPrefix"],
-                 data["NextHop"]) \
+                 data["NextHop"],
+                 data["Metric"]) \
                          for data in routes_data]
 
 class ExperimentParser(object):
@@ -243,21 +242,20 @@ class ExperimentParser(object):
 
     def addresses_to_data(self, data, guid, addresses):
         for addr in addresses:
-             autoconf = addr.get_attribute_value("AutoConfigure")
              address = addr.get_attribute_value("Address")
              netprefix = addr.get_attribute_value("NetPrefix")
              broadcast = addr.get_attribute_value("Broadcast") \
                     if addr.has_attribute("Broadcast") and \
                     addr.is_attribute_modified("Broadcast") else None
-             data.add_address_data(guid, autoconf, address, netprefix, 
-                    broadcast)
+             data.add_address_data(guid, address, netprefix, broadcast)
 
     def routes_to_data(self, data, guid, routes):
         for route in routes:
              destination = route.get_attribute_value("Destination")
              netprefix = route.get_attribute_value("NetPrefix")
              nexthop = route.get_attribute_value("NextHop")
-             data.add_route_data(guid, destination, netprefix, nexthop)
+             metric = route.get_attribute_value("Metric")
+             data.add_route_data(guid, destination, netprefix, nexthop, metric)
 
     def from_data(self, experiment_description, data):
         box_guids = list()
@@ -315,11 +313,8 @@ class ExperimentParser(object):
             box.enable_trace(name)
 
     def addresses_from_data(self, box, data):
-        for (autoconf, address, netprefix, broadcast) \
-                in data.get_address_data(box.guid):
+        for (address, netprefix, broadcast) in data.get_address_data(box.guid):
             addr = box.add_address()
-            if autoconf:
-                addr.set_attribute_value("AutoConfigure", autoconf)
             if address:
                 addr.set_attribute_value("Address", address)
             if netprefix != None:
@@ -328,12 +323,13 @@ class ExperimentParser(object):
                 addr.set_attribute_value("Broadcast", broadcast)
 
     def routes_from_data(self, box, data):
-         for (destination, netprefix, nexthop) \
+         for (destination, netprefix, nexthop, metric) \
                  in data.get_route_data(box.guid):
             addr = box.add_route()
             addr.set_attribute_value("Destination", destination)
             addr.set_attribute_value("NetPrefix", netprefix)
             addr.set_attribute_value("NextHop", nexthop)
+            addr.set_attribute_value("Metric", metric)
 
     def connections_from_data(self, experiment_description, guids, data):
         for guid in guids:
index 4d4a4d9..c78ea9b 100644 (file)
@@ -54,13 +54,19 @@ def is_ip6_address(attribute, value):
         return False
     return True
 
-# TODO: Allow netrefs!
 def is_ip_address(attribute, value):
     if not is_ip4_address(attribute, value) and \
             not is_ip6_address(attribute, value):
         return False
     return True
 
+# TODO: Allow netrefs!
+def is_ref_address(attribute, value):
+    if not is_ip4_address(attribute, value) and \
+            not is_ip6_address(attribute, value):
+        return False
+    return True
+
 def is_mac_address(attribute, value):
     regex = r'^([0-9a-zA-Z]{0,2}:)*[0-9a-zA-Z]{0,2}'
     found = re.search(regex, value)