Index: fedd/federation/topdl.py
===================================================================
--- fedd/federation/topdl.py	(revision cc8d8e971b7119cdebf6c0a7ae1d1da299531ce6)
+++ fedd/federation/topdl.py	(revision 6c57fe9deaa34079254d04e9785091c1e9717115)
@@ -1,3 +1,5 @@
 #!/usr/local/bin/python
+
+import re
 
 class base:
@@ -31,5 +33,14 @@
 	return rv
 
-
+    def set_attribute(self, key, value):
+	attrs = getattr(self, 'attribute', None)
+	if attrs is None:
+	    return
+	for a in attrs:
+	    if a.attribute == key: 
+		a.value = value
+		break
+	else:
+	    attrs.append(Attribute(key, value))
 
 class ConsistencyError(RuntimeError): pass
@@ -207,4 +218,26 @@
 	if self.attribute:
 	    rv['attribute'] = [ a.to_dict() for a in self.attribute ]
+	return rv
+
+class ID(base):
+    def __init__(self, fedid=None, uuid=None, uri=None, localname=None,
+	    kerberosUsername=None):
+	self.fedid=fedid
+	self.uuid = uuid
+	self.uri = uri
+	self.localname = localname
+	self.kerberosUsername = kerberosUsername
+
+    def clone(self):
+	return ID(self.fedid, self.uuid, self.uri, self.localname,
+		self.kernberosUsername)
+
+    def to_dict(self):
+	rv = { }
+	if self.fedid: rv['fedid'] = self.fedid
+	if self.uuid: rv['uuid'] = self.uuid
+	if self.uri: rv['uri'] = self.uri
+	if self.localname: rv['localname'] = self.localname
+	if self.kerberosUsername: rv['kerberosUsername'] = self.kerberosUsername
 	return rv
 
@@ -256,4 +289,56 @@
 	return { 'computer': rv }
 
+
+class Testbed(base):
+    def __init__(self, uri, type, interface=[], attribute=[]):
+	self.uri = uri
+	self.type = type
+	self.interface = [ self.init_class(Interface, c) \
+		for c in self.make_list(interface) ]
+	self.attribute = [ self.init_class(Attribute, c) \
+		for c in self.make_list(attribute) ]
+
+    def clone(self):
+	return Testbed(self.uri, self.type,
+		interface=[i.clone() for i in self.interface],
+		attribute=[a.cone() for a in self.attribute])
+
+    def to_dict(self):
+	rv = { }
+	if self.uri: rv['uri'] = self.uri
+	if self.type: rv['type'] = self.type
+	if self.interface:
+	    rv['interface'] = [ i.to_dict() for i in self.interface]
+	if self.attribute:
+	    rv['attribute'] = [ a.to_dict() for a in self.attribute]
+	return { 'testbed': rv }
+
+class Segment(base):
+    def __init__(self, id, type, uri, interface=[], attribute=[]):
+	self.id = self.init_class(ID, id)
+	self.type = type
+	self.uri = uri
+	self.interface = [ self.init_class(Interface, c) \
+		for c in self.make_list(interface) ]
+	self.attribute = [ self.init_class(Attribute, c) \
+		for c in self.make_list(attribute) ]
+
+    def clone(self):
+	return Segment(self.id.clone(), self.type, self.uri, 
+		interface=[i.clone() for i in self.interface], 
+		attribute=[a.clone() for a in attribute])
+
+    def to_dict(self):
+	rv = { }
+	if self.id: rv['id'] = self.id.to_dict()
+	if self.type: rv['type'] = self.type
+	if self.uri: rv['uri'] = self.uri
+	if self.interface:
+	    rv['interface'] = [ i.to_dict() for i in self.interface ]
+	if self.attribute:
+	    rv['attribute'] = [ a.to_dict() for a in self.attribute ]
+	return { 'segment': rv }
+
+
 class Other(base):
     def __init__(self, interface=[], attribute=[]):
@@ -268,8 +353,10 @@
 
     def to_dict(self):
+	rv = {}
 	if self.interface:
 	    rv['interface'] = [ i.to_dict() for i in self.interface ]
 	if self.attribute:
 	    rv['attribute'] = [ a.to_dict() for a in self.attribute ]
+	return {'other': rv }
 
 
@@ -285,4 +372,6 @@
 	classmap = {
 		'computer': Computer,
+		'testbed': Testbed,
+		'segment': Segment,
 		'other': Other,
 	    }
@@ -489,5 +578,30 @@
     return { 'node': nodes, 'lan': lans }
 
-def topology_to_ns2(t):
+def to_tcl_name(n):
+    t = re.subst('-(\d+)', '(\1)', n)
+    return t
+
+def generate_portal_image_filter(image):
+    def rv(e):
+	s =""
+	if isinstance(e, Computer):
+	    gw = e.get_attribute('portal')
+	    if gw:
+		s = "tb-set-node-os $%s %s" % (to_tcl_name(e.name[0]), image)
+	return s
+    return rv
+
+def generate_portal_command_filter(cmd):
+    def rv(e):
+	s =""
+	if isinstance(e, Computer):
+	    gw = e.get_attribute('portal')
+	    if gw:
+		s = "%s $%s" % (cmd, to_tcl_name(e.name[0]))
+	return s
+    return rv
+
+
+def topology_to_ns2(t, filters=[]):
     out = """
 set ns [new Simulator]
@@ -495,9 +609,10 @@
 
 """
+
     for e in t.elements:
 	rpms = ""
 	tarfiles = ""
 	if isinstance(e, Computer):
-	    name = e.name[0]
+	    name = to_tcl_name(e.name[0])
 	    out += "set %s [$ns node]\n" % name
 	    if e.os and len(e.os) == 1:
@@ -517,4 +632,6 @@
 	    if startcmd:
 		out+= 'tb-set-node-startcmd $%s "%s"\n' % (name, startcmd)
+	    for f in filters:
+		out += f(e)
 	    out+= "\n"
     
@@ -525,10 +642,11 @@
 	else:
 	    delay = 0
-	name = s.name or "sub%d" % idx
+	name = to_tcl_name(s.name or "sub%d" % idx)
 
 	if len(s.interfaces) > 2:
 	    # Lan
-	    members = [ i.element.name[0] for i in s.interfaces]
-	    out += 'set %s [$ns make-lan "%s" %f %fms ]\n' % \
+	    members = [ to_tcl_name("$%s") % i.element.name[0] \
+		    for i in s.interfaces]
+	    out += 'set %s [$ns make-lan "%s" %fkb %fms ]\n' % \
 		    (name, " ".join(members), s.capacity.rate, delay)
 	    if loss:
@@ -541,13 +659,13 @@
 		    out += "tb-set-ip-lan $%s $%s %s\n" % (e.name, name, ip)
 		if i.capacity and i.capacity.rate != s.capacity.rate:
-		    out += "tb-set-node-lan-bandwidth $%s $%s %f\n" % \
-			    (e.name[0], name, i.capacity.rate)
+		    out += "tb-set-node-lan-bandwidth $%s $%s %fkb\n" % \
+			    (to_tcl_name(e.name[0]), name, i.capacity.rate)
 		if i.latency and i.latency.time != delay:
 		    out += "tb-set-node-lan-delay $%s $%s %fms\n" % \
-			    (e.name[0], name, i.latency.time)
+			    (to_tcl_name(e.name[0]), name, i.latency.time)
 		iloss = i.get_attribute('loss')
 		if loss and iloss != loss :
 		    out += "tb-set-node-lan-loss $%s $%s %f" % \
-			    (e.name[0], name, float(loss))
+			    (to_tcl_name(e.name[0]), name, float(loss))
 	    out+= "\n"
 	elif len(s.interfaces) == 2:
@@ -555,6 +673,7 @@
 	    t = s.interfaces[1]
 
-	    out += "set %s [$ns duplex-link $%s $%s %f %fms DropTail]\n" %\
-		    (name, f.element.name[0], t.element.name[0],
+	    out += "set %s [$ns duplex-link $%s $%s %fkb %fms DropTail]\n" %\
+		    (name, to_tcl_name(f.element.name[0]), 
+			    to_tcl_name(t.element.name[0]),
 			    s.capacity.rate, delay)
 	    if loss:
@@ -577,7 +696,10 @@
 		    else: loss = loss or 0.0
 
-		    out += "tb-set-link-simplex-params $%s $%s %fms %f %f\n" % \
-			    (name, i.element.name[0], delay, cap, loss)
+		    out += "tb-set-link-simplex-params $%s $%s %fms %fkb %f\n"\
+			    % (name, to_tcl_name(i.element.name[0]),
+				    delay, cap, loss)
 	    out+= "\n"
+	for f in filters:
+	    out+= f(s)
     out+="""
 $ns run
