diff --git a/start_testbed.py b/start_testbed.py index 3ed384be09b746c522a82342afd91420e784d18e..f8653742627f3be79394c477bc7cdaf1d929651b 100755 --- a/start_testbed.py +++ b/start_testbed.py @@ -37,6 +37,52 @@ def connect_nodes(node1, node2): ctr1 = nodelist[node1] ctr2 = nodelist[node2] print ctr1, ctr2 + # Create a virtual ethernet link. + dev_1 = 'bac0_{n1}_{n2}'.format(n1=node1,n2=node2) + dev_2 = 'bac0_{n2}_{n1}'.format(n1=node1,n2=node2) + subprocess.call([ + 'sudo', + 'ip', 'link', 'add', dev_1, 'type', 'veth', + 'peer', 'name', dev_2 + ]) + # Add the link endpoints to the container namespaces. + def add_to_ns(dev,ns): + subprocess.call([ + 'sudo', 'ip', 'link', 'set', dev, 'netns', ns + ]) + add_to_ns(dev_1,ctr1['name']) + add_to_ns(dev_2,ctr2['name']) + + # Set the IP addresses. + def set_addr(dev,ns,addr): + subprocess.call([ + 'sudo', 'ip', 'netns', 'exec', ns, + 'ip', 'addr', 'add', addr+'/32', 'dev', dev + ]) + set_addr(dev_1,ctr1['name'],ctr1['addr']) + set_addr(dev_2,ctr2['name'],ctr2['addr']) + + # Bring the link up. + def link_up(ns,dev): + subprocess.call([ + 'sudo', 'ip', 'netns', 'exec', ns, + 'ip', 'link', 'set', dev, 'up' + ]) + link_up(ctr1['name'],dev_1) + link_up(ctr2['name'],dev_2) + + # Set initial routes. + def route_from_to(f,t,fdev): + # $ctx ip route add $net dev $dev proto static scope global src $addr + subprocess.call([ + 'sudo', 'ip', 'netns', 'exec', f['name'], + 'ip', 'route', 'add', t['addr']+'/32', + 'dev', fdev, 'proto', 'static', 'scope', 'global', + 'src', f['addr'] + ]) + route_from_to(ctr1,ctr2,dev_1) + route_from_to(ctr2,ctr1,dev_2) + def make_mesh(): global nodelist @@ -51,6 +97,8 @@ def make_star(): def start_node(base_name,i): global nodelist name = base_name + str(i) + + # Start the container. command = ['docker', 'run', '-d', @@ -60,9 +108,12 @@ def start_node(base_name,i): ] command.extend(conf['image_cmd'].split()) retval = subprocess.call(command) + entry = dict() entry['name'] = name + # Determine the IP address to use for this node. entry['addr'] = make_ip(i) + # Find the container's process ID. entry['pid'] = subprocess.check_output([ 'docker', 'inspect', @@ -70,17 +121,22 @@ def start_node(base_name,i): '{{.State.Pid}}', name ]).strip() + + # Set up a network namespace. subprocess.call([ 'sudo', 'ln', '-s', - '/proc/{pid}/ns/net'.format(pid=entry['pid'], + '/proc/{pid}/ns/net'.format(pid=entry['pid']), '/var/run/netns/{name}'.format(name=name) - ]) + ]) + + # Add the node's info to our list. nodelist.append(entry) for n in range(ntwk['num_nodes']): start_node(ntwk['name'],n) +# XXX - need to check if we're a star or mesh network, and call the appropriate function make_mesh()