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 """Lisp utilities library."""
16 from robot.api import logger
17 from ipaddress import IPv4Address, IPv6Address
19 from resources.libraries.python.topology import Topology
20 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
21 from resources.libraries.python.L2Util import L2Util
23 class LispUtil(object):
24 """Implements keywords for Lisp tests."""
30 def vpp_show_lisp_state(node):
31 """Get lisp state from VPP node.
33 :param node: VPP node.
35 :returns: Lisp gpe state.
38 cmd = 'show_lisp_status'
39 err_msg = "Failed to get LISP status on host {host}".format(
42 with PapiSocketExecutor(node) as papi_exec:
43 reply = papi_exec.add(cmd).get_reply(err_msg)
46 data["feature_status"] = "enabled" if reply["feature_status"] else \
48 data["gpe_status"] = "enabled" if reply["gpe_status"] else "disabled"
52 def vpp_show_lisp_locator_set(node, items_filter):
53 """Get lisp locator_set from VPP node.
55 :param node: VPP node.
56 :param items_filter: Filter which specifies which items should be
57 retrieved - local, remote, empty string = both.
59 :type items_filter: str
60 :returns: Lisp locator_set data as python list.
64 ifilter = {"_": 0, "_local": 1, "_remote": 2}
65 args = dict(filter=ifilter["_" + items_filter])
67 cmd = 'lisp_locator_set_dump'
68 err_msg = "Failed to get LISP locator set on host {host}".format(
72 with PapiSocketExecutor(node) as papi_exec:
73 details = papi_exec.add(cmd, **args).get_details(err_msg)
75 for locator in details:
76 data.append({"ls_name": locator["ls_name"].rstrip('\x00'),
77 "ls_index": locator["ls_index"]})
79 except (ValueError, LookupError):
83 def vpp_show_lisp_eid_table(node):
84 """Get lisp eid table from VPP node.
86 :param node: VPP node.
88 :returns: Lisp eid table as python list.
92 cmd = 'lisp_eid_table_dump'
93 err_msg = "Failed to get LISP eid table on host {host}".format(
96 with PapiSocketExecutor(node) as papi_exec:
97 details = papi_exec.add(cmd).get_details(err_msg)
100 for eid_details in details:
102 if eid_details["eid_type"] == 0:
103 prefix = str(eid_details["eid_prefix_len"])
104 eid = str(IPv4Address(eid_details["eid"][0:4])) + "/" + prefix
105 elif eid_details["eid_type"] == 1:
106 prefix = str(eid_details["eid_prefix_len"])
107 eid = str(IPv6Address(eid_details["eid"])) + "/" + prefix
108 elif eid_details["eid_type"] == 2:
109 eid = str(L2Util.bin_to_mac(eid_details["eid"][0:6]))
110 data.append({"action": eid_details["action"],
111 "is_local": eid_details["is_local"],
113 "vni": eid_details["vni"],
114 "ttl": eid_details["ttl"],
115 "authoritative": eid_details["authoritative"]})
119 def vpp_show_lisp_map_resolver(node):
120 """Get lisp map resolver from VPP node.
122 :param node: VPP node.
124 :returns: Lisp map resolver as python list.
128 cmd = 'lisp_map_resolver_dump'
129 err_msg = "Failed to get LISP map resolver on host {host}".format(
132 with PapiSocketExecutor(node) as papi_exec:
133 details = papi_exec.add(cmd).get_details(err_msg)
136 for resolver in details:
137 address = 'Bad is_ipv6 flag'
138 if resolver["is_ipv6"] == 0:
139 address = str(IPv4Address(resolver["ip_address"][0:4]))
140 elif resolver["is_ipv6"] == 1:
141 address = str(IPv6Address(resolver["ip_address"]))
142 data.append({"map resolver": address})
146 def vpp_show_lisp_map_register(node):
147 """Get LISP Map Register from VPP node.
149 :param node: VPP node.
151 :returns: LISP Map Register as python dict.
155 cmd = 'show_lisp_map_register_state'
156 err_msg = "Failed to get LISP map register state on host {host}".format(
159 with PapiSocketExecutor(node) as papi_exec:
160 reply = papi_exec.add(cmd).get_reply(err_msg)
163 data["state"] = "enabled" if reply["is_enabled"] else "disabled"
168 def vpp_show_lisp_map_request_mode(node):
169 """Get LISP Map Request mode from VPP node.
171 :param node: VPP node.
173 :returns: LISP Map Request mode as python dict.
177 cmd = 'show_lisp_map_request_mode'
178 err_msg = "Failed to get LISP map request mode on host {host}".format(
181 with PapiSocketExecutor(node) as papi_exec:
182 reply = papi_exec.add(cmd).get_reply(err_msg)
185 data["map_request_mode"] = "src-dst" if reply["mode"] else "dst-only"
190 def vpp_show_lisp_map_server(node):
191 """Get LISP Map Server from VPP node.
193 :param node: VPP node.
195 :returns: LISP Map Server as python list.
199 cmd = 'lisp_map_server_dump'
200 err_msg = "Failed to get LISP map server on host {host}".format(
203 with PapiSocketExecutor(node) as papi_exec:
204 details = papi_exec.add(cmd).get_details(err_msg)
207 for server in details:
208 address = 'Bad is_ipv6 flag'
209 if server["is_ipv6"] == 0:
210 address = str(IPv4Address(server["ip_address"][0:4]))
211 elif server["is_ipv6"] == 1:
212 address = str(IPv6Address(server["ip_address"]))
213 data.append({"map-server": address})
218 def vpp_show_lisp_petr_config(node):
219 """Get LISP PETR configuration from VPP node.
221 :param node: VPP node.
223 :returns: LISP PETR configuration as python dict.
227 # Note: VAT is returning ipv6 address instead of ipv4
229 cmd = 'show_lisp_use_petr'
230 err_msg = "Failed to get LISP petr config on host {host}".format(
233 with PapiSocketExecutor(node) as papi_exec:
234 reply = papi_exec.add(cmd).get_reply(err_msg)
237 data["status"] = "enabled" if reply["status"] else "disabled"
238 address = 'Bad is_ip4 flag'
239 if reply["is_ip4"] == 0:
240 address = str(IPv6Address(reply["address"]))
241 elif reply["is_ip4"] == 1:
242 address = str(IPv4Address(reply["address"][0:4]))
243 data["address"] = address
248 def vpp_show_lisp_rloc_config(node):
249 """Get LISP RLOC configuration from VPP node.
251 :param node: VPP node.
253 :returns: LISP RLOC configuration as python dict.
257 cmd = 'show_lisp_rloc_probe_state'
258 err_msg = "Failed to get LISP rloc config on host {host}".format(
261 with PapiSocketExecutor(node) as papi_exec:
262 reply = papi_exec.add(cmd).get_reply(err_msg)
265 data["state"] = "enabled" if reply["is_enabled"] else "disabled"
270 def vpp_show_lisp_pitr(node):
271 """Get Lisp PITR feature config from VPP node.
273 :param node: VPP node.
275 :returns: Lisp PITR config data.
279 cmd = 'show_lisp_pitr'
280 err_msg = "Failed to get LISP pitr on host {host}".format(
283 with PapiSocketExecutor(node) as papi_exec:
284 reply = papi_exec.add(cmd).get_reply(err_msg)
287 data["status"] = "enabled" if reply["status"] else "disabled"
291 def lisp_should_be_equal(lisp_val1, lisp_val2):
292 """Fail if the lisp values are not equal.
294 :param lisp_val1: First lisp value.
295 :param lisp_val2: Second lisp value.
296 :type lisp_val1: list
297 :type lisp_val2: list
300 len1 = len(lisp_val1)
301 len2 = len(lisp_val2)
303 raise RuntimeError('Values are not same. '
305 'Value 2 {}.'.format(lisp_val1,
308 for tmp in lisp_val1:
309 if tmp not in lisp_val2:
310 raise RuntimeError('Value {} not found in vpp:\n'
311 '{}'.format(tmp, lisp_val2))
313 def lisp_locator_s_should_be_equal(self, locator_set1, locator_set2):
314 """Fail if the lisp values are not equal.
316 :param locator_set1: Generate lisp value.
317 :param locator_set2: Lisp value from VPP.
318 :type locator_set1: list
319 :type locator_set2: list
322 locator_set_list = []
323 for item in locator_set1:
324 if item not in locator_set_list:
325 locator_set_list.append(item)
326 self.lisp_should_be_equal(locator_set_list, locator_set2)
329 def generate_unique_lisp_locator_set_data(node, locator_set_number):
330 """Generate a list of lisp locator_set we want set to VPP and
331 then check if it is set correctly. All locator_sets are unique.
333 :param node: VPP node.
334 :param locator_set_number: Generate n locator_set.
336 :type locator_set_number: str
337 :returns: list of lisp locator_set, list of lisp locator_set expected
344 locator_set_list = []
345 locator_set_list_vat = []
347 for num in range(0, int(locator_set_number)):
349 for interface in node['interfaces'].values():
350 link = interface.get('link')
355 if_name = topo.get_interface_by_link_name(node, link)
356 sw_if_index = topo.get_interface_sw_index(node, if_name)
357 if if_name is not None:
358 locator = {'locator-index': sw_if_index,
361 locator_list.append(locator)
363 l_name = 'ls{0}'.format(num)
364 locator_set = {'locator-set': l_name,
365 'locator': locator_list}
366 locator_set_list.append(locator_set)
368 locator_set_vat = {"ls_name": l_name,
370 locator_set_list_vat.append(locator_set_vat)
372 return locator_set_list, locator_set_list_vat
375 def generate_duplicate_lisp_locator_set_data(node, locator_set_number):
376 """Generate a list of lisp locator_set we want set to VPP and
377 then check if it is set correctly. Some locator_sets are duplicated.
379 :param node: VPP node.
380 :param locator_set_number: Generate n locator_set.
382 :type locator_set_number: str
383 :returns: list of lisp locator_set, list of lisp locator_set expected
389 locator_set_list = []
390 locator_set_list_vat = []
392 for num in range(0, int(locator_set_number)):
394 for interface in node['interfaces'].values():
395 link = interface.get('link')
400 if_name = topo.get_interface_by_link_name(node, link)
401 sw_if_index = topo.get_interface_sw_index(node, if_name)
402 if if_name is not None:
403 l_name = 'ls{0}'.format(num)
404 locator = {'locator-index': sw_if_index,
407 locator_list.append(locator)
408 locator_set = {'locator-set': l_name,
409 'locator': locator_list}
410 locator_set_list.append(locator_set)
412 locator_set_vat = {"ls_name": l_name,
414 locator_set_list_vat.append(locator_set_vat)
416 return locator_set_list, locator_set_list_vat
418 def lisp_is_empty(self, lisp_params):
419 """Check if the input param are empty.
421 :param lisp_params: Should be empty list.
422 :type lisp_params: list
425 self.lisp_should_be_equal([], lisp_params)