Fix Tap failing tests
[csit.git] / resources / libraries / python / honeycomb / HcAPIKwInterfaces.py
index afd6076..e9ef133 100644 (file)
@@ -1,4 +1,4 @@
-# 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:
 # 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:
@@ -16,6 +16,7 @@
 The keywords make possible to put and get configuration data and to get
 operational data.
 """
 The keywords make possible to put and get configuration data and to get
 operational data.
 """
+from robot.api import logger
 
 from resources.libraries.python.HTTPRequest import HTTPCodes
 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
 
 from resources.libraries.python.HTTPRequest import HTTPCodes
 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
@@ -23,10 +24,9 @@ from resources.libraries.python.honeycomb.HoneycombUtil \
     import DataRepresentation
 from resources.libraries.python.honeycomb.HoneycombUtil \
     import HoneycombUtil as HcUtil
     import DataRepresentation
 from resources.libraries.python.honeycomb.HoneycombUtil \
     import HoneycombUtil as HcUtil
+from resources.libraries.python.topology import Topology
 
 
 
 
-# pylint: disable=too-many-public-methods
-# pylint: disable=too-many-lines
 class InterfaceKeywords(object):
     """Keywords for Interface manipulation.
 
 class InterfaceKeywords(object):
     """Keywords for Interface manipulation.
 
@@ -44,11 +44,14 @@ class InterfaceKeywords(object):
                             "temporary-valid-lifetime",
                             "temporary-preferred-lifetime")
     ETH_PARAMS = ("mtu", )
                             "temporary-valid-lifetime",
                             "temporary-preferred-lifetime")
     ETH_PARAMS = ("mtu", )
-    ROUTING_PARAMS = ("vrf-id", )
+    ROUTING_PARAMS = ("ipv4-vrf-id", "ipv6-vrf-id")
     VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
     L2_PARAMS = ("bridge-domain", "split-horizon-group",
                  "bridged-virtual-interface")
     VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
     L2_PARAMS = ("bridge-domain", "split-horizon-group",
                  "bridged-virtual-interface")
-    TAP_PARAMS = ("tap-name", "mac", "device-instance")
+    TAP_PARAMS = ("id", "tx-ring-size", "rx-ring-size", "host-mac",
+                  "host-interface-name", "host-namespace", "host-bridge",
+                  "host-ipv4-address", "host-ipv6-address", "tag",
+                  "host-ipv4-gateway", "host-ipv6-gateway", "mac")
     VHOST_USER_PARAMS = ("socket", "role")
     SUB_IF_PARAMS = ("identifier",
                      "vlan-type",
     VHOST_USER_PARAMS = ("socket", "role")
     SUB_IF_PARAMS = ("identifier",
                      "vlan-type",
@@ -83,16 +86,16 @@ class InterfaceKeywords(object):
         :type interface: str
         :type data: dict
         :type data_representation: DataRepresentation
         :type interface: str
         :type data: dict
         :type data_representation: DataRepresentation
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the status code in response on PUT is not
         :rtype: bytearray
         :raises HoneycombError: If the status code in response on PUT is not
-        200 = OK.
+            200 = OK.
         """
 
         status_code, resp = HcUtil.\
             put_honeycomb_data(node, "config_vpp_interfaces", data,
                                data_representation=data_representation)
         """
 
         status_code, resp = HcUtil.\
             put_honeycomb_data(node, "config_vpp_interfaces", data,
                                data_representation=data_representation)
-        if status_code != HTTPCodes.OK:
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
             raise HoneycombError(
                 "The configuration of interface '{0}' was not successful. "
                 "Status code: {1}.".format(interface, status_code))
             raise HoneycombError(
                 "The configuration of interface '{0}' was not successful. "
                 "Status code: {1}.".format(interface, status_code))
@@ -104,7 +107,7 @@ class InterfaceKeywords(object):
 
         :param node: Honeycomb node.
         :type node: dict
 
         :param node: Honeycomb node.
         :type node: dict
-        :return: Configuration data about all interfaces from Honeycomb.
+        :returns: Configuration data about all interfaces from Honeycomb.
         :rtype: list
         :raises HoneycombError: If it is not possible to get configuration data.
         """
         :rtype: list
         :raises HoneycombError: If it is not possible to get configuration data.
         """
@@ -129,7 +132,7 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Configuration data about the given interface from Honeycomb.
+        :returns: Configuration data about the given interface from Honeycomb.
         :rtype: dict
         """
 
         :rtype: dict
         """
 
@@ -145,7 +148,7 @@ class InterfaceKeywords(object):
 
         :param node: Honeycomb node.
         :type node: dict
 
         :param node: Honeycomb node.
         :type node: dict
-        :return: Operational data about all interfaces from Honeycomb.
+        :returns: Operational data about all interfaces from Honeycomb.
         :rtype: list
         :raises HoneycombError: If it is not possible to get operational data.
         """
         :rtype: list
         :raises HoneycombError: If it is not possible to get operational data.
         """
@@ -162,6 +165,33 @@ class InterfaceKeywords(object):
         except (KeyError, TypeError):
             return []
 
         except (KeyError, TypeError):
             return []
 
+    @staticmethod
+    def get_disabled_interfaces_oper_data(node):
+        """Get operational data about all disabled interfaces from Honeycomb.
+
+        :param node: Honeycomb node.
+        :type node: dict
+        :returns: Operational data about disabled interfaces.
+        :rtype: list
+        :raises HoneycombError: If it is not possible to get operational data.
+        """
+
+        status_code, resp = HcUtil. \
+            get_honeycomb_data(node, "oper_disabled_interfaces")
+        if status_code == HTTPCodes.NOT_FOUND:
+            raise HoneycombError(
+                "No disabled interfaces present on node."
+            )
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "Not possible to get operational information about the "
+                "interfaces. Status code: {0}.".format(status_code))
+        try:
+            return resp["disabled-interfaces"]["disabled-interface-index"]
+
+        except (KeyError, TypeError):
+            return []
+
     @staticmethod
     def get_interface_oper_data(node, interface):
         """Get operational data about the given interface from Honeycomb.
     @staticmethod
     def get_interface_oper_data(node, interface):
         """Get operational data about the given interface from Honeycomb.
@@ -170,10 +200,20 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Operational data about the given interface from Honeycomb.
+        :returns: Operational data about the given interface from Honeycomb.
         :rtype: dict
         """
 
         :rtype: dict
         """
 
+        try:
+            interface = Topology.convert_interface_reference(
+                node, interface, "name")
+        except RuntimeError:
+            if isinstance(interface, basestring):
+                # Probably name of a custom interface (TAP, VxLAN, Vhost, ...)
+                pass
+            else:
+                raise
+
         intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
         for intf in intfs:
             if intf["name"] == interface:
         intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
         for intf in intfs:
             if intf["name"] == interface:
@@ -191,12 +231,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param path:  Path to data we want to change / create / remove.
         :param new_value: The new value to be set. If None, the item will be
         :param interface: The name of interface.
         :param path:  Path to data we want to change / create / remove.
         :param new_value: The new value to be set. If None, the item will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type path: tuple
         :type new_value: str, dict or list
         :type node: dict
         :type interface: str
         :type path: tuple
         :type new_value: str, dict or list
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If it is not possible to get or set the data.
         """
         :rtype: bytearray
         :raises HoneycombError: If it is not possible to get or set the data.
         """
@@ -215,20 +255,20 @@ class InterfaceKeywords(object):
         return InterfaceKeywords._configure_interface(node, interface, new_data)
 
     @staticmethod
         return InterfaceKeywords._configure_interface(node, interface, new_data)
 
     @staticmethod
-    def set_interface_state(node, interface, state="up"):
+    def honeycomb_set_interface_state(node, interface, state="up"):
         """Set VPP interface state.
 
         The keyword changes the administration state of interface to up or down
         depending on the parameter "state".
 
         :param node: Honeycomb node.
         """Set VPP interface state.
 
         The keyword changes the administration state of interface to up or down
         depending on the parameter "state".
 
         :param node: Honeycomb node.
-        :param interface: The name of interface.
+        :param interface: Interface name, key, link name or sw_if_index.
         :param state: The requested state, only "up" and "down" are valid
         :param state: The requested state, only "up" and "down" are valid
-        values.
+            values.
         :type node: dict
         :type interface: str
         :type state: str
         :type node: dict
         :type interface: str
         :type state: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises KeyError: If the argument "state" is nor "up" or "down".
         :raises HoneycombError: If the interface is not present on the node.
         :rtype: bytearray
         :raises KeyError: If the argument "state" is nor "up" or "down".
         :raises HoneycombError: If the interface is not present on the node.
@@ -237,9 +277,29 @@ class InterfaceKeywords(object):
         intf_state = {"up": "true",
                       "down": "false"}
 
         intf_state = {"up": "true",
                       "down": "false"}
 
-        path = ("interfaces", ("interface", "name", str(interface)), "enabled")
-        return InterfaceKeywords._set_interface_properties(
-            node, interface, path, intf_state[state.lower()])
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
+        intf = interface.replace("/", "%2F")
+        path = "/interface/{0}".format(intf)
+
+        status_code, resp = HcUtil.\
+            get_honeycomb_data(node, "config_vpp_interfaces", path)
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "Not possible to get configuration information about the "
+                "interfaces. Status code: {0}.".format(status_code))
+
+        resp["interface"][0]["enabled"] = intf_state[state.lower()]
+
+        status_code, resp = HcUtil. \
+            put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
 
     @staticmethod
     def set_interface_up(node, interface):
 
     @staticmethod
     def set_interface_up(node, interface):
@@ -249,11 +309,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response
+        :returns: Content of response
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
-        return InterfaceKeywords.set_interface_state(node, interface, "up")
+        return InterfaceKeywords.honeycomb_set_interface_state(
+            node, interface, "up")
 
     @staticmethod
     def set_interface_down(node, interface):
 
     @staticmethod
     def set_interface_down(node, interface):
@@ -263,11 +324,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
-        return InterfaceKeywords.set_interface_state(node, interface, "down")
+        return InterfaceKeywords.honeycomb_set_interface_state(
+            node, interface, "down")
 
     @staticmethod
     def add_bridge_domain_to_interface(node, interface, bd_name,
 
     @staticmethod
     def add_bridge_domain_to_interface(node, interface, bd_name,
@@ -275,7 +337,7 @@ class InterfaceKeywords(object):
         """Add a new bridge domain to an interface and set its parameters.
 
         :param node: Honeycomb node.
         """Add a new bridge domain to an interface and set its parameters.
 
         :param node: Honeycomb node.
-        :param interface: The name of interface.
+        :param interface: Interface name, key, link name or sw_if_index.
         :param bd_name: Bridge domain name.
         :param split_horizon_group: Split-horizon group name.
         :param bvi: The bridged virtual interface.
         :param bd_name: Bridge domain name.
         :param split_horizon_group: Split-horizon group name.
         :param bvi: The bridged virtual interface.
@@ -284,11 +346,14 @@ class InterfaceKeywords(object):
         :type bd_name: str
         :type split_horizon_group: str
         :type bvi: str
         :type bd_name: str
         :type split_horizon_group: str
         :type bvi: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the interface is not present on the node.
         """
 
         :rtype: bytearray
         :raises HoneycombError: If the interface is not present on the node.
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         v3po_l2 = {"bridge-domain": str(bd_name)}
         if split_horizon_group:
             v3po_l2["split-horizon-group"] = str(split_horizon_group)
         v3po_l2 = {"bridge-domain": str(bd_name)}
         if split_horizon_group:
             v3po_l2["split-horizon-group"] = str(split_horizon_group)
@@ -300,6 +365,35 @@ class InterfaceKeywords(object):
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, v3po_l2)
 
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, v3po_l2)
 
+    @staticmethod
+    def remove_bridge_domain_from_interface(node, interface):
+        """Remove bridge domain assignment from interface.
+
+        :param node: Honeycomb node.
+        :param interface: Interface name, key, link name or sw_if_index.
+        :type node: dict
+        :type interface: str or int
+        :raises HoneycombError: If the operation fails.
+        """
+
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
+        intf = interface.replace("/", "%2F")
+
+        path = "/interface/{0}/v3po:l2".format(intf)
+
+        status_code, response = HcUtil.delete_honeycomb_data(
+            node, "config_vpp_interfaces", path)
+
+        if status_code != HTTPCodes.OK:
+            if '"error-tag":"data-missing"' in response:
+                logger.debug("Data does not exist in path.")
+            else:
+                raise HoneycombError(
+                    "Could not remove bridge domain assignment from interface "
+                    "'{0}'. Status code: {1}.".format(interface, status_code))
+
     @staticmethod
     def get_bd_oper_data_from_interface(node, interface):
         """Returns operational data about bridge domain settings in the
     @staticmethod
     def get_bd_oper_data_from_interface(node, interface):
         """Returns operational data about bridge domain settings in the
@@ -307,10 +401,10 @@ class InterfaceKeywords(object):
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
+        :type node: dict
         :type interface: str
         :type interface: str
-        :type param: str
-        :return: Operational data about bridge domain settings in the
-        interface.
+        :returns: Operational data about bridge domain settings in the
+            interface.
         :rtype: dict
         """
 
         :rtype: dict
         """
 
@@ -331,12 +425,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -350,22 +444,25 @@ class InterfaceKeywords(object):
 
     @staticmethod
     def configure_interface_ipv4(node, interface, param, value):
 
     @staticmethod
     def configure_interface_ipv4(node, interface, param, value):
-        """Configure IPv4 parameters of interface
+        """Configure IPv4 parameters of interface.
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         if param not in InterfaceKeywords.IPV4_PARAMS:
             raise HoneycombError("The parameter {0} is invalid.".format(param))
 
         if param not in InterfaceKeywords.IPV4_PARAMS:
             raise HoneycombError("The parameter {0} is invalid.".format(param))
 
@@ -388,20 +485,34 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type network: str or int
         :type interface: str
         :type ip_addr: str
         :type network: str or int
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :rtype: bytearray
+        :raises ValueError: If the provided netmask or prefix is not valid.
+        :raises HoneycombError: If the operation fails.
         """
 
         """
 
-        path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
+        interface = InterfaceKeywords.handle_interface_reference(
+            node, interface)
+
+        path = "/interface/{0}/ietf-ip:ipv4".format(interface)
         if isinstance(network, basestring):
         if isinstance(network, basestring):
-            address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+            data = {
+                "ietf-ip:ipv4": {
+                    "address": [{"ip": ip_addr, "netmask": network}, ]}}
         elif isinstance(network, int) and (0 < network < 33):
         elif isinstance(network, int) and (0 < network < 33):
-            address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+            data = {
+                "ietf-ip:ipv4": {
+                    "address": [{"ip": ip_addr, "prefix-length": network}, ]}}
         else:
         else:
-            raise HoneycombError("Value {0} is not a valid netmask or network "
-                                 "prefix length.".format(network))
-        return InterfaceKeywords._set_interface_properties(
-            node, interface, path, address)
+            raise ValueError("Value {0} is not a valid netmask or network "
+                             "prefix length.".format(network))
+        status_code, _ = HcUtil.put_honeycomb_data(
+            node, "config_vpp_interfaces", data, path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "Configuring IPv4 address failed. "
+                "Status code:{0}".format(status_code))
 
     @staticmethod
     def add_ipv4_address(node, interface, ip_addr, network):
 
     @staticmethod
     def add_ipv4_address(node, interface, ip_addr, network):
@@ -415,16 +526,20 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type network: str or int
         :type interface: str
         :type ip_addr: str
         :type network: str or int
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :rtype: bytearray
+        :raises HoneycombError: If the provided netmask or prefix is not valid.
         """
 
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "address")
         if isinstance(network, basestring):
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "address")
         if isinstance(network, basestring):
-            address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+            address = [{"ip": ip_addr, "netmask": network}]
         elif isinstance(network, int) and (0 < network < 33):
         elif isinstance(network, int) and (0 < network < 33):
-            address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+            address = [{"ip": ip_addr, "prefix-length": network}]
         else:
             raise HoneycombError("Value {0} is not a valid netmask or network "
                                  "prefix length.".format(network))
         else:
             raise HoneycombError("Value {0} is not a valid netmask or network "
                                  "prefix length.".format(network))
@@ -439,39 +554,18 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "address")
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, None)
 
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "address")
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, None)
 
-    @staticmethod
-    def add_first_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
-        """Add the first IPv4 neighbour.
-
-        If there are any other neighbours configured, they will be removed.
-
-        :param node: Honeycomb node.
-        :param interface: The name of interface.
-        :param ip_addr: IPv4 address of neighbour to be set.
-        :param link_layer_address: Link layer address.
-        :type node: dict
-        :type interface: str
-        :type ip_addr: str
-        :type link_layer_address: str
-        :return: Content of response.
-        :rtype: bytearray
-        """
-
-        path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
-        neighbor = {"neighbor": [{"ip": ip_addr,
-                                  "link-layer-address": link_layer_address}, ]}
-        return InterfaceKeywords._set_interface_properties(
-            node, interface, path, neighbor)
-
     @staticmethod
     def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
         """Add the IPv4 neighbour.
     @staticmethod
     def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
         """Add the IPv4 neighbour.
@@ -484,10 +578,13 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type link_layer_address: str
         :type interface: str
         :type ip_addr: str
         :type link_layer_address: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "neighbor")
         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "neighbor")
         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
@@ -502,10 +599,13 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "neighbor")
         return InterfaceKeywords._set_interface_properties(
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
                 "neighbor")
         return InterfaceKeywords._set_interface_properties(
@@ -519,12 +619,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -555,10 +655,13 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type prefix_len: str
         :type interface: str
         :type ip_addr: str
         :type prefix_len: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
         address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
         return InterfaceKeywords._set_interface_properties(
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
         address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
         return InterfaceKeywords._set_interface_properties(
@@ -576,10 +679,13 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type prefix_len: str
         :type interface: str
         :type ip_addr: str
         :type prefix_len: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "address")
         address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "address")
         address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
@@ -594,39 +700,18 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "address")
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, None)
 
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "address")
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, None)
 
-    @staticmethod
-    def add_first_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
-        """Add the first IPv6 neighbour.
-
-        If there are any other neighbours configured, they will be removed.
-
-        :param node: Honeycomb node.
-        :param interface: The name of interface.
-        :param ip_addr: IPv6 address of neighbour to be set.
-        :param link_layer_address: Link layer address.
-        :type node: dict
-        :type interface: str
-        :type ip_addr: str
-        :type link_layer_address: str
-        :return: Content of response.
-        :rtype: bytearray
-        """
-
-        path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
-        neighbor = {"neighbor": [{"ip": ip_addr,
-                                  "link-layer-address": link_layer_address}, ]}
-        return InterfaceKeywords._set_interface_properties(
-            node, interface, path, neighbor)
-
     @staticmethod
     def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
         """Add the IPv6 neighbour.
     @staticmethod
     def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
         """Add the IPv6 neighbour.
@@ -639,10 +724,13 @@ class InterfaceKeywords(object):
         :type interface: str
         :type ip_addr: str
         :type link_layer_address: str
         :type interface: str
         :type ip_addr: str
         :type link_layer_address: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "neighbor")
         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "neighbor")
         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
@@ -657,10 +745,13 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "neighbor")
         return InterfaceKeywords._set_interface_properties(
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
                 "neighbor")
         return InterfaceKeywords._set_interface_properties(
@@ -674,12 +765,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -699,16 +790,19 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+
         if param not in InterfaceKeywords.ROUTING_PARAMS:
             raise HoneycombError("The parameter {0} is invalid.".format(param))
 
         if param not in InterfaceKeywords.ROUTING_PARAMS:
             raise HoneycombError("The parameter {0} is invalid.".format(param))
 
@@ -718,17 +812,17 @@ class InterfaceKeywords(object):
             node, interface, path, value)
 
     @staticmethod
             node, interface, path, value)
 
     @staticmethod
-    def create_vxlan_interface(node, interface, **kwargs):
+    def honeycomb_create_vxlan_interface(node, interface, **kwargs):
         """Create a new VxLAN interface.
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         """Create a new VxLAN interface.
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.VXLAN_PARAMS.
+            defined in InterfaceKeywords.VXLAN_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -757,10 +851,10 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
         :param interface: The name of interface.
         :type node: dict
         :type interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If it is not possible to get information about
         :rtype: bytearray
         :raises HoneycombError: If it is not possible to get information about
-        interfaces or it is not possible to delete the interface.
+            interfaces or it is not possible to delete the interface.
         """
 
         path = ("interfaces", ("interface", "name", interface))
         """
 
         path = ("interfaces", ("interface", "name", interface))
@@ -782,7 +876,7 @@ class InterfaceKeywords(object):
         return resp
 
     @staticmethod
         return resp
 
     @staticmethod
-    def configure_interface_vxlan(node, interface, **kwargs):
+    def honeycomb_configure_interface_vxlan(node, interface, **kwargs):
         """Configure VxLAN on the interface.
 
         The keyword configures VxLAN parameters on the given interface. The type
         """Configure VxLAN on the interface.
 
         The keyword configures VxLAN parameters on the given interface. The type
@@ -795,11 +889,11 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.VXLAN_PARAMS.
+            defined in InterfaceKeywords.VXLAN_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -823,12 +917,12 @@ class InterfaceKeywords(object):
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
         :param interface: The name of interface.
         :param param: Parameter to configure (set, change, remove)
         :param value: The value of parameter. If None, the parameter will be
-        removed.
+            removed.
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
         :type node: dict
         :type interface: str
         :type param: str
         :type value: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -847,25 +941,25 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.TAP_PARAMS.
+            defined in InterfaceKeywords.TAP_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
         new_tap = {
             "name": interface,
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
 
         new_tap = {
             "name": interface,
-            "type": "v3po:tap",
-            "v3po:tap": {}
+            "type": "v3po:tap-v2",
+            "v3po:tap-v2": {}
         }
         for param, value in kwargs.items():
             if param not in InterfaceKeywords.TAP_PARAMS:
         }
         for param, value in kwargs.items():
             if param not in InterfaceKeywords.TAP_PARAMS:
-                raise HoneycombError("The parameter {0} is invalid.".
-                                     format(param))
-            new_tap["v3po:tap"][param] = value
+                raise HoneycombError(
+                    "The parameter {0} is invalid.".format(param))
+            new_tap["v3po:tap-v2"][param] = value
 
         path = ("interfaces", "interface")
         new_tap_structure = [new_tap, ]
 
         path = ("interfaces", "interface")
         new_tap_structure = [new_tap, ]
@@ -877,7 +971,7 @@ class InterfaceKeywords(object):
         """Configure TAP on the interface.
 
         The keyword configures TAP parameters on the given interface. The type
         """Configure TAP on the interface.
 
         The keyword configures TAP parameters on the given interface. The type
-        of interface must be set to "v3po:tap".
+        of interface must be set to "v3po:tap-v2".
         The new TAP parameters overwrite the current configuration. If a
         parameter in new configuration is missing, it is removed from TAP
         configuration.
         The new TAP parameters overwrite the current configuration. If a
         parameter in new configuration is missing, it is removed from TAP
         configuration.
@@ -886,11 +980,11 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.TAP_PARAMS.
+            defined in InterfaceKeywords.TAP_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -902,7 +996,7 @@ class InterfaceKeywords(object):
                                      format(param))
             tap_structure[param] = value
 
                                      format(param))
             tap_structure[param] = value
 
-        path = ("interfaces", ("interface", "name", interface), "v3po:tap")
+        path = ("interfaces", ("interface", "name", interface), "v3po:tap-v2")
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, tap_structure)
 
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, tap_structure)
 
@@ -920,11 +1014,11 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.VHOST_USER_PARAMS.
+            defined in InterfaceKeywords.VHOST_USER_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -948,11 +1042,11 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.VHOST_USER_PARAMS.
+            defined in InterfaceKeywords.VHOST_USER_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         """
@@ -974,27 +1068,31 @@ class InterfaceKeywords(object):
             node, interface, path, new_vhost_structure)
 
     @staticmethod
             node, interface, path, new_vhost_structure)
 
     @staticmethod
-    def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
+    def honeycomb_create_sub_interface(node, super_interface, match, tags=None,
+                                       **kwargs):
         """Create a new sub-interface.
 
         :param node: Honeycomb node.
         :param super_interface: Super interface.
         :param match: Match type. The valid values are defined in
         """Create a new sub-interface.
 
         :param node: Honeycomb node.
         :param super_interface: Super interface.
         :param match: Match type. The valid values are defined in
-        InterfaceKeywords.SUB_IF_MATCH.
+            InterfaceKeywords.SUB_IF_MATCH.
         :param tags: List of tags.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param tags: List of tags.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.SUB_IF_PARAMS.
+            defined in InterfaceKeywords.SUB_IF_PARAMS.
         :type node: dict
         :type super_interface: str
         :type match: str
         :type tags: list
         :type kwargs: dict
         :type node: dict
         :type super_interface: str
         :type match: str
         :type tags: list
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         :raises KeyError: If the parameter 'match' is invalid.
         """
 
         :rtype: bytearray
         :raises HoneycombError: If the parameter is not valid.
         :raises KeyError: If the parameter 'match' is invalid.
         """
 
+        super_interface = Topology.convert_interface_reference(
+            node, super_interface, "name")
+
         match_type = {
             "default":
                 {"default": {}},
         match_type = {
             "default":
                 {"default": {}},
@@ -1045,7 +1143,7 @@ class InterfaceKeywords(object):
         :type node: dict
         :type super_interface: str
         :type identifier: int
         :type node: dict
         :type super_interface: str
         :type identifier: int
-        :return: Sub-interface operational data.
+        :returns: Sub-interface operational data.
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
@@ -1067,7 +1165,7 @@ class InterfaceKeywords(object):
         :param super_interface: Super interface.
         :type node: dict
         :type super_interface: str
         :param super_interface: Super interface.
         :type node: dict
         :type super_interface: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
@@ -1090,17 +1188,20 @@ class InterfaceKeywords(object):
         :type super_interface: str
         :type identifier: int
         :type state: str
         :type super_interface: str
         :type identifier: int
         :type state: str
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        super_interface = Topology.convert_interface_reference(
+            node, super_interface, "name")
+
         intf_state = {"up": "true",
                       "down": "false"}
 
         path = ("interfaces",
                 ("interface", "name", super_interface),
                 "vpp-vlan:sub-interfaces",
         intf_state = {"up": "true",
                       "down": "false"}
 
         path = ("interfaces",
                 ("interface", "name", super_interface),
                 "vpp-vlan:sub-interfaces",
-                ("sub-interface", "identifier", identifier),
+                ("sub-interface", "identifier", int(identifier)),
                 "enabled")
 
         return InterfaceKeywords._set_interface_properties(
                 "enabled")
 
         return InterfaceKeywords._set_interface_properties(
@@ -1119,7 +1220,7 @@ class InterfaceKeywords(object):
         :type super_interface: str
         :type identifier: int
         :type config: dict
         :type super_interface: str
         :type identifier: int
         :type config: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
@@ -1142,7 +1243,7 @@ class InterfaceKeywords(object):
         :type node: dict
         :type super_interface: str
         :type identifier: int
         :type node: dict
         :type super_interface: str
         :type identifier: int
-        :return: Operational data about the bridge domain.
+        :returns: Operational data about the bridge domain.
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
@@ -1167,7 +1268,7 @@ class InterfaceKeywords(object):
         :type super_interface: str
         :type identifier: int
         :type config: dict
         :type super_interface: str
         :type identifier: int
         :type config: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
@@ -1191,7 +1292,7 @@ class InterfaceKeywords(object):
         :type node: dict
         :type super_interface: str
         :type identifier: int
         :type node: dict
         :type super_interface: str
         :type identifier: int
-        :return: Operational data about tag rewrite.
+        :returns: Operational data about tag rewrite.
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
         :rtype: dict
         :raises HoneycombError: If there is no sub-interface with the given ID.
         """
@@ -1205,27 +1306,142 @@ class InterfaceKeywords(object):
                                  "information about the tag-rewrite.")
 
     @staticmethod
                                  "information about the tag-rewrite.")
 
     @staticmethod
-    def compare_data_structures(data, ref):
-        """Checks if data obtained from UUT is as expected.
+    def add_ip_address_to_sub_interface(node, super_interface, identifier,
+                                        ip_addr, network, ip_version):
+        """Add an ipv4 address to the specified sub-interface, with the provided
+        netmask or network prefix length. Any existing ipv4 addresses on the
+        sub-interface will be replaced.
+
+        :param node: Honeycomb node.
+        :param super_interface: Super interface.
+        :param identifier: The ID of sub-interface.
+        :param ip_addr: IPv4 address to be set.
+        :param network: Network mask or network prefix length.
+        :param ip_version: ipv4 or ipv6
+        :type node: dict
+        :type super_interface: str
+        :type identifier: int
+        :type ip_addr: str
+        :type network: str or int
+        :type ip_version: string
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the provided netmask or prefix is not valid.
+        """
+
+        path = ("interfaces",
+                ("interface", "name", super_interface),
+                "vpp-vlan:sub-interfaces",
+                ("sub-interface", "identifier", int(identifier)),
+                ip_version.lower())
+
+        if isinstance(network, basestring) and ip_version.lower() == "ipv4":
+            address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+
+        elif isinstance(network, int) and 0 < network < 33:
+            address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+
+        else:
+            raise HoneycombError("{0} is not a valid netmask or prefix length."
+                                 .format(network))
+
+        return InterfaceKeywords._set_interface_properties(
+            node, super_interface, path, address)
+
+    @staticmethod
+    def remove_all_ip_addresses_from_sub_interface(node, super_interface,
+                                                   identifier, ip_version):
+        """Remove all ipv4 addresses from the specified sub-interface.
+
+        :param node: Honeycomb node.
+        :param super_interface: Super interface.
+        :param identifier: The ID of sub-interface.
+        :param ip_version: ipv4 or ipv6
+        :type node: dict
+        :type super_interface: str
+        :type identifier: int
+        :type ip_version: string
+        :returns: Content of response.
+        :rtype: bytearray
+        """
+
+        path = ("interfaces",
+                ("interface", "name", super_interface),
+                "vpp-vlan:sub-interfaces",
+                ("sub-interface", "identifier", int(identifier)),
+                str(ip_version), "address")
+
+        return InterfaceKeywords._set_interface_properties(
+            node, super_interface, path, None)
+
+    @staticmethod
+    def compare_data_structures(data, ref, _path=''):
+        """Checks if data obtained from UUT is as expected. If it is not,
+        proceeds down the list/dictionary tree and finds the point of mismatch.
 
         :param data: Data to be checked.
         :param ref: Referential data used for comparison.
 
         :param data: Data to be checked.
         :param ref: Referential data used for comparison.
+        :param _path: Used in recursive calls, stores the path taken down
+            the JSON tree.
         :type data: dict
         :type ref: dict
         :type data: dict
         :type ref: dict
-        :raises HoneycombError: If a parameter from referential data is not
-        present in operational data or if it has different value.
+        :type _path: str
+
+        :raises HoneycombError: If the data structures do not match in some way,
+            or if they are not in deserialized JSON format.
         """
 
         """
 
-        for key, item in ref.items():
-            try:
-                if data[key] != item:
-                    raise HoneycombError("The value of parameter '{0}' is "
-                                         "incorrect. It should be "
-                                         "'{1}' but it is '{2}'".
-                                         format(key, item, data[key]))
-            except KeyError:
-                raise HoneycombError("The parameter '{0}' is not present in "
-                                     "operational data".format(key))
+        if data == ref:
+            return True
+
+        elif isinstance(data, dict) and isinstance(ref, dict):
+            for key in ref:
+                if key not in data:
+                    raise HoneycombError(
+                        "Key {key} is not present in path {path}. Keys in path:"
+                        "{data_keys}".format(
+                            key=key,
+                            path=_path,
+                            data_keys=data.keys()))
+
+                if data[key] != ref[key]:
+                    if isinstance(data[key], list) \
+                            or isinstance(data[key], dict):
+                        InterfaceKeywords.compare_data_structures(
+                            data[key], ref[key],
+                            _path + '[{0}]'.format(key))
+                    else:
+                        raise HoneycombError(
+                            "Data mismatch, key {key} in path {path} has value"
+                            " {data}, but should be {ref}".format(
+                                key=key,
+                                path=_path,
+                                data=data[key],
+                                ref=ref[key]))
+
+        elif isinstance(data, list) and isinstance(ref, list):
+            for item in ref:
+                if item not in data:
+                    if isinstance(item, dict):
+                        InterfaceKeywords.compare_data_structures(
+                            data[0], item,
+                            _path + '[{0}]'.format(ref.index(item)))
+                    else:
+                        raise HoneycombError(
+                            "Data mismatch, list item {index} in path {path}"
+                            " has value {data}, but should be {ref}".format(
+                                index=ref.index(item),
+                                path=_path,
+                                data=data[0],
+                                ref=item))
+
+        else:
+            raise HoneycombError(
+                "Unexpected data type {data_type} in path {path}, reference"
+                " type is {ref_type}. Must be list or dictionary.".format(
+                    data_type=type(data),
+                    ref_type=type(ref),
+                    path=_path))
 
     @staticmethod
     def compare_interface_lists(list1, list2):
 
     @staticmethod
     def compare_interface_lists(list1, list2):
@@ -1260,11 +1476,11 @@ class InterfaceKeywords(object):
         :param node: Honeycomb node.
         :param interface: The name of interface to be created.
         :param kwargs: Parameters and their values. The accepted parameters are
         :param node: Honeycomb node.
         :param interface: The name of interface to be created.
         :param kwargs: Parameters and their values. The accepted parameters are
-        defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
+            defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
         :type node: dict
         :type interface: str
         :type kwargs: dict
         :type node: dict
         :type interface: str
         :type kwargs: dict
-        :return: Content of response.
+        :returns: Content of response.
         :rtype: bytearray
         :raises HoneycombError: If a parameter in kwargs is not valid.
         """
         :rtype: bytearray
         :raises HoneycombError: If a parameter in kwargs is not valid.
         """
@@ -1286,3 +1502,407 @@ class InterfaceKeywords(object):
         vxlan_gpe_structure = [new_vxlan_gpe, ]
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, vxlan_gpe_structure)
         vxlan_gpe_structure = [new_vxlan_gpe, ]
         return InterfaceKeywords._set_interface_properties(
             node, interface, path, vxlan_gpe_structure)
+
+    @staticmethod
+    def enable_acl_on_interface(node, interface, table_name):
+        """Enable ACL on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where the ACL will be enabled.
+        :param table_name: Name of the classify table.
+        :type node: dict
+        :type interface: str
+        :type table_name: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+            successful.
+        """
+
+        interface = interface.replace("/", "%2F")
+
+        data = {
+            "vpp-interface-acl:acl": {
+                "ingress": {
+                    "ip4-acl": {
+                        "classify-table": table_name
+                    },
+                    "l2-acl": {
+                        "classify-table": table_name
+                    }
+                }
+            }
+        }
+
+        path = "/interface/" + interface + "/vpp-interface-acl:acl"
+        status_code, resp = HcUtil.\
+            put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
+    @staticmethod
+    def enable_policer_on_interface(node, interface, table_name):
+        """Enable Policer on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where policer will be enabled.
+        :param table_name: Name of the classify table.
+        :type node: dict
+        :type interface: str
+        :type table_name: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+            successful.
+        """
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+        interface = interface.replace("/", "%2F")
+
+        data = {
+            "interface-policer:policer": {
+                "ip4-table": table_name
+                }
+            }
+
+        path = "/interface/" + interface + "/interface-policer:policer"
+        status_code, resp = HcUtil.\
+            put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
+    @staticmethod
+    def disable_policer_on_interface(node, interface):
+        """Disable Policer on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where policer will be disabled.
+        :type node: dict
+        :type interface: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+            successful.
+        """
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+        interface = interface.replace("/", "%2F")
+
+        path = "/interface/" + interface + "/interface-policer:policer"
+        status_code, resp = HcUtil.\
+            delete_honeycomb_data(node, "config_vpp_interfaces", path)
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
+    @staticmethod
+    def disable_acl_on_interface(node, interface):
+        """Disable ACL on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where the ACL will be disabled.
+        :type node: dict
+        :type interface: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+            successful.
+        """
+
+        interface = interface.replace("/", "%2F")
+
+        path = "/interface/" + interface + "/vpp-interface-acl:acl"
+
+        status_code, resp = HcUtil.\
+            delete_honeycomb_data(node, "config_vpp_interfaces", path)
+
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
+    @staticmethod
+    def create_pbb_sub_interface(node, intf, params):
+        """Creates a PBB sub-interface on the given interface and sets its
+        parameters.
+
+        :param node: Honeycomb node.
+        :param intf: The interface where PBB sub-interface will be configured.
+        :param params: Configuration parameters of the sub-interface to be
+            created.
+        :type node: dict
+        :type intf: str
+        :type params: dict
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of sub-interface is not
+            successful.
+        """
+
+        interface = intf.replace("/", "%2F")
+        path = "/interface/{0}/pbb-rewrite".format(interface)
+        status_code, resp = HcUtil. \
+            put_honeycomb_data(node, "config_vpp_interfaces", params, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "The configuration of PBB sub-interface '{0}' was not "
+                "successful. Status code: {1}.".format(intf, status_code))
+        return resp
+
+    @staticmethod
+    def delete_pbb_sub_interface(node, intf):
+        """Deletes the given PBB sub-interface.
+
+        :param node: Honeycomb node.
+        :param intf: The interface where PBB sub-interface will be deleted.
+        :type node: dict
+        :type intf: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the removal of sub-interface is not
+            successful.
+        """
+
+        interface = intf.replace("/", "%2F")
+        path = "/interface/{0}/pbb-rewrite".format(interface)
+
+        status_code, resp = HcUtil. \
+            delete_honeycomb_data(node, "config_vpp_interfaces", path)
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "The removal of pbb sub-interface '{0}' was not successful. "
+                "Status code: {1}.".format(intf, status_code))
+        return resp
+
+    @staticmethod
+    def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
+        """Retrieves PBB sub-interface operational data from Honeycomb.
+
+        :param node: Honeycomb node.
+        :param intf: The interface where PBB sub-interface is located.
+        :param sub_if_id: ID of the PBB sub-interface.
+        :type node: dict
+        :type intf: str
+        :type sub_if_id: str or int
+        :returns: PBB sub-interface operational data.
+        :rtype: dict
+        :raises HoneycombError: If the removal of sub-interface is not
+            successful.
+        """
+
+        raise NotImplementedError
+
+    @staticmethod
+    def check_disabled_interface(node, interface):
+        """Retrieves list of disabled interface indices from Honeycomb,
+        and matches with the provided interface by index.
+
+        :param node: Honeycomb node.
+        :param interface: Index number of an interface on the node.
+        :type node: dict
+        :type interface: int
+        :returns: True if the interface exists in disabled interfaces.
+        :rtype: bool
+        :raises HoneycombError: If the interface is not present
+            in retrieved list of disabled interfaces.
+        """
+        data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
+        # decrement by one = conversion from HC if-index to VPP sw_if_index
+        interface -= 1
+
+        for item in data:
+            if item["index"] == interface:
+                return True
+        raise HoneycombError("Interface index {0} not present in list"
+                             " of disabled interfaces.".format(interface))
+
+    @staticmethod
+    def configure_interface_span(node, dst_interface, src_interfaces=None):
+        """Configure SPAN port mirroring on the specified interfaces. If no
+         source interface is provided, SPAN will be disabled.
+
+        :param node: Honeycomb node.
+        :param dst_interface: Interface to mirror packets to.
+        :param src_interfaces: List of interfaces to mirror packets from.
+        :type node: dict
+        :type dst_interface: str or int
+        :type src_interfaces: list of dict
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If SPAN could not be configured.
+        """
+
+        interface = Topology.convert_interface_reference(
+            node, dst_interface, "name")
+        interface = interface.replace("/", "%2F")
+        path = "/interface/" + interface + "/span"
+
+        if not src_interfaces:
+            status_code, _ = HcUtil.delete_honeycomb_data(
+                node, "config_vpp_interfaces", path)
+        else:
+            for src_interface in src_interfaces:
+                src_interface["iface-ref"] = Topology.\
+                    convert_interface_reference(
+                        node, src_interface["iface-ref"], "name")
+            data = {
+                "span": {
+                    "mirrored-interfaces": {
+                        "mirrored-interface": src_interfaces
+                    }
+                }
+            }
+
+            status_code, _ = HcUtil.put_honeycomb_data(
+                node, "config_vpp_interfaces", data, path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "Configuring SPAN failed. Status code:{0}".format(status_code))
+
+    @staticmethod
+    def configure_sub_interface_span(node, super_interface, dst_interface_index,
+                                     src_interfaces=None):
+        """Configure SPAN port mirroring on the specified sub-interface. If no
+         source interface is provided, SPAN will be disabled.
+
+        Note: Does not support source sub-interfaces, only destination.
+
+        :param node: Honeycomb node.
+        :param super_interface: Name, link name or sw_if_index
+            of the destination interface's super-interface.
+        :param dst_interface_index: Index of sub-interface to mirror packets to.
+        :param src_interfaces: List of interfaces to mirror packets from.
+        :type node: dict
+        :type super_interface: str or int
+        :type dst_interface_index: int
+        :type src_interfaces: list of dict
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If SPAN could not be configured.
+        """
+
+        super_interface = Topology.convert_interface_reference(
+            node, super_interface, "name")
+        super_interface = super_interface.replace("/", "%2F")
+
+        path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
+            .format(super_interface, dst_interface_index)
+
+        if not src_interfaces:
+            status_code, _ = HcUtil.delete_honeycomb_data(
+                node, "config_vpp_interfaces", path)
+        else:
+            for src_interface in src_interfaces:
+                src_interface["iface-ref"] = Topology. \
+                    convert_interface_reference(
+                        node, src_interface["iface-ref"], "name")
+            data = {
+                "span": {
+                    "mirrored-interfaces": {
+                        "mirrored-interface": src_interfaces
+                    }
+                }
+            }
+
+            status_code, _ = HcUtil.put_honeycomb_data(
+                node, "config_vpp_interfaces", data, path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "Configuring SPAN failed. Status code:{0}".format(status_code))
+
+    @staticmethod
+    def add_interface_local0_to_topology(node):
+        """Use Topology methods to add interface "local0" to working topology,
+        if not already present.
+
+        :param node: DUT node.
+        :type node: dict
+        """
+
+        if Topology.get_interface_by_sw_index(node, 0) is None:
+            local0_key = Topology.add_new_port(node, "localzero")
+            Topology.update_interface_sw_if_index(node, local0_key, 0)
+            Topology.update_interface_name(node, local0_key, "local0")
+
+    @staticmethod
+    def configure_interface_unnumbered(node, interface, interface_src=None):
+        """Configure the specified interface as unnumbered. The interface
+        borrows IP address from the specified source interface. If not source
+        interface is provided, unnumbered configuration will be removed.
+
+        :param node: Honeycomb node.
+        :param interface: Name, link name or sw_if_index of an interface.
+        :param interface_src: Name of source interface.
+        :type node: dict
+        :type interface: str or int
+        :type interface_src: str
+        :raises HoneycombError: If the configuration fails.
+        """
+
+        interface = InterfaceKeywords.handle_interface_reference(
+            node, interface)
+
+        path = "/interface/{0}/unnumbered-interfaces:unnumbered"\
+            .format(interface)
+
+        if interface_src:
+            data = {
+                "unnumbered": {
+                    "use": interface_src
+                }
+            }
+            status_code, _ = HcUtil.put_honeycomb_data(
+                node, "config_vpp_interfaces", data, path)
+        else:
+            status_code, _ = HcUtil.delete_honeycomb_data(
+                node, "config_vpp_interfaces", path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "Configuring unnumbered interface failed. "
+                "Status code:{0}".format(status_code))
+
+    @staticmethod
+    def handle_interface_reference(node, interface):
+        """Convert any interface reference to interface name used by Honeycomb.
+
+        :param node: Honeycomb node.
+        :param interface: Name, link name or sw_if_index of an interface,
+            name of a custom interface or name of a sub-interface.
+        :type node: Honeycomb node.
+        :type interface: str or int
+        :returns: Name of interface that can be used in Honeycomb requests.
+        :rtype: str
+        """
+
+        try:
+            interface = Topology.convert_interface_reference(
+                node, interface, "name")
+            interface = interface.replace("/", "%2F")
+        except RuntimeError:
+            # interface is not in topology
+            if "." in interface:
+                # Assume it's the name of a sub-interface
+                interface, index = interface.split(".")
+                interface = interface.replace("/", "%2F")
+                interface = "{0}/vpp-vlan:sub-interfaces/sub-interface/{1}".\
+                    format(interface, index)
+            else:
+                # Assume it's the name of a custom interface (pbb, vxlan, etc.)
+                interface = interface.replace("/", "%2F")
+
+        return interface