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
21 from resources.libraries.python.IPUtil import IPUtil
22 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
23 from resources.libraries.python.topology import Topology
24 from resources.libraries.python.VatExecutor import VatExecutor
27 class TestConfig(object):
28 """Contains special test configurations implemented in python for faster
32 def vpp_create_multiple_vxlan_ipv4_tunnels(
33 node, node_vxlan_if, node_vlan_if, op_node, op_node_if,
34 n_tunnels, vni_start, src_ip_start, dst_ip_start, ip_step,
36 """Create multiple VXLAN tunnel interfaces and VLAN sub-interfaces on
39 Put each pair of VXLAN tunnel interface and VLAN sub-interface to
40 separate bridge-domain.
42 :param node: VPP node to create VXLAN tunnel interfaces.
43 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
45 :param node_vlan_if: VPP node interface key to create VLAN
47 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
48 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
50 :param n_tunnels: Number of tunnel interfaces to create.
51 :param vni_start: VNI start ID.
52 :param src_ip_start: VXLAN tunnel source IP address start.
53 :param dst_ip_start: VXLAN tunnel destination IP address start.
54 :param ip_step: IP address incremental step.
55 :param bd_id_start: Bridge-domain ID start.
57 :type node_vxlan_if: str
58 :type node_vlan_if: str
63 :type src_ip_start: str
64 :type dst_ip_start: str
66 :type bd_id_start: int
68 # configure IPs, create VXLAN interfaces and VLAN sub-interfaces
69 vxlan_count = TestConfig.vpp_create_vxlan_and_vlan_interfaces(
70 node, node_vxlan_if, node_vlan_if, n_tunnels, vni_start,
71 src_ip_start, dst_ip_start, ip_step)
73 # update topology with VXLAN interfaces and VLAN sub-interfaces data
74 # and put interfaces up
75 TestConfig.vpp_put_vxlan_and_vlan_interfaces_up(
76 node, vxlan_count, node_vlan_if)
78 # configure bridge domains, ARPs and routes
79 TestConfig.vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
80 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
84 def vpp_create_vxlan_and_vlan_interfaces(
85 node, node_vxlan_if, node_vlan_if, vxlan_count, vni_start,
86 src_ip_start, dst_ip_start, ip_step):
88 Configure IPs, create VXLAN interfaces and VLAN sub-interfaces on VPP
91 :param node: VPP node.
92 :param node_vxlan_if: VPP node interface key to create VXLAN tunnel
94 :param node_vlan_if: VPP node interface key to create VLAN
96 :param vxlan_count: Number of tunnel interfaces to create.
97 :param vni_start: VNI start ID.
98 :param src_ip_start: VXLAN tunnel source IP address start.
99 :param dst_ip_start: VXLAN tunnel destination IP address start.
100 :param ip_step: IP address incremental step.
102 :type node_vxlan_if: str
103 :type node_vlan_if: str
104 :type vxlan_count: int
106 :type src_ip_start: str
107 :type dst_ip_start: str
109 :returns: Number of created VXLAN interfaces.
112 src_ip_addr_start = ip_address(unicode(src_ip_start))
113 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
117 tmp_fn = '/tmp/create_vxlan_interfaces.config'
118 for i in xrange(0, vxlan_count):
120 src_ip = src_ip_addr_start + i * ip_step
121 dst_ip = dst_ip_addr_start + i * ip_step
122 except AddressValueError:
123 logger.warn("Can't do more iterations - IP address limit "
128 'sw_interface_add_del_address sw_if_index {sw_idx} '
129 '{ip}/{ip_len}\n'.format(
130 sw_idx=Topology.get_interface_sw_index(
131 node, node_vxlan_if),
133 ip_len=128 if src_ip.version == 6 else 32))
135 'vxlan_add_del_tunnel src {srcip} dst {dstip} vni {vni}\n'\
136 .format(srcip=src_ip, dstip=dst_ip,
139 'create_vlan_subif sw_if_index {sw_idx} vlan {vlan}\n'\
140 .format(sw_idx=Topology.get_interface_sw_index(
141 node, node_vlan_if), vlan=i + 1))
142 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
145 cmd1 = 'sw_interface_add_del_address'
147 sw_if_index=InterfaceUtil.get_interface_index(node, node_vxlan_if),
149 is_ipv6=1 if src_ip_addr_start.version == 6 else 0,
151 address_length=128 if src_ip_addr_start.version == 6 else 32,
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,
164 cmd3 = 'create_vlan_subif'
166 sw_if_index=InterfaceUtil.get_interface_index(
169 err_msg = 'Failed to create VXLAN and VLAN interfaces on host {host}'.\
170 format(host=node['host'])
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['address'] = src_ip.packed
183 args2['src_address'] = src_ip.packed
184 args2['dst_address'] = dst_ip.packed
185 args2['vni'] = int(vni_start) + i
186 args3['vlan_id'] = i + 1
187 history = False if 1 < i < vxlan_count else True
188 papi_exec.add(cmd1, history=history, **args1).\
189 add(cmd2, history=history, **args2).\
190 add(cmd3, history=history, **args3)
191 if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 3) == 0:
192 papi_exec.get_replies(err_msg)
193 papi_exec.get_replies()
198 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
200 Update topology with VXLAN interfaces and VLAN sub-interfaces data
201 and put interfaces up.
203 :param node: VPP node.
204 :param vxlan_count: Number of tunnel interfaces.
205 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
208 :type vxlan_count: int
209 :type node_vlan_if: str
211 if_data = InterfaceUtil.vpp_get_interface_data(node)
212 vlan_if_name = Topology.get_interface_name(node, node_vlan_if)
215 tmp_fn = '/tmp/put_subinterfaces_up.config'
217 for i in xrange(0, vxlan_count):
218 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
219 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
221 vxlan_subif_idx = None
222 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
223 vlan_subif_name = '{if_name}.{vlan}'.format(
224 if_name=vlan_if_name, vlan=i + 1)
228 if_name = data['interface_name']
229 if not vxlan_found and if_name == vxlan_subif_name:
230 vxlan_subif_idx = data['sw_if_index']
232 elif not vlan_found and if_name == vlan_subif_name:
233 vlan_idx = data['sw_if_index']
235 if vxlan_found and vlan_found:
237 Topology.update_interface_sw_if_index(
238 node, vxlan_subif_key, vxlan_subif_idx)
239 Topology.update_interface_name(
240 node, vxlan_subif_key, vxlan_subif_name)
242 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
243 'link-up\n'.format(sw_idx=vxlan_subif_idx))
244 Topology.update_interface_sw_if_index(
245 node, vlan_subif_key, vlan_idx)
246 Topology.update_interface_name(
247 node, vlan_subif_key, vlan_subif_name)
249 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
250 'link-up\n'.format(sw_idx=vlan_idx))
251 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
254 cmd = 'sw_interface_set_flags'
261 err_msg = 'Failed to put VXLAN and VLAN interfaces up on host {host}'. \
262 format(host=node['host'])
264 with PapiSocketExecutor(node) as papi_exec:
265 for i in xrange(0, vxlan_count):
266 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
267 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
269 vxlan_subif_idx = None
270 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
271 vlan_subif_name = '{if_name}.{vlan}'.format(
272 if_name=vlan_if_name, vlan=i+1)
277 and data['interface_name'] == vxlan_subif_name:
278 vxlan_subif_idx = data['sw_if_index']
280 elif not vlan_found \
281 and data['interface_name'] == vlan_subif_name:
282 vlan_idx = data['sw_if_index']
284 if vxlan_found and vlan_found:
286 Topology.update_interface_sw_if_index(
287 node, vxlan_subif_key, vxlan_subif_idx)
288 Topology.update_interface_name(
289 node, vxlan_subif_key, vxlan_subif_name)
290 args1['sw_if_index'] = vxlan_subif_idx
291 Topology.update_interface_sw_if_index(
292 node, vlan_subif_key, vlan_idx)
293 Topology.update_interface_name(
294 node, vlan_subif_key, vlan_subif_name)
295 args2['sw_if_index'] = vlan_idx
296 history = False if 1 < i < vxlan_count else True
297 papi_exec.add(cmd, history=history, **args1). \
298 add(cmd, history=history, **args2)
299 if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 2) == 0:
300 papi_exec.get_replies(err_msg)
301 papi_exec.add(cmd, **args1).add(cmd, **args2)
302 papi_exec.get_replies()
305 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
306 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
307 ip_step, bd_id_start):
309 Configure ARPs and routes for VXLAN interfaces and put each pair of
310 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
312 :param node: VPP node.
313 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
314 interfaces have been created.
315 :param vxlan_count: Number of tunnel interfaces.
316 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
317 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
319 :param dst_ip_start: VXLAN tunnel destination IP address start.
320 :param ip_step: IP address incremental step.
321 :param bd_id_start: Bridge-domain ID start.
323 :type node_vxlan_if: str
324 :type vxlan_count: int
327 :type dst_ip_start: str
329 :type bd_id_start: int
331 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
334 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
335 tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
337 for i in xrange(0, vxlan_count):
338 dst_ip = dst_ip_addr_start + i * ip_step
340 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
341 'mac {mac}\n'.format(
344 mac=Topology.get_interface_mac(op_node, op_node_if)))
346 'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
347 'sw_if_index {sw_idx}\n'.format(
349 ip_len=128 if dst_ip.version == 6 else 32,
350 sw_idx=sw_idx_vxlan))
352 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
353 'bd_id {bd_id} shg 0 enable\n'.format(
354 sw_idx=Topology.get_interface_sw_index(
355 node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
356 bd_id=bd_id_start + i))
358 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
359 'bd_id {bd_id} shg 0 enable\n'.format(
360 sw_idx=Topology.get_interface_sw_index(
361 node, 'vlan_subif{nr}'.format(nr=i + 1)),
362 bd_id=bd_id_start + i))
363 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
366 cmd1 = 'ip_neighbor_add_del'
368 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
370 mac_address=Topology.get_interface_mac(op_node, op_node_if),
375 cmd2 = 'ip_route_add_del'
377 interface=node_vxlan_if,
378 gateway=str(dst_ip_addr_start))
379 route = IPUtil.compose_vpp_route_structure(
381 str(dst_ip_addr_start),
382 128 if dst_ip_addr_start.version == 6 else 32,
388 cmd3 = 'sw_interface_set_l2_bridge'
401 err_msg = 'Failed to put VXLAN and VLAN interfaces to bridge domain ' \
402 'on host {host}'.format(host=node['host'])
404 with PapiSocketExecutor(node) as papi_exec:
405 for i in xrange(0, vxlan_count):
406 dst_ip = dst_ip_addr_start + i * ip_step
407 args1['neighbor']['ip_address'] = str(dst_ip)
408 args2['route']['prefix']['address']['un'] = \
409 IPUtil.union_addr(dst_ip)
410 args2['route']['paths'][0]['nh']['address'] = \
411 IPUtil.union_addr(dst_ip)
412 args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
413 node, 'vxlan_tunnel{nr}'.format(nr=i+1))
414 args3['bd_id'] = int(bd_id_start+i)
415 args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
416 node, 'vlan_subif{nr}'.format(nr=i+1))
417 args4['bd_id'] = int(bd_id_start+i)
418 history = False if 1 < i < vxlan_count else True
419 papi_exec.add(cmd1, history=history, **args1). \
420 add(cmd2, history=history, **args2). \
421 add(cmd3, history=history, **args3). \
422 add(cmd3, history=history, **args4)
423 if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 4) == 0:
424 papi_exec.get_replies(err_msg)
425 papi_exec.get_replies()