CSIT-1471: Policer - VAT API to PAPI 26/20826/58
authorpremkumarv <preym17@gmail.com>
Wed, 24 Jul 2019 12:43:23 +0000 (08:43 -0400)
committerJan Gelety <jgelety@cisco.com>
Thu, 26 Sep 2019 15:26:32 +0000 (17:26 +0200)
Change-Id: I6c7eff8d9cbb196ccb684a45579ac59942351cfe
Signed-off-by: premkumarv <preym17@gmail.com>
26 files changed:
resources/api/vpp/supported_crcs.yaml
resources/libraries/python/Classify.py
resources/libraries/python/PapiExecutor.py
resources/libraries/python/Policer.py
resources/libraries/robot/features/policer.robot
resources/libraries/robot/shared/default.robot
resources/libraries/robot/shared/test_teardown.robot
resources/libraries/robot/shared/traffic.robot
resources/templates/vat/acl_plugin/macip_acl_dump.vat [deleted file]
resources/templates/vat/classify_add_table.vat [deleted file]
resources/templates/vat/cop_interface.vat [deleted file]
resources/templates/vat/cop_whitelist.vat [deleted file]
resources/templates/vat/policer/policer_add_3c.vat [deleted file]
resources/templates/vat/policer/policer_classify_add_session.vat [deleted file]
resources/templates/vat/policer/policer_classify_set_interface.vat [deleted file]
resources/templates/vat/tap.vat [deleted file]
tests/vpp/device/ip4/eth2p-ethip4-ip4base-iacldstbase-dev.robot
tests/vpp/device/ip4/eth2p-ethip4-ip4base-ipolicemarkbase-dev.robot
tests/vpp/device/ip6/eth2p-ethip6-ip6base-iacldstbase-dev.robot
tests/vpp/device/ip6/eth2p-ethip6-ip6base-ipolicemarkbase-dev.robot
tests/vpp/perf/ip4/10ge2p1x710-ethip4-ip4base-iacldstbase-ndrpdr.robot
tests/vpp/perf/ip4/10ge2p1x710-ethip4-ip4base-ipolicemarkbase-ndrpdr.robot
tests/vpp/perf/ip4/2n1l-10ge2p1x710-ethip4-ip4base-iacldstbase-ndrpdr.robot
tests/vpp/perf/ip4/2n1l-10ge2p1x710-ethip4-ip4base-ipolicemarkbase-ndrpdr.robot
tests/vpp/perf/ip6/10ge2p1x710-ethip6-ip6base-iacldstbase-ndrpdr.robot
tests/vpp/perf/ip6/2n1l-10ge2p1x710-ethip6-ip6base-iacldstbase-ndrpdr.robot

index a8b41b5..b51d439 100644 (file)
     vxlan_add_del_tunnel_reply: '0xfda5941f'  # dev
     # vxlan_gpe_tunnel_dump / details # honeycomb
     # vxlan_tunnel_dump /details # unused L2 keyword: Get VXLAN dump
+    policer_add_del: '0xdfea2be8'  # dev
+    policer_add_del_reply: '0xa177cef2'  # dev
+    policer_classify_set_interface: '0xe09537b0' # dev
+    policer_classify_set_interface_reply: '0xe8d4e804' # dev
+    # 4x^ tc01-64B-ethip4-ip4base-ipolicemarkbase-dev
 
 
 # Hint to see the currently used command messages:
index 6f05a61..6d4b84c 100644 (file)
@@ -20,6 +20,7 @@ from ipaddress import ip_address
 
 from robot.api import logger
 
+from resources.libraries.python.Constants import Constants
 from resources.libraries.python.topology import Topology
 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
 
@@ -40,16 +41,10 @@ class Classify(object):
         :returns MAC ACL mask in hexstring format.
         :rtype: str
         """
-        if ether_type:
-            end = 28
-        elif src_mac:
-            end = 24
-        else:
-            end = 12
 
         return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
             dst_mac.replace(':', ''), src_mac.replace(':', ''),
-            ether_type))[0:end]
+            ether_type)).decode('hex').rstrip('\0')
 
     @staticmethod
     def _build_ip_mask(proto='', src_ip='', dst_ip='', src_port='',
@@ -69,19 +64,10 @@ class Classify(object):
         :returns: IP mask in hexstring format.
         :rtype: str
         """
-        if dst_port:
-            end = 48
-        elif src_port:
-            end = 44
-        elif dst_ip:
-            end = 40
-        elif src_ip:
-            end = 32
-        else:
-            end = 20
 
         return ('{!s:0>20}{!s:0>12}{!s:0>8}{!s:0>4}{!s:0>4}'.format(
-            proto, src_ip, dst_ip, src_port, dst_port))[0:end]
+            proto, src_ip, dst_ip, src_port, dst_port)).decode('hex').\
+            rstrip('\0')
 
     @staticmethod
     def _build_ip6_mask(next_hdr='', src_ip='', dst_ip='', src_port='',
@@ -101,19 +87,10 @@ class Classify(object):
         :returns: IPv6 ACL mask in hexstring format.
         :rtype: str
         """
-        if dst_port:
-            end = 88
-        elif src_port:
-            end = 84
-        elif dst_ip:
-            end = 80
-        elif src_ip:
-            end = 48
-        else:
-            end = 14
 
         return ('{!s:0>14}{!s:0>34}{!s:0>32}{!s:0>4}{!s:0>4}'.format(
-            next_hdr, src_ip, dst_ip, src_port, dst_port))[0:end]
+            next_hdr, src_ip, dst_ip, src_port, dst_port)).decode('hex').\
+            rstrip('\0')
 
     @staticmethod
     def _build_mac_match(dst_mac='', src_mac='', ether_type=''):
@@ -128,24 +105,18 @@ class Classify(object):
         :returns: MAC ACL match data in hexstring format.
         :rtype: str
         """
-        if ether_type:
-            end = 28
-        elif src_mac:
-            end = 24
-        else:
-            end = 12
 
         return ('{!s:0>12}{!s:0>12}{!s:0>4}'.format(
             dst_mac.replace(':', ''), src_mac.replace(':', ''),
-            ether_type))[0:end]
+            ether_type)).decode('hex').rstrip('\0')
 
     @staticmethod
     def _build_ip_match(proto=0, src_ip='', dst_ip='', src_port=0, dst_port=0):
-        """Build IP ACL match data in hexstring format.
+        """Build IP ACL match data in byte-string format.
 
         :param proto: Protocol number with valid option "x".
-        :param src_ip: Source ip address with format of "x.x.x.x".
-        :param dst_ip: Destination ip address with format of "x.x.x.x".
+        :param src_ip: Source ip address in packed format.
+        :param dst_ip: Destination ip address in packed format.
         :param src_port: Source port number "x".
         :param dst_port: Destination port number "x".
         :type proto: int
@@ -153,37 +124,22 @@ class Classify(object):
         :type dst_ip: str
         :type src_port: int
         :type dst_port: int
-        :returns: IP ACL match data in hexstring format.
+        :returns: IP ACL match data in byte-string format.
         :rtype: str
         """
-        if src_ip:
-            src_ip = binascii.hexlify(ip_address(unicode(src_ip)).packed)
-        if dst_ip:
-            dst_ip = binascii.hexlify(ip_address(unicode(dst_ip)).packed)
-        if dst_port:
-            end = 48
-        elif src_port:
-            end = 44
-        elif dst_ip:
-            end = 40
-        elif src_ip:
-            end = 32
-        else:
-            end = 20
 
         return ('{!s:0>20}{!s:0>12}{!s:0>8}{!s:0>4}{!s:0>4}'.format(
             hex(proto)[2:], src_ip, dst_ip, hex(src_port)[2:],
-            hex(dst_port)[2:]))[0:end]
+            hex(dst_port)[2:])).decode('hex').rstrip('\0')
 
     @staticmethod
     def _build_ip6_match(next_hdr=0, src_ip='', dst_ip='', src_port=0,
                          dst_port=0):
-        """Build IPv6 ACL match data in hexstring format.
+        """Build IPv6 ACL match data in byte-string format.
 
         :param next_hdr: Next header number with valid option "x".
-        :param src_ip: Source ip6 address with format of "xxxx:xxxx::xxxx".
-        :param dst_ip: Destination ip6 address with format of
-            "xxxx:xxxx::xxxx".
+        :param src_ip: Source ip6 address in packed format.
+        :param dst_ip: Destination ip6 address in packed format.
         :param src_port: Source port number "x".
         :param dst_port: Destination port number "x".
         :type next_hdr: int
@@ -191,52 +147,36 @@ class Classify(object):
         :type dst_ip: str
         :type src_port: int
         :type dst_port: int
-        :returns: IPv6 ACL match data in hexstring format.
+        :returns: IPv6 ACL match data in byte-string format.
         :rtype: str
         """
-        if src_ip:
-            src_ip = binascii.hexlify(ip_address(unicode(src_ip)).packed)
-        if dst_ip:
-            dst_ip = binascii.hexlify(ip_address(unicode(dst_ip)).packed)
-        if dst_port:
-            end = 88
-        elif src_port:
-            end = 84
-        elif dst_ip:
-            end = 80
-        elif src_ip:
-            end = 48
-        else:
-            end = 14
 
         return ('{!s:0>14}{!s:0>34}{!s:0>32}{!s:0>4}{!s:0>4}'.format(
             hex(next_hdr)[2:], src_ip, dst_ip, hex(src_port)[2:],
-            hex(dst_port)[2:]))[0:end]
+            hex(dst_port)[2:])).decode('hex').rstrip('\0')
 
     @staticmethod
-    def _classify_add_del_table(node, is_add, mask, match_n_vectors=1,
-                                table_index=0xFFFFFFFF, nbuckets=2,
-                                memory_size=2097152, skip_n_vectors=0,
-                                next_table_index=0xFFFFFFFF,
-                                miss_next_index=0xFFFFFFFF, current_data_flag=0,
-                                current_data_offset=0):
+    def _classify_add_del_table(
+            node, is_add, mask, match_n_vectors=Constants.BITWISE_NON_ZERO,
+            table_index=Constants.BITWISE_NON_ZERO, nbuckets=2,
+            memory_size=2097152, skip_n_vectors=Constants.BITWISE_NON_ZERO,
+            next_table_index=Constants.BITWISE_NON_ZERO,
+            miss_next_index=Constants.BITWISE_NON_ZERO,
+            current_data_flag=0, current_data_offset=0):
         """Add or delete a classify table.
 
         :param node: VPP node to create classify table.
         :param is_add: If 1 the table is added, if 0 the table is deleted.
         :param mask: ACL mask in hexstring format.
-        :param match_n_vectors: Number of vectors to match (Default value = 1).
-        :param table_index: Index of the classify table.
-            (Default value = 0xFFFFFFFF)
+        :param match_n_vectors: Number of vectors to match (Default value = ~0).
+        :param table_index: Index of the classify table. (Default value = ~0)
         :param nbuckets: Number of buckets when adding a table.
             (Default value = 2)
         :param memory_size: Memory size when adding a table.
             (Default value = 2097152)
-        :param skip_n_vectors: Number of skip vectors (Default value = 0).
-        :param next_table_index: Index of next table.
-            (Default value = 0xFFFFFFFF)
-        :param miss_next_index: Index of miss table.
-            (Default value = 0xFFFFFFFF)
+        :param skip_n_vectors: Number of skip vectors (Default value = ~0).
+        :param next_table_index: Index of next table. (Default value = ~0)
+        :param miss_next_index: Index of miss table. (Default value = ~0)
         :param current_data_flag: Option to use current node's packet payload
             as the starting point from where packets are classified.
             This option is only valid for L2/L3 input ACL for now.
@@ -267,9 +207,7 @@ class Classify(object):
             match_n: Number of match vectors.
         :rtype: tuple(int, int, int)
         """
-        mask_len = ((len(mask) - 1) / 16 + 1) * 16
-        mask = mask + '\0' * (mask_len - len(mask))
-
+        cmd = 'classify_add_del_table'
         args = dict(
             is_add=is_add,
             table_index=table_index,
@@ -281,11 +219,9 @@ class Classify(object):
             miss_next_index=miss_next_index,
             current_data_flag=current_data_flag,
             current_data_offset=current_data_offset,
-            mask_len=mask_len,
+            mask_len=len(mask),
             mask=mask
         )
-
-        cmd = 'classify_add_del_table'
         err_msg = "Failed to create a classify table on host {host}".format(
             host=node['host'])
 
@@ -296,10 +232,11 @@ class Classify(object):
             int(reply["match_n_vectors"])
 
     @staticmethod
-    def _classify_add_del_session(node, is_add, table_index, match,
-                                  opaque_index=0xFFFFFFFF,
-                                  hit_next_index=0xFFFFFFFF, advance=0,
-                                  action=0, metadata=0):
+    def _classify_add_del_session(
+            node, is_add, table_index, match,
+            opaque_index=Constants.BITWISE_NON_ZERO,
+            hit_next_index=Constants.BITWISE_NON_ZERO, advance=0,
+            action=0, metadata=0):
         """Add or delete a classify session.
 
         :param node: VPP node to create classify session.
@@ -309,9 +246,9 @@ class Classify(object):
             include bytes in front with length of skip_n_vectors of target table
             times sizeof (u32x4) (values of those bytes will be ignored).
         :param opaque_index: For add, opaque_index of new session.
-            (Default value = 0xFFFFFFFF)
+            (Default value = ~0)
         :param hit_next_index: For add, hit_next_index of new session.
-            (Default value = 0xFFFFFFFF)
+            (Default value = ~0)
         :param advance: For add, advance value for session. (Default value = 0)
         :param action: 0: No action (by default) metadata is not used.
             1: Classified IP packets will be looked up from the specified ipv4
@@ -337,9 +274,7 @@ class Classify(object):
         :type action: int
         :type metadata: int
         """
-
-        match_len = ((len(match) - 1) / 16 + 1) * 16
-        match = match + '\0' * (match_len - len(match))
+        cmd = 'classify_add_del_session'
         args = dict(
             is_add=is_add,
             table_index=table_index,
@@ -348,10 +283,9 @@ class Classify(object):
             advance=advance,
             action=action,
             metadata=metadata,
-            match_len=match_len,
+            match_len=len(match),
             match=match
         )
-        cmd = 'classify_add_del_session'
         err_msg = "Failed to create a classify session on host {host}".format(
             host=node['host'])
 
@@ -438,18 +372,18 @@ class Classify(object):
             papi_exec.add(cmd, **args).get_reply(err_msg)
 
     @staticmethod
-    def vpp_creates_classify_table_l3(node, ip_version, direction, ip_addr):
+    def vpp_creates_classify_table_l3(node, ip_version, direction, netmask):
         """Create classify table for IP address filtering.
 
         :param node: VPP node to create classify table.
         :param ip_version: Version of IP protocol.
         :param direction: Direction of traffic - src/dst.
-        :param ip_addr: IPv4 or Ipv6 (depending on the parameter 'ip_version')
-            address.
+        :param netmask: IPv4 or Ipv6 (depending on the parameter 'ip_version')
+            netmask (decimal, e.g. 255.255.255.255).
         :type node: dict
         :type ip_version: str
         :type direction: str
-        :type ip_addr: str
+        :type netmask: str
         :returns: (table_index, skip_n, match_n)
             table_index: Classify table index.
             skip_n: Number of skip vectors.
@@ -462,181 +396,114 @@ class Classify(object):
             ip4=Classify._build_ip_mask,
             ip6=Classify._build_ip6_mask
         )
+
         if ip_version == "ip4" or ip_version == "ip6":
-            ip_addr = binascii.hexlify(ip_address(unicode(ip_addr)).packed)
+            netmask = binascii.hexlify(ip_address(unicode(netmask)).packed)
         else:
-            raise ValueError("IP version {ver} is not supported.".
-                             format(ver=ip_version))
+            raise ValueError("IP version {ver} is not supported.".format(
+                ver=ip_version))
 
         if direction == "src":
-            mask = mask_f[ip_version](src_ip=ip_addr)
+            mask = mask_f[ip_version](src_ip=netmask)
         elif direction == "dst":
-            mask = mask_f[ip_version](dst_ip=ip_addr)
+            mask = mask_f[ip_version](dst_ip=netmask)
         else:
-            raise ValueError("Direction {dir} is not supported.".
-                             format(dir=direction))
+            raise ValueError("Direction {dir} is not supported.".format(
+                dir=direction))
 
-        return Classify._classify_add_del_table(
-            node,
-            is_add=1,
-            mask=binascii.unhexlify(mask),
-            match_n_vectors=(len(mask) - 1) // 32 + 1
-        )
+        # Add l2 ethernet header to mask
+        mask = 14 * '\0' + mask
 
-    @staticmethod
-    def vpp_creates_classify_table_l2(node, direction, mac=""):
-        """Create classify table for MAC address filtering.
+        # Get index of the first significant mask octet
+        i = len(mask) - len(mask.lstrip('\0'))
 
-        :param node: VPP node to create classify table.
-        :param direction: Direction of traffic - src/dst.
-        :param mac: Source or destination (depending on the parameter
-            'direction') MAC address.
-        :type node: dict
-        :type direction: str
-        :type mac: str
-        :returns: (table_index, skip_n, match_n)
-            table_index: Classify table index.
-            skip_n: Number of skip vectors.
-            match_n: Number of match vectors.
-        :rtype: tuple(int, int, int)
-        :raises ValueError: If the parameter 'direction' has incorrect value.
-        """
-        if direction == "src":
-            mask = Classify._build_mac_mask(src_mac=mac)
-        elif direction == "dst":
-            mask = Classify._build_mac_mask(dst_mac=mac)
-        else:
-            raise ValueError("Direction {dir} is not supported.".
-                             format(dir=direction))
-
-        return Classify._classify_add_del_table(
-            node,
-            is_add=1,
-            mask=binascii.unhexlify(mask),
-            match_n_vectors=(len(mask) - 1) // 32 + 1
-        )
-
-    @staticmethod
-    def vpp_creates_classify_table_hex(node, hex_mask):
-        """Create classify table with hex mask.
+        # Compute skip_n parameter
+        skip_n = i // 16
+        # Remove octets to be skipped from the mask
+        mask = mask[skip_n*16:]
+        # Pad mask to an even multiple of the vector size
+        mask = mask + (16 - len(mask) % 16 if len(mask) % 16 else 0) * '\0'
+        # Compute match_n parameter
+        match_n = len(mask) // 16
 
-        :param node: VPP node to create classify table based on hex mask.
-        :param hex_mask: Classify hex mask.
-        :type node: dict
-        :type hex_mask: str
-        :returns: (table_index, skip_n, match_n)
-            table_index: Classify table index.
-            skip_n: Number of skip vectors.
-            match_n: Number of match vectors.
-        :rtype: tuple(int, int, int)
-        """
         return Classify._classify_add_del_table(
             node,
             is_add=1,
-            mask=binascii.unhexlify(hex_mask),
-            match_n_vectors=(len(hex_mask) - 1) // 32 + 1
+            mask=mask,
+            match_n_vectors=match_n,
+            skip_n_vectors=skip_n
         )
 
     @staticmethod
-    def vpp_configures_classify_session_l3(node, acl_method, table_index,
-                                           ip_version, direction, address):
+    def vpp_configures_classify_session_l3(
+            node, acl_method, table_index, skip_n, match_n, ip_version,
+            direction, address, hit_next_index=Constants.BITWISE_NON_ZERO,
+            opaque_index=Constants.BITWISE_NON_ZERO):
         """Configuration of classify session for IP address filtering.
 
         :param node: VPP node to setup classify session.
         :param acl_method: ACL method - deny/permit.
         :param table_index: Classify table index.
+        :param skip_n: Number of skip vectors.
+        :param match_n: Number of vectors to match.
         :param ip_version: Version of IP protocol.
         :param direction: Direction of traffic - src/dst.
         :param address: IPv4 or IPv6 address.
+        :param hit_next_index: hit_next_index of new session.
+            (Default value = ~0)
+        :param opaque_index: opaque_index of new session. (Default value = ~0)
         :type node: dict
         :type acl_method: str
         :type table_index: int
+        :type skip_n: int
+        :type match_n: int
         :type ip_version: str
         :type direction: str
         :type address: str
+        :type hit_next_index: int
+        :type opaque_index: int
         :raises ValueError: If the parameter 'direction' has incorrect value.
         """
         match_f = dict(
             ip4=Classify._build_ip_match,
             ip6=Classify._build_ip6_match
         )
-        if direction == "src":
-            match = match_f[ip_version](src_ip=address)
-        elif direction == "dst":
-            match = match_f[ip_version](dst_ip=address)
-        else:
-            raise ValueError("Direction {dir} is not supported.".
-                             format(dir=direction))
         action = dict(
             permit=0,
             deny=1
         )
-        Classify._classify_add_del_session(
-            node,
-            is_add=1,
-            table_index=table_index,
-            match=binascii.unhexlify(match),
-            action=action[acl_method])
 
-    @staticmethod
-    def vpp_configures_classify_session_l2(node, acl_method, table_index,
-                                           direction, address):
-        """Configuration of classify session for MAC address filtering.
+        if ip_version == "ip4" or ip_version == "ip6":
+            address = binascii.hexlify(ip_address(unicode(address)).packed)
+        else:
+            raise ValueError("IP version {ver} is not supported.".format(
+                ver=ip_version))
 
-        :param node: VPP node to setup classify session.
-        :param acl_method: ACL method - deny/permit.
-        :param table_index: Classify table index.
-        :param direction: Direction of traffic - src/dst.
-        :param address: MAC address.
-        :type node: dict
-        :type acl_method: str
-        :type table_index: int
-        :type direction: str
-        :type address: str
-        :raises ValueError: If the parameter 'direction' has incorrect value.
-        """
         if direction == "src":
-            match = Classify._build_mac_match(src_mac=address)
+            match = match_f[ip_version](src_ip=address)
         elif direction == "dst":
-            match = Classify._build_mac_match(dst_mac=address)
+            match = match_f[ip_version](dst_ip=address)
         else:
-            raise ValueError("Direction {dir} is not supported.".
-                             format(dir=direction))
-        action = dict(
-            permit=0,
-            deny=1
-        )
-        Classify._classify_add_del_session(
-            node,
-            is_add=1,
-            table_index=table_index,
-            match=binascii.unhexlify(match),
-            action=action[acl_method])
+            raise ValueError("Direction {dir} is not supported.".format(
+                dir=direction))
 
-    @staticmethod
-    def vpp_configures_classify_session_hex(node, acl_method, table_index,
-                                            hex_value):
-        """Configuration of classify session with hex value.
+        # Prepend match with l2 ethernet header part
+        match = 14 * '\0' + match
+
+        # Pad match to match skip_n_vector + match_n_vector size
+        match = match + ((match_n + skip_n) * 16 - len(match)
+                         if len(match) < (match_n + skip_n) * 16
+                         else 0) * '\0'
 
-        :param node: VPP node to setup classify session.
-        :param acl_method: ACL method - deny/permit.
-        :param table_index: Classify table index.
-        :param hex_value: Classify hex value.
-        :type node: dict
-        :type acl_method: str
-        :type table_index: int
-        :type hex_value: str
-        """
-        action = dict(
-            permit=0,
-            deny=1
-        )
         Classify._classify_add_del_session(
             node,
             is_add=1,
             table_index=table_index,
-            match=binascii.unhexlify(hex_value),
-            action=action[acl_method])
+            hit_next_index=hit_next_index,
+            opaque_index=opaque_index,
+            match=match,
+            action=action[acl_method]
+        )
 
     @staticmethod
     def compute_classify_hex_mask(ip_version, protocol, direction):
@@ -756,6 +623,18 @@ class Classify(object):
 
         return details
 
+    @staticmethod
+    def show_classify_tables_verbose(node):
+        """Show classify tables verbose.
+
+        :param node: Topology node.
+        :type node: dict
+        :returns: Classify tables verbose data.
+        :rtype: str
+        """
+        return PapiSocketExecutor.run_cli_cmd(
+            node, "show classify tables verbose")
+
     @staticmethod
     def vpp_log_plugin_acl_settings(node):
         """Retrieve configured settings from the ACL plugin and write to robot
index d651e78..60d35a8 100644 (file)
@@ -442,7 +442,7 @@ class PapiSocketExecutor(object):
         cmd = 'cli_inband'
         args = dict(cmd=cli_cmd)
         err_msg = "Failed to run 'cli_inband {cmd}' PAPI command on host " \
-                  "{host}".format(host=node['host'], cmd=cmd)
+                  "{host}".format(host=node['host'], cmd=cli_cmd)
         with PapiSocketExecutor(node, remote_vpp_socket) as papi_exec:
             reply = papi_exec.add(cmd, **args).get_reply(err_msg)["reply"]
         if log:
index 9e14a4f..a51f996 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 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:
 
 """Policer utilities library."""
 
-from enum import Enum
+from enum import IntEnum
 
-from ipaddress import ip_address
-
-from resources.libraries.python.VatExecutor import VatExecutor
-from resources.libraries.python.VatJsonUtil import VatJsonUtil
+from resources.libraries.python.Constants import Constants
+from resources.libraries.python.PapiExecutor import PapiSocketExecutor
 from resources.libraries.python.topology import Topology
 
 
-class PolicerRateType(Enum):
+class PolicerRateType(IntEnum):
     """Policer rate types."""
-    KBPS = 'kbps'
-    PPS = 'pps'
-
-    def __init__(self, string):
-        self.string = string
+    KBPS = 0
+    PPS = 1
+    INVALID = 2
 
 
-# pylint: disable=invalid-name
-class PolicerRoundType(Enum):
+class PolicerRoundType(IntEnum):
     """Policer round types."""
-    CLOSEST = 'closest'
-    UP = 'up'
-    DOWN = 'down'
-
-    def __init__(self, string):
-        self.string = string
+    ROUND_TO_CLOSEST = 0
+    ROUND_TO_UP = 1
+    ROUND_TO_DOWN = 2
+    ROUND_TO_INVALID = 3
 
 
-class PolicerType(Enum):
+class PolicerType(IntEnum):
     """Policer type."""
-    P_1R2C = '1r2c'
-    P_1R3C = '1r3c'
-    P_2R3C_2698 = '2r3c-2698'
-    P_2R3C_4115 = '2r3c-4115'
-    P_2R3C_MEF5CF1 = '2r3c-mef5cf1'
+    TYPE_1R2C = 0
+    TYPE_1R3C_RFC_2697 = 1
+    TYPE_2R3C_RFC_2698 = 2
+    TYPE_2R3C_RFC_4115 = 3
+    TYPE_2R3C_RFC_MEF5CF1 = 4
+    TYPE_MAX = 5
 
-    def __init__(self, string):
-        self.string = string
 
-
-class PolicerAction(Enum):
+class PolicerAction(IntEnum):
     """Policer action."""
-    DROP = 'drop'
-    TRANSMIT = 'transmit'
-    MARK_AND_TRANSMIT = 'mark-and-transmit'
-
-    def __init__(self, string):
-        self.string = string
-
-
-class DSCP(Enum):
-    """DSCP for mark-and-transmit action."""
-    CS0 = ('CS0', 0)
-    CS1 = ('CS1', 8)
-    CS2 = ('CS2', 16)
-    CS3 = ('CS3', 24)
-    CS4 = ('CS4', 32)
-    CS5 = ('CS5', 40)
-    CS6 = ('CS6', 48)
-    CS7 = ('CS7', 56)
-    AF11 = ('AF11', 10)
-    AF12 = ('AF12', 12)
-    AF13 = ('AF13', 14)
-    AF21 = ('AF21', 18)
-    AF22 = ('AF22', 20)
-    AF23 = ('AF23', 22)
-    AF31 = ('AF31', 26)
-    AF32 = ('AF32', 28)
-    AF33 = ('AF33', 30)
-    EF = ('EF', 46)
-
-    def __init__(self, string, num):
-        self.string = string
-        self.num = num
-
+    DROP = 0
+    TRANSMIT = 1
+    MARK_AND_TRANSMIT = 2
 
-class PolicerClassifyPreColor(Enum):
-    """Policer classify precolor."""
-    CONFORM_COLOR = 'conform-color'
-    EXCEED_COLOR = 'exceed-color'
 
-    def __init__(self, string):
-        self.string = string
+class PolicerPreColor(IntEnum):
+    """Policer Pre-color."""
+    CONFORM_COLOR = 0
+    EXCEED_COLOR = 1
+    VIOLATE_COLOR = 2
 
 
-class PolicerClassifyTableType(Enum):
-    """Policer classify table type."""
-    IP4_TABLE = 'ip4-table'
-    IP6_TABLE = 'ip6-table'
-    L2_TABLE = 'l2-table'
-
-    def __init__(self, string):
-        self.string = string
+class DSCP(IntEnum):
+    """DSCP for mark-and-transmit action."""
+    D_CS0 = 0
+    D_CS1 = 8
+    D_CS2 = 16
+    D_CS3 = 24
+    D_CS4 = 32
+    D_vCS5 = 40
+    D_CS6 = 48
+    D_CS7 = 56
+    D_AF11 = 10
+    D_AF12 = 12
+    D_AF13 = 14
+    D_AF21 = 18
+    D_AF22 = 20
+    D_AF23 = 22
+    D_AF31 = 26
+    D_AF32 = 28
+    D_AF33 = 30
+    D_EF = 46
 
 
 class Policer(object):
     """Policer utilities."""
 
-    def __init__(self):
-        self._cir = 0
-        self._eir = 0
-        self._cb = 0
-        self._eb = 0
-        self._rate_type = None
-        self._round_type = None
-        self._policer_type = None
-        self._conform_action = None
-        self._conform_dscp = None
-        self._exceed_action = None
-        self._exceed_dscp = None
-        self._violate_action = None
-        self._violate_dscp = None
-        self._color_aware = False
-        self._classify_match_ip = ''
-        self._classify_match_is_src = True
-        self._classify_precolor = None
-        self._sw_if_index = 0
-        self._node = None
-        self._policer_name = ''
-
-    def policer_set_configuration(self):
+    # pylint: disable=too-many-arguments, too-many-locals
+    @staticmethod
+    def policer_set_configuration(
+            node, policer_name, cir, eir, cbs, ebs, rate_type, round_type,
+            policer_type, conform_action_type, exceed_action_type,
+            violate_action_type, color_aware, is_add=True, conform_dscp=None,
+            exceed_dscp=None, violate_dscp=None):
         """Configure policer on VPP node.
 
-        ...note:: First set all required parameters.
-        """
-        node = self._node
-
-        # create policer
-        color_aware = 'color-aware' if self._color_aware else ''
-
-        conform_action = self._conform_action.value
-
-        if PolicerAction.MARK_AND_TRANSMIT == self._conform_action:
-            conform_action += ' {0}'.format(self._conform_dscp.string)
-
-        exceed_action = self._exceed_action.value
-        if PolicerAction.MARK_AND_TRANSMIT == self._exceed_action:
-            exceed_action += ' {0}'.format(self._exceed_dscp.string)
-
-        violate_action = self._violate_action.value
-        if PolicerAction.MARK_AND_TRANSMIT == self._violate_action:
-            violate_action += ' {0}'.format(self._violate_dscp.string)
-
-        out = VatExecutor.cmd_from_template(node,
-                                            "policer/policer_add_3c.vat",
-                                            name=self._policer_name,
-                                            cir=self._cir,
-                                            eir=self._eir,
-                                            cb=self._cb,
-                                            eb=self._eb,
-                                            rate_type=self._rate_type.value,
-                                            round_type=self._round_type.value,
-                                            p_type=self._policer_type.value,
-                                            conform_action=conform_action,
-                                            exceed_action=exceed_action,
-                                            violate_action=violate_action,
-                                            color_aware=color_aware)
-
-        VatJsonUtil.verify_vat_retval(
-            out[0],
-            err_msg='Add policer {0} failed on {1}'.format(self._policer_name,
-                                                           node['host']))
-
-        policer_index = out[0].get('policer_index')
-
-        # create classify table
-        direction = 'src' if self._classify_match_is_src else 'dst'
-
-        if ip_address(unicode(self._classify_match_ip)).version == 6:
-            ip_version = 'ip6'
-            table_type = PolicerClassifyTableType.IP6_TABLE
-        else:
-            ip_version = 'ip4'
-            table_type = PolicerClassifyTableType.IP4_TABLE
-
-        out = VatExecutor.cmd_from_template(node,
-                                            "classify_add_table.vat",
-                                            ip_version=ip_version,
-                                            direction=direction)
-
-        VatJsonUtil.verify_vat_retval(
-            out[0],
-            err_msg='Add classify table failed on {0}'.format(node['host']))
-
-        new_table_index = out[0].get('new_table_index')
-        skip_n_vectors = out[0].get('skip_n_vectors')
-        match_n_vectors = out[0].get('match_n_vectors')
-
-        # create classify session
-        match = 'l3 {0} {1} {2}'.format(ip_version,
-                                        direction,
-                                        self._classify_match_ip)
-
-        out = VatExecutor.cmd_from_template(
-            node,
-            "policer/policer_classify_add_session.vat",
-            policer_index=policer_index,
-            pre_color=self._classify_precolor.value,
-            table_index=new_table_index,
-            skip_n=skip_n_vectors,
-            match_n=match_n_vectors,
-            match=match)
-
-        VatJsonUtil.verify_vat_retval(
-            out[0],
-            err_msg='Add classify session failed on {0}'.format(node['host']))
-
-        # set classify interface
-        out = VatExecutor.cmd_from_template(
-            node,
-            "policer/policer_classify_set_interface.vat",
-            sw_if_index=self._sw_if_index,
-            table_type=table_type.value,
-            table_index=new_table_index)
-
-        VatJsonUtil.verify_vat_retval(
-            out[0],
-            err_msg='Set classify interface failed on {0}'.format(node['host']))
-
-    def policer_clear_settings(self):
-        """Clear policer settings."""
-        self._cir = 0
-        self._eir = 0
-        self._cb = 0
-        self._eb = 0
-        self._rate_type = None
-        self._round_type = None
-        self._policer_type = None
-        self._conform_action = None
-        self._conform_dscp = None
-        self._exceed_action = None
-        self._exceed_dscp = None
-        self._violate_action = None
-        self._violate_dscp = None
-        self._color_aware = False
-        self._classify_match_ip = ''
-        self._classify_match_is_src = True
-        self._classify_precolor = None
-        self._sw_if_index = 0
-        self._node = None
-        self._policer_name = ''
-
-    def policer_set_name(self, name):
-        """Set policer name.
-
-        :param name: Policer name.
-        :type name: str
-        """
-        self._policer_name = name
-
-    def policer_set_node(self, node):
-        """Set node to setup policer on.
-
         :param node: VPP node.
+        :param policer_name: Name of the policer.
+        :param cir: Committed information rate.
+        :param eir: Excess (or Peak) information rate.
+        :param cbs: Committed burst size.
+        :param ebs: Excess (or Peak) burst size.
+        :param rate_type: Rate type.
+        :param round_type: Round type.
+        :param policer_type: Policer algorithm.
+        :param conform_action_type: Conform action type.
+        :param exceed_action_type: Exceed action type.
+        :param violate_action_type: Violate action type.
+        :param color_aware: Color-blind (cb) or color-aware (ca).
+        :param is_add: Add policer if True, else delete.
+        :param conform_dscp: DSCP for conform mark_and_transmit action.
+        :param exceed_dscp: DSCP for exceed mark_and_transmit action.
+        :param violate_dscp: DSCP for vilate mark_and_transmit action.
         :type node: dict
-        """
-        self._node = node
-
-    def policer_set_cir(self, cir):
-        """Set policer CIR.
-
-        :param cir: Committed Information Rate.
+        :type policer_name: str
         :type cir: int
-        """
-        self._cir = cir
-
-    def policer_set_eir(self, eir):
-        """Set polcier EIR.
-
-        :param eir: Excess Information Rate.
         :type eir: int
-        """
-        self._eir = eir
-
-    def policer_set_cb(self, cb):
-        """Set policer CB.
-
-        :param cb: Committed Burst size.
-        :type cb: int or str
-        """
-        if cb == "IMIX_v4_1":
-            self._cb = 1518
-        else:
-            self._cb = cb
-
-    def policer_set_eb(self, eb):
-        """Set policer EB.
-
-        :param eb: Excess Burst size.
-        :type eb: int or str
-        """
-        if eb == "IMIX_v4_1":
-            self._eb = 1518
-        else:
-            self._eb = eb
-
-    def policer_set_rate_type_kbps(self):
-        """Set policer rate type to kbps."""
-        self._rate_type = PolicerRateType.KBPS
-
-    def policer_set_rate_type_pps(self):
-        """Set policer rate type to pps."""
-        self._rate_type = PolicerRateType.PPS
-
-    def policer_set_round_type_closest(self):
-        """Set policer round type to closest."""
-        self._round_type = PolicerRoundType.CLOSEST
-
-    def policer_set_round_type_up(self):
-        """Set policer round type to up."""
-        self._round_type = PolicerRoundType.UP
-
-    def policer_set_round_type_down(self):
-        """Set policer round type to down."""
-        self._round_type = PolicerRoundType.DOWN
-
-    def policer_set_type_1r2c(self):
-        """Set policer type to 1r2c."""
-        self._policer_type = PolicerType.P_1R2C
-
-    def policer_set_type_1r3c(self):
-        """Set policer type to 1r3c RFC2697."""
-        self._policer_type = PolicerType.P_1R3C
-
-    def policer_set_type_2r3c_2698(self):
-        """Set policer type to 2r3c RFC2698."""
-        self._policer_type = PolicerType.P_2R3C_2698
-
-    def policer_set_type_2r3c_4115(self):
-        """Set policer type to 2r3c RFC4115."""
-        self._policer_type = PolicerType.P_2R3C_4115
-
-    def policer_set_type_2r3c_mef5cf1(self):
-        """Set policer type to 2r3c MEF5CF1."""
-        self._policer_type = PolicerType.P_2R3C_MEF5CF1
-
-    def policer_set_conform_action_drop(self):
-        """Set policer conform-action to drop."""
-        self._conform_action = PolicerAction.DROP
-
-    def policer_set_conform_action_transmit(self):
-        """Set policer conform-action to transmit."""
-        self._conform_action = PolicerAction.TRANSMIT
-
-    def policer_set_conform_action_mark_and_transmit(self, dscp):
-        """Set policer conform-action to mark-and-transmit.
-
-        :param dscp: DSCP value to mark.
-        :type dscp: DSCP
-        """
-        self._conform_action = PolicerAction.MARK_AND_TRANSMIT
-        self._conform_dscp = dscp
-
-    def policer_set_exceed_action_drop(self):
-        """Set policer exceed-action to drop."""
-        self._exceed_action = PolicerAction.DROP
-
-    def policer_set_exceed_action_transmit(self):
-        """Set policer exceed-action to transmit."""
-        self._exceed_action = PolicerAction.TRANSMIT
-
-    def policer_set_exceed_action_mark_and_transmit(self, dscp):
-        """Set policer exceed-action to mark-and-transmit.
-
-        :param dscp: DSCP value to mark.
-        :type dscp: DSCP
-        """
-        self._exceed_action = PolicerAction.MARK_AND_TRANSMIT
-        self._exceed_dscp = dscp
-
-    def policer_set_violate_action_drop(self):
-        """Set policer violate-action to drop."""
-        self._violate_action = PolicerAction.DROP
-
-    def policer_set_violate_action_transmit(self):
-        """Set policer violate-action to transmit."""
-        self._violate_action = PolicerAction.TRANSMIT
-
-    def policer_set_violate_action_mark_and_transmit(self, dscp):
-        """Set policer violate-action to mark-and-transmit.
+        :type cbs: int
+        :type ebs: int
+        :type rate_type: str
+        :type round_type: str
+        :type policer_type: str
+        :type conform_action_type: str
+        :type exceed_action_type: str
+        :type violate_action_type: str
+        :type color_aware: str
+        :type is_add: bool
+        :type conform_dscp: str
+        :type exceed_dscp: str
+        :type violate_dscp: str
+        """
+        cmd = 'policer_add_del'
+        args = dict(
+            is_add=int(is_add),
+            name=str(policer_name),
+            cir=int(cir),
+            eir=int(eir),
+            cb=int(cbs),
+            eb=int(ebs),
+            rate_type=getattr(PolicerRateType, rate_type.upper()).value,
+            round_type=getattr(
+                PolicerRoundType, 'ROUND_TO_{rt}'.format(
+                    rt=round_type.upper())).value,
+            type=getattr(PolicerType, 'TYPE_{pt}'.format(
+                pt=policer_type.upper())).value,
+            conform_action_type=getattr(
+                PolicerAction, conform_action_type.upper()).value,
+            conform_dscp=getattr(DSCP, 'D_{dscp}'.format(
+                dscp=conform_dscp.upper())).value
+            if
+            conform_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
+            else 0,
+            exceed_action_type=getattr(
+                PolicerAction, exceed_action_type.upper()).value,
+            exceed_dscp=getattr(DSCP, 'D_{dscp}'.format(
+                dscp=exceed_dscp.upper())).value
+            if
+            exceed_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
+            else 0,
+            violate_action_type=getattr(
+                PolicerAction, violate_action_type.upper()).value,
+            violate_dscp=getattr(DSCP, 'D_{dscp}'.format(
+                dscp=violate_dscp.upper())).value
+            if
+            violate_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
+            else 0,
+            color_aware=1 if color_aware == "'ca'" else 0
+        )
+        err_msg = 'Failed to configure policer {pn} on host {host}'.format(
+            pn=policer_name, host=node['host'])
+
+        with PapiSocketExecutor(node) as papi_exec:
+            reply = papi_exec.add(cmd, **args).get_reply(err_msg)
+
+        return reply['policer_index']
+
+    @staticmethod
+    def policer_classify_set_interface(
+            node, interface, ip4_table_index=Constants.BITWISE_NON_ZERO,
+            ip6_table_index=Constants.BITWISE_NON_ZERO,
+            l2_table_index=Constants.BITWISE_NON_ZERO, is_add=1):
+        """Set/unset policer classify interface.
 
-        :param dscp: DSCP value to mark.
-        :type dscp: DSCP
-        """
-        self._violate_action = PolicerAction.MARK_AND_TRANSMIT
-        self._violate_dscp = dscp
-
-    def policer_enable_color_aware(self):
-        """Enable color-aware mode for policer."""
-        self._color_aware = True
-
-    def policer_classify_set_precolor_conform(self):
-        """Set policer classify pre-color to conform-color."""
-        self._classify_precolor = PolicerClassifyPreColor.CONFORM_COLOR
-
-    def policer_classify_set_precolor_exceed(self):
-        """Set policer classify pre-color to exceeed-color."""
-        self._classify_precolor = PolicerClassifyPreColor.EXCEED_COLOR
-
-    def policer_classify_set_interface(self, interface):
-        """Set policer classify interface.
-
-        .. note:: First set node with policer_set_node.
-
-        :param interface: Interface name or sw_if_index.
+        :param node: VPP node.
+        :param interface: Interface name or sw_if_index to set/unset policer
+            classify.
+        :param ip4_table_index: IP4 classify table index (~0 to skip).
+            (Default value = ~0)
+        :param ip6_table_index: IP6 classify table index (~0 to skip).
+            (Default value = ~0)
+        :param l2_table_index: L2 classify table index (~0 to skip).
+            (Default value = ~0)
+        :param is_add: Set if non-zero, else unset.
+        :type node: dict
         :type interface: str or int
+        :type ip4_table_index: int
+        :type ip6_table_index: int
+        :type l2_table_index: int
         """
         if isinstance(interface, basestring):
-            self._sw_if_index = Topology.get_interface_sw_index(self._node,
-                                                                interface)
+            sw_if_index = Topology.get_interface_sw_index(node, interface)
         else:
-            self._sw_if_index = interface
-
-    def policer_classify_set_match_ip(self, ip, is_src=True):
-        """Set policer classify match source IP address.
-
-        :param ip: IPv4 or IPv6 address.
-        :param is_src: Match src IP if True otherwise match dst IP.
-        :type ip: str
-        :type is_src: bool
-        """
-        self._classify_match_ip = ip
-        self._classify_match_is_src = is_src
-
-    @staticmethod
-    def dscp_cs0():
-        """Return DSCP CS0.
-
-        :returns: DSCP enum CS0 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS0
-
-    @staticmethod
-    def dscp_cs1():
-        """Return DSCP CS1.
-
-        :returns: DSCP enum CS1 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS1
-
-    @staticmethod
-    def dscp_cs2():
-        """Return DSCP CS2.
-
-        :returns: DSCP enum CS2 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS2
-
-    @staticmethod
-    def dscp_cs3():
-        """Return DSCP CS3.
-
-        :returns: DSCP enum CS3 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS3
-
-    @staticmethod
-    def dscp_cs4():
-        """Return DSCP CS4.
-
-        :returns: DSCP enum CS4 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS4
-
-    @staticmethod
-    def dscp_cs5():
-        """Return DSCP CS5.
-
-        :returns: DSCP enum CS5 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS5
-
-    @staticmethod
-    def dscp_cs6():
-        """Return DSCP CS6.
-
-        :returns: DSCP enum CS6 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS6
-
-    @staticmethod
-    def dscp_cs7():
-        """Return DSCP CS7.
-
-        :returns: DSCP enum CS7 object.
-        :rtype: DSCP
-        """
-        return DSCP.CS7
-
-    @staticmethod
-    def dscp_ef():
-        """Return DSCP EF.
-
-        :returns: DSCP enum EF object.
-        :rtype: DSCP
-        """
-        return DSCP.EF
-
-    @staticmethod
-    def dscp_af11():
-        """Return DSCP AF11.
-
-        :returns: DSCP enum AF11 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF11
-
-    @staticmethod
-    def dscp_af12():
-        """Return DSCP AF12.
+            sw_if_index = interface
 
-        :returns: DSCP enum AF12 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF12
+        cmd = 'policer_classify_set_interface'
 
-    @staticmethod
-    def dscp_af13():
-        """Return DSCP AF13.
+        args = dict(
+            is_add=int(is_add),
+            sw_if_index=sw_if_index,
+            ip4_table_index=int(ip4_table_index),
+            ip6_table_index=int(ip6_table_index),
+            l2_table_index=int(l2_table_index)
+        )
+        err_msg = 'Failed to set/unset policer classify interface {ifc} ' \
+                  'on host {host}'.format(ifc=interface, host=node['host'])
 
-        :returns: DSCP enum AF13 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF13
+        with PapiSocketExecutor(node) as papi_exec:
+            papi_exec.add(cmd, **args).get_reply(err_msg)
 
     @staticmethod
-    def dscp_af21():
-        """Return DSCP AF21.
-
-        :returns: DSCP enum AF21 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF21
+    def policer_classify_get_precolor(precolor):
+        """Return policer pre-color numeric value.
 
-    @staticmethod
-    def dscp_af22():
-        """Return DSCP AF22.
-
-        :returns: DSCP enum AF22 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF22
-
-    @staticmethod
-    def dscp_af23():
-        """Return DSCP AF23.
-
-        :returns: DSCP enum AF23 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF23
-
-    @staticmethod
-    def dscp_af31():
-        """Return DSCP AF31.
-
-        :returns: DSCP enum AF31 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF31
-
-    @staticmethod
-    def dscp_af32():
-        """Return DSCP AF32.
-
-        :returns: DSCP enum AF32 object.
-        :rtype: DSCP
-        """
-        return DSCP.AF32
-
-    @staticmethod
-    def dscp_af33():
-        """Return DSCP AF33.
-
-        :returns: DSCP enum AF33 object.
-        :rtype: DSCP
+        :param precolor: Policer pre-color name.
+        :type precolor: str
+        :returns: Policer pre-color numeric value.
+        :rtype: int
         """
-        return DSCP.AF33
+        return getattr(PolicerPreColor, precolor.upper()).value
 
     @staticmethod
     def get_dscp_num_value(dscp):
         """Return DSCP numeric value.
 
-        :param dscp: DSCP enum object.
-        :type dscp: DSCP
+        :param dscp: DSCP name.
+        :type dscp: str
         :returns: DSCP numeric value.
         :rtype: int
         """
-        return dscp.num
+        return getattr(DSCP, 'D_{dscp}'.format(dscp=dscp.upper())).value
index 111b932..962f4cf 100644 (file)
@@ -12,6 +12,7 @@
 # limitations under the License.
 
 *** Settings ***
+| Library | resources.libraries.python.Classify
 | Library | resources.libraries.python.Policer
 | ...
 | Documentation | Policer keywords
 | | ... | on all DUT nodes in 2-node / 3-node circular topology. Policer is
 | | ... | applied on links TG - DUTx.
 | | ...
-| | ${dscp}= | DSCP AF22
-| | Policer Set Name | policer1
-| | Policer Set CIR | ${cir}
-| | Policer Set EIR | ${eir}
-| | Policer Set CB | ${cb}
-| | Policer Set EB | ${eb}
-| | Policer Set Rate Type pps
-| | Policer Set Round Type Closest
-| | Policer Set Type 2R3C 2698
-| | Policer Set Conform Action Transmit
-| | Policer Set Exceed Action Mark and Transmit | ${dscp}
-| | Policer Set Violate Action Transmit
-| | Policer Enable Color Aware
-| | Run Keyword If | ${t} == 'ca' | Policer Enable Color Aware
-| | Policer Classify Set Precolor Exceed
-| | Policer Set Node | ${dut1}
-| | Policer Classify Set Interface | ${dut1_if1}
-| | Policer Classify Set Match IP | 20.20.20.2 | ${False}
-| | Policer Set Configuration
+| | ${policer_index}= | Policer Set Configuration | ${dut1} | policer1 | ${cir}
+| | ... | ${eir} | ${cb} | ${eb} | pps | Closest | 2R3C_RFC_2698 | Transmit
+| | ... | Mark_and_Transmit | Transmit | ${t} | exceed_dscp=${dscp}
+| | ${table_idx} | ${skip_n} | ${match_n}= | Vpp Creates Classify Table L3
+| | ... | ${dut1} | ip4 | dst | 255.255.255.255
+| | ${pre_color}= | Policer Classify Get Precolor | exceed_color
+| | Vpp Configures Classify Session L3 | ${dut1} | permit | ${table_idx}
+| | ... | ${skip_n} | ${match_n} | ip4 | dst | 20.20.20.2
+| | ... | hit_next_index=${policer_index} | opaque_index=${pre_color}
+| | Policer Classify Set Interface | ${dut1} | ${dut1_if1}
+| | ... | ip4_table_index=${table_idx}
+| | ...
 | | ${dut2_status} | ${value}= | Run Keyword And Ignore Error
 | | ... | Variable Should Exist | ${dut2}
 | | ${dut}= | Run Keyword If | '${dut2_status}' == 'PASS'
 | | ${dut_if2}= | Run Keyword If | '${dut2_status}' == 'PASS'
 | | ... | Set Variable | ${dut2_if2}
 | | ... | ELSE | Set Variable | ${dut1_if2}
-| | Run Keyword Unless | '${dut2_status}' == 'PASS'
-| | ... | Policer Set Name | policer2
-| | Policer Set Node | ${dut}
-| | Policer Classify Set Interface | ${dut_if2}
-| | Policer Classify Set Match IP | 10.10.10.2 | ${False}
-| | Policer Set Configuration
+| | ...
+| | ${policer_index}= | Run Keyword If | '${dut2_status}' == 'PASS'
+| | ... | Policer Set Configuration | ${dut} | policer2 | ${cir}
+| | ... | ${eir} | ${cb} | ${eb} | pps | Closest | 2R3C_RFC_2698 | Transmit
+| | ... | Mark_and_Transmit | Transmit | ${t} | exceed_dscp=${dscp}
+| | ... | ELSE | Set Variable | ${policer_index}
+| | ${table_idx} | ${skip_n} | ${match_n}=
+| | ... | Run Keyword If | '${dut2_status}' == 'PASS'
+| | ... | Vpp Creates Classify Table L3 | ${dut} | ip4 | dst | 255.255.255.255
+| | ... | ELSE | Set Variable | ${table_idx} | ${skip_n} | ${match_n}
+| | Vpp Configures Classify Session L3 | ${dut} | permit | ${table_idx}
+| | ... | ${skip_n} | ${match_n} | ip4 | dst | 10.10.10.2
+| | ... | hit_next_index=${policer_index} | opaque_index=${pre_color}
+| | Policer Classify Set Interface | ${dut} | ${dut_if2}
+| | ... | ip4_table_index=${table_idx}
 
 | Initialize IPv6 policer 2r3c-${t} in circular topology
 | | [Documentation]
 | | ... | on all DUT nodes in 2-node / 3-node circular topology. Policer is
 | | ... | applied on links TG - DUTx.
 | | ...
-| | ${dscp}= | DSCP AF22
-| | Policer Set Name | policer1
-| | Policer Set CIR | ${cir}
-| | Policer Set EIR | ${eir}
-| | Policer Set CB | ${cb}
-| | Policer Set EB | ${eb}
-| | Policer Set Rate Type pps
-| | Policer Set Round Type Closest
-| | Policer Set Type 2R3C 2698
-| | Policer Set Conform Action Transmit
-| | Policer Set Exceed Action Mark and Transmit | ${dscp}
-| | Policer Set Violate Action Transmit
-| | Policer Enable Color Aware
-| | Run Keyword If | ${t} == 'ca' | Policer Enable Color Aware
-| | Policer Classify Set Precolor Exceed
-| | Policer Set Node | ${dut1}
-| | Policer Classify Set Interface | ${dut1_if1}
-| | Policer Classify Set Match IP | 2001:2::2 | ${False}
-| | Policer Set Configuration
+| | ${policer_index}= | Policer Set Configuration | ${dut1} | policer1 | ${cir}
+| | ... | ${eir} | ${cb} | ${eb} | pps | Closest | 2R3C_RFC_2698 | Transmit
+| | ... | Mark_and_Transmit | Transmit | ${t} | exceed_dscp=${dscp}
+| | ${table_idx} | ${skip_n} | ${match_n}= | Vpp Creates Classify Table L3
+| | ... | ${dut1} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+| | ${pre_color}= | Policer Classify Get Precolor | exceed_color
+| | Vpp Configures Classify Session L3 | ${dut1} | permit | ${table_idx}
+| | ... | ${skip_n} | ${match_n} | ip6 | dst | 2001:2::2
+| | ... | hit_next_index=${policer_index} | opaque_index=${pre_color}
+| | Policer Classify Set Interface | ${dut1} | ${dut1_if1}
+| | ... | ip6_table_index=${table_idx}
+| | ...
 | | ${dut2_status} | ${value}= | Run Keyword And Ignore Error
 | | ... | Variable Should Exist | ${dut2}
 | | ${dut}= | Run Keyword If | '${dut2_status}' == 'PASS'
 | | ${dut_if2}= | Run Keyword If | '${dut2_status}' == 'PASS'
 | | ... | Set Variable | ${dut2_if2}
 | | ... | ELSE | Set Variable | ${dut1_if2}
-| | Run Keyword Unless | '${dut2_status}' == 'PASS'
-| | ... | Policer Set Name | policer2
-| | Policer Set Node | ${dut}
-| | Policer Classify Set Interface | ${dut_if2}
-| | Policer Classify Set Match IP | 2001:1::2 | ${False}
-| | Policer Set Configuration
+| | ...
+| | ${policer_index}= | Run Keyword If | '${dut2_status}' == 'PASS'
+| | ... | Policer Set Configuration | ${dut} | policer2 | ${cir}
+| | ... | ${eir} | ${cb} | ${eb} | pps | Closest | 2R3C_RFC_2698 | Transmit
+| | ... | Mark_and_Transmit | Transmit | ${t} | exceed_dscp=${dscp}
+| | ... | ELSE | Set Variable | ${policer_index}
+| | ${table_idx} | ${skip_n} | ${match_n}=
+| | ... | Run Keyword If | '${dut2_status}' == 'PASS'
+| | ... | Vpp Creates Classify Table L3
+| | ... | ${dut} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+| | ... | ELSE | Set Variable | ${table_idx} | ${skip_n} | ${match_n}
+| | Vpp Configures Classify Session L3 | ${dut} | permit | ${table_idx}
+| | ... | ${skip_n} | ${match_n} | ip6 | dst | 2001:1::2
+| | ... | hit_next_index=${policer_index} | opaque_index=${pre_color}
+| | Policer Classify Set Interface | ${dut} | ${dut_if2}
+| | ... | ip6_table_index=${table_idx}
+
+| Show Classify Tables Verbose on all DUTs
+| | [Documentation] | Show classify tables verbose on all DUT nodes in topology.
+| | ...
+| | ... | *Arguments:*
+| | ... | - nodes - Topology. Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Show Classify Tables Verbose on all DUTs \| ${nodes} \|
+| | ...
+| | [Arguments] | ${nodes}
+| | ...
+| | ${duts}= | Get Matches | ${nodes} | DUT*
+| | :FOR | ${dut} | IN | @{duts}
+| | | Show Classify Tables Verbose | ${nodes['${dut}']}
index 8985bd2..c560dcf 100644 (file)
@@ -20,7 +20,7 @@
 | Library | OperatingSystem
 | Library | String
 | ...
-| Library | resources.libraries.python.Classify.Classify
+| Library | resources.libraries.python.Classify
 | Library | resources.libraries.python.CpuUtils
 | Library | resources.libraries.python.CoreDumpUtil
 | Library | resources.libraries.python.Cop
index 8ba914b..1cc5262 100644 (file)
 | | Run Keyword If Test Failed
 | | ... | Vpp Log Macip Acl Interface Assignment | ${dut1}
 
+| Additional Test Tear Down Action For classify
+| | [Documentation]
+| | ... | Additional teardown for tests which uses classify tables.
+| | ...
+| | Run Keyword If Test Failed
+| | ... | Show Classify Tables Verbose on all DUTs | ${nodes}
+
 | Additional Test Tear Down Action For srv6
 | | [Documentation]
 | | ... | Additional teardown for tests which uses SRv6.
index 294d0a7..b3e0309 100644 (file)
 | | [Arguments] | ${node} | ${tx_if} | ${rx_if} | ${src_mac} | ${dst_mac}
 | | ... | ${src_ip} | ${dst_ip}
 | | ...
-| | ${dscp}= | DSCP AF22
 | | ${tx_if_name}= | Get Interface Name | ${node} | ${tx_if}
 | | ${rx_if_name}= | Get Interface Name | ${node} | ${rx_if}
 | | ${args}= | Traffic Script Gen Arg | ${rx_if_name} | ${tx_if_name}
diff --git a/resources/templates/vat/acl_plugin/macip_acl_dump.vat b/resources/templates/vat/acl_plugin/macip_acl_dump.vat
deleted file mode 100644 (file)
index ad33578..0000000
+++ /dev/null
@@ -1 +0,0 @@
-macip_acl_dump
\ No newline at end of file
diff --git a/resources/templates/vat/classify_add_table.vat b/resources/templates/vat/classify_add_table.vat
deleted file mode 100644 (file)
index fea8926..0000000
+++ /dev/null
@@ -1 +0,0 @@
-classify_add_del_table mask l3 {ip_version} {direction}
\ No newline at end of file
diff --git a/resources/templates/vat/cop_interface.vat b/resources/templates/vat/cop_interface.vat
deleted file mode 100644 (file)
index 1912fa2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-cop_interface_enable_disable sw_if_index {sw_if_index} {state}
\ No newline at end of file
diff --git a/resources/templates/vat/cop_whitelist.vat b/resources/templates/vat/cop_whitelist.vat
deleted file mode 100644 (file)
index 487d553..0000000
+++ /dev/null
@@ -1 +0,0 @@
-cop_whitelist_enable_disable sw_if_index {sw_if_index} {ip} fib-id {fib_id}
\ No newline at end of file
diff --git a/resources/templates/vat/policer/policer_add_3c.vat b/resources/templates/vat/policer/policer_add_3c.vat
deleted file mode 100644 (file)
index a1a4ade..0000000
+++ /dev/null
@@ -1 +0,0 @@
-policer_add_del name {name}  cir {cir} eir {eir} cb {cb} eb {eb} rate_type {rate_type} round_type {round_type} type {p_type} conform_action {conform_action} exceed_action {exceed_action} violate_action {violate_action} {color_aware}
diff --git a/resources/templates/vat/policer/policer_classify_add_session.vat b/resources/templates/vat/policer/policer_classify_add_session.vat
deleted file mode 100644 (file)
index 7ba466d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-classify_add_del_session policer-hit-next {policer_index} {pre_color} table-index {table_index} skip_n {skip_n} match_n {match_n} match {match}
diff --git a/resources/templates/vat/policer/policer_classify_set_interface.vat b/resources/templates/vat/policer/policer_classify_set_interface.vat
deleted file mode 100644 (file)
index d0141c9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-policer_classify_set_interface sw_if_index {sw_if_index} {table_type} {table_index}
diff --git a/resources/templates/vat/tap.vat b/resources/templates/vat/tap.vat
deleted file mode 100644 (file)
index bac63e8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tap_{tap_command}_v2 {tap_arguments}
\ No newline at end of file
index 35026a1..ccdc74f 100644 (file)
@@ -19,7 +19,7 @@
 | ...
 | Suite Setup | Setup suite single link | scapy
 | Test Setup | Setup test
-| Test Teardown | Tear down test | packet_trace
+| Test Teardown | Tear down test | packet_trace | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs | with_trace=${True}
 | | When Initialize IPv4 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | ip4 | dst | 255.255.255.255
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip4 | dst
+| | ... | 20.20.20.2
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip4 | ${table_idx}
 | | Then Send packet and verify headers
 | | ... | ${tg} | 10.10.10.2 | 20.20.20.2
 | | ... | ${tg_if1} | ${tg_if1_mac} | ${dut1_if1_mac}
 | | ... | ${tg_if2} | ${dut1_if2_mac} | ${tg_if2_mac}
+# TODO: Add check of number of hits of the classify session after traffic
+# Until there is implemented check of number of hits of the classify session
+# after passing the traffic log the show classify tables verbose to allow visual
+# check of hit number when needed.
+| | And Show Classify Tables Verbose | ${dut1}
 
 *** Test Cases ***
 | tc01-64B-ethip4-ip4base-iacldstbase-dev
index 1b4b51d..de479f8 100644 (file)
@@ -19,7 +19,7 @@
 | ...
 | Suite Setup | Setup suite single link | scapy
 | Test Setup | Setup test
-| Test Teardown | Tear down test | packet_trace
+| Test Teardown | Tear down test | packet_trace | classify
 | ...
 | Test Template | Local Template
 | ...
@@ -41,6 +41,7 @@
 | ${overhead}= | ${0}
 | ${cir}= | ${100}
 | ${eir}= | ${150}
+| ${dscp}= | AF22
 
 *** Keywords ***
 | Local Template
 | | Then Send packet and verify marking
 | | ... | ${tg} | ${tg_if1} | ${tg_if2} | ${tg_if1_mac} | ${dut1_if1_mac}
 | | ... | 10.10.10.2 | 20.20.20.2
+# TODO: Add check of number of hits of the classify session after traffic
+# Until there is implemented check of number of hits of the classify session
+# after passing the traffic log the show classify tables verbose to allow visual
+# check of hit number when needed.
+| | And Show Classify Tables Verbose | ${dut1}
 
 *** Test Cases ***
 | tc01-64B-ethip4-ip4base-ipolicemarkbase-dev
 | | [Tags] | 64B
-| | frame_size=${64} | phy_cores=${0}
\ No newline at end of file
+| | frame_size=${64} | phy_cores=${0}
index 50ae506..e75f3ed 100644 (file)
@@ -19,7 +19,7 @@
 | ...
 | Suite Setup | Setup suite single link | scapy
 | Test Setup | Setup test
-| Test Teardown | Tear down test | packet_trace
+| Test Teardown | Tear down test | packet_trace | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs | with_trace=${True}
 | | When Initialize IPv6 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip6 | dst
+| | ... | 2001:2::2
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip6 | ${table_idx}
 | | Then Send packet and verify headers
 | | ... | ${tg} | 2001:1::2 | 2001:2::2
 | | ... | ${tg_if1} | ${tg_if1_mac} | ${dut1_if1_mac}
 | | ... | ${tg_if2} | ${dut1_if2_mac} | ${tg_if2_mac}
+# TODO: Add check of number of hits of the classify session after traffic
+# Until there is implemented check of number of hits of the classify session
+# after passing the traffic log the show classify tables verbose to allow visual
+# check of hit number when needed.
+| | And Show Classify Tables Verbose | ${dut1}
 
 *** Test Cases ***
 | tc01-78B-ethip6-ip6base-iacldstbase-dev
index e0ea687..73abe62 100644 (file)
@@ -19,7 +19,7 @@
 | ...
 | Suite Setup | Setup suite single link | scapy
 | Test Setup | Setup test
-| Test Teardown | Tear down test | packet_trace
+| Test Teardown | Tear down test | packet_trace | classify
 | ...
 | Test Template | Local Template
 | ...
@@ -41,6 +41,7 @@
 | ${overhead}= | ${0}
 | ${cir}= | ${100}
 | ${eir}= | ${150}
+| ${dscp}= | AF22
 
 *** Keywords ***
 | Local Template
 | | Then Send packet and verify marking
 | | ... | ${tg} | ${tg_if1} | ${tg_if2} | ${tg_if1_mac} | ${dut1_if1_mac}
 | | ... | 2001:1::2 | 2001:2::2
+# TODO: Add check of number of hits of the classify session after traffic
+# Until there is implemented check of number of hits of the classify session
+# after passing the traffic log the show classify tables verbose to allow visual
+# check of hit number when needed.
+| | And Show Classify Tables Verbose | ${dut1}
 
 *** Test Cases ***
 | tc01-78B-ethip6-ip6base-ipolicemarkbase-dev
index 02ef9e2..27e6a9c 100644 (file)
@@ -20,7 +20,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs
 | | When Initialize IPv4 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | ip4 | dst | 255.255.255.0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip4 | dst
+| | ... | 20.20.20.0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip4 | ${table_idx}
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut2} | ip4 | dst | 10.10.10.2
+| | ... | ${dut2} | ip4 | dst | 255.255.255.0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut2} | permit | ${table_idx} | ip4 | dst | 10.10.10.2
+| | ... | ${dut2} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip4 | dst
+| | ... | 10.10.10.0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut2} | ${dut2_if2} | ip4 | ${table_idx}
 | | Then Find NDR and PDR intervals using optimized search
index 0678175..f5fbaa0 100644 (file)
@@ -21,7 +21,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
@@ -53,6 +53,7 @@
 | ${overhead}= | ${0}
 | ${cir}= | ${100}
 | ${eir}= | ${150}
+| ${dscp}= | AF22
 # Traffic profile:
 | ${traffic_profile}= | trex-sl-3n-ethip4-ip4src253
 
index 4888d02..b1ce401 100644 (file)
@@ -20,7 +20,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs
 | | When Initialize IPv4 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | ip4 | dst | 255.255.255.0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip4 | dst | 20.20.20.2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip4 | dst
+| | ... | 20.20.20.0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip4 | ${table_idx}
+| | And Vpp Configures Classify Session L3
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip4 | dst
+| | ... | 10.10.10.0
+| | And Vpp Enable Input Acl Interface
+| | ... | ${dut1} | ${dut1_if2} | ip4 | ${table_idx}
 | | Then Find NDR and PDR intervals using optimized search
 
 *** Test Cases ***
index 325d83d..de42e17 100644 (file)
@@ -20,7 +20,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
@@ -51,6 +51,7 @@
 | ${overhead}= | ${0}
 | ${cir}= | ${100}
 | ${eir}= | ${150}
+| ${dscp}= | AF22
 # Traffic profile:
 | ${traffic_profile}= | trex-sl-2n-ethip4-ip4src253
 
index 36d612c..0a6239e 100644 (file)
@@ -20,7 +20,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs
 | | When Initialize IPv6 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip6 | dst
+| | ... | 2001:2::0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip6 | ${table_idx}
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut2} | ip6 | dst | 2001:1::2
+| | ... | ${dut2} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut2} | permit | ${table_idx} | ip6 | dst | 2001:1::2
+| | ... | ${dut2} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip6 | dst
+| | ... | 2001:1::0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut2} | ${dut2_if2} | ip6 | ${table_idx}
 | | Then Find NDR and PDR intervals using optimized search
index 2bc668f..8d9335e 100644 (file)
@@ -20,7 +20,7 @@
 | Suite Setup | Setup suite single link | performance
 | Suite Teardown | Tear down suite | performance
 | Test Setup | Setup test
-| Test Teardown | Tear down test | performance
+| Test Teardown | Tear down test | performance | classify
 | ...
 | Test Template | Local Template
 | ...
 | | And Apply startup configuration on all VPP DUTs
 | | When Initialize IPv6 forwarding in circular topology
 | | ${table_idx} | ${skip_n} | ${match_n}= | And Vpp Creates Classify Table L3
-| | ... | ${dut1} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | ip6 | dst | ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
 | | And Vpp Configures Classify Session L3
-| | ... | ${dut1} | permit | ${table_idx} | ip6 | dst | 2001:2::2
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip6 | dst
+| | ... | 2001:2::0
 | | And Vpp Enable Input Acl Interface
 | | ... | ${dut1} | ${dut1_if1} | ip6 | ${table_idx}
+| | And Vpp Configures Classify Session L3
+| | ... | ${dut1} | permit | ${table_idx} | ${skip_n} | ${match_n} | ip6 | dst
+| | ... | 2001:1::0
+| | And Vpp Enable Input Acl Interface
+| | ... | ${dut1} | ${dut1_if2} | ip6 | ${table_idx}
 | | Then Find NDR and PDR intervals using optimized search
 
 *** Test Cases ***