aboutsummaryrefslogtreecommitdiffstats
path: root/test/vpp_qemu_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/vpp_qemu_utils.py')
-rw-r--r--test/vpp_qemu_utils.py202
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: