1 # Copyright (c) 2021 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Special test configurations library."""
16 from ipaddress import ip_address, AddressValueError
17 from robot.api import logger
19 from resources.libraries.python.Constants import Constants
20 from resources.libraries.python.InterfaceUtil import InterfaceUtil, \
22 from resources.libraries.python.IPAddress import IPAddress
23 from resources.libraries.python.IPUtil import IPUtil
24 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
25 from resources.libraries.python.topology import Topology
26 from resources.libraries.python.VatExecutor import VatExecutor
30 """Contains special test configurations implemented in python for faster
34 def vpp_create_multiple_vxlan_ipv4_tunnels(
35 node, node_vxlan_if, node_vlan_if, op_node, op_node_if,
36 n_tunnels, vni_start, src_ip_start, dst_ip_start, ip_step,
38 """Create multiple VXLAN tunnel interfaces and VLAN sub-interfaces on
41 Put each pair of VXLAN tunnel interface and VLAN sub-interface to
42 separate bridge-domain.
44 :param node: VPP node to create VXLAN tunnel interfaces.
45 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
47 :param node_vlan_if: VPP node interface key to create VLAN
49 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
50 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
52 :param n_tunnels: Number of tunnel interfaces to create.
53 :param vni_start: VNI start ID.
54 :param src_ip_start: VXLAN tunnel source IP address start.
55 :param dst_ip_start: VXLAN tunnel destination IP address start.
56 :param ip_step: IP address incremental step.
57 :param bd_id_start: Bridge-domain ID start.
59 :type node_vxlan_if: str
60 :type node_vlan_if: str
65 :type src_ip_start: str
66 :type dst_ip_start: str
68 :type bd_id_start: int
70 # configure IPs, create VXLAN interfaces and VLAN sub-interfaces
71 vxlan_count = TestConfig.vpp_create_vxlan_and_vlan_interfaces(
72 node, node_vxlan_if, node_vlan_if, n_tunnels, vni_start,
73 src_ip_start, dst_ip_start, ip_step
76 # update topology with VXLAN interfaces and VLAN sub-interfaces data
77 # and put interfaces up
78 TestConfig.vpp_put_vxlan_and_vlan_interfaces_up(
79 node, vxlan_count, node_vlan_if
82 # configure bridge domains, ARPs and routes
83 TestConfig.vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
84 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
89 def vpp_create_vxlan_and_vlan_interfaces(
90 node, node_vxlan_if, node_vlan_if, vxlan_count, vni_start,
91 src_ip_start, dst_ip_start, ip_step):
93 Configure IPs, create VXLAN interfaces and VLAN sub-interfaces on VPP
96 :param node: VPP node.
97 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
99 :param node_vlan_if: VPP node interface key to create VLAN
101 :param vxlan_count: Number of tunnel interfaces to create.
102 :param vni_start: VNI start ID.
103 :param src_ip_start: VXLAN tunnel source IP address start.
104 :param dst_ip_start: VXLAN tunnel destination IP address start.
105 :param ip_step: IP address incremental step.
107 :type node_vxlan_if: str
108 :type node_vlan_if: str
109 :type vxlan_count: int
111 :type src_ip_start: str
112 :type dst_ip_start: str
114 :returns: Number of created VXLAN interfaces.
117 src_ip_start = ip_address(src_ip_start)
118 dst_ip_start = ip_address(dst_ip_start)
122 for i in range(0, vxlan_count):
124 src_ip = src_ip_start + i * ip_step
125 dst_ip = dst_ip_start + i * ip_step
126 except AddressValueError:
128 u"Can't do more iterations - IP address limit "
134 f"sw_interface_add_del_address sw_if_index "
135 f"{Topology.get_interface_sw_index(node, node_vxlan_if)} "
136 f"{src_ip}/{128 if src_ip.version == 6 else 32}\n"
139 f"vxlan_add_del_tunnel src {src_ip} dst {dst_ip} "
140 f"vni {vni_start + i}\n"
143 f"create_vlan_subif sw_if_index "
144 f"{Topology.get_interface_sw_index(node, node_vlan_if)} "
147 VatExecutor().write_and_execute_script(
148 node, u"/tmp/create_vxlan_interfaces.config", commands
152 cmd1 = u"sw_interface_add_del_address"
154 sw_if_index=InterfaceUtil.get_interface_index(node, node_vxlan_if),
159 cmd2 = u"vxlan_add_del_tunnel_v3"
162 instance=Constants.BITWISE_NON_ZERO,
165 mcast_sw_if_index=Constants.BITWISE_NON_ZERO,
167 decap_next_index=Constants.BITWISE_NON_ZERO,
170 cmd3 = u"create_vlan_subif"
172 sw_if_index=InterfaceUtil.get_interface_index(
177 with PapiSocketExecutor(node) as papi_exec:
178 for i in range(0, vxlan_count):
180 src_ip = src_ip_start + i * ip_step
181 dst_ip = dst_ip_start + i * ip_step
182 except AddressValueError:
184 u"Can't do more iterations - IP address limit "
189 args1[u"prefix"] = IPUtil.create_prefix_object(
190 src_ip, 128 if src_ip_start.version == 6 else 32
192 args2[u"src_address"] = IPAddress.create_ip_address_object(
195 args2[u"dst_address"] = IPAddress.create_ip_address_object(
198 args2[u"vni"] = int(vni_start) + i
199 args3[u"vlan_id"] = i + 1
200 history = bool(not 1 < i < vxlan_count - 1)
201 papi_exec.add(cmd1, history=history, **args1).\
202 add(cmd2, history=history, **args2).\
203 add(cmd3, history=history, **args3)
204 papi_exec.get_replies()
209 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
211 Update topology with VXLAN interfaces and VLAN sub-interfaces data
212 and put interfaces up.
214 :param node: VPP node.
215 :param vxlan_count: Number of tunnel interfaces.
216 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
219 :type vxlan_count: int
220 :type node_vlan_if: str
222 if_data = InterfaceUtil.vpp_get_interface_data(node)
225 for i in range(0, vxlan_count):
226 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
227 vxlan_subif_name = f"vxlan_tunnel{i}"
228 founds = dict(vxlan=False, vlan=False)
229 vxlan_subif_idx = None
230 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
232 f"{Topology.get_interface_name(node, node_vlan_if)}.{i + 1}"
235 if_name = data[u"interface_name"]
236 if not founds[u"vxlan"] and if_name == vxlan_subif_name:
237 vxlan_subif_idx = data[u"sw_if_index"]
238 founds[u"vxlan"] = True
239 elif not founds[u"vlan"] and if_name == vlan_subif_name:
240 vlan_idx = data[u"sw_if_index"]
241 founds[u"vlan"] = True
242 if founds[u"vxlan"] and founds[u"vlan"]:
244 Topology.update_interface_sw_if_index(
245 node, vxlan_subif_key, vxlan_subif_idx)
246 Topology.update_interface_name(
247 node, vxlan_subif_key, vxlan_subif_name)
249 f"sw_interface_set_flags sw_if_index {vxlan_subif_idx} "
250 f"admin-up link-up\n"
252 Topology.update_interface_sw_if_index(
253 node, vlan_subif_key, vlan_idx
255 Topology.update_interface_name(
256 node, vlan_subif_key, vlan_subif_name
259 f"sw_interface_set_flags sw_if_index {vlan_idx} admin-up "
262 VatExecutor().write_and_execute_script(
263 node, u"/tmp/put_subinterfaces_up.config", commands
267 cmd = u"sw_interface_set_flags"
270 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
274 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
277 with PapiSocketExecutor(node) as papi_exec:
278 for i in range(0, vxlan_count):
279 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
280 vxlan_subif_name = f"vxlan_tunnel{i}"
281 founds = dict(vxlan=False, vlan=False)
282 vxlan_subif_idx = None
283 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
285 f"{Topology.get_interface_name(node, node_vlan_if)}.{i+1}"
288 if not founds[u"vxlan"] \
289 and data[u"interface_name"] == vxlan_subif_name:
290 vxlan_subif_idx = data[u"sw_if_index"]
291 founds[u"vxlan"] = True
292 elif not founds[u"vlan"] \
293 and data[u"interface_name"] == vlan_subif_name:
294 vlan_idx = data[u"sw_if_index"]
295 founds[u"vlan"] = True
296 if founds[u"vxlan"] and founds[u"vlan"]:
298 Topology.update_interface_sw_if_index(
299 node, vxlan_subif_key, vxlan_subif_idx
301 Topology.update_interface_name(
302 node, vxlan_subif_key, vxlan_subif_name
304 args1[u"sw_if_index"] = vxlan_subif_idx
305 Topology.update_interface_sw_if_index(
306 node, vlan_subif_key, vlan_idx
308 Topology.update_interface_name(
309 node, vlan_subif_key, vlan_subif_name
311 args2[u"sw_if_index"] = vlan_idx
312 history = bool(not 1 < i < vxlan_count - 1)
313 papi_exec.add(cmd, history=history, **args1). \
314 add(cmd, history=history, **args2)
315 papi_exec.add(cmd, **args1).add(cmd, **args2)
316 papi_exec.get_replies()
319 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
320 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
321 ip_step, bd_id_start):
323 Configure ARPs and routes for VXLAN interfaces and put each pair of
324 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
326 :param node: VPP node.
327 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
328 interfaces have been created.
329 :param vxlan_count: Number of tunnel interfaces.
330 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
331 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
333 :param dst_ip_start: VXLAN tunnel destination IP address start.
334 :param ip_step: IP address incremental step.
335 :param bd_id_start: Bridge-domain ID start.
337 :type node_vxlan_if: str
338 :type vxlan_count: int
341 :type dst_ip_start: str
343 :type bd_id_start: int
345 dst_ip_start = ip_address(dst_ip_start)
348 idx_vxlan_if = Topology.get_interface_sw_index(node, node_vxlan_if)
350 for i in range(0, vxlan_count):
351 dst_ip = dst_ip_start + i * ip_step
354 f"{Topology.get_interface_name(node, node_vxlan_if)} "
356 f"{Topology.get_interface_mac(op_node, op_node_if)} static "
361 f"{dst_ip}/{128 if dst_ip.version == 6 else 32} count 1 "
362 f"via {dst_ip} sw_if_index {idx_vxlan_if}\n"
364 sw_idx_vxlan = Topology.get_interface_sw_index(
365 node, f"vxlan_tunnel{i + 1}"
368 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vxlan} "
369 f"bd_id {bd_id_start + i} shg 0 enable\n"
371 sw_idx_vlan = Topology.get_interface_sw_index(
372 node, f"vlan_subif{i + 1}"
375 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vlan} "
376 f"bd_id {bd_id_start + i} shg 0 enable\n"
378 VatExecutor().write_and_execute_script(
379 node, u"/tmp/configure_routes_and_bridge_domains.config",
384 cmd1 = u"ip_neighbor_add_del"
386 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
388 mac_address=Topology.get_interface_mac(op_node, op_node_if),
395 cmd2 = u"ip_route_add_del"
397 interface=node_vxlan_if,
398 gateway=str(dst_ip_start)
400 route = IPUtil.compose_vpp_route_structure(
401 node, str(dst_ip_start),
402 128 if dst_ip_start.version == 6 else 32, **kwargs
409 cmd3 = u"sw_interface_set_l2_bridge"
425 with PapiSocketExecutor(node) as papi_exec:
426 for i in range(0, vxlan_count):
427 args1[u"neighbor"][u"ip_address"] = \
428 str(dst_ip_start + i * ip_step)
429 args2[u"route"][u"prefix"][u"address"][u"un"] = \
430 IPAddress.union_addr(dst_ip_start + i * ip_step)
431 args2[u"route"][u"paths"][0][u"nh"][u"address"] = \
432 IPAddress.union_addr(dst_ip_start + i * ip_step)
433 args3[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
434 node, f"vxlan_tunnel{i+1}"
436 args3[u"bd_id"] = int(bd_id_start+i)
437 args4[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
438 node, f"vlan_subif{i+1}"
440 args4[u"bd_id"] = int(bd_id_start+i)
441 history = bool(not 1 < i < vxlan_count - 1)
442 papi_exec.add(cmd1, history=history, **args1). \
443 add(cmd2, history=history, **args2). \
444 add(cmd3, history=history, **args3). \
445 add(cmd3, history=history, **args4)
446 papi_exec.get_replies()