from nepi.core import metadata
from nepi.core.attributes import Attribute
from nepi.util import validation
-from nepi.util.constants import AF_INET, STATUS_NOT_STARTED, STATUS_RUNNING, \
+from nepi.util.constants import STATUS_NOT_STARTED, STATUS_RUNNING, \
STATUS_FINISHED
NODE = "Node"
### Connection functions ####
-def connect_switch(switch, interface):
+def connect_switch(testbed_instance, switch_guid, interface_guid):
+ switch = testbed_instance._elements[switch_guid]
+ interface = testbed_instance._elements[interface_guid]
switch.connect(interface)
-#XXX: This connection function cannot be use to transfer a file descriptor
-# to a remote tap device
-def connect_fd_local(tap, fdnd):
+def connect_fd(testbed_instance, tap_guid, cross_data):
import passfd
import socket
+ tap = testbed_instance._elements[tap_guid]
fd = tap.file_descriptor
- address = fdnd.socket_address
+ address = cross_data["LinuxSocketAddress"]
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.connect(address)
passfd.sendfd(sock, fd, '0')
### Creation functions ###
-def create_node(testbed_instance, guid, parameters):
+def create_node(testbed_instance, guid):
+ parameters = testbed_instance._get_parameters(guid)
forward_X11 = False
if "forward_X11" in parameters:
forward_X11 = parameters["forward_X11"]
element = testbed_instance.netns.Node(forward_X11 = forward_X11)
testbed_instance.elements[guid] = element
-def create_p2piface(testbed_instance, guid, parameters):
+def create_p2piface(testbed_instance, guid):
if guid in testbed_instance.elements:
# The interface pair was already instantiated
return
testbed_instance.elements[guid] = element1
testbed_instance.elements[guid2] = element2
-def create_tapiface(testbed_instance, guid, parameters):
+def create_tapiface(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 \
element = node.add_tap()
testbed_instance.elements[guid] = element
-def create_nodeiface(testbed_instance, guid, parameters):
+def create_nodeiface(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 \
element = node.add_if()
testbed_instance.elements[guid] = element
-def create_switch(testbed_instance, guid, parameters):
+def create_switch(testbed_instance, guid):
element = testbed_instance.netns.Switch()
testbed_instance.elements[guid] = element
-def create_application(testbed_instance, guid, parameters):
+def create_application(testbed_instance, guid):
testbed_instance.elements[guid] = None # Delayed construction
### Start/Stop functions ###
-def start_application(testbed_instance, guid, parameters, traces):
+def start_application(testbed_instance, guid):
+ parameters = testbed_instance._get_parameters(guid)
+ traces = testbed_instance._get_traces(guid)
user = parameters["user"]
command = parameters["command"]
stdout = stderr = None
return STATUS_RUNNING
return STATUS_FINISHED
+### Configure functions ###
+
+def configure_device(testbed_instance, guid):
+ element = testbed_instance._elements[guid]
+ if not guid in testbed_instance._add_address:
+ return
+ addresses = testbed_instance._add_address[guid]
+ for address in addresses:
+ (address, netprefix, broadcast) = address
+ # TODO: Decide if we should add a ipv4 or ipv6 address
+ element.add_v4_address(address, netprefix)
+
+def configure_node(testbed_instance, guid):
+ element = testbed_instance._elements[guid]
+ if not guid in testbed_instance._add_route:
+ return
+ routes = testbed_instance._add_route[guid]
+ for route in routes:
+ (destination, netprefix, nexthop) = route
+ element.add_route(prefix = destination, prefix_len = netprefix,
+ nexthop = nexthop)
+
### Factory information ###
connector_types = dict({
dict({
"from": (TESTBED_ID, NODE, "devs"),
"to": (TESTBED_ID, P2PIFACE, "node"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, NODE, "devs"),
"to": (TESTBED_ID, TAPIFACE, "node"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, NODE, "devs"),
"to": (TESTBED_ID, NODEIFACE, "node"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, P2PIFACE, "p2p"),
"to": (TESTBED_ID, P2PIFACE, "p2p"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, TAPIFACE, "fd"),
"to": (NS3_TESTBED_ID, FDNETDEV, "fd"),
- "code": connect_fd_local,
+ "compl_code": connect_fd,
"can_cross": True
}),
dict({
"from": (TESTBED_ID, SWITCH, "devs"),
"to": (TESTBED_ID, NODEIFACE, "switch"),
- "code": connect_switch,
+ "init_code": connect_switch,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, NODE, "apps"),
"to": (TESTBED_ID, APPLICATION, "node"),
- "code": None,
"can_cross": False
})
]
"help": "Forward x11 from main namespace to the node",
"type": Attribute.BOOL,
"value": False,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_bool
}),
"lladdr": dict({
"name": "lladdr",
"help": "Mac address",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_mac_address
}),
"up": dict({
"help": "Link up",
"type": Attribute.BOOL,
"value": False,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
"validation_function": validation.is_bool
}),
"device_name": dict({
"name": "name",
"help": "Device name",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_string
}),
"mtu": dict({
"name": "mtu",
"help": "Maximum transmition unit for device",
"type": Attribute.INTEGER,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
"validation_function": validation.is_integer
}),
"broadcast": dict({
"name": "broadcast",
"help": "Broadcast address",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
"validation_function": validation.is_string # TODO: should be is address!
}),
"multicast": dict({
"help": "Multicast enabled",
"type": Attribute.BOOL,
"value": False,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
"validation_function": validation.is_bool
}),
"arp": dict({
"help": "ARP enabled",
"type": Attribute.BOOL,
"value": False,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
"validation_function": validation.is_bool
}),
"command": dict({
"name": "command",
"help": "Command line string",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_string
}),
"user": dict({
"name": "user",
"help": "System user",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_string
}),
"stdin": dict({
"name": "stdin",
"help": "Standard input",
"type": Attribute.STRING,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": False,
- "visible": True,
+ "flags": Attribute.DesignOnly,
"validation_function": validation.is_string
}),
- "max_addresses": dict({
- "name": "MaxAddresses",
- "help": "Maximum number of addresses allowed by the device",
- "type": Attribute.INTEGER,
- "value": None,
- "range": None,
- "allowed": None,
- "readonly": True,
- "visible": False,
- "validation_function": validation.is_integer
- }),
- "family": dict({
- "name": "Family",
- "help": "IP address family",
- "type": Attribute.INTEGER,
- "value": AF_INET,
- "range": None,
- "allowed": None,
- "readonly": True,
- "visible": False,
- "validation_function": validation.is_integer
- }),
-
})
traces = dict({
})
})
-factories_order = [ NODE, P2PIFACE, NODEIFACE, TAPIFACE, SWITCH,
+create_order = [ NODE, P2PIFACE, NODEIFACE, TAPIFACE, SWITCH,
+ APPLICATION ]
+
+configure_order = [ P2PIFACE, NODEIFACE, TAPIFACE, SWITCH, NODE,
APPLICATION ]
factories_info = dict({
"help": "Emulated Node with virtualized network stack",
"category": "topology",
"create_function": create_node,
- "start_function": None,
- "stop_function": None,
- "status_function": None,
+ "configure_function": configure_node,
"box_attributes": ["forward_X11"],
"connector_types": ["devs", "apps"]
}),
"help": "Point to point network interface",
"category": "devices",
"create_function": create_p2piface,
- "start_function": None,
- "stop_function": None,
- "status_function": None,
- "factory_attributes": ["family", "max_addresses"],
+ "configure_function": configure_device,
"box_attributes": ["lladdr", "up", "device_name", "mtu",
"multicast", "broadcast", "arp"],
"connector_types": ["node", "p2p"]
"help": "Tap device network interface",
"category": "devices",
"create_function": create_tapiface,
- "start_function": None,
- "stop_function": None,
- "status_function": None,
- "factory_attributes": ["family", "max_addresses"],
+ "configure_function": configure_device,
"box_attributes": ["lladdr", "up", "device_name", "mtu",
"multicast", "broadcast", "arp"],
"connector_types": ["node", "fd"]
"help": "Node network interface",
"category": "devices",
"create_function": create_nodeiface,
- "start_function": None,
- "stop_function": None,
- "status_function": None,
- "factory_attributes": ["family", "max_addresses"],
+ "configure_function": configure_device,
"box_attributes": ["lladdr", "up", "device_name", "mtu",
"multicast", "broadcast", "arp"],
"connector_types": ["node", "switch"]
"help": "Switch interface",
"category": "devices",
"create_function": create_switch,
- "start_function": None,
- "stop_function": None,
- "status_function": None,
"box_attributes": ["up", "device_name", "mtu", "multicast"],
#TODO: Add attribute ("Stp", help, type, value, range, allowed, readonly, validation_function),
#TODO: Add attribute ("ForwarddDelay", help, type, value, range, allowed, readonly, validation_function),
"category": "applications",
"create_function": create_application,
"start_function": start_application,
- "stop_function": None,
"status_function": status_application,
"box_attributes": ["command", "user"],
"connector_types": ["node"],
}),
})
+testbed_attributes = dict({
+ "enable_debug": dict({
+ "name": "enableDebug",
+ "help": "Enable netns debug output",
+ "type": Attribute.BOOL,
+ "value": False,
+ "validation_function": validation.is_bool
+ }),
+ })
+
class VersionedMetadataInfo(metadata.VersionedMetadataInfo):
@property
- def connections_types(self):
- return connection_types
+ def connector_types(self):
+ return connector_types
@property
def connections(self):
return traces
@property
- def factories_order(self):
- return factories_order
+ def create_order(self):
+ return create_order
+
+ @property
+ def configure_order(self):
+ return configure_order
@property
def factories_info(self):
return factories_info
+ @property
+ def testbed_attributes(self):
+ return testbed_attributes
+