classify: add API to retrieve punt ACL tables

Type: feature

Change-Id: Ica3e60836c0f26518ba2c238a8c03ce3648ea69b
Signed-off-by: Benoît Ganne <bganne@cisco.com>
diff --git a/src/vnet/classify/classify.api b/src/vnet/classify/classify.api
index d1d7340..00963f6 100644
--- a/src/vnet/classify/classify.api
+++ b/src/vnet/classify/classify.api
@@ -436,6 +436,30 @@
   bool is_add [default=true];
 };
 
+/** \brief Get classify table ids configured for punt ACL
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+*/
+define punt_acl_get
+{
+  u32 client_index;
+  u32 context;
+};
+
+/** \brief Reply for punt_acl_get
+    @param context - sender context which was passed in the request
+    @param retval - return value (0 for success)
+    @param ip4_table_index - ip4 punt classify table index (~0 for none)
+    @param ip6_table_index - ip6 punt classify table index (~0 for none)
+*/
+define punt_acl_get_reply
+{
+  u32 context;
+  i32 retval;
+  u32 ip4_table_index;
+  u32 ip6_table_index;
+};
+
 /** \brief Set/unset output ACL interface
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
diff --git a/src/vnet/classify/classify_api.c b/src/vnet/classify/classify_api.c
index 3e8dc51..0f9243c 100644
--- a/src/vnet/classify/classify_api.c
+++ b/src/vnet/classify/classify_api.c
@@ -912,6 +912,27 @@
   REPLY_MACRO (VL_API_PUNT_ACL_ADD_DEL_REPLY);
 }
 
+static void
+vl_api_punt_acl_get_t_handler (vl_api_punt_acl_get_t *mp)
+{
+  vl_api_punt_acl_get_reply_t *rmp;
+  int rv = 0;
+
+  const in_out_acl_main_t *am = &in_out_acl_main;
+
+  u32 *const *tables =
+    am->classify_table_index_by_sw_if_index[IN_OUT_ACL_INPUT_TABLE_GROUP];
+  const u32 *ip4_table = tables[IN_OUT_ACL_TABLE_IP4_PUNT];
+  const u32 *ip6_table = tables[IN_OUT_ACL_TABLE_IP6_PUNT];
+  const u32 ip4_table_index = vec_len (ip4_table) ? ip4_table[0] : ~0;
+  const u32 ip6_table_index = vec_len (ip6_table) ? ip6_table[0] : ~0;
+
+  REPLY_MACRO2 (VL_API_PUNT_ACL_GET_REPLY, ({
+		  rmp->ip4_table_index = ntohl (ip4_table_index);
+		  rmp->ip6_table_index = ntohl (ip6_table_index);
+		}));
+}
+
 static void vl_api_output_acl_set_interface_t_handler
   (vl_api_output_acl_set_interface_t * mp)
 {
diff --git a/test/test_classifier.py b/test/test_classifier.py
index 74851f9..9f0fdbf 100644
--- a/test/test_classifier.py
+++ b/test/test_classifier.py
@@ -915,10 +915,20 @@
                                 proto=socket.IPPROTO_UDP, src_port=sport))
         self.send_and_expect_only(self.pg0, pkts, self.pg1)
 
+        # test dump api: ip4 is set, ip6 is not
+        r = self.vapi.punt_acl_get()
+        self.assertEqual(r.ip4_table_index, table_index)
+        self.assertEqual(r.ip6_table_index, 0xffffffff)
+
         # cleanup
         self.acl_active_table = ''
         self.vapi.punt_acl_add_del(ip4_table_index=table_index, is_add=0)
 
+        # test dump api: nothing set
+        r = self.vapi.punt_acl_get()
+        self.assertEqual(r.ip4_table_index, 0xffffffff)
+        self.assertEqual(r.ip6_table_index, 0xffffffff)
+
 
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)