1 # Copyright (c) 2019 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.IPUtil import IPUtil
23 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
24 from resources.libraries.python.topology import Topology
25 from resources.libraries.python.VatExecutor import VatExecutor
29 """Contains special test configurations implemented in python for faster
33 def vpp_create_multiple_vxlan_ipv4_tunnels(
34 node, node_vxlan_if, node_vlan_if, op_node, op_node_if,
35 n_tunnels, vni_start, src_ip_start, dst_ip_start, ip_step,
37 """Create multiple VXLAN tunnel interfaces and VLAN sub-interfaces on
40 Put each pair of VXLAN tunnel interface and VLAN sub-interface to
41 separate bridge-domain.
43 :param node: VPP node to create VXLAN tunnel interfaces.
44 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
46 :param node_vlan_if: VPP node interface key to create VLAN
48 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
49 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
51 :param n_tunnels: Number of tunnel interfaces to create.
52 :param vni_start: VNI start ID.
53 :param src_ip_start: VXLAN tunnel source IP address start.
54 :param dst_ip_start: VXLAN tunnel destination IP address start.
55 :param ip_step: IP address incremental step.
56 :param bd_id_start: Bridge-domain ID start.
58 :type node_vxlan_if: str
59 :type node_vlan_if: str
64 :type src_ip_start: str
65 :type dst_ip_start: str
67 :type bd_id_start: int
69 # configure IPs, create VXLAN interfaces and VLAN sub-interfaces
70 vxlan_count = TestConfig.vpp_create_vxlan_and_vlan_interfaces(
71 node, node_vxlan_if, node_vlan_if, n_tunnels, vni_start,
72 src_ip_start, dst_ip_start, ip_step
75 # update topology with VXLAN interfaces and VLAN sub-interfaces data
76 # and put interfaces up
77 TestConfig.vpp_put_vxlan_and_vlan_interfaces_up(
78 node, vxlan_count, node_vlan_if
81 # configure bridge domains, ARPs and routes
82 TestConfig.vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
83 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
88 def vpp_create_vxlan_and_vlan_interfaces(
89 node, node_vxlan_if, node_vlan_if, vxlan_count, vni_start,
90 src_ip_start, dst_ip_start, ip_step):
92 Configure IPs, create VXLAN interfaces and VLAN sub-interfaces on VPP
95 :param node: VPP node.
96 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
98 :param node_vlan_if: VPP node interface key to create VLAN
100 :param vxlan_count: Number of tunnel interfaces to create.
101 :param vni_start: VNI start ID.
102 :param src_ip_start: VXLAN tunnel source IP address start.
103 :param dst_ip_start: VXLAN tunnel destination IP address start.
104 :param ip_step: IP address incremental step.
106 :type node_vxlan_if: str
107 :type node_vlan_if: str
108 :type vxlan_count: int
110 :type src_ip_start: str
111 :type dst_ip_start: str
113 :returns: Number of created VXLAN interfaces.
116 src_ip_start = ip_address(src_ip_start)
117 dst_ip_start = ip_address(dst_ip_start)
121 for i in range(0, vxlan_count):
123 src_ip = src_ip_start + i * ip_step
124 dst_ip = dst_ip_start + i * ip_step
125 except AddressValueError:
127 u"Can't do more iterations - IP address limit "
133 f"sw_interface_add_del_address sw_if_index "
134 f"{Topology.get_interface_sw_index(node, node_vxlan_if)} "
135 f"{src_ip}/{128 if src_ip.version == 6 else 32}\n"
138 f"vxlan_add_del_tunnel src {src_ip} dst {dst_ip} "
139 f"vni {vni_start + i}\n"
142 f"create_vlan_subif sw_if_index "
143 f"{Topology.get_interface_sw_index(node, node_vlan_if)} "
146 VatExecutor().write_and_execute_script(
147 node, u"/tmp/create_vxlan_interfaces.config", commands
151 cmd1 = u"sw_interface_add_del_address"
153 sw_if_index=InterfaceUtil.get_interface_index(node, node_vxlan_if),
158 cmd2 = u"vxlan_add_del_tunnel"
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"] = getattr(src_ip, u"packed")
193 args2[u"dst_address"] = getattr(dst_ip, u"packed")
194 args2[u"vni"] = int(vni_start) + i
195 args3[u"vlan_id"] = i + 1
196 history = bool(not 1 < i < vxlan_count - 1)
197 papi_exec.add(cmd1, history=history, **args1).\
198 add(cmd2, history=history, **args2).\
199 add(cmd3, history=history, **args3)
200 papi_exec.get_replies()
205 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
207 Update topology with VXLAN interfaces and VLAN sub-interfaces data
208 and put interfaces up.
210 :param node: VPP node.
211 :param vxlan_count: Number of tunnel interfaces.
212 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
215 :type vxlan_count: int
216 :type node_vlan_if: str
218 if_data = InterfaceUtil.vpp_get_interface_data(node)
221 for i in range(0, vxlan_count):
222 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
223 vxlan_subif_name = f"vxlan_tunnel{i}"
224 founds = dict(vxlan=False, vlan=False)
225 vxlan_subif_idx = None
226 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
228 f"{Topology.get_interface_name(node, node_vlan_if)}.{i + 1}"
231 if_name = data[u"interface_name"]
232 if not founds[u"vxlan"] and if_name == vxlan_subif_name:
233 vxlan_subif_idx = data[u"sw_if_index"]
234 founds[u"vxlan"] = True
235 elif not founds[u"vlan"] and if_name == vlan_subif_name:
236 vlan_idx = data[u"sw_if_index"]
237 founds[u"vlan"] = True
238 if founds[u"vxlan"] and founds[u"vlan"]:
240 Topology.update_interface_sw_if_index(
241 node, vxlan_subif_key, vxlan_subif_idx)
242 Topology.update_interface_name(
243 node, vxlan_subif_key, vxlan_subif_name)
245 f"sw_interface_set_flags sw_if_index {vxlan_subif_idx} "
246 f"admin-up link-up\n"
248 Topology.update_interface_sw_if_index(
249 node, vlan_subif_key, vlan_idx
251 Topology.update_interface_name(
252 node, vlan_subif_key, vlan_subif_name
255 f"sw_interface_set_flags sw_if_index {vlan_idx} admin-up "
258 VatExecutor().write_and_execute_script(
259 node, u"/tmp/put_subinterfaces_up.config", commands
263 cmd = u"sw_interface_set_flags"
266 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
270 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
273 with PapiSocketExecutor(node) as papi_exec:
274 for i in range(0, vxlan_count):
275 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
276 vxlan_subif_name = f"vxlan_tunnel{i}"
277 founds = dict(vxlan=False, vlan=False)
278 vxlan_subif_idx = None
279 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
281 f"{Topology.get_interface_name(node, node_vlan_if)}.{i+1}"
284 if not founds[u"vxlan"] \
285 and data[u"interface_name"] == vxlan_subif_name:
286 vxlan_subif_idx = data[u"sw_if_index"]
287 founds[u"vxlan"] = True
288 elif not founds[u"vlan"] \
289 and data[u"interface_name"] == vlan_subif_name:
290 vlan_idx = data[u"sw_if_index"]
291 founds[u"vlan"] = True
292 if founds[u"vxlan"] and founds[u"vlan"]:
294 Topology.update_interface_sw_if_index(
295 node, vxlan_subif_key, vxlan_subif_idx
297 Topology.update_interface_name(
298 node, vxlan_subif_key, vxlan_subif_name
300 args1[u"sw_if_index"] = vxlan_subif_idx
301 Topology.update_interface_sw_if_index(
302 node, vlan_subif_key, vlan_idx
304 Topology.update_interface_name(
305 node, vlan_subif_key, vlan_subif_name
307 args2[u"sw_if_index"] = vlan_idx
308 history = bool(not 1 < i < vxlan_count - 1)
309 papi_exec.add(cmd, history=history, **args1). \
310 add(cmd, history=history, **args2)
311 papi_exec.add(cmd, **args1).add(cmd, **args2)
312 papi_exec.get_replies()
315 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
316 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
317 ip_step, bd_id_start):
319 Configure ARPs and routes for VXLAN interfaces and put each pair of
320 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
322 :param node: VPP node.
323 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
324 interfaces have been created.
325 :param vxlan_count: Number of tunnel interfaces.
326 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
327 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
329 :param dst_ip_start: VXLAN tunnel destination IP address start.
330 :param ip_step: IP address incremental step.
331 :param bd_id_start: Bridge-domain ID start.
333 :type node_vxlan_if: str
334 :type vxlan_count: int
337 :type dst_ip_start: str
339 :type bd_id_start: int
341 dst_ip_start = ip_address(dst_ip_start)
344 idx_vxlan_if = Topology.get_interface_sw_index(node, node_vxlan_if)
346 for i in range(0, vxlan_count):
347 dst_ip = dst_ip_start + i * ip_step
350 f"{Topology.get_interface_name(node, node_vxlan_if)} "
352 f"{Topology.get_interface_mac(op_node, op_node_if)} static "
357 f"{dst_ip}/{128 if dst_ip.version == 6 else 32} count 1 "
358 f"via {dst_ip} sw_if_index {idx_vxlan_if}\n"
360 sw_idx_vxlan = Topology.get_interface_sw_index(
361 node, f"vxlan_tunnel{i + 1}"
364 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vxlan} "
365 f"bd_id {bd_id_start + i} shg 0 enable\n"
367 sw_idx_vlan = Topology.get_interface_sw_index(
368 node, f"vlan_subif{i + 1}"
371 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vlan} "
372 f"bd_id {bd_id_start + i} shg 0 enable\n"
374 VatExecutor().write_and_execute_script(
375 node, u"/tmp/configure_routes_and_bridge_domains.config",
380 cmd1 = u"ip_neighbor_add_del"
382 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
384 mac_address=Topology.get_interface_mac(op_node, op_node_if),
391 cmd2 = u"ip_route_add_del"
393 interface=node_vxlan_if,
394 gateway=str(dst_ip_start)
396 route = IPUtil.compose_vpp_route_structure(
397 node, str(dst_ip_start),
398 128 if dst_ip_start.version == 6 else 32, **kwargs
405 cmd3 = u"sw_interface_set_l2_bridge"
421 with PapiSocketExecutor(node) as papi_exec:
422 for i in range(0, vxlan_count):
423 args1[u"neighbor"][u"ip_address"] = \
424 str(dst_ip_start + i * ip_step)
425 args2[u"route"][u"prefix"][u"address"][u"un"] = \
426 IPUtil.union_addr(dst_ip_start + i * ip_step)
427 args2[u"route"][u"paths"][0][u"nh"][u"address"] = \
428 IPUtil.union_addr(dst_ip_start + i * ip_step)
429 args3[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
430 node, f"vxlan_tunnel{i+1}"
432 args3[u"bd_id"] = int(bd_id_start+i)
433 args4[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
434 node, f"vlan_subif{i+1}"
436 args4[u"bd_id"] = int(bd_id_start+i)
437 history = bool(not 1 < i < vxlan_count - 1)
438 papi_exec.add(cmd1, history=history, **args1). \
439 add(cmd2, history=history, **args2). \
440 add(cmd3, history=history, **args3). \
441 add(cmd3, history=history, **args4)
442 papi_exec.get_replies()