vppinfra: fix corner-cases in bihash lookup
[vpp.git] / test / vpp_qemu_utils.py
1 #!/usr/bin/env python
2
3 # Utility functions for QEMU tests ##
4
5 import subprocess
6 import sys
7
8
9 def create_namespace(ns):
10     """create one or more namespaces.
11
12     arguments:
13     ns -- a string value or an iterable of namespace names
14     """
15     if isinstance(ns, str):
16         namespaces = [ns]
17     else:
18         namespaces = ns
19     try:
20         for namespace in namespaces:
21             subprocess.run(["ip", "netns", "add", namespace])
22     except subprocess.CalledProcessError as e:
23         raise Exception("Error creating namespace:", e.output)
24
25
26 def add_namespace_route(ns, prefix, gw_ip):
27     """Add a route to a namespace.
28
29     arguments:
30     ns -- namespace string value
31     prefix -- NETWORK/MASK or "default"
32     gw_ip -- Gateway IP
33     """
34     try:
35         subprocess.run(
36             ["ip", "netns", "exec", ns, "ip", "route", "add", prefix, "via", gw_ip],
37             capture_output=True,
38         )
39     except subprocess.CalledProcessError as e:
40         raise Exception("Error adding route to namespace:", e.output)
41
42
43 def delete_host_interfaces(*host_interface_names):
44     """Delete host interfaces.
45
46     arguments:
47     host_interface_names - sequence of host interface names to be deleted
48     """
49     for host_interface_name in host_interface_names:
50         try:
51             subprocess.run(
52                 ["ip", "link", "del", host_interface_name], capture_output=True
53             )
54         except subprocess.CalledProcessError as e:
55             raise Exception("Error deleting host interface:", e.output)
56
57
58 def create_host_interface(
59     host_interface_name, vpp_interface_name, host_namespace, *host_ip_prefixes
60 ):
61     """Create a host interface of type veth.
62
63     arguments:
64     host_interface_name -- name of the veth interface on the host side
65     vpp_interface_name -- name of the veth interface on the VPP side
66     host_namespace -- host namespace into which the host_interface needs to be set
67     host_ip_prefixes -- a sequence of ip/prefix-lengths to be set
68                         on the host_interface
69     """
70     try:
71         process = subprocess.run(
72             [
73                 "ip",
74                 "link",
75                 "add",
76                 "name",
77                 vpp_interface_name,
78                 "type",
79                 "veth",
80                 "peer",
81                 "name",
82                 host_interface_name,
83             ],
84             capture_output=True,
85         )
86         if process.returncode != 0:
87             print(f"Error creating host interface: {process.stderr}")
88             sys.exit(1)
89
90         process = subprocess.run(
91             ["ip", "link", "set", host_interface_name, "netns", host_namespace],
92             capture_output=True,
93         )
94         if process.returncode != 0:
95             print(f"Error setting host interface namespace: {process.stderr}")
96             sys.exit(1)
97
98         process = subprocess.run(
99             ["ip", "link", "set", "dev", vpp_interface_name, "up"], capture_output=True
100         )
101         if process.returncode != 0:
102             print(f"Error bringing up the host interface: {process.stderr}")
103             sys.exit(1)
104
105         process = subprocess.run(
106             [
107                 "ip",
108                 "netns",
109                 "exec",
110                 host_namespace,
111                 "ip",
112                 "link",
113                 "set",
114                 "dev",
115                 host_interface_name,
116                 "up",
117             ],
118             capture_output=True,
119         )
120         if process.returncode != 0:
121             print(
122                 f"Error bringing up the host interface in namespace: "
123                 f"{process.stderr}"
124             )
125             sys.exit(1)
126
127         for host_ip_prefix in host_ip_prefixes:
128             process = subprocess.run(
129                 [
130                     "ip",
131                     "netns",
132                     "exec",
133                     host_namespace,
134                     "ip",
135                     "addr",
136                     "add",
137                     host_ip_prefix,
138                     "dev",
139                     host_interface_name,
140                 ],
141                 capture_output=True,
142             )
143             if process.returncode != 0:
144                 print(
145                     f"Error setting ip prefix on the host interface: "
146                     f"{process.stderr}"
147                 )
148                 sys.exit(1)
149     except subprocess.CalledProcessError as e:
150         raise Exception("Error adding route to namespace:", e.output)
151
152
153 def set_interface_mtu(namespace, interface, mtu, logger):
154     """set an mtu number on a linux device interface."""
155     args = ["ip", "link", "set", "mtu", str(mtu), "dev", interface]
156     if namespace:
157         args = ["ip", "netns", "exec", namespace] + args
158     try:
159         logger.debug(
160             f"Setting mtu:{mtu} on linux interface:{interface} "
161             f"in namespace:{namespace}"
162         )
163         subprocess.run(args)
164     except subprocess.CalledProcessError as e:
165         raise Exception("Error updating mtu:", e.output)
166
167
168 def enable_interface_gso(namespace, interface):
169     """enable gso offload on a linux device interface."""
170     args = ["ethtool", "-K", interface, "rx", "on", "tx", "on"]
171     if namespace:
172         args = ["ip", "netns", "exec", namespace] + args
173     try:
174         process = subprocess.run(args, capture_output=True)
175         if process.returncode != 0:
176             print(
177                 f"Error enabling GSO offload on linux device interface: "
178                 f"{process.stderr}"
179             )
180             sys.exit(1)
181     except subprocess.CalledProcessError as e:
182         raise Exception("Error enabling gso:", e.output)
183
184
185 def disable_interface_gso(namespace, interface):
186     """disable gso offload on a linux device interface."""
187     args = ["ethtool", "-K", interface, "rx", "off", "tx", "off"]
188     if namespace:
189         args = ["ip", "netns", "exec", namespace] + args
190     try:
191         process = subprocess.run(args, capture_output=True)
192         if process.returncode != 0:
193             print(
194                 f"Error disabling GSO offload on linux device interface: "
195                 f"{process.stderr}"
196             )
197             sys.exit(1)
198     except subprocess.CalledProcessError as e:
199         raise Exception("Error disabling gso:", e.output)
200
201
202 def delete_namespace(namespaces):
203     """delete one or more namespaces.
204
205     arguments:
206     namespaces -- a list of namespace names
207     """
208     try:
209         for namespace in namespaces:
210             subprocess.run(["ip", "netns", "del", namespace], capture_output=True)
211     except subprocess.CalledProcessError as e:
212         raise Exception("Error deleting namespace:", e.output)
213
214
215 def list_namespace(ns):
216     """List the IP address of a namespace"""
217     try:
218         subprocess.run(["ip", "netns", "exec", ns, "ip", "addr"])
219     except subprocess.CalledProcessError as e:
220         raise Exception("Error listing namespace IP:", e.output)