1#!/usr/bin/python 2# Copyright (c) PLUMgrid, Inc. 3# Licensed under the Apache License, Version 2.0 (the "License") 4 5from builtins import input 6from http.server import HTTPServer, SimpleHTTPRequestHandler 7from netaddr import IPNetwork 8from os import chdir 9from pyroute2 import IPRoute, NetNS, IPDB, NSPopen 10from random import choice, randint 11from simulation import Simulation 12from socket import htons 13from threading import Thread 14import sys 15 16ipr = IPRoute() 17ipdb = IPDB(nl=ipr) 18 19num_hosts = 9 20num_vnis = 4 21null = open("/dev/null", "w") 22 23class TunnelSimulation(Simulation): 24 def __init__(self, ipdb): 25 super(TunnelSimulation, self).__init__(ipdb) 26 self.available_ips = [list(IPNetwork("192.168.%d.0/24" % i)[1:-1]) 27 for i in range(0, num_vnis)] 28 29 def start(self): 30 # each entry is tuple of ns_ipdb, out_ifc, in_ifc 31 host_info = [] 32 for i in range(0, num_hosts): 33 print("Launching host %i of %i" % (i + 1, num_hosts)) 34 ipaddr = "172.16.1.%d/24" % (100 + i) 35 host_info.append(self._create_ns("host%d" % i, ipaddr=ipaddr)) 36 with self.ipdb.create(ifname="br100", kind="bridge") as br100: 37 for host in host_info: br100.add_port(host[1]) 38 br100.up() 39 # create a vxlan device inside each namespace 40 for host in host_info: 41 print("Starting tunnel %i of %i" % (len(self.processes) + 1, num_hosts)) 42 cmd = ["netserver", "-D"] 43 self.processes.append(NSPopen(host[0].nl.netns, cmd, stdout=null)) 44 for i in range(0, num_vnis): 45 with host[0].create(ifname="vxlan%d" % i, kind="vxlan", 46 vxlan_id=10000 + i, 47 vxlan_link=host[0].interfaces.eth0, 48 vxlan_port=4789, 49 vxlan_group="239.1.1.%d" % (1 + i)) as vx: 50 vx.up() 51 with host[0].create(ifname="br%d" % i, kind="bridge") as br: 52 br.add_port(host[0].interfaces["vxlan%d" % i]) 53 br.up() 54 with host[0].create(ifname="c%da" % i, kind="veth", 55 peer="c%db" % i) as c: 56 c.up() 57 c.add_ip("%s/24" % self.available_ips[i].pop(0)) 58 c.mtu = 1450 59 br.add_port(host[0].interfaces["c%db" % i]) 60 host[0].interfaces["c%db" % i].up().commit() 61 62 # pick one host to start the monitor in 63 host = host_info[0] 64 cmd = ["python", "monitor.py"] 65 p = NSPopen(host[0].nl.netns, cmd) 66 self.processes.append(p) 67 68 def serve_http(self): 69 chdir("chord-transitions") 70 # comment below line to see http server log messages 71 SimpleHTTPRequestHandler.log_message = lambda self, format, *args: None 72 self.srv = HTTPServer(("", 8080), SimpleHTTPRequestHandler) 73 self.t = Thread(target=self.srv.serve_forever) 74 self.t.setDaemon(True) 75 self.t.start() 76 print("HTTPServer listening on 0.0.0.0:8080") 77 78try: 79 sim = TunnelSimulation(ipdb) 80 sim.start() 81 sim.serve_http() 82 input("Press enter to quit:") 83finally: 84 if "br100" in ipdb.interfaces: ipdb.interfaces.br100.remove().commit() 85 sim.release() 86 ipdb.release() 87 null.close() 88