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:
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 """Library to set up IPv6 in topology."""
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
24 class IPv6Networks(object):
25 """IPv6 network iterator.
27 :param networks: List of the available IPv6 networks.
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)
37 raise Exception('No IPv6 networks')
39 def next_network(self):
40 """Get the next elemnt of the iterator.
42 :return: IPv6 network.
43 :rtype: IPv6Network object
44 :raises: StopIteration if there is no more elements.
46 if len(self._networks):
47 return self._networks.pop()
52 class IPv6Setup(object):
53 """IPv6 setup in topology."""
58 def nodes_setup_ipv6_addresses(self, nodes, nodes_addr):
59 """Setup IPv6 addresses on all VPP nodes in topology.
61 :param nodes: Nodes of the test topology.
62 :param nodes_addr: Available nodes IPv6 adresses.
64 :type nodes_addr: dict
66 for net in nodes_addr.values():
67 for port in net['ports'].values():
68 host = port.get('node')
72 node = topo.get_node_by_hostname(nodes, host)
75 if node['type'] == NodeType.DUT:
76 self.vpp_set_if_ipv6_addr(node, port['if'], port['addr'],
79 def nodes_clear_ipv6_addresses(self, nodes, nodes_addr):
80 """Remove IPv6 addresses from all VPP nodes in topology.
82 :param nodes: Nodes of the test topology.
83 :param nodes_addr: Available nodes IPv6 adresses.
85 :type nodes_addr: dict
87 for net in nodes_addr.values():
88 for port in net['ports'].values():
89 host = port.get('node')
93 node = topo.get_node_by_hostname(nodes, host)
96 if node['type'] == NodeType.DUT:
97 self.vpp_del_if_ipv6_addr(node, port['if'], port['addr'],
101 def linux_set_if_ipv6_addr(node, interface, addr, prefix):
102 """Set IPv6 address on linux host.
104 :param node: Linux node.
105 :param interface: Node interface.
106 :param addr: IPv6 address.
107 :param prefix: IPv6 address prefix.
116 cmd = "ifconfig {dev} inet6 add {ip}/{p} up".format(dev=interface,
118 (ret_code, _, _) = ssh.exec_command_sudo(cmd)
119 if int(ret_code) != 0:
120 raise Exception('TG ifconfig failed')
123 def linux_del_if_ipv6_addr(node, interface, addr, prefix):
124 """Delete IPv6 address on linux host.
126 :param node: Linux node.
127 :param interface: Node interface.
128 :param addr: IPv6 address.
129 :param prefix: IPv6 address prefix.
138 cmd = "ifconfig {dev} inet6 del {ip}/{p}".format(dev=interface,
141 (ret_code, _, _) = ssh.exec_command_sudo(cmd)
142 if int(ret_code) != 0:
143 raise Exception('TG ifconfig failed')
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')
151 def vpp_set_if_ipv6_addr(node, interface, addr, prefix):
152 """Set IPv6 address on VPP.
154 :param node: VPP node.
155 :param interface: Node interface.
156 :param addr: IPv6 address.
157 :param prefix: IPv6 address prefix.
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,
168 prefix_length=prefix)
169 vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
170 sw_if_index=sw_if_index,
172 vat.vat_terminal_close()
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))
184 def vpp_del_if_ipv6_addr(node, interface, addr, prefix):
185 """Delete IPv6 address on VPP.
187 :param node: VPP node.
188 :param interface: Node interface.
189 :param addr: IPv6 address.
190 :param prefix: IPv6 address prefix.
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,
201 prefix_length=prefix)
202 vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
203 sw_if_index=sw_if_index,
205 vat.vat_terminal_close()
208 def vpp_ra_supress_link_layer(node, interface):
209 """Supress ICMPv6 router advertisement message for link scope address
211 :param node: VPP node.
212 :param interface: Interface name.
219 cmd = '{c}'.format(c=Constants.VAT_BIN_NAME)
220 cmd_input = 'exec ip6 nd {0} ra-surpress-link-layer'.format(
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,
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
231 :param nodes: Nodes of the test topology.
234 for node in nodes.values():
235 if node['type'] == NodeType.TG:
237 for port_k, port_v in node['interfaces'].items():
240 if_name = port_v.get('name')
243 self.vpp_ra_supress_link_layer(node, if_name)
246 def get_link_address(link, nodes_addr):
247 """Get link IPv6 address.
249 :param link: Link name.
250 :param nodes_addr: Available nodes IPv6 adresses.
252 :type nodes_addr: dict
253 :return: Link IPv6 address.
256 net = nodes_addr.get(link)
258 raise ValueError('Link "{0}" address not found'.format(link))
259 return net.get('net_addr')
262 def get_link_prefix(link, nodes_addr):
263 """Get link IPv6 address prefix.
265 :param link: Link name.
266 :param nodes_addr: Available nodes IPv6 adresses.
268 :type nodes_addr: dict
269 :return: Link IPv6 address prefix.
272 net = nodes_addr.get(link)
274 raise ValueError('Link "{0}" address not found'.format(link))
275 return net.get('prefix')