You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
3.3 KiB
88 lines
3.3 KiB
#!/usr/bin/env python
|
|
# Copyright (c) PLUMgrid, Inc.
|
|
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
|
|
from builtins import input
|
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
|
from netaddr import IPNetwork
|
|
from os import chdir
|
|
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
|
|
from random import choice, randint
|
|
from simulation import Simulation
|
|
from socket import htons
|
|
from threading import Thread
|
|
import sys
|
|
|
|
ipr = IPRoute()
|
|
ipdb = IPDB(nl=ipr)
|
|
|
|
num_hosts = 9
|
|
num_vnis = 4
|
|
null = open("/dev/null", "w")
|
|
|
|
class TunnelSimulation(Simulation):
|
|
def __init__(self, ipdb):
|
|
super(TunnelSimulation, self).__init__(ipdb)
|
|
self.available_ips = [list(IPNetwork("192.168.%d.0/24" % i)[1:-1])
|
|
for i in range(0, num_vnis)]
|
|
|
|
def start(self):
|
|
# each entry is tuple of ns_ipdb, out_ifc, in_ifc
|
|
host_info = []
|
|
for i in range(0, num_hosts):
|
|
print("Launching host %i of %i" % (i + 1, num_hosts))
|
|
ipaddr = "172.16.1.%d/24" % (100 + i)
|
|
host_info.append(self._create_ns("host%d" % i, ipaddr=ipaddr))
|
|
with self.ipdb.create(ifname="br100", kind="bridge") as br100:
|
|
for host in host_info: br100.add_port(host[1])
|
|
br100.up()
|
|
# create a vxlan device inside each namespace
|
|
for host in host_info:
|
|
print("Starting tunnel %i of %i" % (len(self.processes) + 1, num_hosts))
|
|
cmd = ["netserver", "-D"]
|
|
self.processes.append(NSPopen(host[0].nl.netns, cmd, stdout=null))
|
|
for i in range(0, num_vnis):
|
|
with host[0].create(ifname="vxlan%d" % i, kind="vxlan",
|
|
vxlan_id=10000 + i,
|
|
vxlan_link=host[0].interfaces.eth0,
|
|
vxlan_port=4789,
|
|
vxlan_group="239.1.1.%d" % (1 + i)) as vx:
|
|
vx.up()
|
|
with host[0].create(ifname="br%d" % i, kind="bridge") as br:
|
|
br.add_port(host[0].interfaces["vxlan%d" % i])
|
|
br.up()
|
|
with host[0].create(ifname="c%da" % i, kind="veth",
|
|
peer="c%db" % i) as c:
|
|
c.up()
|
|
c.add_ip("%s/24" % self.available_ips[i].pop(0))
|
|
c.mtu = 1450
|
|
br.add_port(host[0].interfaces["c%db" % i])
|
|
host[0].interfaces["c%db" % i].up().commit()
|
|
|
|
# pick one host to start the monitor in
|
|
host = host_info[0]
|
|
cmd = ["python", "monitor.py"]
|
|
p = NSPopen(host[0].nl.netns, cmd)
|
|
self.processes.append(p)
|
|
|
|
def serve_http(self):
|
|
chdir("chord-transitions")
|
|
# comment below line to see http server log messages
|
|
SimpleHTTPRequestHandler.log_message = lambda self, format, *args: None
|
|
self.srv = HTTPServer(("", 8080), SimpleHTTPRequestHandler)
|
|
self.t = Thread(target=self.srv.serve_forever)
|
|
self.t.setDaemon(True)
|
|
self.t.start()
|
|
print("HTTPServer listening on 0.0.0.0:8080")
|
|
|
|
try:
|
|
sim = TunnelSimulation(ipdb)
|
|
sim.start()
|
|
sim.serve_http()
|
|
input("Press enter to quit:")
|
|
finally:
|
|
if "br100" in ipdb.interfaces: ipdb.interfaces.br100.remove().commit()
|
|
sim.release()
|
|
ipdb.release()
|
|
null.close()
|