cross_data[cross_testbed_guid] = dict()
cross_testbed = self._testbeds[cross_testbed_guid]
for cross_guid in guid_list:
- elem_cross_data = dict()
+ elem_cross_data = dict(
+ _guid = cross_guid,
+ _testbed_guid = cross_testbed_guid,
+ _testbed_id = cross_testbed.testbed_id,
+ _testbed_version = cross_testbed.testbed_version)
cross_data[cross_testbed_guid][cross_guid] = elem_cross_data
attributes_list = cross_testbed.get_attribute_list(cross_guid)
for attr_name in attributes_list:
del DC
+
+ STANDARD_ATTRIBUTE_BUNDLES = {
+ "tun_proto" : dict({
+ "name": "tun_proto",
+ "help": "TUNneling protocol used",
+ "type": Attribute.STRING,
+ "flags": Attribute.Invisible | Attribute.ReadOnly,
+ "validation_function": validation.is_string,
+ }),
+ "tun_addr" : dict({
+ "name": "tun_addr",
+ "help": "IP address of the tunnel endpoint",
+ "type": Attribute.STRING,
+ "flags": Attribute.Invisible | Attribute.ReadOnly,
+ "validation_function": validation.is_ip_address,
+ }),
+ "tun_port" : dict({
+ "name": "tun_port",
+ "help": "IP port of the tunnel endpoint",
+ "type": Attribute.INTEGER,
+ "flags": Attribute.Invisible | Attribute.ReadOnly,
+ "validation_function": validation.is_integer,
+ }),
+ }
+
def __init__(self, testbed_id, version):
self._version = version
def _add_attributes(self, factory, info, attr_key, box_attributes = False, attr_bundle = ()):
if not attr_bundle and info and attr_key in info:
- attr_bundle = [ (attr_id, self._metadata.attributes[attr_id])
+ definitions = self.STANDARD_ATTRIBUTE_BUNDLES.copy()
+ definitions.update(self._metadata.attributes)
+ attr_bundle = [ (attr_id, definitions[attr_id])
for attr_id in info[attr_key] ]
for attr_id, attr_info in attr_bundle:
name = attr_info["name"]
raise RuntimeError, "All external interface devices must be connected to the Internet"
+class _CrossIface(object):
+ def __init__(self, proto, addr, port):
+ self.tun_proto = proto
+ self.tun_addr = addr
+ self.tun_port = port
+
class TunIface(object):
def __init__(self, api=None):
if not api:
raise RuntimeError, "Misconfigured TUN iface - missing address"
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))):
+ # Ad-hoc peer_iface
+ self.peer_iface = CrossIface(
+ self.peer_proto,
+ self.peer_addr,
+ self.peer_port)
if self.peer_iface:
if not self.peer_proto_impl:
self.peer_proto_impl = tunproto.PROTO_MAP[self.peer_proto](
self.peer_proto_impl.prepare()
def setup(self):
- if self.peer_iface:
+ if self.peer_proto_impl:
self.peer_proto_impl.setup()
def cleanup(self):
iface.peer_proto = \
iface.tun_proto = proto
+def crossconnect_tun_iface_peer_init(proto, testbed_instance, iface_guid, peer_iface_data):
+ iface = testbed_instance._elements[iface_guid]
+ iface.peer_iface = None
+ iface.peer_addr = peer_iface_data.get("tun_addr")
+ iface.peer_proto = peer_iface_data.get("tun_proto")
+ iface.peer_port = peer_iface_data.get("tun_port")
+ iface.tun_proto = proto
+
+ preconfigure_tuniface(testbed_instance, iface_guid)
+
+def crossconnect_tun_iface_peer_compl(proto, testbed_instance, iface_guid, peer_iface_data):
+ postconfigure_tuniface(testbed_instance, iface_guid)
+
def connect_dep(testbed_instance, node_guid, app_guid):
node = testbed_instance._elements[node_guid]
app = testbed_instance._elements[app_guid]
break
# Set standard TUN attributes
- element.tun_addr = element.external_iface.address
- element.tun_port = 15000 + int(guid)
+ if (not element.tun_addr or not element.tun_port) and element.external_iface:
+ element.tun_addr = element.external_iface.address
+ element.tun_port = 15000 + int(guid)
# Set enabled traces
traces = testbed_instance._get_traces(guid)
element.validate()
# First-phase setup
- element.prepare(
- 'tun-%s' % (guid,),
- id(element) < id(element.peer_iface) )
+ if element.peer_proto:
+ if element.peer_iface and isinstance(element.peer_iface, testbed_instance._interfaces.TunIface):
+ # intra tun
+ listening = id(element) < id(element.peer_iface)
+ else:
+ # cross tun
+ if not element.tun_addr or not element.tun_port:
+ listening = True
+ elif not element.peer_addr or not element.peer_port:
+ listening = True
+ else:
+ # both have addresses...
+ # ...the one with the lesser address listens
+ listening = element.tun_addr < element.peer_addr
+ element.prepare(
+ 'tun-%s' % (guid,),
+ listening)
def postconfigure_tuniface(testbed_instance, guid):
element = testbed_instance._elements[guid]
"init_code": functools.partial(connect_tun_iface_peer,"udp"),
"can_cross": False
}),
+ dict({
+ "from": (TESTBED_ID, TUNIFACE, "tcp"),
+ "to": (None, None, "tcp"),
+ "init_code": functools.partial(crossconnect_tun_iface_peer_init,"tcp"),
+ "compl_code": functools.partial(crossconnect_tun_iface_peer_compl,"tcp"),
+ "can_cross": True
+ }),
+ dict({
+ "from": (TESTBED_ID, TUNIFACE, "udp"),
+ "to": (None, None, "udp"),
+ "init_code": functools.partial(crossconnect_tun_iface_peer_init,"udp"),
+ "compl_code": functools.partial(crossconnect_tun_iface_peer_compl,"udp"),
+ "can_cross": True
+ }),
]
attributes = dict({
"configure_function": postconfigure_tuniface,
"box_attributes": [
"up", "device_name", "mtu", "snat",
- "txqueuelen"
+ "txqueuelen",
+ "tun_proto", "tun_addr", "tun_port"
],
"traces": ["packets"],
"connector_types": ["node","udp","tcp"]