policer: API cleanup 66/25566/8
authorJakub Grajciar <jgrajcia@cisco.com>
Mon, 2 Mar 2020 12:16:53 +0000 (13:16 +0100)
committerOle Trøan <otroan@employees.org>
Thu, 12 Mar 2020 12:28:47 +0000 (12:28 +0000)
Use consistent API types.

Type: fix

Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
Change-Id: Ia14f33992353b419b70b55beed63ab8ed6a2e837
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
MAINTAINERS
src/vat/api_format.c
src/vnet/CMakeLists.txt
src/vnet/policer/policer.api
src/vnet/policer/policer_api.c
src/vnet/policer/policer_types.api [new file with mode: 0644]
src/vpp/api/custom_dump.c
test/test_ip4.py
test/test_ip6.py
test/vpp_papi_provider.py
test/vpp_policer.py [new file with mode: 0644]

index d0abdff..08b8bc4 100644 (file)
@@ -83,6 +83,11 @@ I:   classify
 M:     Dave Barach <dave@barachs.net>
 F:     src/vnet/classify
 
+VNET Policer
+I:     policer
+M:     N/A
+F:     src/vnet/policer/
+
 VNET Device Drivers
 I:     devices
 Y:     src/vnet/devices/af_packet/FEATURE.yaml
index a98e2ed..a18eb91 100644 (file)
@@ -4555,18 +4555,18 @@ vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
   vat_main_t *vam = &vat_main;
   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
 
-  if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
-    conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
+  if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
+    conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
   else
     conform_dscp_str = format (0, "");
 
-  if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
-    exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
+  if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
+    exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
   else
     exceed_dscp_str = format (0, "");
 
-  if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
-    violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
+  if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
+    violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
   else
     violate_dscp_str = format (0, "");
 
@@ -4593,11 +4593,11 @@ vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
         ntohl (mp->extended_limit),
         ntohl (mp->extended_bucket),
         clib_net_to_host_u64 (mp->last_update_time),
-        format_policer_action_type, mp->conform_action_type,
+        format_policer_action_type, mp->conform_action.type,
         conform_dscp_str,
-        format_policer_action_type, mp->exceed_action_type,
+        format_policer_action_type, mp->exceed_action.type,
         exceed_dscp_str,
-        format_policer_action_type, mp->violate_action_type,
+        format_policer_action_type, mp->violate_action.type,
         violate_dscp_str);
 
   vec_free (conform_dscp_str);
@@ -4618,11 +4618,11 @@ static void vl_api_policer_details_t_handler_json
     format (0, "%U", format_policer_round_type, mp->round_type);
   type_str = format (0, "%U", format_policer_type, mp->type);
   conform_action_str = format (0, "%U", format_policer_action_type,
-                              mp->conform_action_type);
+                              mp->conform_action.type);
   exceed_action_str = format (0, "%U", format_policer_action_type,
-                             mp->exceed_action_type);
+                             mp->exceed_action.type);
   violate_action_str = format (0, "%U", format_policer_action_type,
-                              mp->violate_action_type);
+                              mp->violate_action.type);
 
   if (VAT_JSON_ARRAY != vam->json_tree.type)
     {
@@ -4658,24 +4658,24 @@ static void vl_api_policer_details_t_handler_json
                            ntohl (mp->last_update_time));
   vat_json_object_add_string_copy (node, "conform_action",
                                   conform_action_str);
-  if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+  if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
     {
-      u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
+      u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
       vec_free (dscp_str);
     }
   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
-  if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+  if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
     {
-      u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
+      u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
       vec_free (dscp_str);
     }
   vat_json_object_add_string_copy (node, "violate_action",
                                   violate_action_str);
-  if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+  if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
     {
-      u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
+      u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
       vec_free (dscp_str);
     }
@@ -17382,12 +17382,12 @@ api_policer_add_del (vat_main_t * vam)
   mp->rate_type = rate_type;
   mp->round_type = round_type;
   mp->type = type;
-  mp->conform_action_type = conform_action.action_type;
-  mp->conform_dscp = conform_action.dscp;
-  mp->exceed_action_type = exceed_action.action_type;
-  mp->exceed_dscp = exceed_action.dscp;
-  mp->violate_action_type = violate_action.action_type;
-  mp->violate_dscp = violate_action.dscp;
+  mp->conform_action.type = conform_action.action_type;
+  mp->conform_action.dscp = conform_action.dscp;
+  mp->exceed_action.type = exceed_action.action_type;
+  mp->exceed_action.dscp = exceed_action.dscp;
+  mp->violate_action.type = violate_action.action_type;
+  mp->violate_action.dscp = violate_action.dscp;
   mp->color_aware = color_aware;
 
   S (mp);
index 5ea5f16..0ae1b0a 100644 (file)
@@ -98,7 +98,10 @@ list(APPEND VNET_HEADERS
   policer/xlate.h
 )
 
-list(APPEND VNET_API_FILES policer/policer.api)
+list(APPEND VNET_API_FILES
+  policer/policer.api
+  policer/policer_types.api
+)
 
 ##############################################################################
 # Cop - junk filter
index 8ca0ffb..946cc35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 Cisco and/or its affiliates.
+ * Copyright (c) 2015-2020 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:
@@ -13,7 +13,9 @@
  * limitations under the License.
  */
 
-option version = "1.0.0";
+option version = "2.0.0";
+
+import "vnet/policer/policer_types.api";
 
 /** \brief Add/del policer
     @param client_index - opaque cookie to identify the sender
@@ -28,34 +30,28 @@ option version = "1.0.0";
     @param round_type - rounding type
     @param type - policer algorithm
     @param color_aware - 0=color-blind, 1=color-aware
-    @param conform_action_type - conform action type
-    @param conform_dscp - DSCP for conform mar-and-transmit action
-    @param exceed_action_type - exceed action type
-    @param exceed_dscp - DSCP for exceed mar-and-transmit action
-    @param violate_action_type - violate action type
-    @param violate_dscp - DSCP for violate mar-and-transmit action
+    @param conform_action - conform action
+    @param exceed_action - exceed action type
+    @param violate_action - violate action type
 */
 define policer_add_del
 {
   u32 client_index;
   u32 context;
 
-  u8 is_add;
-  u8 name[64];
+  bool is_add;
+  string name[64];
   u32 cir;
   u32 eir;
   u64 cb;
   u64 eb;
-  u8 rate_type;
-  u8 round_type;
-  u8 type;
-  u8 color_aware;
-  u8 conform_action_type;
-  u8 conform_dscp;
-  u8 exceed_action_type;
-  u8 exceed_dscp;
-  u8 violate_action_type;
-  u8 violate_dscp;
+  vl_api_sse2_qos_rate_type_t rate_type;
+  vl_api_sse2_qos_round_type_t round_type;
+  vl_api_sse2_qos_policer_type_t type;
+  bool color_aware;
+  vl_api_sse2_qos_action_t conform_action;
+  vl_api_sse2_qos_action_t exceed_action;
+  vl_api_sse2_qos_action_t violate_action;
 };
 
 /** \brief Add/del policer response
@@ -81,8 +77,8 @@ define policer_dump
   u32 client_index;
   u32 context;
 
-  u8 match_name_valid;
-  u8 match_name[64];
+  bool match_name_valid;
+  string match_name[64];
 };
 
 /** \brief Policer operational state response.
@@ -95,12 +91,9 @@ define policer_dump
     @param rate_type - rate type
     @param round_type - rounding type
     @param type - policer algorithm
-    @param conform_action_type - conform action type
-    @param conform_dscp - DSCP for conform mar-and-transmit action
-    @param exceed_action_type - exceed action type
-    @param exceed_dscp - DSCP for exceed mar-and-transmit action
-    @param violate_action_type - violate action type
-    @param violate_dscp - DSCP for violate mar-and-transmit action
+    @param conform_action - conform action
+    @param exceed_action - exceed action
+    @param violate_action - violate action
     @param single_rate - 1 = single rate policer, 0 = two rate policer
     @param color_aware - for hierarchical policing
     @param scale - power-of-2 shift amount for lower rates
@@ -116,22 +109,19 @@ define policer_details
 {
   u32 context;
 
-  u8 name[64];
+  string name[64];
   u32 cir;
   u32 eir;
   u64 cb;
   u64 eb;
-  u8 rate_type;
-  u8 round_type;
-  u8 type;
-  u8 conform_action_type;
-  u8 conform_dscp;
-  u8 exceed_action_type;
-  u8 exceed_dscp;
-  u8 violate_action_type;
-  u8 violate_dscp;
-  u8 single_rate;
-  u8 color_aware;
+  vl_api_sse2_qos_rate_type_t rate_type;
+  vl_api_sse2_qos_round_type_t round_type;
+  vl_api_sse2_qos_policer_type_t type;
+  vl_api_sse2_qos_action_t conform_action;
+  vl_api_sse2_qos_action_t exceed_action;
+  vl_api_sse2_qos_action_t violate_action;
+  bool single_rate;
+  bool color_aware;
   u32 scale;
   u32 cir_tokens_per_period;
   u32 pir_tokens_per_period;
index ae57a93..b543a3c 100644 (file)
@@ -68,12 +68,16 @@ vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
   cfg.rb.kbps.eir_kbps = ntohl (mp->eir);
   cfg.rb.kbps.cb_bytes = clib_net_to_host_u64 (mp->cb);
   cfg.rb.kbps.eb_bytes = clib_net_to_host_u64 (mp->eb);
-  cfg.conform_action.action_type = mp->conform_action_type;
-  cfg.conform_action.dscp = mp->conform_dscp;
-  cfg.exceed_action.action_type = mp->exceed_action_type;
-  cfg.exceed_action.dscp = mp->exceed_dscp;
-  cfg.violate_action.action_type = mp->violate_action_type;
-  cfg.violate_action.dscp = mp->violate_dscp;
+  cfg.conform_action.action_type =
+    (sse2_qos_action_type_en) mp->conform_action.type;
+  cfg.conform_action.dscp = mp->conform_action.dscp;
+  cfg.exceed_action.action_type =
+    (sse2_qos_action_type_en) mp->exceed_action.type;
+  cfg.exceed_action.dscp = mp->exceed_action.dscp;
+  cfg.violate_action.action_type =
+    (sse2_qos_action_type_en) mp->violate_action.type;
+  cfg.violate_action.dscp = mp->violate_action.dscp;
+
   cfg.color_aware = mp->color_aware;
 
   error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add);
@@ -111,12 +115,15 @@ send_policer_details (u8 * name,
   mp->rate_type = config->rate_type;
   mp->round_type = config->rnd_type;
   mp->type = config->rfc;
-  mp->conform_action_type = config->conform_action.action_type;
-  mp->conform_dscp = config->conform_action.dscp;
-  mp->exceed_action_type = config->exceed_action.action_type;
-  mp->exceed_dscp = config->exceed_action.dscp;
-  mp->violate_action_type = config->violate_action.action_type;
-  mp->violate_dscp = config->violate_action.dscp;
+  mp->conform_action.type =
+    (vl_api_sse2_qos_action_type_t) config->conform_action.action_type;
+  mp->conform_action.dscp = config->conform_action.dscp;
+  mp->exceed_action.type =
+    (vl_api_sse2_qos_action_type_t) config->exceed_action.action_type;
+  mp->exceed_action.dscp = config->exceed_action.dscp;
+  mp->violate_action.type =
+    (vl_api_sse2_qos_action_type_t) config->violate_action.action_type;
+  mp->violate_action.dscp = config->violate_action.dscp;
   mp->single_rate = templ->single_rate ? 1 : 0;
   mp->color_aware = templ->color_aware ? 1 : 0;
   mp->scale = htonl (templ->scale);
diff --git a/src/vnet/policer/policer_types.api b/src/vnet/policer/policer_types.api
new file mode 100644 (file)
index 0000000..903bb60
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020 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:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+enum sse2_qos_rate_type : u8
+{
+  SSE2_QOS_RATE_API_KBPS = 0,
+  SSE2_QOS_RATE_API_PPS,
+  SSE2_QOS_RATE_API_INVALID,
+};
+
+enum sse2_qos_round_type : u8
+{
+  SSE2_QOS_ROUND_API_TO_CLOSEST = 0,
+  SSE2_QOS_ROUND_API_TO_UP,
+  SSE2_QOS_ROUND_API_TO_DOWN,
+  SSE2_QOS_ROUND_API_INVALID,
+};
+
+enum sse2_qos_policer_type : u8
+{
+  SSE2_QOS_POLICER_TYPE_API_1R2C = 0,
+  SSE2_QOS_POLICER_TYPE_API_1R3C_RFC_2697 = 1,
+  SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_2698 = 2,
+  SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_4115 = 3,
+  SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_MEF5CF1 = 4,
+  SSE2_QOS_POLICER_TYPE_API_MAX,
+};
+
+enum sse2_qos_action_type : u8
+{
+  SSE2_QOS_ACTION_API_DROP = 0,
+  SSE2_QOS_ACTION_API_TRANSMIT,
+  SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT,
+};
+
+/** \brief SSE2 QOS action
+    @param conform_action_type - conform action type
+    @param conform_dscp - DSCP for conform mark-and-transmit action
+*/
+typedef sse2_qos_action
+{
+  vl_api_sse2_qos_action_type_t type;
+  u8 dscp;
+};
+
+/*
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
index a4e04eb..1cc2aa6 100644 (file)
@@ -2189,11 +2189,11 @@ static void *vl_api_policer_add_del_t_print
     }
 
   s = format (s, "conform_action %U ", format_policer_action,
-             mp->conform_action_type, mp->conform_dscp);
+             mp->conform_action.type, mp->conform_action.dscp);
   s = format (s, "exceed_action %U ", format_policer_action,
-             mp->exceed_action_type, mp->exceed_dscp);
+             mp->exceed_action.type, mp->exceed_action.dscp);
   s = format (s, "violate_action %U ", format_policer_action,
-             mp->violate_action_type, mp->violate_dscp);
+             mp->violate_action.type, mp->violate_action.dscp);
 
   if (mp->color_aware)
     s = format (s, "color-aware ");
index 46a8306..87059c7 100644 (file)
@@ -21,6 +21,7 @@ from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
 from vpp_papi import VppEnum
 from vpp_neighbor import VppNeighbor
 from vpp_lo_interface import VppLoInterface
+from vpp_policer import VppPolicer
 
 NUM_PKTS = 67
 
@@ -1390,8 +1391,8 @@ class TestIPPunt(VppTestCase):
         #
         # add a policer
         #
-        policer = self.vapi.policer_add_del(b"ip4-punt", 400, 0, 10, 0,
-                                            rate_type=1)
+        policer = VppPolicer(self, "ip4-punt", 400, 0, 10, 0, rate_type=1)
+        policer.add_vpp_config()
         self.vapi.ip_punt_police(policer.policer_index)
 
         self.vapi.cli("clear trace")
@@ -1411,8 +1412,7 @@ class TestIPPunt(VppTestCase):
         # remove the policer. back to full rx
         #
         self.vapi.ip_punt_police(policer.policer_index, is_add=0)
-        self.vapi.policer_add_del(b"ip4-punt", 400, 0, 10, 0,
-                                  rate_type=1, is_add=0)
+        policer.remove_vpp_config()
         self.send_and_expect(self.pg0, pkts, self.pg1)
 
         #
index f4b9ef8..b27cfdb 100644 (file)
@@ -28,6 +28,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
 from vpp_neighbor import find_nbr, VppNeighbor
 from vpp_pg_interface import is_ipv6_misc
 from vpp_sub_interface import VppSubInterface, VppDot1QSubint
+from vpp_policer import VppPolicer
 from ipaddress import IPv6Network, IPv6Address
 
 AF_INET6 = socket.AF_INET6
@@ -2118,8 +2119,8 @@ class TestIP6Punt(VppTestCase):
         #
         # add a policer
         #
-        policer = self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0,
-                                            rate_type=1)
+        policer = VppPolicer(self, "ip6-punt", 400, 0, 10, 0, rate_type=1)
+        policer.add_vpp_config()
         self.vapi.ip_punt_police(policer.policer_index, is_ip6=1)
 
         self.vapi.cli("clear trace")
@@ -2139,8 +2140,7 @@ class TestIP6Punt(VppTestCase):
         # remove the policer. back to full rx
         #
         self.vapi.ip_punt_police(policer.policer_index, is_add=0, is_ip6=1)
-        self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0,
-                                  rate_type=1, is_add=0)
+        policer.remove_vpp_config()
         self.send_and_expect(self.pg0, pkts, self.pg1)
 
         #
index 832fd8f..52ce492 100644 (file)
@@ -96,7 +96,7 @@ defaultmapping = {
                                  'ip6_table_index': 4294967295,
                                  'l2_table_index': 4294967295, },
     'pppoe_add_del_session': {'is_add': 1, },
-    'policer_add_del': {'is_add': 1, 'conform_action_type': 1, },
+    'policer_add_del': {'is_add': 1, 'conform_action': {'type': 1}, },
     'proxy_arp_add_del': {'is_add': 1, },
     'proxy_arp_intfc_enable_disable': {'is_enable': 1, },
     'set_ip_flow_hash': {'src': 1, 'dst': 1, 'sport': 1, 'dport': 1,
@@ -1166,41 +1166,6 @@ class VppPapiProvider(object):
         return self.api(
             self.papi.macip_acl_dump, {'acl_index': acl_index})
 
-    def policer_add_del(self,
-                        name,
-                        cir,
-                        eir,
-                        cb,
-                        eb,
-                        is_add=1,
-                        rate_type=0,
-                        round_type=0,
-                        ptype=0,
-                        color_aware=0,
-                        conform_action_type=1,
-                        conform_dscp=0,
-                        exceed_action_type=0,
-                        exceed_dscp=0,
-                        violate_action_type=0,
-                        violate_dscp=0):
-        return self.api(self.papi.policer_add_del,
-                        {'name': name,
-                         'cir': cir,
-                         'eir': eir,
-                         'cb': cb,
-                         'eb': eb,
-                         'is_add': is_add,
-                         'rate_type': rate_type,
-                         'round_type': round_type,
-                         'type': ptype,
-                         'color_aware': color_aware,
-                         'conform_action_type': conform_action_type,
-                         'conform_dscp': conform_dscp,
-                         'exceed_action_type': exceed_action_type,
-                         'exceed_dscp': exceed_dscp,
-                         'violate_action_type': violate_action_type,
-                         'violate_dscp': violate_dscp})
-
     def ip_punt_police(self,
                        policer_index,
                        is_ip6=0,
diff --git a/test/vpp_policer.py b/test/vpp_policer.py
new file mode 100644 (file)
index 0000000..49d1185
--- /dev/null
@@ -0,0 +1,69 @@
+from vpp_object import VppObject
+from vpp_ip import INVALID_INDEX
+
+
+class PolicerAction():
+    """ sse2 qos action """
+
+    def __init__(self, type, dscp):
+        self.type = type
+        self.dscp = dscp
+
+    def encode(self):
+        return {'type': self.type, 'dscp': self.dscp}
+
+
+class VppPolicer(VppObject):
+    """ Policer """
+
+    def __init__(self, test, name, cir, eir, commited_burst, excess_burst,
+                 rate_type=0, round_type=0, type=0, color_aware=False,
+                 conform_action=PolicerAction(1, 0),
+                 exceed_action=PolicerAction(0, 0),
+                 violate_action=PolicerAction(0, 0)):
+        self._test = test
+        self.name = name
+        self.cir = cir
+        self.eir = eir
+        self.commited_burst = commited_burst
+        self.excess_burst = excess_burst
+        self.rate_type = rate_type
+        self.round_type = round_type
+        self.type = type
+        self.color_aware = color_aware
+        self.conform_action = conform_action
+        self.exceed_action = exceed_action
+        self.violate_action = violate_action
+        self._policer_index = INVALID_INDEX
+
+    @property
+    def policer_index(self):
+        return self._policer_index
+
+    def add_vpp_config(self):
+        r = self._test.vapi.policer_add_del(
+            name=self.name, cir=self.cir,
+            eir=self.eir, cb=self.commited_burst, eb=self.excess_burst,
+            rate_type=self.rate_type, round_type=self.round_type,
+            type=self.type, color_aware=self.color_aware,
+            conform_action=self.conform_action.encode(),
+            exceed_action=self.exceed_action.encode(),
+            violate_action=self.violate_action.encode())
+        self._test.registry.register(self, self._test.logger)
+        self._policer_index = r.policer_index
+        return self
+
+    def remove_vpp_config(self):
+        self._test.vapi.policer_add_del(is_add=False, name=self.name)
+        self._policer_index = INVALID_INDEX
+
+    def query_vpp_config(self):
+        dump = self._test.vapi.policer_dump(
+            match_name_valid=True, match_name=self.name)
+        for policer in dump:
+            if policer.name == self.name:
+                return True
+        return False
+
+    def object_id(self):
+        return ("policer-%s" % (self.name))