#!/usr/bin/env python # Copyright (c) PLUMgrid, Inc. # Licensed under the Apache License, Version 2.0 (the "License") from sys import argv from builtins import input from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from simulation import Simulation from subprocess import PIPE, call, Popen import re multicast = 1 dhcp = 0 gretap = 0 if "mesh" in argv: multicast = 0 if "dhcp" in argv: dhcp = 1 multicast = 0 if "gretap" in argv: gretap = 1 multicast = 0 print("multicast %d dhcp %d gretap %d" % (multicast, dhcp, gretap)) ipr = IPRoute() ipdb = IPDB(nl=ipr) num_hosts = 3 null = open("/dev/null", "w") class TunnelSimulation(Simulation): def __init__(self, ipdb): super(TunnelSimulation, self).__init__(ipdb) 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, disable_ipv6=True)) if multicast: cmd = ["python", "tunnel.py", str(i)] else: cmd = ["python", "tunnel_mesh.py", str(num_hosts), str(i), str(dhcp), str(gretap)] p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE) self.processes.append(p) with self.ipdb.create(ifname="br-fabric", kind="bridge") as br: for host in host_info: br.add_port(host[1]) 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): interface = host_info[0][0].interfaces["br%d" % j] interface.wait_ip("99.1.0.0", 16, timeout=60) host0_br_ips = [x[0] for x in interface.ipaddr if x[0].startswith("99.1")] else: host0_br_ips.append("99.1.0.1") host0_br_ips.append("99.1.1.1") # traffic test print("Validating connectivity") for i in range(1, num_hosts): for j in range(0, 2): interface = host_info[i][0].interfaces["br%d" % j] interface.wait_ip("99.1.0.0", 16, timeout=60) print("VNI%d between host0 and host%d" % (10000 + j, i)) call(["ip", "netns", "exec", "host%d" % i, "ping", host0_br_ips[j], "-c", "3", "-i", "0.2", "-q"]) try: sim = TunnelSimulation(ipdb) sim.start() input("Press enter to quit:") for p in sim.processes: p.communicate(b"\n") except: if "sim" in locals(): for p in sim.processes: p.kill(); p.wait(); p.release() finally: if "br-fabric" in ipdb.interfaces: ipdb.interfaces["br-fabric"].remove().commit() if "sim" in locals(): sim.release() ipdb.release() null.close()