Tolerate failures when setting MTU
[csit.git] / resources / libraries / python / IPv6Util.py
index a96683b..28e5f7d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 
 """IPv6 utilities library."""
 
-import re
-from ssh import SSH
+from resources.libraries.python.InterfaceUtil import InterfaceUtil
+from resources.libraries.python.IPUtil import IPUtil
+from resources.libraries.python.PapiExecutor import PapiExecutor
+from resources.libraries.python.topology import NodeType
 
 
 class IPv6Util(object):
     """IPv6 utilities"""
 
-    def __init__(self):
-        pass
-
     @staticmethod
-    def ipv6_ping(src_node, dst_addr, count=3, data_size=56, timeout=1):
-        """IPv6 ping.
-
-           Args:
-              src_node (Dict): Node where ping run.
-              dst_addr (str): Destination IPv6 address.
-              count (Optional[int]): Number of echo requests.
-              data_size (Optional[int]): Number of the data bytes.
-              timeout (Optional[int]): Time to wait for a response, in seconds.
+    def vpp_ra_suppress_link_layer(node, interface):
+        """Suppress ICMPv6 router advertisement message for link scope address.
 
-           Returns:
-              Number of lost packets.
+        :param node: VPP node.
+        :param interface: Interface name.
+        :type node: dict
+        :type interface: str
         """
-        ssh = SSH()
-        ssh.connect(src_node)
-
-        cmd = "ping6 -c {c} -s {s} -W {W} {dst}".format(c=count, s=data_size,
-                                                        W=timeout,
-                                                        dst=dst_addr)
-        (ret_code, stdout, _) = ssh.exec_command(cmd)
+        cmd = 'sw_interface_ip6nd_ra_config'
+        args = dict(
+            sw_if_index=InterfaceUtil.get_interface_index(node, interface),
+            suppress=1)
+        err_msg = 'Failed to suppress ICMPv6 router advertisement message on ' \
+                  'interface {ifc}'.format(ifc=interface)
 
-        regex = re.compile(r'(\d+) packets transmitted, (\d+) received')
-        match = regex.search(stdout)
-        sent, received = match.groups()
-        packet_lost = int(sent) - int(received)
-
-        return packet_lost
+        with PapiExecutor(node) as papi_exec:
+            papi_exec.add(cmd, **args).get_replies(err_msg). \
+                verify_reply(err_msg=err_msg)
 
     @staticmethod
-    def ipv6_ping_port(nodes_ip, src_node, dst_node, port, cnt=3,
-                       size=56, timeout=1):
-        """Send IPv6 ping to the node port.
-
-           Args:
-              nodes_ip (Dict): Nodes IPv6 adresses.
-              src_node (Dict): Node where ping run.
-              dst_node (Dict): Destination node.
-              port (str): Port on the destination node.
-              cnt (Optional[int]): Number of echo requests.
-              size (Optional[int]): Number of the data bytes.
-              timeout (Optional[int]): Time to wait for a response, in seconds.
-
-           Returns:
-              Number of lost packets.
+    def vpp_ra_send_after_interval(node, interface, interval=2):
+        """Setup vpp router advertisement(RA) in such way it sends RA packet
+        after every interval value.
+
+        :param node: VPP node.
+        :param interface: Interface name.
+        :param interval: Interval in seconds for RA resend.
+        :type node: dict
+        :type interface: str
+        :type interval: int
         """
-        dst_ip = IPv6Util.get_node_port_ipv6_address(dst_node, port, nodes_ip)
-        return IPv6Util.ipv6_ping(src_node, dst_ip, cnt, size, timeout)
+        cmd = 'sw_interface_ip6nd_ra_config'
+        args = dict(
+            sw_if_index=InterfaceUtil.get_interface_index(node, interface),
+            initial_interval=int(interval))
+        err_msg = 'Failed to set router advertisement interval on ' \
+                  'interface {ifc}'.format(ifc=interface)
 
-    @staticmethod
-    def get_node_port_ipv6_address(node, interface, nodes_addr):
-        """Return IPv6 address of the node port.
+        with PapiExecutor(node) as papi_exec:
+            papi_exec.add(cmd, **args).get_replies(err_msg). \
+                verify_reply(err_msg=err_msg)
 
-           Args:
-               node (Dict): Node in the topology.
-               interface (str): Interface name of the node.
-               nodes_addr (Dict): Nodes IPv6 adresses.
+    @staticmethod
+    def vpp_all_ra_suppress_link_layer(nodes):
+        """Suppress ICMPv6 router advertisement message for link scope address
+        on all VPP nodes in the topology.
 
-           Returns:
-               IPv6 address string.
+        :param nodes: Nodes of the test topology.
+        :type nodes: dict
         """
-        for net in nodes_addr.values():
-            for port in net['ports'].values():
-                host = port.get('node')
-                dev = port.get('if')
-                if host == node['host'] and dev == interface:
-                    ip = port.get('addr')
-                    if ip is not None:
-                        return ip
-                    else:
-                        raise Exception(
-                            'Node {n} port {p} IPv6 address is not set'.format(
-                                n=node['host'], p=interface))
-
-        raise Exception('Node {n} port {p} IPv6 address not found.'.format(
-            n=node['host'], p=interface))
+        for node in nodes.values():
+            if node['type'] == NodeType.TG:
+                continue
+            for port_k in node['interfaces'].keys():
+                ip6_addr_list = IPUtil.vpp_get_interface_ip_addresses(
+                    node, port_k, 'ipv6')
+                if ip6_addr_list:
+                    IPv6Util.vpp_ra_suppress_link_layer(node, port_k)