1#!/usr/bin/python 2# Copyright (c) PLUMgrid, Inc. 3# Licensed under the Apache License, Version 2.0 (the "License") 4 5from sys import argv 6from builtins import input 7from pyroute2 import IPRoute, NetNS, IPDB, NSPopen 8from simulation import Simulation 9from subprocess import PIPE, call, Popen 10import re 11 12multicast = 1 13dhcp = 0 14gretap = 0 15 16if "mesh" in argv: 17 multicast = 0 18 19if "dhcp" in argv: 20 dhcp = 1 21 multicast = 0 22 23if "gretap" in argv: 24 gretap = 1 25 multicast = 0 26 27print("multicast %d dhcp %d gretap %d" % (multicast, dhcp, gretap)) 28 29ipr = IPRoute() 30ipdb = IPDB(nl=ipr) 31 32num_hosts = 3 33null = open("/dev/null", "w") 34 35class TunnelSimulation(Simulation): 36 def __init__(self, ipdb): 37 super(TunnelSimulation, self).__init__(ipdb) 38 39 def start(self): 40 # each entry is tuple of ns_ipdb, out_ifc, in_ifc 41 host_info = [] 42 for i in range(0, num_hosts): 43 print("Launching host %i of %i" % (i + 1, num_hosts)) 44 ipaddr = "172.16.1.%d/24" % (100 + i) 45 host_info.append(self._create_ns("host%d" % i, ipaddr=ipaddr, 46 disable_ipv6=True)) 47 if multicast: 48 cmd = ["python", "tunnel.py", str(i)] 49 else: 50 cmd = ["python", "tunnel_mesh.py", str(num_hosts), str(i), str(dhcp), str(gretap)] 51 p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE) 52 self.processes.append(p) 53 with self.ipdb.create(ifname="br-fabric", kind="bridge") as br: 54 for host in host_info: br.add_port(host[1]) 55 br.up() 56 57 # get host0 bridge ip's 58 host0_br_ips = [] 59 if dhcp == 1: 60 print("Waiting for host0 br1/br2 ip addresses available") 61 for j in range(0, 2): 62 interface = host_info[0][0].interfaces["br%d" % j] 63 interface.wait_ip("99.1.0.0", 16, timeout=60) 64 host0_br_ips = [x[0] for x in interface.ipaddr 65 if x[0].startswith("99.1")] 66 else: 67 host0_br_ips.append("99.1.0.1") 68 host0_br_ips.append("99.1.1.1") 69 70 # traffic test 71 print("Validating connectivity") 72 for i in range(1, num_hosts): 73 for j in range(0, 2): 74 interface = host_info[i][0].interfaces["br%d" % j] 75 interface.wait_ip("99.1.0.0", 16, timeout=60) 76 print("VNI%d between host0 and host%d" % (10000 + j, i)) 77 call(["ip", "netns", "exec", "host%d" % i, 78 "ping", host0_br_ips[j], "-c", "3", "-i", "0.2", "-q"]) 79 80try: 81 sim = TunnelSimulation(ipdb) 82 sim.start() 83 input("Press enter to quit:") 84 for p in sim.processes: p.communicate(b"\n") 85except: 86 if "sim" in locals(): 87 for p in sim.processes: p.kill(); p.wait(); p.release() 88finally: 89 if "br-fabric" in ipdb.interfaces: ipdb.interfaces["br-fabric"].remove().commit() 90 if "sim" in locals(): sim.release() 91 ipdb.release() 92 null.close() 93