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'] = getattr(src_ip, 'packed')
183 args2['src_address'] = getattr(src_ip, 'packed')
184 args2['dst_address'] = getattr(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 papi_exec.get_replies()
196 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
198 Update topology with VXLAN interfaces and VLAN sub-interfaces data
199 and put interfaces up.
201 :param node: VPP node.
202 :param vxlan_count: Number of tunnel interfaces.
203 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
206 :type vxlan_count: int
207 :type node_vlan_if: str
209 if_data = InterfaceUtil.vpp_get_interface_data(node)
210 vlan_if_name = Topology.get_interface_name(node, node_vlan_if)
213 tmp_fn = '/tmp/put_subinterfaces_up.config'
215 for i in xrange(0, vxlan_count):
216 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
217 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
219 vxlan_subif_idx = None
220 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
221 vlan_subif_name = '{if_name}.{vlan}'.format(
222 if_name=vlan_if_name, vlan=i + 1)
226 if_name = data['interface_name']
227 if not vxlan_found and if_name == vxlan_subif_name:
228 vxlan_subif_idx = data['sw_if_index']
230 elif not vlan_found and if_name == vlan_subif_name:
231 vlan_idx = data['sw_if_index']
233 if vxlan_found and vlan_found:
235 Topology.update_interface_sw_if_index(
236 node, vxlan_subif_key, vxlan_subif_idx)
237 Topology.update_interface_name(
238 node, vxlan_subif_key, vxlan_subif_name)
240 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
241 'link-up\n'.format(sw_idx=vxlan_subif_idx))
242 Topology.update_interface_sw_if_index(
243 node, vlan_subif_key, vlan_idx)
244 Topology.update_interface_name(
245 node, vlan_subif_key, vlan_subif_name)
247 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
248 'link-up\n'.format(sw_idx=vlan_idx))
249 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
252 cmd = 'sw_interface_set_flags'
259 err_msg = 'Failed to put VXLAN and VLAN interfaces up on host {host}'. \
260 format(host=node['host'])
262 with PapiSocketExecutor(node) as papi_exec:
263 for i in xrange(0, vxlan_count):
264 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
265 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
267 vxlan_subif_idx = None
268 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
269 vlan_subif_name = '{if_name}.{vlan}'.format(
270 if_name=vlan_if_name, vlan=i+1)
275 and data['interface_name'] == vxlan_subif_name:
276 vxlan_subif_idx = data['sw_if_index']
278 elif not vlan_found \
279 and data['interface_name'] == vlan_subif_name:
280 vlan_idx = data['sw_if_index']
282 if vxlan_found and vlan_found:
284 Topology.update_interface_sw_if_index(
285 node, vxlan_subif_key, vxlan_subif_idx)
286 Topology.update_interface_name(
287 node, vxlan_subif_key, vxlan_subif_name)
288 args1['sw_if_index'] = vxlan_subif_idx
289 Topology.update_interface_sw_if_index(
290 node, vlan_subif_key, vlan_idx)
291 Topology.update_interface_name(
292 node, vlan_subif_key, vlan_subif_name)
293 args2['sw_if_index'] = vlan_idx
294 history = False if 1 < i < vxlan_count else True
295 papi_exec.add(cmd, history=history, **args1). \
296 add(cmd, history=history, **args2)
297 papi_exec.add(cmd, **args1).add(cmd, **args2)
298 papi_exec.get_replies()
301 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
302 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
303 ip_step, bd_id_start):
305 Configure ARPs and routes for VXLAN interfaces and put each pair of
306 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
308 :param node: VPP node.
309 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
310 interfaces have been created.
311 :param vxlan_count: Number of tunnel interfaces.
312 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
313 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
315 :param dst_ip_start: VXLAN tunnel destination IP address start.
316 :param ip_step: IP address incremental step.
317 :param bd_id_start: Bridge-domain ID start.
319 :type node_vxlan_if: str
320 :type vxlan_count: int
323 :type dst_ip_start: str
325 :type bd_id_start: int
327 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
330 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
331 tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
333 for i in xrange(0, vxlan_count):
334 dst_ip = dst_ip_addr_start + i * ip_step
336 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
337 'mac {mac}\n'.format(
340 mac=Topology.get_interface_mac(op_node, op_node_if)))
342 'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
343 'sw_if_index {sw_idx}\n'.format(
345 ip_len=128 if dst_ip.version == 6 else 32,
346 sw_idx=sw_idx_vxlan))
348 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
349 'bd_id {bd_id} shg 0 enable\n'.format(
350 sw_idx=Topology.get_interface_sw_index(
351 node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
352 bd_id=bd_id_start + i))
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, 'vlan_subif{nr}'.format(nr=i + 1)),
358 bd_id=bd_id_start + i))
359 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
362 cmd1 = 'ip_neighbor_add_del'
364 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
366 mac_address=Topology.get_interface_mac(op_node, op_node_if),
371 cmd2 = 'ip_route_add_del'
373 interface=node_vxlan_if,
374 gateway=str(dst_ip_addr_start))
375 route = IPUtil.compose_vpp_route_structure(
377 str(dst_ip_addr_start),
378 128 if dst_ip_addr_start.version == 6 else 32,
384 cmd3 = 'sw_interface_set_l2_bridge'
397 err_msg = 'Failed to put VXLAN and VLAN interfaces to bridge domain ' \
398 'on host {host}'.format(host=node['host'])
400 with PapiSocketExecutor(node) as papi_exec:
401 for i in xrange(0, vxlan_count):
402 dst_ip = dst_ip_addr_start + i * ip_step
403 args1['neighbor']['ip_address'] = str(dst_ip)
404 args2['route']['prefix']['address']['un'] = \
405 IPUtil.union_addr(dst_ip)
406 args2['route']['paths'][0]['nh']['address'] = \
407 IPUtil.union_addr(dst_ip)
408 args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
409 node, 'vxlan_tunnel{nr}'.format(nr=i+1))
410 args3['bd_id'] = int(bd_id_start+i)
411 args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
412 node, 'vlan_subif{nr}'.format(nr=i+1))
413 args4['bd_id'] = int(bd_id_start+i)
414 history = False if 1 < i < vxlan_count else True
415 papi_exec.add(cmd1, history=history, **args1). \
416 add(cmd2, history=history, **args2). \
417 add(cmd3, history=history, **args3). \
418 add(cmd3, history=history, **args4)
419 papi_exec.get_replies()