xref: /aosp_15_r20/external/bcc/examples/networking/tunnel_monitor/main.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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