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
28 class TestConfig(object):
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)
74 # update topology with VXLAN interfaces and VLAN sub-interfaces data
75 # and put interfaces up
76 TestConfig.vpp_put_vxlan_and_vlan_interfaces_up(
77 node, vxlan_count, node_vlan_if)
79 # configure bridge domains, ARPs and routes
80 TestConfig.vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
81 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
85 def vpp_create_vxlan_and_vlan_interfaces(
86 node, node_vxlan_if, node_vlan_if, vxlan_count, vni_start,
87 src_ip_start, dst_ip_start, ip_step):
89 Configure IPs, create VXLAN interfaces and VLAN sub-interfaces on VPP
92 :param node: VPP node.
93 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
95 :param node_vlan_if: VPP node interface key to create VLAN
97 :param vxlan_count: Number of tunnel interfaces to create.
98 :param vni_start: VNI start ID.
99 :param src_ip_start: VXLAN tunnel source IP address start.
100 :param dst_ip_start: VXLAN tunnel destination IP address start.
101 :param ip_step: IP address incremental step.
103 :type node_vxlan_if: str
104 :type node_vlan_if: str
105 :type vxlan_count: int
107 :type src_ip_start: str
108 :type dst_ip_start: str
110 :returns: Number of created VXLAN interfaces.
113 src_ip_addr_start = ip_address(unicode(src_ip_start))
114 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
118 tmp_fn = '/tmp/create_vxlan_interfaces.config'
119 for i in xrange(0, vxlan_count):
121 src_ip = src_ip_addr_start + i * ip_step
122 dst_ip = dst_ip_addr_start + i * ip_step
123 except AddressValueError:
124 logger.warn("Can't do more iterations - IP address limit "
129 'sw_interface_add_del_address sw_if_index {sw_idx} '
130 '{ip}/{ip_len}\n'.format(
131 sw_idx=Topology.get_interface_sw_index(
132 node, node_vxlan_if),
134 ip_len=128 if src_ip.version == 6 else 32))
136 'vxlan_add_del_tunnel src {srcip} dst {dstip} vni {vni}\n'\
137 .format(srcip=src_ip, dstip=dst_ip,
140 'create_vlan_subif sw_if_index {sw_idx} vlan {vlan}\n'\
141 .format(sw_idx=Topology.get_interface_sw_index(
142 node, node_vlan_if), vlan=i + 1))
143 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
146 cmd1 = 'sw_interface_add_del_address'
148 sw_if_index=InterfaceUtil.get_interface_index(node, node_vxlan_if),
153 cmd2 = 'vxlan_add_del_tunnel'
157 instance=Constants.BITWISE_NON_ZERO,
160 mcast_sw_if_index=Constants.BITWISE_NON_ZERO,
162 decap_next_index=Constants.BITWISE_NON_ZERO,
165 cmd3 = 'create_vlan_subif'
167 sw_if_index=InterfaceUtil.get_interface_index(
172 with PapiSocketExecutor(node) as papi_exec:
173 for i in xrange(0, vxlan_count):
175 src_ip = src_ip_addr_start + i * ip_step
176 dst_ip = dst_ip_addr_start + i * ip_step
177 except AddressValueError:
178 logger.warn("Can't do more iterations - IP address limit "
182 args1['prefix'] = IPUtil.create_prefix_object(
183 src_ip, 128 if src_ip_addr_start.version == 6 else 32)
184 args2['src_address'] = getattr(src_ip, 'packed')
185 args2['dst_address'] = getattr(dst_ip, 'packed')
186 args2['vni'] = int(vni_start) + i
187 args3['vlan_id'] = i + 1
188 history = False if 1 < i < vxlan_count else True
189 papi_exec.add(cmd1, history=history, **args1).\
190 add(cmd2, history=history, **args2).\
191 add(cmd3, history=history, **args3)
192 papi_exec.get_replies()
197 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
199 Update topology with VXLAN interfaces and VLAN sub-interfaces data
200 and put interfaces up.
202 :param node: VPP node.
203 :param vxlan_count: Number of tunnel interfaces.
204 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
207 :type vxlan_count: int
208 :type node_vlan_if: str
210 if_data = InterfaceUtil.vpp_get_interface_data(node)
211 vlan_if_name = Topology.get_interface_name(node, node_vlan_if)
214 tmp_fn = '/tmp/put_subinterfaces_up.config'
216 for i in xrange(0, vxlan_count):
217 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
218 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
220 vxlan_subif_idx = None
221 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
222 vlan_subif_name = '{if_name}.{vlan}'.format(
223 if_name=vlan_if_name, vlan=i + 1)
227 if_name = data['interface_name']
228 if not vxlan_found and if_name == vxlan_subif_name:
229 vxlan_subif_idx = data['sw_if_index']
231 elif not vlan_found and if_name == vlan_subif_name:
232 vlan_idx = data['sw_if_index']
234 if vxlan_found and vlan_found:
236 Topology.update_interface_sw_if_index(
237 node, vxlan_subif_key, vxlan_subif_idx)
238 Topology.update_interface_name(
239 node, vxlan_subif_key, vxlan_subif_name)
241 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
242 'link-up\n'.format(sw_idx=vxlan_subif_idx))
243 Topology.update_interface_sw_if_index(
244 node, vlan_subif_key, vlan_idx)
245 Topology.update_interface_name(
246 node, vlan_subif_key, vlan_subif_name)
248 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
249 'link-up\n'.format(sw_idx=vlan_idx))
250 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
253 cmd = 'sw_interface_set_flags'
256 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
260 flags=InterfaceStatusFlags.IF_STATUS_API_FLAG_ADMIN_UP.value
263 with PapiSocketExecutor(node) as papi_exec:
264 for i in xrange(0, vxlan_count):
265 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
266 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
268 vxlan_subif_idx = None
269 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
270 vlan_subif_name = '{if_name}.{vlan}'.format(
271 if_name=vlan_if_name, vlan=i+1)
276 and data['interface_name'] == vxlan_subif_name:
277 vxlan_subif_idx = data['sw_if_index']
279 elif not vlan_found \
280 and data['interface_name'] == vlan_subif_name:
281 vlan_idx = data['sw_if_index']
283 if vxlan_found and vlan_found:
285 Topology.update_interface_sw_if_index(
286 node, vxlan_subif_key, vxlan_subif_idx)
287 Topology.update_interface_name(
288 node, vxlan_subif_key, vxlan_subif_name)
289 args1['sw_if_index'] = vxlan_subif_idx
290 Topology.update_interface_sw_if_index(
291 node, vlan_subif_key, vlan_idx)
292 Topology.update_interface_name(
293 node, vlan_subif_key, vlan_subif_name)
294 args2['sw_if_index'] = vlan_idx
295 history = False if 1 < i < vxlan_count else True
296 papi_exec.add(cmd, history=history, **args1). \
297 add(cmd, history=history, **args2)
298 papi_exec.add(cmd, **args1).add(cmd, **args2)
299 papi_exec.get_replies()
302 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
303 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
304 ip_step, bd_id_start):
306 Configure ARPs and routes for VXLAN interfaces and put each pair of
307 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
309 :param node: VPP node.
310 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
311 interfaces have been created.
312 :param vxlan_count: Number of tunnel interfaces.
313 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
314 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
316 :param dst_ip_start: VXLAN tunnel destination IP address start.
317 :param ip_step: IP address incremental step.
318 :param bd_id_start: Bridge-domain ID start.
320 :type node_vxlan_if: str
321 :type vxlan_count: int
324 :type dst_ip_start: str
326 :type bd_id_start: int
328 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
331 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
332 tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
334 for i in xrange(0, vxlan_count):
335 dst_ip = dst_ip_addr_start + i * ip_step
337 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
338 'mac {mac}\n'.format(
341 mac=Topology.get_interface_mac(op_node, op_node_if)))
343 'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
344 'sw_if_index {sw_idx}\n'.format(
346 ip_len=128 if dst_ip.version == 6 else 32,
347 sw_idx=sw_idx_vxlan))
349 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
350 'bd_id {bd_id} shg 0 enable\n'.format(
351 sw_idx=Topology.get_interface_sw_index(
352 node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
353 bd_id=bd_id_start + i))
355 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
356 'bd_id {bd_id} shg 0 enable\n'.format(
357 sw_idx=Topology.get_interface_sw_index(
358 node, 'vlan_subif{nr}'.format(nr=i + 1)),
359 bd_id=bd_id_start + i))
360 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
363 cmd1 = 'ip_neighbor_add_del'
365 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
367 mac_address=Topology.get_interface_mac(op_node, op_node_if),
372 cmd2 = 'ip_route_add_del'
374 interface=node_vxlan_if,
375 gateway=str(dst_ip_addr_start))
376 route = IPUtil.compose_vpp_route_structure(
378 str(dst_ip_addr_start),
379 128 if dst_ip_addr_start.version == 6 else 32,
385 cmd3 = 'sw_interface_set_l2_bridge'
399 with PapiSocketExecutor(node) as papi_exec:
400 for i in xrange(0, vxlan_count):
401 dst_ip = dst_ip_addr_start + i * ip_step
402 args1['neighbor']['ip_address'] = str(dst_ip)
403 args2['route']['prefix']['address']['un'] = \
404 IPUtil.union_addr(dst_ip)
405 args2['route']['paths'][0]['nh']['address'] = \
406 IPUtil.union_addr(dst_ip)
407 args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
408 node, 'vxlan_tunnel{nr}'.format(nr=i+1))
409 args3['bd_id'] = int(bd_id_start+i)
410 args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
411 node, 'vlan_subif{nr}'.format(nr=i+1))
412 args4['bd_id'] = int(bd_id_start+i)
413 history = False if 1 < i < vxlan_count else True
414 papi_exec.add(cmd1, history=history, **args1). \
415 add(cmd2, history=history, **args2). \
416 add(cmd3, history=history, **args3). \
417 add(cmd3, history=history, **args4)
418 papi_exec.get_replies()