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
220 for i in range(0, vxlan_count):
221 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
222 vxlan_subif_name = f"vxlan_tunnel{i}"
223 founds = dict(vxlan=False, vlan=False)
224 vxlan_subif_idx = None
225 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
227 f"{Topology.get_interface_name(node, node_vlan_if)}.{i + 1}"
229 for data in InterfaceUtil.vpp_get_interface_data(node):
230 if_name = data[u"interface_name"]
231 if not founds[u"vxlan"] and if_name == vxlan_subif_name:
232 vxlan_subif_idx = data[u"sw_if_index"]
233 founds[u"vxlan"] = True
234 elif not founds[u"vlan"] and if_name == vlan_subif_name:
235 vlan_idx = data[u"sw_if_index"]
236 founds[u"vlan"] = True
237 if founds[u"vxlan"] and founds[u"vlan"]:
239 Topology.update_interface_sw_if_index(
240 node, vxlan_subif_key, vxlan_subif_idx)
241 Topology.update_interface_name(
242 node, vxlan_subif_key, vxlan_subif_name)
244 f"sw_interface_set_flags sw_if_index {vxlan_subif_idx} "
245 f"admin-up link-up\n"
247 Topology.update_interface_sw_if_index(
248 node, vlan_subif_key, vlan_idx
250 Topology.update_interface_name(
251 node, vlan_subif_key, vlan_subif_name
254 f"sw_interface_set_flags sw_if_index {vlan_idx} admin-up "
257 VatExecutor().write_and_execute_script(
258 node, u"/tmp/put_subinterfaces_up.config", commands
262 cmd = u"sw_interface_set_flags"
265 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
269 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
272 with PapiSocketExecutor(node) as papi_exec:
273 for i in range(0, vxlan_count):
274 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
275 vxlan_subif_name = f"vxlan_tunnel{i}"
276 founds = dict(vxlan=False, vlan=False)
277 vxlan_subif_idx = None
278 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
280 f"{Topology.get_interface_name(node, node_vlan_if)}.{i+1}"
282 for data in InterfaceUtil.vpp_get_interface_data(node):
283 if not founds[u"vxlan"] \
284 and data[u"interface_name"] == vxlan_subif_name:
285 vxlan_subif_idx = data[u"sw_if_index"]
286 founds[u"vxlan"] = True
287 elif not founds[u"vlan"] \
288 and data[u"interface_name"] == vlan_subif_name:
289 vlan_idx = data[u"sw_if_index"]
290 founds[u"vlan"] = True
291 if founds[u"vxlan"] and founds[u"vlan"]:
293 Topology.update_interface_sw_if_index(
294 node, vxlan_subif_key, vxlan_subif_idx
296 Topology.update_interface_name(
297 node, vxlan_subif_key, vxlan_subif_name
299 args1[u"sw_if_index"] = vxlan_subif_idx
300 Topology.update_interface_sw_if_index(
301 node, vlan_subif_key, vlan_idx
303 Topology.update_interface_name(
304 node, vlan_subif_key, vlan_subif_name
306 args2[u"sw_if_index"] = vlan_idx
307 history = bool(not 1 < i < vxlan_count - 1)
308 papi_exec.add(cmd, history=history, **args1). \
309 add(cmd, history=history, **args2)
310 papi_exec.add(cmd, **args1).add(cmd, **args2)
311 papi_exec.get_replies()
314 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
315 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
316 ip_step, bd_id_start):
318 Configure ARPs and routes for VXLAN interfaces and put each pair of
319 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
321 :param node: VPP node.
322 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
323 interfaces have been created.
324 :param vxlan_count: Number of tunnel interfaces.
325 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
326 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
328 :param dst_ip_start: VXLAN tunnel destination IP address start.
329 :param ip_step: IP address incremental step.
330 :param bd_id_start: Bridge-domain ID start.
332 :type node_vxlan_if: str
333 :type vxlan_count: int
336 :type dst_ip_start: str
338 :type bd_id_start: int
340 dst_ip_start = ip_address(dst_ip_start)
343 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
345 for i in range(0, vxlan_count):
346 dst_ip = dst_ip_start + i * ip_step
348 f"ip_neighbor_add_del sw_if_index {sw_idx_vxlan} "
350 f"mac {Topology.get_interface_mac(op_node, op_node_if)}\n"
354 f"{dst_ip}/{128 if dst_ip.version == 6 else 32} count 1 "
355 f"via {dst_ip} sw_if_index {sw_idx_vxlan}\n"
357 sw_idx_vxlan = Topology.get_interface_sw_index(
358 node, f"vxlan_tunnel{i + 1}"
361 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vxlan} "
362 f"bd_id {bd_id_start + i} shg 0 enable\n"
364 sw_idx_vlan = Topology.get_interface_sw_index(
365 node, f"vlan_subif{i + 1}"
368 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vlan} "
369 f"bd_id {bd_id_start + i} shg 0 enable\n"
371 VatExecutor().write_and_execute_script(
372 node, u"/tmp/configure_routes_and_bridge_domains.config",
377 cmd1 = u"ip_neighbor_add_del"
379 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
381 mac_address=Topology.get_interface_mac(op_node, op_node_if),
388 cmd2 = u"ip_route_add_del"
390 interface=node_vxlan_if,
391 gateway=str(dst_ip_start)
393 route = IPUtil.compose_vpp_route_structure(
394 node, str(dst_ip_start),
395 128 if dst_ip_start.version == 6 else 32, **kwargs
402 cmd3 = u"sw_interface_set_l2_bridge"
418 with PapiSocketExecutor(node) as papi_exec:
419 for i in range(0, vxlan_count):
420 args1[u"neighbor"][u"ip_address"] = \
421 str(dst_ip_start + i * ip_step)
422 args2[u"route"][u"prefix"][u"address"][u"un"] = \
423 IPUtil.union_addr(dst_ip_start + i * ip_step)
424 args2[u"route"][u"paths"][0][u"nh"][u"address"] = \
425 IPUtil.union_addr(dst_ip_start + i * ip_step)
426 args3[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
427 node, f"vxlan_tunnel{i+1}"
429 args3[u"bd_id"] = int(bd_id_start+i)
430 args4[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
431 node, f"vlan_subif{i+1}"
433 args4[u"bd_id"] = int(bd_id_start+i)
434 history = bool(not 1 < i < vxlan_count - 1)
435 papi_exec.add(cmd1, history=history, **args1). \
436 add(cmd2, history=history, **args2). \
437 add(cmd3, history=history, **args3). \
438 add(cmd3, history=history, **args4)
439 papi_exec.get_replies()