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 PapiExecutor
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 {src_ip} dst {dst_ip} vni {vni}\n'
136 .format(src_ip=src_ip, dst_ip=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 PapiExecutor(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).verify_replies(
194 papi_exec.get_replies().verify_replies()
199 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
201 Update topology with VXLAN interfaces and VLAN sub-interfaces data
202 and put interfaces up.
204 :param node: VPP node.
205 :param vxlan_count: Number of tunnel interfaces.
206 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
209 :type vxlan_count: int
210 :type node_vlan_if: str
212 if_data = InterfaceUtil.vpp_get_interface_data(node)
213 vlan_if_name = Topology.get_interface_name(node, node_vlan_if)
216 tmp_fn = '/tmp/put_subinterfaces_up.config'
218 for i in xrange(0, vxlan_count):
219 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
220 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
222 vxlan_subif_idx = None
223 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
224 vlan_subif_name = '{if_name}.{vlan}'.format(
225 if_name=vlan_if_name, vlan=i + 1)
229 if_name = data['interface_name']
230 if not vxlan_found and if_name == vxlan_subif_name:
231 vxlan_subif_idx = data['sw_if_index']
233 elif not vlan_found and if_name == vlan_subif_name:
234 vlan_idx = data['sw_if_index']
236 if vxlan_found and vlan_found:
238 Topology.update_interface_sw_if_index(
239 node, vxlan_subif_key, vxlan_subif_idx)
240 Topology.update_interface_name(
241 node, vxlan_subif_key, vxlan_subif_name)
243 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
244 'link-up\n'.format(sw_idx=vxlan_subif_idx))
245 Topology.update_interface_sw_if_index(
246 node, vlan_subif_key, vlan_idx)
247 Topology.update_interface_name(
248 node, vlan_subif_key, vlan_subif_name)
250 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
251 'link-up\n'.format(sw_idx=vlan_idx))
252 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
255 cmd = 'sw_interface_set_flags'
262 err_msg = 'Failed to put VXLAN and VLAN interfaces up on host {host}'. \
263 format(host=node['host'])
265 with PapiExecutor(node) as papi_exec:
266 for i in xrange(0, vxlan_count):
267 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
268 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
270 vxlan_subif_idx = None
271 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
272 vlan_subif_name = '{if_name}.{vlan}'.format(
273 if_name=vlan_if_name, vlan=i+1)
278 and data['interface_name'] == vxlan_subif_name:
279 vxlan_subif_idx = data['sw_if_index']
281 elif not vlan_found \
282 and data['interface_name'] == vlan_subif_name:
283 vlan_idx = data['sw_if_index']
285 if vxlan_found and vlan_found:
287 Topology.update_interface_sw_if_index(
288 node, vxlan_subif_key, vxlan_subif_idx)
289 Topology.update_interface_name(
290 node, vxlan_subif_key, vxlan_subif_name)
291 args1['sw_if_index'] = vxlan_subif_idx
292 Topology.update_interface_sw_if_index(
293 node, vlan_subif_key, vlan_idx)
294 Topology.update_interface_name(
295 node, vlan_subif_key, vlan_subif_name)
296 args2['sw_if_index'] = vlan_idx
297 history = False if 1 < i < vxlan_count else True
298 papi_exec.add(cmd, history=history, **args1). \
299 add(cmd, history=history, **args2)
300 if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 2) == 0:
301 papi_exec.get_replies(err_msg).verify_replies(
303 papi_exec.add(cmd, **args1).add(cmd, **args2)
304 papi_exec.get_replies().verify_replies()
307 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
308 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
309 ip_step, bd_id_start):
311 Configure ARPs and routes for VXLAN interfaces and put each pair of
312 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
314 :param node: VPP node.
315 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
316 interfaces have been created.
317 :param vxlan_count: Number of tunnel interfaces.
318 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
319 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
321 :param dst_ip_start: VXLAN tunnel destination IP address start.
322 :param ip_step: IP address incremental step.
323 :param bd_id_start: Bridge-domain ID start.
325 :type node_vxlan_if: str
326 :type vxlan_count: int
329 :type dst_ip_start: str
331 :type bd_id_start: int
333 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
336 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
337 tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
339 for i in xrange(0, vxlan_count):
340 dst_ip = dst_ip_addr_start + i * ip_step
342 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
343 'mac {mac}\n'.format(
346 mac=Topology.get_interface_mac(op_node, op_node_if)))
348 'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
349 'sw_if_index {sw_idx}\n'.format(
351 ip_len=128 if dst_ip.version == 6 else 32,
352 sw_idx=sw_idx_vxlan))
354 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
355 'bd_id {bd_id} shg 0 enable\n'.format(
356 sw_idx=Topology.get_interface_sw_index(
357 node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
358 bd_id=bd_id_start + i))
360 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
361 'bd_id {bd_id} shg 0 enable\n'.format(
362 sw_idx=Topology.get_interface_sw_index(
363 node, 'vlan_subif{nr}'.format(nr=i + 1)),
364 bd_id=bd_id_start + i))
365 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
368 cmd1 = 'ip_neighbor_add_del'
370 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
372 mac_address=Topology.get_interface_mac(op_node, op_node_if),
377 cmd2 = 'ip_route_add_del'
379 interface=node_vxlan_if,
380 gateway=str(dst_ip_addr_start))
381 route = IPUtil.compose_vpp_route_structure(
383 str(dst_ip_addr_start),
384 128 if dst_ip_addr_start.version == 6 else 32,
390 cmd3 = 'sw_interface_set_l2_bridge'
403 err_msg = 'Failed to put VXLAN and VLAN interfaces to bridge domain ' \
404 'on host {host}'.format(host=node['host'])
406 with PapiExecutor(node) as papi_exec:
407 for i in xrange(0, vxlan_count):
408 dst_ip = dst_ip_addr_start + i * ip_step
409 args1['neighbor']['ip_address'] = str(dst_ip)
410 args2['route']['prefix']['address']['un'] = \
411 IPUtil.union_addr(dst_ip)
412 args2['route']['paths'][0]['nh']['address'] = \
413 IPUtil.union_addr(dst_ip)
414 args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
415 node, 'vxlan_tunnel{nr}'.format(nr=i+1))
416 args3['bd_id'] = int(bd_id_start+i)
417 args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
418 node, 'vlan_subif{nr}'.format(nr=i+1))
419 args4['bd_id'] = int(bd_id_start+i)
420 history = False if 1 < i < vxlan_count else True
421 papi_exec.add(cmd1, history=history, **args1). \
422 add(cmd2, history=history, **args2). \
423 add(cmd3, history=history, **args3). \
424 add(cmd3, history=history, **args4)
425 if i > 0 and i % (Constants.PAPI_MAX_API_BULK / 4) == 0:
426 papi_exec.get_replies(err_msg).verify_replies(
428 papi_exec.get_replies().verify_replies()