1 # Copyright (c) 2020 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"
163 instance=Constants.BITWISE_NON_ZERO,
166 mcast_sw_if_index=Constants.BITWISE_NON_ZERO,
168 decap_next_index=Constants.BITWISE_NON_ZERO,
171 cmd3 = u"create_vlan_subif"
173 sw_if_index=InterfaceUtil.get_interface_index(
178 with PapiSocketExecutor(node) as papi_exec:
179 for i in range(0, vxlan_count):
181 src_ip = src_ip_start + i * ip_step
182 dst_ip = dst_ip_start + i * ip_step
183 except AddressValueError:
185 u"Can't do more iterations - IP address limit "
190 args1[u"prefix"] = IPUtil.create_prefix_object(
191 src_ip, 128 if src_ip_start.version == 6 else 32
193 args2[u"src_address"] = getattr(src_ip, u"packed")
194 args2[u"dst_address"] = getattr(dst_ip, u"packed")
195 args2[u"vni"] = int(vni_start) + i
196 args3[u"vlan_id"] = i + 1
197 history = bool(not 1 < i < vxlan_count - 1)
198 papi_exec.add(cmd1, history=history, **args1).\
199 add(cmd2, history=history, **args2).\
200 add(cmd3, history=history, **args3)
201 papi_exec.get_replies()
206 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
208 Update topology with VXLAN interfaces and VLAN sub-interfaces data
209 and put interfaces up.
211 :param node: VPP node.
212 :param vxlan_count: Number of tunnel interfaces.
213 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
216 :type vxlan_count: int
217 :type node_vlan_if: str
219 if_data = InterfaceUtil.vpp_get_interface_data(node)
222 for i in range(0, vxlan_count):
223 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
224 vxlan_subif_name = f"vxlan_tunnel{i}"
225 founds = dict(vxlan=False, vlan=False)
226 vxlan_subif_idx = None
227 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
229 f"{Topology.get_interface_name(node, node_vlan_if)}.{i + 1}"
232 if_name = data[u"interface_name"]
233 if not founds[u"vxlan"] and if_name == vxlan_subif_name:
234 vxlan_subif_idx = data[u"sw_if_index"]
235 founds[u"vxlan"] = True
236 elif not founds[u"vlan"] and if_name == vlan_subif_name:
237 vlan_idx = data[u"sw_if_index"]
238 founds[u"vlan"] = True
239 if founds[u"vxlan"] and founds[u"vlan"]:
241 Topology.update_interface_sw_if_index(
242 node, vxlan_subif_key, vxlan_subif_idx)
243 Topology.update_interface_name(
244 node, vxlan_subif_key, vxlan_subif_name)
246 f"sw_interface_set_flags sw_if_index {vxlan_subif_idx} "
247 f"admin-up link-up\n"
249 Topology.update_interface_sw_if_index(
250 node, vlan_subif_key, vlan_idx
252 Topology.update_interface_name(
253 node, vlan_subif_key, vlan_subif_name
256 f"sw_interface_set_flags sw_if_index {vlan_idx} admin-up "
259 VatExecutor().write_and_execute_script(
260 node, u"/tmp/put_subinterfaces_up.config", commands
264 cmd = u"sw_interface_set_flags"
267 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
271 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
274 with PapiSocketExecutor(node) as papi_exec:
275 for i in range(0, vxlan_count):
276 vxlan_subif_key = Topology.add_new_port(node, u"vxlan_tunnel")
277 vxlan_subif_name = f"vxlan_tunnel{i}"
278 founds = dict(vxlan=False, vlan=False)
279 vxlan_subif_idx = None
280 vlan_subif_key = Topology.add_new_port(node, u"vlan_subif")
282 f"{Topology.get_interface_name(node, node_vlan_if)}.{i+1}"
285 if not founds[u"vxlan"] \
286 and data[u"interface_name"] == vxlan_subif_name:
287 vxlan_subif_idx = data[u"sw_if_index"]
288 founds[u"vxlan"] = True
289 elif not founds[u"vlan"] \
290 and data[u"interface_name"] == vlan_subif_name:
291 vlan_idx = data[u"sw_if_index"]
292 founds[u"vlan"] = True
293 if founds[u"vxlan"] and founds[u"vlan"]:
295 Topology.update_interface_sw_if_index(
296 node, vxlan_subif_key, vxlan_subif_idx
298 Topology.update_interface_name(
299 node, vxlan_subif_key, vxlan_subif_name
301 args1[u"sw_if_index"] = vxlan_subif_idx
302 Topology.update_interface_sw_if_index(
303 node, vlan_subif_key, vlan_idx
305 Topology.update_interface_name(
306 node, vlan_subif_key, vlan_subif_name
308 args2[u"sw_if_index"] = vlan_idx
309 history = bool(not 1 < i < vxlan_count - 1)
310 papi_exec.add(cmd, history=history, **args1). \
311 add(cmd, history=history, **args2)
312 papi_exec.add(cmd, **args1).add(cmd, **args2)
313 papi_exec.get_replies()
316 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
317 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
318 ip_step, bd_id_start):
320 Configure ARPs and routes for VXLAN interfaces and put each pair of
321 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
323 :param node: VPP node.
324 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
325 interfaces have been created.
326 :param vxlan_count: Number of tunnel interfaces.
327 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
328 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
330 :param dst_ip_start: VXLAN tunnel destination IP address start.
331 :param ip_step: IP address incremental step.
332 :param bd_id_start: Bridge-domain ID start.
334 :type node_vxlan_if: str
335 :type vxlan_count: int
338 :type dst_ip_start: str
340 :type bd_id_start: int
342 dst_ip_start = ip_address(dst_ip_start)
345 idx_vxlan_if = Topology.get_interface_sw_index(node, node_vxlan_if)
347 for i in range(0, vxlan_count):
348 dst_ip = dst_ip_start + i * ip_step
351 f"{Topology.get_interface_name(node, node_vxlan_if)} "
353 f"{Topology.get_interface_mac(op_node, op_node_if)} static "
358 f"{dst_ip}/{128 if dst_ip.version == 6 else 32} count 1 "
359 f"via {dst_ip} sw_if_index {idx_vxlan_if}\n"
361 sw_idx_vxlan = Topology.get_interface_sw_index(
362 node, f"vxlan_tunnel{i + 1}"
365 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vxlan} "
366 f"bd_id {bd_id_start + i} shg 0 enable\n"
368 sw_idx_vlan = Topology.get_interface_sw_index(
369 node, f"vlan_subif{i + 1}"
372 f"sw_interface_set_l2_bridge sw_if_index {sw_idx_vlan} "
373 f"bd_id {bd_id_start + i} shg 0 enable\n"
375 VatExecutor().write_and_execute_script(
376 node, u"/tmp/configure_routes_and_bridge_domains.config",
381 cmd1 = u"ip_neighbor_add_del"
383 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
385 mac_address=Topology.get_interface_mac(op_node, op_node_if),
392 cmd2 = u"ip_route_add_del"
394 interface=node_vxlan_if,
395 gateway=str(dst_ip_start)
397 route = IPUtil.compose_vpp_route_structure(
398 node, str(dst_ip_start),
399 128 if dst_ip_start.version == 6 else 32, **kwargs
406 cmd3 = u"sw_interface_set_l2_bridge"
422 with PapiSocketExecutor(node) as papi_exec:
423 for i in range(0, vxlan_count):
424 args1[u"neighbor"][u"ip_address"] = \
425 str(dst_ip_start + i * ip_step)
426 args2[u"route"][u"prefix"][u"address"][u"un"] = \
427 IPAddress.union_addr(dst_ip_start + i * ip_step)
428 args2[u"route"][u"paths"][0][u"nh"][u"address"] = \
429 IPAddress.union_addr(dst_ip_start + i * ip_step)
430 args3[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
431 node, f"vxlan_tunnel{i+1}"
433 args3[u"bd_id"] = int(bd_id_start+i)
434 args4[u"rx_sw_if_index"] = Topology.get_interface_sw_index(
435 node, f"vlan_subif{i+1}"
437 args4[u"bd_id"] = int(bd_id_start+i)
438 history = bool(not 1 < i < vxlan_count - 1)
439 papi_exec.add(cmd1, history=history, **args1). \
440 add(cmd2, history=history, **args2). \
441 add(cmd3, history=history, **args3). \
442 add(cmd3, history=history, **args4)
443 papi_exec.get_replies()