blob: 5c433201650ffe57a71736e4a61014c8a79b0d92 [file] [log] [blame]
Naveen Joy7ea7ab52021-05-11 10:31:18 -07001#!/usr/bin/env python
2
3# Utility functions for QEMU tests ##
4
5import subprocess
Naveen Joye4168932022-10-04 14:22:05 -07006import sys
Naveen Joy7ea7ab52021-05-11 10:31:18 -07007
8
9def create_namespace(ns):
Naveen Joye4168932022-10-04 14:22:05 -070010 """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
Naveen Joy7ea7ab52021-05-11 10:31:18 -070019 try:
Naveen Joye4168932022-10-04 14:22:05 -070020 for namespace in namespaces:
21 subprocess.run(["ip", "netns", "add", namespace])
Naveen Joy7ea7ab52021-05-11 10:31:18 -070022 except subprocess.CalledProcessError as e:
23 raise Exception("Error creating namespace:", e.output)
24
25
Naveen Joye4168932022-10-04 14:22:05 -070026def 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
43def 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
58def 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
153def 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
168def 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
185def 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
202def 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
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700215def 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)