Commit 703bad5b authored by Yonghong Song's avatar Yonghong Song

add dhcp support for tunnel-mesh

Signed-off-by: default avatarYonghong Song <yhs@plumgrid.com>
parent f7a261d8
...@@ -7,11 +7,14 @@ from builtins import input ...@@ -7,11 +7,14 @@ from builtins import input
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
from simulation import Simulation from simulation import Simulation
from subprocess import PIPE, call, Popen from subprocess import PIPE, call, Popen
import re
dhcp = 0
multicast = 1
if len(argv) > 1 and argv[1] == "mesh": if len(argv) > 1 and argv[1] == "mesh":
multicast = 0 multicast = 0
else: if len(argv) > 2 and argv[2] == "dhcp":
multicast = 1 dhcp = 1
ipr = IPRoute() ipr = IPRoute()
ipdb = IPDB(nl=ipr) ipdb = IPDB(nl=ipr)
...@@ -34,12 +37,33 @@ class TunnelSimulation(Simulation): ...@@ -34,12 +37,33 @@ class TunnelSimulation(Simulation):
if multicast: if multicast:
cmd = ["python", "tunnel.py", str(i)] cmd = ["python", "tunnel.py", str(i)]
else: else:
cmd = ["python", "tunnel_mesh.py", str(num_hosts), str(i)] cmd = ["python", "tunnel_mesh.py", str(num_hosts), str(i), str(dhcp)]
p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE) p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE)
self.processes.append(p) self.processes.append(p)
with self.ipdb.create(ifname="br-fabric", kind="bridge") as br: with self.ipdb.create(ifname="br-fabric", kind="bridge") as br:
for host in host_info: br.add_port(host[1]) for host in host_info: br.add_port(host[1])
br.up() br.up()
# get host0 bridge ip's
host0_br_ips = []
if dhcp == 1:
print("Waiting for host0 br1/br2 ip addresses available")
for j in range(0, 2):
retry = -1
ip_out = None
while retry < 0:
check = Popen(["ip", "netns", "exec", "host0",
"ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE)
ip_out = check.stdout.read()
checkip = "99.1.%d" % j
retry = ip_out.find(checkip)
p = re.compile(("99.1.%d." % j) + "\d+")
host0_br_ips.append(p.findall(ip_out)[0])
else:
host0_br_ips.append("99.1.0.1")
host0_br_ips.append("99.1.1.1")
# traffic test
print("Validating connectivity") print("Validating connectivity")
for i in range(1, num_hosts): for i in range(1, num_hosts):
for j in range(0, 2): for j in range(0, 2):
...@@ -48,11 +72,11 @@ class TunnelSimulation(Simulation): ...@@ -48,11 +72,11 @@ class TunnelSimulation(Simulation):
check = Popen(["ip", "netns", "exec", "host%d" % i, check = Popen(["ip", "netns", "exec", "host%d" % i,
"ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE) "ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE)
out = check.stdout.read() out = check.stdout.read()
checkip = "99.1.%d.%d" % (j, i+1) checkip = "99.1.%d" % j
retry = out.find(checkip) retry = out.find(checkip)
print("VNI%d between host0 and host%d" % (10000 + j, i)) print("VNI%d between host0 and host%d" % (10000 + j, i))
call(["ip", "netns", "exec", "host%d" % i, call(["ip", "netns", "exec", "host%d" % i,
"ping", "99.1.%d.1" % j, "-c", "3", "-i", "0.2", "-q"]) "ping", host0_br_ips[j], "-c", "3", "-i", "0.2", "-q"])
try: try:
sim = TunnelSimulation(ipdb) sim = TunnelSimulation(ipdb)
......
...@@ -12,10 +12,11 @@ from netaddr import EUI, IPAddress ...@@ -12,10 +12,11 @@ from netaddr import EUI, IPAddress
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
from socket import htons, AF_INET from socket import htons, AF_INET
from threading import Thread from threading import Thread
from subprocess import call from subprocess import call, Popen, PIPE
num_hosts = int(argv[1]) num_hosts = int(argv[1])
host_id = int(argv[2]) host_id = int(argv[2])
dhcp = int(argv[3])
b = BPF(src_file="tunnel_mesh.c") b = BPF(src_file="tunnel_mesh.c")
ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS)
...@@ -32,6 +33,10 @@ ifc = ipdb.interfaces.eth0 ...@@ -32,6 +33,10 @@ ifc = ipdb.interfaces.eth0
# ifcs to cleanup at the end # ifcs to cleanup at the end
ifc_gc = [] ifc_gc = []
# dhcp server and client processes
d_serv = []
d_client = []
def run(): def run():
with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0, with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0,
vxlan_link=ifc, vxlan_port=htons(4789), vxlan_link=ifc, vxlan_port=htons(4789),
...@@ -68,13 +73,58 @@ def run(): ...@@ -68,13 +73,58 @@ def run():
br.add_port(v) br.add_port(v)
br.up() br.up()
ifc_gc.append(v.ifname) ifc_gc.append(v.ifname)
if dhcp == 0:
ipaddr = "99.1.%d.%d/24" % (j, host_id + 1) ipaddr = "99.1.%d.%d/24" % (j, host_id + 1)
br.add_ip(ipaddr) br.add_ip(ipaddr)
ifc_gc.append(br.ifname) ifc_gc.append(br.ifname)
# dhcp server only runs on host 0
if dhcp == 1 and host_id == 0:
for j in range(0, 2):
v1 = "dhcp%d_v1" % j
v2 = "dhcp%d_v2" % j
br = ipdb.interfaces["br%d" % j]
with ipdb.create(ifname=v1, kind="veth", peer=v2) as v:
v.up()
br.add_port(ipdb.interfaces[v1]).commit()
dhcp_v2 = ipdb.interfaces[v2]
dhcp_v2.add_ip("99.1.%d.1/24" % j).up().commit()
call(["/bin/rm", "-f", "/tmp/dnsmasq.%d.leases" % j])
cmd = ["dnsmasq", "-d", "--bind-interfaces", "--strict-order",
"--conf-file=",
"--dhcp-range", "99.1.%d.2,99.1.%d.254,255.255.255.0,12h" % (j, j),
"--dhcp-no-override", "--except-interface=lo",
"--interface=dhcp%d_v2" % j,
"--dhcp-authoritative",
"--dhcp-leasefile=/tmp/dnsmasq.%d.leases" % j]
d_serv.append(Popen(cmd, stdout=PIPE, stderr=PIPE))
# dhcp client to assign ip address for each bridge
if dhcp == 1:
for j in range(0, 2):
call(["/bin/rm", "-rf", "/tmp/dhcp_%d_%d" % (host_id, j)])
call(["mkdir", "/tmp/dhcp_%d_%d" % (host_id, j)])
call(["touch", "/tmp/dhcp_%d_%d/dhclient.conf" % (host_id, j)])
call(["touch", "/tmp/dhcp_%d_%d/dhclient.lease" % (host_id, j)])
cmd = ["dhclient", "-d", "br%d" % j,
"-cf", "/tmp/dhcp_%d_%d/dhclient.conf" % (host_id, j),
"-lf", "/tmp/dhcp_%d_%d/dhclient.lease" % (host_id, j)]
d_client.append(Popen(cmd, stdout=PIPE, stderr=PIPE))
# make sure we get address for eth0
retry = -1
while retry < 0:
check = Popen(["ip", "addr", "show", "br%d" % j], stdout=PIPE, stderr=PIPE)
out = check.stdout.read()
checkip = "99.1.%d" % j
retry = out.find(checkip)
try: try:
run() run()
ipdb.release()
input("") input("")
finally: finally:
for v in ifc_gc: call(["ip", "link", "del", v]) for v in ifc_gc: call(["ip", "link", "del", v])
ipdb.release()
for p in d_client: p.kill()
for p in d_serv: p.kill()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment