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, VatExecutor
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 with VatTerminal(node) as vat:
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,
175 cmd_input = 'exec show int'
176 (ret_code, stdout, stderr) = ssh.exec_command_sudo(
177 Constants.VAT_BIN_NAME, cmd_input)
178 logger.debug('ret: {0}'.format(ret_code))
179 logger.debug('stdout: {0}'.format(stdout))
180 logger.debug('stderr: {0}'.format(stderr))
183 def vpp_del_if_ipv6_addr(node, interface, addr, prefix):
184 """Delete IPv6 address on VPP.
186 :param node: VPP node.
187 :param interface: Node interface.
188 :param addr: IPv6 address.
189 :param prefix: IPv6 address prefix.
195 sw_if_index = Topology.get_interface_sw_index(node, interface)
196 with VatTerminal(node) as vat:
197 vat.vat_terminal_exec_cmd_from_template('del_ip_address.vat',
198 sw_if_index=sw_if_index,
200 prefix_length=prefix)
201 vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
202 sw_if_index=sw_if_index,
206 def vpp_ra_supress_link_layer(node, interface):
207 """Supress ICMPv6 router advertisement message for link scope address
209 :param node: VPP node.
210 :param interface: Interface name.
214 sw_if_index = Topology.get_interface_sw_index(node, interface)
215 VatExecutor.cmd_from_template(node,
216 'sw_interface_ip6nd_ra_config.vat',
217 sw_if_id=sw_if_index,
220 def vpp_all_ra_supress_link_layer(self, nodes):
221 """Supress ICMPv6 router advertisement message for link scope address
222 on all VPP nodes in the topology
224 :param nodes: Nodes of the test topology.
227 for node in nodes.values():
228 if node['type'] == NodeType.TG:
230 for port_k, port_v in node['interfaces'].items():
233 if_name = port_v.get('name')
236 self.vpp_ra_supress_link_layer(node, if_name)
239 def get_link_address(link, nodes_addr):
240 """Get link IPv6 address.
242 :param link: Link name.
243 :param nodes_addr: Available nodes IPv6 adresses.
245 :type nodes_addr: dict
246 :return: Link IPv6 address.
249 net = nodes_addr.get(link)
251 raise ValueError('Link "{0}" address not found'.format(link))
252 return net.get('net_addr')
255 def get_link_prefix(link, nodes_addr):
256 """Get link IPv6 address prefix.
258 :param link: Link name.
259 :param nodes_addr: Available nodes IPv6 adresses.
261 :type nodes_addr: dict
262 :return: Link IPv6 address prefix.
265 net = nodes_addr.get(link)
267 raise ValueError('Link "{0}" address not found'.format(link))
268 return net.get('prefix')