diff options
Diffstat (limited to 'test/vpp_qemu_utils.py')
-rw-r--r-- | test/vpp_qemu_utils.py | 202 |
1 files changed, 201 insertions, 1 deletions
diff --git a/test/vpp_qemu_utils.py b/test/vpp_qemu_utils.py index 50fc1c865a6..5c433201650 100644 --- a/test/vpp_qemu_utils.py +++ b/test/vpp_qemu_utils.py @@ -3,15 +3,215 @@ # Utility functions for QEMU tests ## import subprocess +import sys def create_namespace(ns): + """create one or more namespaces. + + arguments: + ns -- a string value or an iterable of namespace names + """ + if isinstance(ns, str): + namespaces = [ns] + else: + namespaces = ns try: - subprocess.run(["ip", "netns", "add", ns]) + for namespace in namespaces: + subprocess.run(["ip", "netns", "add", namespace]) except subprocess.CalledProcessError as e: raise Exception("Error creating namespace:", e.output) +def add_namespace_route(ns, prefix, gw_ip): + """Add a route to a namespace. + + arguments: + ns -- namespace string value + prefix -- NETWORK/MASK or "default" + gw_ip -- Gateway IP + """ + try: + subprocess.run( + ["ip", "netns", "exec", ns, "ip", "route", "add", prefix, "via", gw_ip], + capture_output=True, + ) + except subprocess.CalledProcessError as e: + raise Exception("Error adding route to namespace:", e.output) + + +def delete_host_interfaces(*host_interface_names): + """Delete host interfaces. + + arguments: + host_interface_names - sequence of host interface names to be deleted + """ + for host_interface_name in host_interface_names: + try: + subprocess.run( + ["ip", "link", "del", host_interface_name], capture_output=True + ) + except subprocess.CalledProcessError as e: + raise Exception("Error deleting host interface:", e.output) + + +def create_host_interface( + host_interface_name, vpp_interface_name, host_namespace, *host_ip_prefixes +): + """Create a host interface of type veth. + + arguments: + host_interface_name -- name of the veth interface on the host side + vpp_interface_name -- name of the veth interface on the VPP side + host_namespace -- host namespace into which the host_interface needs to be set + host_ip_prefixes -- a sequence of ip/prefix-lengths to be set + on the host_interface + """ + try: + process = subprocess.run( + [ + "ip", + "link", + "add", + "name", + vpp_interface_name, + "type", + "veth", + "peer", + "name", + host_interface_name, + ], + capture_output=True, + ) + if process.returncode != 0: + print(f"Error creating host interface: {process.stderr}") + sys.exit(1) + + process = subprocess.run( + ["ip", "link", "set", host_interface_name, "netns", host_namespace], + capture_output=True, + ) + if process.returncode != 0: + print(f"Error setting host interface namespace: {process.stderr}") + sys.exit(1) + + process = subprocess.run( + ["ip", "link", "set", "dev", vpp_interface_name, "up"], capture_output=True + ) + if process.returncode != 0: + print(f"Error bringing up the host interface: {process.stderr}") + sys.exit(1) + + process = subprocess.run( + [ + "ip", + "netns", + "exec", + host_namespace, + "ip", + "link", + "set", + "dev", + host_interface_name, + "up", + ], + capture_output=True, + ) + if process.returncode != 0: + print( + f"Error bringing up the host interface in namespace: " + f"{process.stderr}" + ) + sys.exit(1) + + for host_ip_prefix in host_ip_prefixes: + process = subprocess.run( + [ + "ip", + "netns", + "exec", + host_namespace, + "ip", + "addr", + "add", + host_ip_prefix, + "dev", + host_interface_name, + ], + capture_output=True, + ) + if process.returncode != 0: + print( + f"Error setting ip prefix on the host interface: " + f"{process.stderr}" + ) + sys.exit(1) + except subprocess.CalledProcessError as e: + raise Exception("Error adding route to namespace:", e.output) + + +def set_interface_mtu(namespace, interface, mtu, logger): + """set an mtu number on a linux device interface.""" + args = ["ip", "link", "set", "mtu", str(mtu), "dev", interface] + if namespace: + args = ["ip", "netns", "exec", namespace] + args + try: + logger.debug( + f"Setting mtu:{mtu} on linux interface:{interface} " + f"in namespace:{namespace}" + ) + subprocess.run(args) + except subprocess.CalledProcessError as e: + raise Exception("Error updating mtu:", e.output) + + +def enable_interface_gso(namespace, interface): + """enable gso offload on a linux device interface.""" + args = ["ethtool", "-K", interface, "rx", "on", "tx", "on"] + if namespace: + args = ["ip", "netns", "exec", namespace] + args + try: + process = subprocess.run(args, capture_output=True) + if process.returncode != 0: + print( + f"Error enabling GSO offload on linux device interface: " + f"{process.stderr}" + ) + sys.exit(1) + except subprocess.CalledProcessError as e: + raise Exception("Error enabling gso:", e.output) + + +def disable_interface_gso(namespace, interface): + """disable gso offload on a linux device interface.""" + args = ["ethtool", "-K", interface, "rx", "off", "tx", "off"] + if namespace: + args = ["ip", "netns", "exec", namespace] + args + try: + process = subprocess.run(args, capture_output=True) + if process.returncode != 0: + print( + f"Error disabling GSO offload on linux device interface: " + f"{process.stderr}" + ) + sys.exit(1) + except subprocess.CalledProcessError as e: + raise Exception("Error disabling gso:", e.output) + + +def delete_namespace(namespaces): + """delete one or more namespaces. + + arguments: + namespaces -- a list of namespace names + """ + try: + for namespace in namespaces: + subprocess.run(["ip", "netns", "del", namespace], capture_output=True) + except subprocess.CalledProcessError as e: + raise Exception("Error deleting namespace:", e.output) + + def list_namespace(ns): """List the IP address of a namespace""" try: |