-# Copyright (c) 2016 Cisco and/or its affiliates.
+# Copyright (c) 2018 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:
"""Library to set up IPv6 in topology."""
-from ssh import SSH
+from robot.api import logger
from ipaddress import IPv6Network
-from topology import NodeType
-from topology import Topology
-from constants import Constants
+
+from resources.libraries.python.ssh import SSH
+from resources.libraries.python.topology import NodeType, Topology
+from resources.libraries.python.constants import Constants
+from resources.libraries.python.VatExecutor import VatTerminal, VatExecutor
class IPv6Networks(object):
"""IPv6 network iterator.
- :param networks: List of the available IPv6 networks.
- :type networks: list
+ :param networks: List of the available IPv6 networks.
+ :type networks: list
"""
def __init__(self, networks):
self._networks = list()
raise Exception('No IPv6 networks')
def next_network(self):
- """Get the next elemnt of the iterator.
+ """Get the next element of the iterator.
- :return: IPv6 network.
- :rtype: IPv6Network object
- :raises: StopIteration if there is no more elements.
+ :returns: IPv6 network.
+ :rtype: IPv6Network object
+ :raises StopIteration: If there is no more elements.
"""
if len(self._networks):
return self._networks.pop()
def __init__(self):
pass
- def nodes_setup_ipv6_addresses(self, nodes, nodes_addr):
- """Setup IPv6 addresses on all VPP nodes in topology.
+ def nodes_set_ipv6_addresses(self, nodes, nodes_addr):
+ """Set IPv6 addresses on all VPP nodes in topology.
- :param nodes: Nodes of the test topology.
- :param nodes_addr: Available nodes IPv6 adresses.
- :type nodes: dict
- :type nodes_addr: dict
+ :param nodes: Nodes of the test topology.
+ :param nodes_addr: Available nodes IPv6 addresses.
+ :type nodes: dict
+ :type nodes_addr: dict
+ :returns: Affected interfaces as list of (node, interface) tuples.
+ :rtype: list
"""
+ interfaces = []
+
for net in nodes_addr.values():
for port in net['ports'].values():
host = port.get('node')
if node is None:
continue
if node['type'] == NodeType.DUT:
- self.vpp_set_if_ipv6_addr(node, port['if'], port['addr'],
+ port_key = topo.get_interface_by_name(node, port['if'])
+ self.vpp_set_if_ipv6_addr(node, port_key, port['addr'],
net['prefix'])
+ interfaces.append((node, port['if']))
+ return interfaces
+
def nodes_clear_ipv6_addresses(self, nodes, nodes_addr):
"""Remove IPv6 addresses from all VPP nodes in topology.
- :param nodes: Nodes of the test topology.
- :param nodes_addr: Available nodes IPv6 adresses.
- :type nodes: dict
- :type nodes_addr: dict
- """
+ :param nodes: Nodes of the test topology.
+ :param nodes_addr: Available nodes IPv6 addresses.
+ :type nodes: dict
+ :type nodes_addr: dict
+ """
for net in nodes_addr.values():
for port in net['ports'].values():
host = port.get('node')
def linux_set_if_ipv6_addr(node, interface, addr, prefix):
"""Set IPv6 address on linux host.
- :param node: Linux node.
- :param interface: Node interface.
- :param addr: IPv6 address.
- :param prefix: IPv6 address prefix.
- :type node: dict
- :type interface: str
- :type addr: str
- :type prefix: str
+ :param node: Linux node.
+ :param interface: Node interface.
+ :param addr: IPv6 address.
+ :param prefix: IPv6 address prefix.
+ :type node: dict
+ :type interface: str
+ :type addr: str
+ :type prefix: str
"""
ssh = SSH()
ssh.connect(node)
def linux_del_if_ipv6_addr(node, interface, addr, prefix):
"""Delete IPv6 address on linux host.
- :param node: Linux node.
- :param interface: Node interface.
- :param addr: IPv6 address.
- :param prefix: IPv6 address prefix.
- :type node: dict
- :type interface: str
- :type addr: str
- :type prefix: str
+ :param node: Linux node.
+ :param interface: Node interface.
+ :param addr: IPv6 address.
+ :param prefix: IPv6 address prefix.
+ :type node: dict
+ :type interface: str
+ :type addr: str
+ :type prefix: str
"""
ssh = SSH()
ssh.connect(node)
raise Exception('TG ifconfig failed')
@staticmethod
- def vpp_set_if_ipv6_addr(node, interface, addr, prefix):
+ def vpp_set_if_ipv6_addr(node, iface_key, addr, prefix):
"""Set IPv6 address on VPP.
- :param node: VPP node.
- :param interface: Node interface.
- :param addr: IPv6 address.
- :param prefix: IPv6 address prefix.
- :type node: dict
- :type interface: str
- :type addr: str
- :type prefix: str
+ :param node: VPP node.
+ :param iface_key: Node interface key.
+ :param addr: IPv6 address.
+ :param prefix: IPv6 address prefix.
+ :type node: dict
+ :type iface_key: str
+ :type addr: str
+ :type prefix: str
"""
+ sw_if_index = Topology.get_interface_sw_index(node, iface_key)
+ with VatTerminal(node) as vat:
+ vat.vat_terminal_exec_cmd_from_template('add_ip_address.vat',
+ sw_if_index=sw_if_index,
+ address=addr,
+ prefix_length=prefix)
+ vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
+ sw_if_index=sw_if_index,
+ state='admin-up')
+
ssh = SSH()
ssh.connect(node)
-
- cmd = '{c}'.format(c=Constants.VAT_BIN_NAME)
- cmd_input = 'sw_interface_add_del_address {dev} {ip}/{p}'.format(
- dev=interface, ip=addr, p=prefix)
- (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
- if int(ret_code) != 0:
- raise Exception('VPP sw_interface_add_del_address failed on {h}'
- .format(h=node['host']))
-
- cmd_input = 'sw_interface_set_flags {dev} admin-up'.format(
- dev=interface)
- (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
- if int(ret_code) != 0:
- raise Exception('VPP sw_interface_set_flags failed on {h}'.format(
- h=node['host']))
+ cmd_input = 'exec show int'
+ (ret_code, stdout, stderr) = ssh.exec_command_sudo(
+ Constants.VAT_BIN_NAME, cmd_input)
+ logger.debug('ret: {0}'.format(ret_code))
+ logger.debug('stdout: {0}'.format(stdout))
+ logger.debug('stderr: {0}'.format(stderr))
@staticmethod
def vpp_del_if_ipv6_addr(node, interface, addr, prefix):
"""Delete IPv6 address on VPP.
- :param node: VPP node.
- :param interface: Node interface.
- :param addr: IPv6 address.
- :param prefix: IPv6 address prefix.
- :type node: dict
- :type interface: str
- :type addr: str
- :type prefix: str
+ :param node: VPP node.
+ :param interface: Node interface.
+ :param addr: IPv6 address.
+ :param prefix: IPv6 address prefix.
+ :type node: dict
+ :type interface: str
+ :type addr: str
+ :type prefix: str
"""
- ssh = SSH()
- ssh.connect(node)
-
- cmd = '{c}'.format(c=Constants.VAT_BIN_NAME)
- cmd_input = 'sw_interface_add_del_address {dev} {ip}/{p} del'.format(
- dev=interface, ip=addr, p=prefix)
- (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
- if int(ret_code) != 0:
- raise Exception(
- 'sw_interface_add_del_address failed on {h}'.
- format(h=node['host']))
-
- cmd_input = 'sw_interface_set_flags {dev} admin-down'.format(
- dev=interface)
- (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
- if int(ret_code) != 0:
- raise Exception('VPP sw_interface_set_flags failed on {h}'.format(
- h=node['host']))
+ sw_if_index = Topology.get_interface_sw_index(node, interface)
+ with VatTerminal(node) as vat:
+ vat.vat_terminal_exec_cmd_from_template('del_ip_address.vat',
+ sw_if_index=sw_if_index,
+ address=addr,
+ prefix_length=prefix)
+ vat.vat_terminal_exec_cmd_from_template('set_if_state.vat',
+ sw_if_index=sw_if_index,
+ state='admin-down')
@staticmethod
- def vpp_ra_supress_link_layer(node, interface):
- """Supress ICMPv6 router advertisement message for link scope address
+ def vpp_ra_suppress_link_layer(node, interface):
+ """Suppress ICMPv6 router advertisement message for link scope address.
- :param node: VPP node.
- :param interface: Interface name.
- :type node: dict
- :type interface: str
+ :param node: VPP node.
+ :param interface: Interface name.
+ :type node: dict
+ :type interface: str
"""
- ssh = SSH()
- ssh.connect(node)
+ sw_if_index = Topology.get_interface_sw_index(node, interface)
+ if sw_if_index:
+ VatExecutor.cmd_from_template(node,
+ 'sw_interface_ip6nd_ra_config.vat',
+ sw_if_id=sw_if_index,
+ param='surpress')
- cmd = '{c}'.format(c=Constants.VAT_BIN_NAME)
- cmd_input = 'exec ip6 nd {0} ra-surpress-link-layer'.format(
- interface)
- (ret_code, _, _) = ssh.exec_command_sudo(cmd, cmd_input)
- if int(ret_code) != 0:
- raise Exception("'{0}' failed on {1}".format(cmd_input,
- node['host']))
-
- def vpp_all_ra_supress_link_layer(self, nodes):
- """Supress ICMPv6 router advertisement message for link scope address
- on all VPP nodes in the topology
-
- :param nodes: Nodes of the test topology.
- :type nodes: dict
+ @staticmethod
+ def vpp_ra_send_after_interval(node, interface, interval=2):
+ """Setup vpp router advertisement(RA) in such way it sends RA packet
+ after and every interval value.
+
+ :param node: VPP node.
+ :param interface: Interface name.
+ :param interval: Interval for RA resend
+ :type node: dict
+ :type interface: str
+ :type interval: int
+ """
+ sw_if_index = Topology.get_interface_sw_index(node, interface)
+ if sw_if_index:
+ VatExecutor.cmd_from_template(node,
+ 'sw_interface_ip6nd_ra_config.vat',
+ sw_if_id=sw_if_index,
+ param='interval {0}'.format(interval))
+
+ def vpp_all_ra_suppress_link_layer(self, nodes):
+ """Suppress ICMPv6 router advertisement message for link scope address
+ on all VPP nodes in the topology.
+
+ :param nodes: Nodes of the test topology.
+ :type nodes: dict
"""
for node in nodes.values():
if node['type'] == NodeType.TG:
continue
- for port_k, port_v in node['interfaces'].items():
- if port_k == 'mgmt':
- continue
- if_name = port_v.get('name')
- if if_name is None:
- continue
- self.vpp_ra_supress_link_layer(node, if_name)
+ for port_k in node['interfaces'].keys():
+ self.vpp_ra_suppress_link_layer(node, port_k)
@staticmethod
- def vpp_ipv6_route_add(node, link, interface, nodes_addr):
- """Setup IPv6 route on the VPP node.
-
- :param node: Node to add route on.
- :param link: Route to following link.
- :param interface: Route output interface.
- :param nodes_addr: Available nodes IPv6 adresses.
- :type node: dict
- :type link: str
- :type interface: str
- :type nodes_addr: dict
+ def get_link_address(link, nodes_addr):
+ """Get link IPv6 address.
+
+ :param link: Link name.
+ :param nodes_addr: Available nodes IPv6 addresses.
+ :type link: str
+ :type nodes_addr: dict
+ :returns: Link IPv6 address.
+ :rtype: str
"""
- ssh = SSH()
- ssh.connect(node)
-
- # Get route destination address from link name
net = nodes_addr.get(link)
if net is None:
- raise ValueError('No network for link "{0}"'.format(link))
- dst_net = '{0}/{1}'.format(net['net_addr'], net['prefix'])
+ raise ValueError('Link "{0}" address not found'.format(link))
+ return net.get('net_addr')
- # Get next-hop address
- nh_addr = None
- for net in nodes_addr.values():
- for port in net['ports'].values():
- if port['if'] == interface and port['node'] == node['host']:
- for nh in net['ports'].values():
- if nh['if'] != interface and nh['node'] != node['host']:
- nh_addr = nh['addr']
- if nh_addr is None:
- raise Exception('next-hop not found')
-
- cmd_input = 'ip_add_del_route {0} via {1} {2} resolve-attempts 10'. \
- format(dst_net, nh_addr, interface)
- (ret_code, _, _) = ssh.exec_command_sudo(Constants.VAT_BIN_NAME,
- cmd_input)
- if int(ret_code) != 0:
- raise Exception("'{0}' failed on {1}".format(cmd_input,
- node['host']))
+ @staticmethod
+ def get_link_prefix(link, nodes_addr):
+ """Get link IPv6 address prefix.
+
+ :param link: Link name.
+ :param nodes_addr: Available nodes IPv6 addresses.
+ :type link: str
+ :type nodes_addr: dict
+ :returns: Link IPv6 address prefix.
+ :rtype: int
+ """
+ net = nodes_addr.get(link)
+ if net is None:
+ raise ValueError('Link "{0}" address not found'.format(link))
+ return net.get('prefix')