IPv6 VPP setup changed to VAT templates
[csit.git] / resources / libraries / python / IPv6Setup.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 """Library to set up IPv6 in topology."""
15
16 from ssh import SSH
17 from ipaddress import IPv6Network
18 from topology import NodeType, Topology
19 from constants import Constants
20 from VatExecutor import VatTerminal
21 from robot.api import logger
22
23
24 class IPv6Networks(object):
25     """IPv6 network iterator.
26
27        :param networks: List of the available IPv6 networks.
28        :type networks: list
29     """
30     def __init__(self, networks):
31         self._networks = list()
32         for network in networks:
33             net = IPv6Network(unicode(network))
34             self._networks.append(net)
35         num = len(self._networks)
36         if num == 0:
37             raise Exception('No IPv6 networks')
38
39     def next_network(self):
40         """Get the next elemnt of the iterator.
41
42            :return: IPv6 network.
43            :rtype: IPv6Network object
44            :raises: StopIteration if there is no more elements.
45         """
46         if len(self._networks):
47             return self._networks.pop()
48         else:
49             raise StopIteration()
50
51
52 class IPv6Setup(object):
53     """IPv6 setup in topology."""
54
55     def __init__(self):
56         pass
57
58     def nodes_setup_ipv6_addresses(self, nodes, nodes_addr):
59         """Setup IPv6 addresses on all VPP nodes in topology.
60
61            :param nodes: Nodes of the test topology.
62            :param nodes_addr: Available nodes IPv6 adresses.
63            :type nodes: dict
64            :type nodes_addr: dict
65         """
66         for net in nodes_addr.values():
67             for port in net['ports'].values():
68                 host = port.get('node')
69                 if host is None:
70                     continue
71                 topo = Topology()
72                 node = topo.get_node_by_hostname(nodes, host)
73                 if node is None:
74                     continue
75                 if node['type'] == NodeType.DUT:
76                     self.vpp_set_if_ipv6_addr(node, port['if'], port['addr'],
77                                               net['prefix'])
78
79     def nodes_clear_ipv6_addresses(self, nodes, nodes_addr):
80         """Remove IPv6 addresses from all VPP nodes in topology.
81
82            :param nodes: Nodes of the test topology.
83            :param nodes_addr: Available nodes IPv6 adresses.
84            :type nodes: dict
85            :type nodes_addr: dict
86          """
87         for net in nodes_addr.values():
88             for port in net['ports'].values():
89                 host = port.get('node')
90                 if host is None:
91                     continue
92                 topo = Topology()
93                 node = topo.get_node_by_hostname(nodes, host)
94                 if node is None:
95                     continue
96                 if node['type'] == NodeType.DUT:
97                     self.vpp_del_if_ipv6_addr(node, port['if'], port['addr'],
98                                               net['prefix'])
99
100     @staticmethod
101     def linux_set_if_ipv6_addr(node, interface, addr, prefix):
102         """Set IPv6 address on linux host.
103
104            :param node: Linux node.
105            :param interface: Node interface.
106            :param addr: IPv6 address.
107            :param prefix: IPv6 address prefix.
108            :type node: dict
109            :type interface: str
110            :type addr: str
111            :type prefix: str
112         """
113         ssh = SSH()
114         ssh.connect(node)
115
116         cmd = "ifconfig {dev} inet6 add {ip}/{p} up".format(dev=interface,
117                                                             ip=addr, p=prefix)
118         (ret_code, _, _) = ssh.exec_command_sudo(cmd)
119         if int(ret_code) != 0:
120             raise Exception('TG ifconfig failed')
121
122     @staticmethod
123     def linux_del_if_ipv6_addr(node, interface, addr, prefix):
124         """Delete IPv6 address on linux host.
125
126            :param node: Linux node.
127            :param interface: Node interface.
128            :param addr: IPv6 address.
129            :param prefix: IPv6 address prefix.
130            :type node: dict
131            :type interface: str
132            :type addr: str
133            :type prefix: str
134         """
135         ssh = SSH()
136         ssh.connect(node)
137
138         cmd = "ifconfig {dev} inet6 del {ip}/{p}".format(dev=interface,
139                                                          ip=addr,
140                                                          p=prefix)
141         (ret_code, _, _) = ssh.exec_command_sudo(cmd)
142         if int(ret_code) != 0:
143             raise Exception('TG ifconfig failed')
144
145         cmd = "ifconfig {dev} down".format(dev=interface)
146         (ret_code, _, _) = ssh.exec_command_sudo(cmd)
147         if int(ret_code) != 0:
148             raise Exception('TG ifconfig failed')
149
150     @staticmethod
151     def vpp_set_if_ipv6_addr(node, interface, addr, prefix):
152         """Set IPv6 address on VPP.
153
154            :param node: VPP node.
155            :param interface: Node interface.
156            :param addr: IPv6 address.
157            :param prefix: IPv6 address prefix.
158            :type node: dict
159            :type interface: str
160            :type addr: str
161            :type prefix: str
162         """
163         sw_if_index = Topology.get_interface_sw_index(node, interface)
164         vat = VatTerminal(node)
165         vat.vat_terminal_exec_cmd_from_template('add_ip_address.vat',
166                                                 sw_if_index=sw_if_index,
167                                                 address=addr,
168                                                 prefix_length=prefix)
169         vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
170                                                 sw_if_index=sw_if_index,
171                                                 state='admin-up')
172         vat.vat_terminal_close()
173
174         ssh = SSH()
175         ssh.connect(node)
176         cmd_input = 'exec show int'
177         (ret_code, stdout, stderr) = ssh.exec_command_sudo(
178             Constants.VAT_BIN_NAME, cmd_input)
179         logger.debug('ret: {0}'.format(ret_code))
180         logger.debug('stdout: {0}'.format(stdout))
181         logger.debug('stderr: {0}'.format(stderr))
182
183     @staticmethod
184     def vpp_del_if_ipv6_addr(node, interface, addr, prefix):
185         """Delete IPv6 address on VPP.
186
187            :param node: VPP node.
188            :param interface: Node interface.
189            :param addr: IPv6 address.
190            :param prefix: IPv6 address prefix.
191            :type node: dict
192            :type interface: str
193            :type addr: str
194            :type prefix: str
195         """
196         sw_if_index = Topology.get_interface_sw_index(node, interface)
197         vat = VatTerminal(node)
198         vat.vat_terminal_exec_cmd_from_template('del_ip_address.vat',
199                                                 sw_if_index=sw_if_index,
200                                                 address=addr,
201                                                 prefix_length=prefix)
202         vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
203                                                 sw_if_index=sw_if_index,
204                                                 state='admin-down')
205         vat.vat_terminal_close()
206
207     @staticmethod
208     def vpp_ra_supress_link_layer(node, interface):
209         """Supress ICMPv6 router advertisement message for link scope address
210
211            :param node: VPP node.
212            :param interface: Interface name.
213            :type node: dict
214            :type interface: str
215         """
216         ssh = SSH()
217         ssh.connect(node)
218
219         cmd = '{c}'.format(c=Constants.VAT_BIN_NAME)
220         cmd_input = 'exec ip6 nd {0} ra-surpress-link-layer'.format(
221             interface)
222         (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
223         if int(ret_code) != 0:
224             raise Exception("'{0}' failed on {1}".format(cmd_input,
225                                                          node['host']))
226
227     def vpp_all_ra_supress_link_layer(self, nodes):
228         """Supress ICMPv6 router advertisement message for link scope address
229            on all VPP nodes in the topology
230
231            :param nodes: Nodes of the test topology.
232            :type nodes: dict
233         """
234         for node in nodes.values():
235             if node['type'] == NodeType.TG:
236                 continue
237             for port_k, port_v in node['interfaces'].items():
238                 if port_k == 'mgmt':
239                     continue
240                 if_name = port_v.get('name')
241                 if if_name is None:
242                     continue
243                 self.vpp_ra_supress_link_layer(node, if_name)
244
245     @staticmethod
246     def get_link_address(link, nodes_addr):
247         """Get link IPv6 address.
248
249         :param link: Link name.
250         :param nodes_addr: Available nodes IPv6 adresses.
251         :type link: str
252         :type nodes_addr: dict
253         :return: Link IPv6 address.
254         :rtype: str
255         """
256         net = nodes_addr.get(link)
257         if net is None:
258             raise ValueError('Link "{0}" address not found'.format(link))
259         return net.get('net_addr')
260
261     @staticmethod
262     def get_link_prefix(link, nodes_addr):
263         """Get link IPv6 address prefix.
264
265         :param link: Link name.
266         :param nodes_addr: Available nodes IPv6 adresses.
267         :type link: str
268         :type nodes_addr: dict
269         :return: Link IPv6 address prefix.
270         :rtype: int
271         """
272         net = nodes_addr.get(link)
273         if net is None:
274             raise ValueError('Link "{0}" address not found'.format(link))
275         return net.get('prefix')