aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Gelety <jgelety@cisco.com>2019-07-12 14:53:24 +0200
committerJan Gelety <jgelety@cisco.com>2019-08-07 13:49:30 +0000
commitfb2fb651fa600a94c2e02891db2676c66490e875 (patch)
tree461bab0fb9ceb2951481a2b14aeb523425149fff
parentae75dfb6b8f640ea6696007b7bbee102436af8fe (diff)
CSIT-1473: Migrate Tap library from VAT to PAPI
Change-Id: Ibf4a4839c2e8b799b03eebd9dffae891d8f00dd4 Signed-off-by: Jan Gelety <jgelety@cisco.com>
-rw-r--r--resources/api/vpp/supported_crcs.yaml4
-rw-r--r--resources/libraries/python/InterfaceUtil.py211
-rw-r--r--resources/libraries/python/Tap.py209
3 files changed, 174 insertions, 250 deletions
diff --git a/resources/api/vpp/supported_crcs.yaml b/resources/api/vpp/supported_crcs.yaml
index d0c7cc7463..677efd9d98 100644
--- a/resources/api/vpp/supported_crcs.yaml
+++ b/resources/api/vpp/supported_crcs.yaml
@@ -174,8 +174,12 @@
sw_interface_set_table_reply: '0xe8d4e804' # dev
sw_interface_set_vxlan_bypass: '0xe74ca095' # dev
sw_interface_set_vxlan_bypass_reply: '0xe8d4e804' # dev
+ sw_interface_tap_v2_dump: '0x51077d14' # dev
+ sw_interface_tap_v2_details: '0x5ee87a5f' # dev
sw_interface_vhost_user_details: '0x91ff3307' # dev
sw_interface_vhost_user_dump: '0x51077d14' # dev
+ tap_create_v2: '0x8fa99320' # dev
+ tap_create_v2_reply: '0xfda5941f' # dev
vxlan_add_del_tunnel: '0x00f4bdd0' # virl
vxlan_add_del_tunnel_reply: '0xfda5941f' # virl
vxlan_tunnel_details: '0xce38e127' # virl
diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py
index 34ccd7cadc..7024e85dc8 100644
--- a/resources/libraries/python/InterfaceUtil.py
+++ b/resources/libraries/python/InterfaceUtil.py
@@ -13,7 +13,6 @@
"""Interface util library."""
-from socket import AF_INET, AF_INET6, inet_ntop
from time import sleep
from enum import IntEnum
@@ -305,6 +304,21 @@ class InterfaceUtil(object):
:raises TypeError: if the data type of interface is neither basestring
nor int.
"""
+ def process_if_dump(if_dump):
+ """Process interface dump.
+
+ :param if_dump: Interface dump.
+ :type if_dump: dict
+ :returns: Processed interface dump.
+ :rtype: dict
+ """
+ if_dump['interface_name'] = if_dump['interface_name'].rstrip('\x00')
+ if_dump['tag'] = if_dump['tag'].rstrip('\x00')
+ if_dump['l2_address'] = L2Util.bin_to_mac(if_dump['l2_address'])
+ if_dump['b_dmac'] = L2Util.bin_to_mac(if_dump['b_dmac'])
+ if_dump['b_smac'] = L2Util.bin_to_mac(if_dump['b_smac'])
+ return if_dump
+
if interface is not None:
if isinstance(interface, basestring):
param = 'interface_name'
@@ -324,27 +338,12 @@ class InterfaceUtil(object):
with PapiSocketExecutor(node) as papi_exec:
details = papi_exec.add(cmd, **args).get_details(err_msg)
- def process_if_dump(if_dump):
- """Process interface dump.
-
- :param if_dump: Interface dump.
- :type if_dump: dict
- :returns: Processed interface dump.
- :rtype: dict
- """
- if_dump['interface_name'] = if_dump['interface_name'].rstrip('\x00')
- if_dump['tag'] = if_dump['tag'].rstrip('\x00')
- if_dump['l2_address'] = L2Util.bin_to_mac(if_dump['l2_address'])
- if_dump['b_dmac'] = L2Util.bin_to_mac(if_dump['b_dmac'])
- if_dump['b_smac'] = L2Util.bin_to_mac(if_dump['b_smac'])
- return if_dump
-
data = list() if interface is None else dict()
- for if_dump in details:
+ for dump in details:
if interface is None:
- data.append(process_if_dump(if_dump))
- elif str(if_dump.get(param)).rstrip('\x00') == str(interface):
- data = process_if_dump(if_dump)
+ data.append(process_if_dump(dump))
+ elif str(dump.get(param)).rstrip('\x00') == str(interface):
+ data = process_if_dump(dump)
break
logger.debug('Interface data:\n{if_data}'.format(if_data=data))
@@ -823,18 +822,6 @@ class InterfaceUtil(object):
:raises TypeError: if the data type of interface is neither basestring
nor int.
"""
- if interface is not None:
- sw_if_index = InterfaceUtil.get_interface_index(node, interface)
- else:
- sw_if_index = int(Constants.BITWISE_NON_ZERO)
-
- cmd = 'vxlan_tunnel_dump'
- args = dict(sw_if_index=sw_if_index)
- err_msg = 'Failed to get VXLAN dump on host {host}'.format(
- host=node['host'])
- with PapiSocketExecutor(node) as papi_exec:
- details = papi_exec.add(cmd, **args).get_details(err_msg)
-
def process_vxlan_dump(vxlan_dump):
"""Process vxlan dump.
@@ -845,22 +832,34 @@ class InterfaceUtil(object):
"""
if vxlan_dump['is_ipv6']:
vxlan_dump['src_address'] = \
- inet_ntop(AF_INET6, vxlan_dump['src_address'])
+ ip_address(unicode(vxlan_dump['src_address']))
vxlan_dump['dst_address'] = \
- inet_ntop(AF_INET6, vxlan_dump['dst_address'])
+ ip_address(unicode(vxlan_dump['dst_address']))
else:
vxlan_dump['src_address'] = \
- inet_ntop(AF_INET, vxlan_dump['src_address'][0:4])
+ ip_address(unicode(vxlan_dump['src_address'][0:4]))
vxlan_dump['dst_address'] = \
- inet_ntop(AF_INET, vxlan_dump['dst_address'][0:4])
+ ip_address(unicode(vxlan_dump['dst_address'][0:4]))
return vxlan_dump
+ if interface is not None:
+ sw_if_index = InterfaceUtil.get_interface_index(node, interface)
+ else:
+ sw_if_index = int(Constants.BITWISE_NON_ZERO)
+
+ cmd = 'vxlan_tunnel_dump'
+ args = dict(sw_if_index=sw_if_index)
+ err_msg = 'Failed to get VXLAN dump on host {host}'.format(
+ host=node['host'])
+ with PapiSocketExecutor(node) as papi_exec:
+ details = papi_exec.add(cmd, **args).get_details(err_msg)
+
data = list() if interface is None else dict()
- for vxlan_dump in details:
+ for dump in details:
if interface is None:
- data.append(process_vxlan_dump(vxlan_dump))
- elif vxlan_dump['sw_if_index'] == sw_if_index:
- data = process_vxlan_dump(vxlan_dump)
+ data.append(process_vxlan_dump(dump))
+ elif dump['sw_if_index'] == sw_if_index:
+ data = process_vxlan_dump(dump)
break
logger.debug('VXLAN data:\n{vxlan_data}'.format(vxlan_data=data))
@@ -877,12 +876,6 @@ class InterfaceUtil(object):
:returns: List of dictionaries with all vhost-user interfaces.
:rtype: list
"""
- cmd = 'sw_interface_vhost_user_dump'
- err_msg = 'Failed to get vhost-user dump on host {host}'.format(
- host=node['host'])
- with PapiSocketExecutor(node) as papi_exec:
- details = papi_exec.add(cmd).get_details(err_msg)
-
def process_vhost_dump(vhost_dump):
"""Process vhost dump.
@@ -897,65 +890,19 @@ class InterfaceUtil(object):
vhost_dump['sock_filename'].rstrip('\x00')
return vhost_dump
- for vhost_dump in details:
- # In-place edits.
- process_vhost_dump(vhost_dump)
-
- logger.debug('Vhost-user details:\n{vhost_details}'.format(
- vhost_details=details))
- return details
-
- @staticmethod
- def tap_dump(node, name=None):
- """Get all TAP interface data from the given node, or data about
- a specific TAP interface.
-
- TODO: Move to Tap.py
-
- :param node: VPP node to get data from.
- :param name: Optional name of a specific TAP interface.
- :type node: dict
- :type name: str
- :returns: Dictionary of information about a specific TAP interface, or
- a List of dictionaries containing all TAP data for the given node.
- :rtype: dict or list
- """
- cmd = 'sw_interface_tap_v2_dump'
- err_msg = 'Failed to get TAP dump on host {host}'.format(
+ cmd = 'sw_interface_vhost_user_dump'
+ err_msg = 'Failed to get vhost-user dump on host {host}'.format(
host=node['host'])
with PapiSocketExecutor(node) as papi_exec:
details = papi_exec.add(cmd).get_details(err_msg)
- def process_tap_dump(tap_dump):
- """Process tap dump.
-
- :param tap_dump: Tap interface dump.
- :type tap_dump: dict
- :returns: Processed tap interface dump.
- :rtype: dict
- """
- tap_dump['dev_name'] = tap_dump['dev_name'].rstrip('\x00')
- tap_dump['host_if_name'] = tap_dump['host_if_name'].rstrip('\x00')
- tap_dump['host_namespace'] = \
- tap_dump['host_namespace'].rstrip('\x00')
- tap_dump['host_mac_addr'] = \
- L2Util.bin_to_mac(tap_dump['host_mac_addr'])
- tap_dump['host_ip4_addr'] = \
- inet_ntop(AF_INET, tap_dump['host_ip4_addr'])
- tap_dump['host_ip6_addr'] = \
- inet_ntop(AF_INET6, tap_dump['host_ip6_addr'])
- return tap_dump
-
- data = list() if name is None else dict()
- for tap_dump in details:
- if name is None:
- data.append(process_tap_dump(tap_dump))
- elif tap_dump.get('dev_name').rstrip('\x00') == name:
- data = process_tap_dump(tap_dump)
- break
+ for dump in details:
+ # In-place edits.
+ process_vhost_dump(dump)
- logger.debug('TAP data:\n{tap_data}'.format(tap_data=data))
- return data
+ logger.debug('Vhost-user details:\n{vhost_details}'.format(
+ vhost_details=details))
+ return details
@staticmethod
def create_subinterface(node, interface, sub_id, outer_vlan_id=None,
@@ -1246,15 +1193,6 @@ class InterfaceUtil(object):
:returns: Bond slave interface data.
:rtype: dict
"""
- cmd = 'sw_interface_slave_dump'
- args = dict(sw_if_index=Topology.get_interface_sw_index(
- node, interface))
- err_msg = 'Failed to get slave dump on host {host}'.format(
- host=node['host'])
-
- with PapiSocketExecutor(node) as papi_exec:
- details = papi_exec.add(cmd, **args).get_details(err_msg)
-
def process_slave_dump(slave_dump):
"""Process slave dump.
@@ -1267,9 +1205,18 @@ class InterfaceUtil(object):
rstrip('\x00')
return slave_dump
- for slave_dump in details:
+ cmd = 'sw_interface_slave_dump'
+ args = dict(sw_if_index=Topology.get_interface_sw_index(
+ node, interface))
+ err_msg = 'Failed to get slave dump on host {host}'.format(
+ host=node['host'])
+
+ with PapiSocketExecutor(node) as papi_exec:
+ details = papi_exec.add(cmd, **args).get_details(err_msg)
+
+ for dump in details:
# In-place edits.
- process_slave_dump(slave_dump)
+ process_slave_dump(dump)
logger.debug('Slave data:\n{slave_data}'.format(slave_data=details))
return details
@@ -1372,19 +1319,6 @@ class InterfaceUtil(object):
interfaces.
:rtype: dict or list
"""
- if interface_name is not None:
- sw_if_index = InterfaceUtil.get_interface_index(
- node, interface_name)
- else:
- sw_if_index = int(Constants.BITWISE_NON_ZERO)
-
- cmd = 'vxlan_gpe_tunnel_dump'
- args = dict(sw_if_index=sw_if_index)
- err_msg = 'Failed to get VXLAN-GPE dump on host {host}'.format(
- host=node['host'])
- with PapiSocketExecutor(node) as papi_exec:
- details = papi_exec.add(cmd, **args).get_details(err_msg)
-
def process_vxlan_gpe_dump(vxlan_dump):
"""Process vxlan_gpe dump.
@@ -1395,22 +1329,35 @@ class InterfaceUtil(object):
"""
if vxlan_dump['is_ipv6']:
vxlan_dump['local'] = \
- inet_ntop(AF_INET6, vxlan_dump['local'])
+ ip_address(unicode(vxlan_dump['local']))
vxlan_dump['remote'] = \
- inet_ntop(AF_INET6, vxlan_dump['remote'])
+ ip_address(unicode(vxlan_dump['remote']))
else:
vxlan_dump['local'] = \
- inet_ntop(AF_INET, vxlan_dump['local'][0:4])
+ ip_address(unicode(vxlan_dump['local'][0:4]))
vxlan_dump['remote'] = \
- inet_ntop(AF_INET, vxlan_dump['remote'][0:4])
+ ip_address(unicode(vxlan_dump['remote'][0:4]))
return vxlan_dump
+ if interface_name is not None:
+ sw_if_index = InterfaceUtil.get_interface_index(
+ node, interface_name)
+ else:
+ sw_if_index = int(Constants.BITWISE_NON_ZERO)
+
+ cmd = 'vxlan_gpe_tunnel_dump'
+ args = dict(sw_if_index=sw_if_index)
+ err_msg = 'Failed to get VXLAN-GPE dump on host {host}'.format(
+ host=node['host'])
+ with PapiSocketExecutor(node) as papi_exec:
+ details = papi_exec.add(cmd, **args).get_details(err_msg)
+
data = list() if interface_name is None else dict()
- for vxlan_dump in details:
+ for dump in details:
if interface_name is None:
- data.append(process_vxlan_gpe_dump(vxlan_dump))
- elif vxlan_dump['sw_if_index'] == sw_if_index:
- data = process_vxlan_gpe_dump(vxlan_dump)
+ data.append(process_vxlan_gpe_dump(dump))
+ elif dump['sw_if_index'] == sw_if_index:
+ data = process_vxlan_gpe_dump(dump)
break
logger.debug('VXLAN-GPE data:\n{vxlan_gpe_data}'.format(
diff --git a/resources/libraries/python/Tap.py b/resources/libraries/python/Tap.py
index 2a1d7efbc8..103eeffd9e 100644
--- a/resources/libraries/python/Tap.py
+++ b/resources/libraries/python/Tap.py
@@ -13,8 +13,13 @@
"""Tap utilities library."""
-from resources.libraries.python.VatExecutor import VatTerminal
+from ipaddress import ip_address
+from robot.api import logger
+
+from resources.libraries.python.Constants import Constants
+from resources.libraries.python.L2Util import L2Util
from resources.libraries.python.InterfaceUtil import InterfaceUtil
+from resources.libraries.python.PapiExecutor import PapiSocketExecutor
from resources.libraries.python.topology import Topology
@@ -29,147 +34,115 @@ class Tap(object):
:param tap_name: Tap interface name for linux tap.
:param mac: Optional MAC address for VPP tap.
:type node: dict
- :type tap_name: str
+ :type tap_name: str or unicode
:type mac: str
:returns: Returns a interface index.
:rtype: int
"""
- command = 'create'
- if mac is not None:
- args = 'tapname {} mac {}'.format(tap_name, mac)
- else:
- args = 'tapname {}'.format(tap_name)
- with VatTerminal(node) as vat:
- resp = vat.vat_terminal_exec_cmd_from_template('tap.vat',
- tap_command=command,
- tap_arguments=args)
- sw_if_index = resp[0]['sw_if_index']
+ if isinstance(tap_name, unicode):
+ tap_name = str(tap_name)
+ cmd = 'tap_create_v2'
+ args = dict(
+ id=Constants.BITWISE_NON_ZERO,
+ use_random_mac=0 if mac else 1,
+ mac_address=L2Util.mac_to_bin(mac) if mac else 6 * b'\x00',
+ host_namespace=64 * b'\x00',
+ host_mac_addr=6 * b'\x00',
+ host_if_name_set=1,
+ host_if_name=tap_name + (64 - len(tap_name)) * b'\x00',
+ host_bridge=64 * b'\x00',
+ host_ip4_addr=4 * b'\x00',
+ host_ip6_addr=16 * b'\x00',
+ host_ip4_gw=4 * b'\x00',
+ host_ip6_gw=16 * b'\x00'
+ )
+ err_msg = 'Failed to create tap interface {tap} on host {host}'.format(
+ tap=tap_name, host=node['host'])
+
+ with PapiSocketExecutor(node) as papi_exec:
+ sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg)
+
if_key = Topology.add_new_port(node, 'tap')
Topology.update_interface_sw_if_index(node, if_key, sw_if_index)
- ifc_name = Tap.vpp_get_tap_interface_name(node, sw_if_index)
- Topology.update_interface_name(node, if_key, ifc_name)
+ Topology.update_interface_name(node, if_key, tap_name)
if mac is None:
- mac = Tap.vpp_get_tap_interface_mac(node, sw_if_index)
+ mac = Tap.vpp_get_tap_interface_mac(node, tap_name)
Topology.update_interface_mac_address(node, if_key, mac)
- Topology.update_interface_tap_dev_name(node, if_key, tap_name)
+ tap_dev_name = Tap.vpp_get_tap_dev_name(node, tap_name)
+ Topology.update_interface_tap_dev_name(node, if_key, tap_dev_name)
return sw_if_index
@staticmethod
- def modify_tap_interface(node, sw_if_index, tap_name, mac=None):
- """Modify tap interface like linux interface name or VPP MAC.
-
- :param node: Node to modify tap on.
- :param sw_if_index: Index of tap interface to be modified.
- :param tap_name: Tap interface name for linux tap.
- :param mac: Optional MAC address for VPP tap.
- :type node: dict
- :type sw_if_index: int
- :type tap_name: str
- :type mac: str
- :returns: Returns a interface index.
- :rtype: int
- """
- command = 'modify'
- if mac is not None:
- args = 'sw_if_index {} tapname {} mac {}'.format(
- sw_if_index, tap_name, mac)
- else:
- args = 'sw_if_index {} tapname {}'.format(sw_if_index, tap_name)
- with VatTerminal(node) as vat:
- resp = vat.vat_terminal_exec_cmd_from_template('tap.vat',
- tap_command=command,
- tap_arguments=args)
- if_key = Topology.get_interface_by_sw_index(node, sw_if_index)
- Topology.update_interface_tap_dev_name(node, if_key, tap_name)
- if mac:
- Topology.update_interface_mac_address(node, if_key, mac)
-
- return resp[0]['sw_if_index']
-
- @staticmethod
- def delete_tap_interface(node, sw_if_index):
- """Delete tap interface.
-
- :param node: Node to delete tap on.
- :param sw_if_index: Index of tap interface to be deleted.
- :type node: dict
- :type sw_if_index: int
- :raises RuntimeError: Deletion was not successful.
- """
- command = 'delete'
- args = 'sw_if_index {}'.format(sw_if_index)
- with VatTerminal(node) as vat:
- resp = vat.vat_terminal_exec_cmd_from_template('tap.vat',
- tap_command=command,
- tap_arguments=args)
- if int(resp[0]['retval']) != 0:
- raise RuntimeError(
- 'Could not remove tap interface: {}'.format(resp))
- if_key = Topology.get_interface_sw_index(node, sw_if_index)
- Topology.remove_port(node, if_key)
-
- @staticmethod
- def check_tap_present(node, tap_name):
- """Check whether specific tap interface exists.
+ def vpp_get_tap_dev_name(node, host_if_name):
+ """Get VPP tap interface name from hardware interfaces dump.
- :param node: Node to check tap on.
- :param tap_name: Tap interface name for linux tap.
+ :param node: DUT node.
+ :param host_if_name: Tap host interface name.
:type node: dict
- :type tap_name: str
- :raises RuntimeError: Specified interface was not found.
+ :type host_if_name: str
+ :returns: VPP tap interface dev_name.
+ :rtype: str
"""
- tap_if = InterfaceUtil.tap_dump(node, tap_name)
- if not tap_if:
- raise RuntimeError(
- 'Tap interface :{} does not exist'.format(tap_name))
+ return Tap.tap_dump(node, host_if_name).get('dev_name')
@staticmethod
- def vpp_get_tap_interface_name(node, sw_if_index):
- """Get VPP tap interface name from hardware interfaces dump.
+ def vpp_get_tap_interface_mac(node, interface_name):
+ """Get tap interface MAC address from interfaces dump.
:param node: DUT node.
- :param sw_if_index: DUT node.
+ :param interface_name: Tap interface name.
:type node: dict
- :type sw_if_index: int
- :returns: VPP tap interface name.
+ :type interface_name: str
+ :returns: Tap interface MAC address.
:rtype: str
"""
- with VatTerminal(node, json_param=False) as vat:
- response = vat.vat_terminal_exec_cmd_from_template(
- 'show_hardware_detail.vat')
-
- for line in str(response[0]).splitlines():
- if line.startswith('tap-'):
- line_split = line.split()
- if line_split[1] == sw_if_index:
- return line_split[0]
-
- return None
+ return InterfaceUtil.vpp_get_interface_mac(node, interface_name)
@staticmethod
- def vpp_get_tap_interface_mac(node, sw_if_index):
- """Get tap interface MAC address from hardware interfaces dump.
+ def tap_dump(node, name=None):
+ """Get all TAP interface data from the given node, or data about
+ a specific TAP interface.
- :param node: DUT node.
- :param sw_if_index: DUT node.
+ :param node: VPP node to get data from.
+ :param name: Optional name of a specific TAP interface.
:type node: dict
- :type sw_if_index: int
- :returns: Tap interface MAC address.
- :rtype: str
+ :type name: str
+ :returns: Dictionary of information about a specific TAP interface, or
+ a List of dictionaries containing all TAP data for the given node.
+ :rtype: dict or list
"""
- with VatTerminal(node, json_param=False) as vat:
- response = vat.vat_terminal_exec_cmd_from_template(
- 'show_hardware_detail.vat')
-
- tap_if_match = False
- for line in str(response[0]).splitlines():
- if tap_if_match:
- line_split = line.split()
- return line_split[-1]
- if line.startswith('tap-'):
- line_split = line.split()
- if line_split[1] == sw_if_index:
- tap_if_match = True
-
- return None
+ def process_tap_dump(tap_dump):
+ """Process tap dump.
+
+ :param tap_dump: Tap interface dump.
+ :type tap_dump: dict
+ :returns: Processed tap interface dump.
+ :rtype: dict
+ """
+ tap_dump['dev_name'] = tap_dump['dev_name'].rstrip('\x00')
+ tap_dump['host_if_name'] = tap_dump['host_if_name'].rstrip('\x00')
+ tap_dump['host_namespace'] = \
+ tap_dump['host_namespace'].rstrip('\x00')
+ tap_dump['host_mac_addr'] = \
+ L2Util.bin_to_mac(tap_dump['host_mac_addr'])
+ tap_dump['host_ip4_addr'] = ip_address(tap_dump['host_ip4_addr'])
+ tap_dump['host_ip6_addr'] = ip_address(tap_dump['host_ip6_addr'])
+ return tap_dump
+
+ cmd = 'sw_interface_tap_v2_dump'
+ err_msg = 'Failed to get TAP dump on host {host}'.format(
+ host=node['host'])
+ with PapiSocketExecutor(node) as papi_exec:
+ details = papi_exec.add(cmd).get_details(err_msg)
+
+ data = list() if name is None else dict()
+ for dump in details:
+ if name is None:
+ data.append(process_tap_dump(dump))
+ elif dump.get('host_if_name').rstrip('\x00') == name:
+ data = process_tap_dump(dump)
+ break
+
+ logger.debug('TAP data:\n{tap_data}'.format(tap_data=data))
+ return data