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(
170 with PapiSocketExecutor(node) as papi_exec:
171 for i in xrange(0, vxlan_count):
173 src_ip = src_ip_addr_start + i * ip_step
174 dst_ip = dst_ip_addr_start + i * ip_step
175 except AddressValueError:
176 logger.warn("Can't do more iterations - IP address limit "
180 args1['address'] = getattr(src_ip, 'packed')
181 args2['src_address'] = getattr(src_ip, 'packed')
182 args2['dst_address'] = getattr(dst_ip, 'packed')
183 args2['vni'] = int(vni_start) + i
184 args3['vlan_id'] = i + 1
185 history = False if 1 < i < vxlan_count else True
186 papi_exec.add(cmd1, history=history, **args1).\
187 add(cmd2, history=history, **args2).\
188 add(cmd3, history=history, **args3)
189 papi_exec.get_replies()
194 def vpp_put_vxlan_and_vlan_interfaces_up(node, vxlan_count, node_vlan_if):
196 Update topology with VXLAN interfaces and VLAN sub-interfaces data
197 and put interfaces up.
199 :param node: VPP node.
200 :param vxlan_count: Number of tunnel interfaces.
201 :param node_vlan_if: VPP node interface key where VLAN sub-interfaces
204 :type vxlan_count: int
205 :type node_vlan_if: str
207 if_data = InterfaceUtil.vpp_get_interface_data(node)
208 vlan_if_name = Topology.get_interface_name(node, node_vlan_if)
211 tmp_fn = '/tmp/put_subinterfaces_up.config'
213 for i in xrange(0, vxlan_count):
214 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
215 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
217 vxlan_subif_idx = None
218 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
219 vlan_subif_name = '{if_name}.{vlan}'.format(
220 if_name=vlan_if_name, vlan=i + 1)
224 if_name = data['interface_name']
225 if not vxlan_found and if_name == vxlan_subif_name:
226 vxlan_subif_idx = data['sw_if_index']
228 elif not vlan_found and if_name == vlan_subif_name:
229 vlan_idx = data['sw_if_index']
231 if vxlan_found and vlan_found:
233 Topology.update_interface_sw_if_index(
234 node, vxlan_subif_key, vxlan_subif_idx)
235 Topology.update_interface_name(
236 node, vxlan_subif_key, vxlan_subif_name)
238 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
239 'link-up\n'.format(sw_idx=vxlan_subif_idx))
240 Topology.update_interface_sw_if_index(
241 node, vlan_subif_key, vlan_idx)
242 Topology.update_interface_name(
243 node, vlan_subif_key, vlan_subif_name)
245 'sw_interface_set_flags sw_if_index {sw_idx} admin-up '
246 'link-up\n'.format(sw_idx=vlan_idx))
247 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
250 cmd = 'sw_interface_set_flags'
258 with PapiSocketExecutor(node) as papi_exec:
259 for i in xrange(0, vxlan_count):
260 vxlan_subif_key = Topology.add_new_port(node, 'vxlan_tunnel')
261 vxlan_subif_name = 'vxlan_tunnel{nr}'.format(nr=i)
263 vxlan_subif_idx = None
264 vlan_subif_key = Topology.add_new_port(node, 'vlan_subif')
265 vlan_subif_name = '{if_name}.{vlan}'.format(
266 if_name=vlan_if_name, vlan=i+1)
271 and data['interface_name'] == vxlan_subif_name:
272 vxlan_subif_idx = data['sw_if_index']
274 elif not vlan_found \
275 and data['interface_name'] == vlan_subif_name:
276 vlan_idx = data['sw_if_index']
278 if vxlan_found and vlan_found:
280 Topology.update_interface_sw_if_index(
281 node, vxlan_subif_key, vxlan_subif_idx)
282 Topology.update_interface_name(
283 node, vxlan_subif_key, vxlan_subif_name)
284 args1['sw_if_index'] = vxlan_subif_idx
285 Topology.update_interface_sw_if_index(
286 node, vlan_subif_key, vlan_idx)
287 Topology.update_interface_name(
288 node, vlan_subif_key, vlan_subif_name)
289 args2['sw_if_index'] = vlan_idx
290 history = False if 1 < i < vxlan_count else True
291 papi_exec.add(cmd, history=history, **args1). \
292 add(cmd, history=history, **args2)
293 papi_exec.add(cmd, **args1).add(cmd, **args2)
294 papi_exec.get_replies()
297 def vpp_put_vxlan_and_vlan_interfaces_to_bridge_domain(
298 node, node_vxlan_if, vxlan_count, op_node, op_node_if, dst_ip_start,
299 ip_step, bd_id_start):
301 Configure ARPs and routes for VXLAN interfaces and put each pair of
302 VXLAN tunnel interface and VLAN sub-interface to separate bridge-domain.
304 :param node: VPP node.
305 :param node_vxlan_if: VPP node interface key where VXLAN tunnel
306 interfaces have been created.
307 :param vxlan_count: Number of tunnel interfaces.
308 :param op_node: Opposite VPP node for VXLAN tunnel interfaces.
309 :param op_node_if: Opposite VPP node interface key for VXLAN tunnel
311 :param dst_ip_start: VXLAN tunnel destination IP address start.
312 :param ip_step: IP address incremental step.
313 :param bd_id_start: Bridge-domain ID start.
315 :type node_vxlan_if: str
316 :type vxlan_count: int
319 :type dst_ip_start: str
321 :type bd_id_start: int
323 dst_ip_addr_start = ip_address(unicode(dst_ip_start))
326 sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
327 tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
329 for i in xrange(0, vxlan_count):
330 dst_ip = dst_ip_addr_start + i * ip_step
332 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} '
333 'mac {mac}\n'.format(
336 mac=Topology.get_interface_mac(op_node, op_node_if)))
338 'ip_route_add_del {ip}/{ip_len} count 1 via {ip} '
339 'sw_if_index {sw_idx}\n'.format(
341 ip_len=128 if dst_ip.version == 6 else 32,
342 sw_idx=sw_idx_vxlan))
344 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
345 'bd_id {bd_id} shg 0 enable\n'.format(
346 sw_idx=Topology.get_interface_sw_index(
347 node, 'vxlan_tunnel{nr}'.format(nr=i + 1)),
348 bd_id=bd_id_start + i))
350 'sw_interface_set_l2_bridge sw_if_index {sw_idx} '
351 'bd_id {bd_id} shg 0 enable\n'.format(
352 sw_idx=Topology.get_interface_sw_index(
353 node, 'vlan_subif{nr}'.format(nr=i + 1)),
354 bd_id=bd_id_start + i))
355 VatExecutor().write_and_execute_script(node, tmp_fn, commands)
358 cmd1 = 'ip_neighbor_add_del'
360 sw_if_index=Topology.get_interface_sw_index(node, node_vxlan_if),
362 mac_address=Topology.get_interface_mac(op_node, op_node_if),
367 cmd2 = 'ip_route_add_del'
369 interface=node_vxlan_if,
370 gateway=str(dst_ip_addr_start))
371 route = IPUtil.compose_vpp_route_structure(
373 str(dst_ip_addr_start),
374 128 if dst_ip_addr_start.version == 6 else 32,
380 cmd3 = 'sw_interface_set_l2_bridge'
394 with PapiSocketExecutor(node) as papi_exec:
395 for i in xrange(0, vxlan_count):
396 dst_ip = dst_ip_addr_start + i * ip_step
397 args1['neighbor']['ip_address'] = str(dst_ip)
398 args2['route']['prefix']['address']['un'] = \
399 IPUtil.union_addr(dst_ip)
400 args2['route']['paths'][0]['nh']['address'] = \
401 IPUtil.union_addr(dst_ip)
402 args3['rx_sw_if_index'] = Topology.get_interface_sw_index(
403 node, 'vxlan_tunnel{nr}'.format(nr=i+1))
404 args3['bd_id'] = int(bd_id_start+i)
405 args4['rx_sw_if_index'] = Topology.get_interface_sw_index(
406 node, 'vlan_subif{nr}'.format(nr=i+1))
407 args4['bd_id'] = int(bd_id_start+i)
408 history = False if 1 < i < vxlan_count else True
409 papi_exec.add(cmd1, history=history, **args1). \
410 add(cmd2, history=history, **args2). \
411 add(cmd3, history=history, **args3). \
412 add(cmd3, history=history, **args4)
413 papi_exec.get_replies()