LISP - implement changes done in VPP-376
[csit.git] / resources / libraries / python / IPv6Util.py
1 # Copyright (c) 2016 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:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
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.
13
14 """IPv6 utilities library."""
15
16 import re
17
18 from resources.libraries.python.ssh import SSH
19 from resources.libraries.python.VatExecutor import VatTerminal
20 from resources.libraries.python.topology import Topology
21
22
23 class IPv6Util(object):
24     """IPv6 utilities"""
25
26     @staticmethod
27     def ipv6_ping(src_node, dst_addr, count=3, data_size=56, timeout=1):
28         """IPv6 ping.
29
30         :param src_node: Node where ping run.
31         :param dst_addr: Destination IPv6 address.
32         :param count: Number of echo requests. (Optional)
33         :param data_size: Number of the data bytes. (Optional)
34         :param timeout: Time to wait for a response, in seconds. (Optional)
35         :type src_node: dict
36         :type dst_addr: str
37         :type count: int
38         :type data_size: int
39         :type timeout: int
40         :return: Number of lost packets.
41         :rtype: int
42         """
43         ssh = SSH()
44         ssh.connect(src_node)
45
46         cmd = "ping6 -c {c} -s {s} -W {W} {dst}".format(c=count, s=data_size,
47                                                         W=timeout,
48                                                         dst=dst_addr)
49         (ret_code, stdout, _) = ssh.exec_command(cmd)
50
51         regex = re.compile(r'(\d+) packets transmitted, (\d+) received')
52         match = regex.search(stdout)
53         sent, received = match.groups()
54         packet_lost = int(sent) - int(received)
55
56         return packet_lost
57
58     @staticmethod
59     def ipv6_ping_port(nodes_ip, src_node, dst_node, port, cnt=3,
60                        size=56, timeout=1):
61         """Send IPv6 ping to the node port.
62
63         :param nodes_ip: Nodes IPv6 addresses.
64         :param src_node: Node where ping run.
65         :param dst_node: Destination node.
66         :param port: Port on the destination node.
67         :param cnt: Number of echo requests. (Optional)
68         :param size: Number of the data bytes. (Optional)
69         :param timeout: Time to wait for a response, in seconds. (Optional)
70         :type nodes_ip: dict
71         :type src_node: dict
72         :type dst_node: dict
73         :type port: str
74         :type cnt: int
75         :type size: int
76         :type timeout: int
77         :return: Number of lost packets.
78         :rtype: int
79         """
80         dst_ip = IPv6Util.get_node_port_ipv6_address(dst_node, port, nodes_ip)
81         return IPv6Util.ipv6_ping(src_node, dst_ip, cnt, size, timeout)
82
83     @staticmethod
84     def get_node_port_ipv6_address(node, iface_key, nodes_addr):
85         """Return IPv6 address of the node port.
86
87         :param node: Node in the topology.
88         :param iface_key: Interface key of the node.
89         :param nodes_addr: Nodes IPv6 addresses.
90         :type node: dict
91         :type iface_key: str
92         :type nodes_addr: dict
93         :return: IPv6 address string.
94         :rtype: str
95         """
96         interface = Topology.get_interface_name(node, iface_key)
97         for net in nodes_addr.values():
98             for port in net['ports'].values():
99                 host = port.get('node')
100                 dev = port.get('if')
101                 if host == node['host'] and dev == interface:
102                     ip = port.get('addr')
103                     if ip is not None:
104                         return ip
105                     else:
106                         raise Exception(
107                             'Node {n} port {p} IPv6 address is not set'.format(
108                                 n=node['host'], p=interface))
109
110         raise Exception('Node {n} port {p} IPv6 address not found.'.format(
111             n=node['host'], p=interface))
112
113     @staticmethod
114     def add_ip_neighbor(node, interface, ip_address, mac_address, vrf=None):
115         """Add IP neighbor.
116
117         :param node: VPP node to add ip neighbor.
118         :param interface: Interface name or sw_if_index.
119         :param ip_address: IP address.
120         :param mac_address: MAC address.
121         :param vrf: VRF table ID (Optional).
122         :type node: dict
123         :type interface: str or int
124         :type ip_address: str
125         :type mac_address: str
126         :type vrf: int
127         """
128         vrf = "vrf {}".format(vrf) if vrf else ''
129
130         if isinstance(interface, basestring):
131             sw_if_index = Topology.get_interface_sw_index(node, interface)
132         else:
133             sw_if_index = interface
134
135         with VatTerminal(node) as vat:
136             vat.vat_terminal_exec_cmd_from_template("add_ip_neighbor.vat",
137                                                     sw_if_index=sw_if_index,
138                                                     ip_address=ip_address,
139                                                     mac_address=mac_address,
140                                                     vrf=vrf)