1#!/usr/bin/env python 2# Copyright (c) PLUMgrid, Inc. 3# Licensed under the Apache License, Version 2.0 (the "License") 4 5from bcc import BPF 6from pyroute2 import IPRoute, NetNS, IPDB, NSPopen 7from simulation import Simulation 8import sys 9from time import sleep 10from builtins import input 11 12ipr = IPRoute() 13ipdb = IPDB(nl=ipr) 14b = BPF(src_file="tc_neighbor_sharing.c", debug=0) 15 16wan_fn = b.load_func("classify_wan", BPF.SCHED_CLS) 17pass_fn = b.load_func("pass", BPF.SCHED_CLS) 18neighbor_fn = b.load_func("classify_neighbor", BPF.SCHED_CLS) 19 20num_neighbors = 3 21num_locals = 2 22 23# class to build the simulation network 24class SharedNetSimulation(Simulation): 25 26 def __init__(self, ipdb): 27 super(SharedNetSimulation, self).__init__(ipdb) 28 29 # Create the wan namespace, and attach an ingress filter for throttling 30 # inbound (download) traffic 31 wan_if = self._create_ns("wan0", ipaddr="172.16.1.5/24")[1] 32 ipr.tc("add", "ingress", wan_if["index"], "ffff:") 33 ipr.tc("add-filter", "bpf", wan_if["index"], ":1", fd=wan_fn.fd, 34 prio=1, name=wan_fn.name, parent="ffff:", action="drop", 35 classid=1, rate="128kbit", burst=1024 * 32, mtu=16 * 1024) 36 ipr.tc("add-filter", "bpf", wan_if["index"], ":2", fd=pass_fn.fd, 37 prio=2, name=pass_fn.name, parent="ffff:", action="drop", 38 classid=2, rate="1024kbit", burst=1024 * 32, mtu=16 * 1024) 39 self.wan_if = wan_if 40 41 # start the namespaces that compose the network, interconnect them with the 42 # bridge, and attach the tc filters 43 def start(self): 44 neighbor_list = [] 45 local_list = [] 46 cmd = ["netserver", "-D"] 47 for i in range(0, num_neighbors): 48 ipaddr = "172.16.1.%d/24" % (i + 100) 49 ret = self._create_ns("neighbor%d" % i, ipaddr=ipaddr, 50 fn=neighbor_fn, cmd=cmd) 51 neighbor_list.append(ret) 52 for i in range(0, num_locals): 53 ipaddr = "172.16.1.%d/24" % (i + 150) 54 ret = self._create_ns("local%d" % i, ipaddr=ipaddr, 55 fn=pass_fn, cmd=cmd) 56 local_list.append(ret) 57 58 with ipdb.create(ifname="br100", kind="bridge") as br100: 59 for x in neighbor_list: 60 br100.add_port(x[1]) 61 for x in local_list: 62 br100.add_port(x[1]) 63 br100.add_port(self.wan_if) 64 br100.up() 65 66try: 67 sim = SharedNetSimulation(ipdb) 68 sim.start() 69 print("Network ready. Create a shell in the wan0 namespace and test with netperf") 70 print(" (Neighbors are 172.16.1.100-%d, and LAN clients are 172.16.1.150-%d)" 71 % (100 + num_neighbors - 1, 150 + num_locals - 1)) 72 print(" e.g.: ip netns exec wan0 netperf -H 172.16.1.100 -l 2") 73 input("Press enter when finished: ") 74finally: 75 if "sim" in locals(): sim.release() 76 if "br100" in ipdb.interfaces: ipdb.interfaces.br100.remove().commit() 77 ipdb.release() 78 79 80