def setup_networking(): """ Create multiple tap devices and a matching configuration file for running tests """ cleanup_network() # create network devices mac = {} for i in range(0, 8): mac[f"test{i}"] = create_test_interface(f"test{i}") # set mac on test1 subprocess.check_output( ["ip", "link", "set", "address", "fa:16:3e:31:c8:d8", "dev", "test7"]) # create network namespaces for i in range(0, 5): create_namespace(f"test-ns-{i}") # move interfaces into the namespace move_interface("test-ns-1", "test0", "eth0") move_interface("test-ns-2", "test1", "eth0") move_interface("test-ns-2", "test2", "eth1") move_interface("test-ns-3", "test3", "eth0") move_interface("test-ns-3", "test4", "eth1") move_interface("test-ns-3", "test5", "eth2") move_interface("test-ns-4", "test6", "eth0") # set an ip on test 6 run_in_ns("test-ns-4", ["ip", "link", "set", "up", "dev", "eth0"]) run_in_ns("test-ns-4", ["ip", "address", "add", "192.0.2.1/24", "dev", "eth0"]) yield cleanup_network()
def traceroute_from_ns(namespace): namespace = util.process_namespace(namespace, allow_none=True) dest = request.args.get("destination") if app.simulate: if dest == "1.1.1.1": return jsonify( { "destination_ip": "1.1.1.1", "destination_name": "host", "hops": [ { "index": 1, "probes": ["host (1.1.1.1) 0.013 ms", "host (1.1.1.1) 0.003 ms", "host (1.1.1.1) 0.003 ms"], } ], } ) else: return jsonify({}) else: try: result = util.run_in_ns(namespace, ["traceroute", dest]) parsed = trparse.loads(result) hops = [] for hop in parsed.hops: probes = [] for probe in hop.probes: probes.append(str(probe).strip()) hops.append({"index": hop.idx, "probes": probes}) traceroute = {"destination_name": parsed.dest_name, "destination_ip": parsed.dest_ip, "hops": hops} return jsonify(traceroute) except subprocess.CalledProcessError as e: LOGGER.exception("status: %s, out: %s, err: %s", e.returncode, e.stdout, e.stderr) return jsonify({})
def ping_from_ns(namespace): namespace = util.process_namespace(namespace, allow_none=True) dest = request.args.get("destination") if app.simulate: if dest == "1.1.1.1": return jsonify( { "destination": "1.1.1.1", "packet_duplicate_count": 0, "packet_duplicate_rate": 0, "packet_loss_count": 0, "packet_loss_rate": 0, "packet_receive": 4, "packet_transmit": 4, "rtt_avg": 5.472, "rtt_max": 10.635, "rtt_mdev": 3.171, "rtt_min": 2.533, } ) else: return jsonify({}) else: ping_parser = pingparsing.PingParsing() try: result = util.run_in_ns(namespace, ["ping", "-c", "4", "-i", "0.2", dest]) return jsonify(ping_parser.parse(result).as_dict()) except subprocess.CalledProcessError as e: LOGGER.exception("status: %s, out: %s, err: %s", e.returncode, e.stdout, e.stderr) return jsonify({})
def list_routes(namespace): result = util.run_in_ns(namespace, ["ip", "-j", "route", "ls"]) routes = json.loads(result) for route in routes: if route["dst"] == "default": route["dst"] = "0.0.0.0/0" return routes
def add_route_from_ns(namespace): namespace = util.process_namespace(namespace, allow_none=True) subnet = request.get_json(force=True).get("subnet") gateway = request.get_json(force=True).get("gateway", None) interface = request.get_json(force=True).get("interface", None) if gateway is None and interface is None: raise exceptions.ServerError("gateway or interface should be set.") if app.simulate: cfg = get_config() if namespace not in cfg.namespaces: abort(404) ns = cfg.namespaces[namespace] route = Route(subnet, gateway, interface) if route in ns.routes: abort(409) else: ns.routes.append(route) return jsonify([route.to_json() for route in ns.routes]) else: try: util.run_in_ns( namespace, [ "ip", "route", "add", subnet, *(["via", gateway] if gateway is not None else []), *(["dev", interface] if interface is not None else []), ], ) routes = util.list_routes(namespace) return jsonify(routes) except subprocess.CalledProcessError as e: LOGGER.exception("status: %s, out: %s, err: %s", e.returncode, e.stdout, e.stderr) return jsonify({})