Debugging VPP MACIP ACLs

=== So, first let's launch VPP:

ayourtch@ceehost:~/vpp$ make run
WARNING: STARTUP_CONF not defined or file doesn't exist.
         Running with minimal startup config:  unix { interactive cli-listen /run/vpp/cli.sock gid 1000 }

[sudo] password for ayourtch:
vlib_plugin_early_init:356: plugin path /home/ayourtch/vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_plugins
load_one_plugin:184: Loaded plugin: acl_plugin.so (Access Control Lists)
load_one_plugin:184: Loaded plugin: dpdk_plugin.so (Data Plane Development Kit (DPDK))
load_one_plugin:184: Loaded plugin: flowprobe_plugin.so (Flow per Packet)
load_one_plugin:184: Loaded plugin: gtpu_plugin.so (GTPv1-U)
load_one_plugin:184: Loaded plugin: ila_plugin.so (Identifier-locator addressing for IPv6)
load_one_plugin:184: Loaded plugin: ioam_plugin.so (Inbound OAM)
load_one_plugin:114: Plugin disabled (default): ixge_plugin.so
load_one_plugin:184: Loaded plugin: lb_plugin.so (Load Balancer)
load_one_plugin:184: Loaded plugin: libsixrd_plugin.so (IPv6 Rapid Deployment on IPv4 Infrastructure (RFC5969))
load_one_plugin:184: Loaded plugin: memif_plugin.so (Packet Memory Interface (experimetal))
load_one_plugin:184: Loaded plugin: nat_plugin.so (Network Address Translation)
load_one_plugin:184: Loaded plugin: pppoe_plugin.so (PPPoE)
load_one_plugin:184: Loaded plugin: stn_plugin.so (VPP Steals the NIC for Container integration)
dpdk_bind_devices_to_uio:753: Unsupported PCI device 0x10ec:0x8168 found at PCI address 0000:06:00.0
dpdk_config:1216: EAL init args: -c 1 -n 4 --huge-dir /run/vpp/hugepages --file-prefix vpp --master-lcore 0 --socket-mem 64
DPDK physical memory layout:
Segment 0: IOVA:0x91f600000, len:6291456, virt:0x7f57b6600000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 1: IOVA:0x920800000, len:2097152, virt:0x7f57b6200000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 2: IOVA:0x920c00000, len:2097152, virt:0x7f57b5e00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 3: IOVA:0x921200000, len:2097152, virt:0x7f57b5a00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 4: IOVA:0x921800000, len:4194304, virt:0x7f57b5400000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 5: IOVA:0x921e00000, len:2097152, virt:0x7f57b5000000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 6: IOVA:0x922400000, len:2097152, virt:0x7f57b4c00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 7: IOVA:0x922800000, len:2097152, virt:0x7f57b4800000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 8: IOVA:0x922e00000, len:2097152, virt:0x7f57b4400000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 9: IOVA:0x923400000, len:2097152, virt:0x7f57b4000000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 10: IOVA:0x923800000, len:33554432, virt:0x7f57b1e00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 11: IOVA:0x94ac00000, len:6291456, virt:0x7f57b0a00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
0: dpdk_ipsec_process:1011: not enough DPDK crypto resources, default to OpenSSL
0: dpdk_lib_init:221: DPDK drivers found no ports...
0: dpdk_lib_init:225: DPDK drivers found 0 ports...
0: svm_client_scan_this_region_nolock:1181: /vpe-api: cleanup ghost pid 23089
0: svm_client_scan_this_region_nolock:1181: /global_vm: cleanup ghost pid 23089
    _______    _        _   _____  ___
 __/ __/ _ \  (_)__    | | / / _ \/ _ \
 _/ _// // / / / _ \   | |/ / ___/ ___/
 /_/ /____(_)_/\___/   |___/_/  /_/

DBGvpp#

=== Now, in another window let's launch VAT:

ayourtch@ceehost:~/vpp$ cat ~/bin/run-vat
#!/bin/sh
sudo ./build-root/install-vpp_debug-native/vpp/bin/vpp_api_test plugin_path ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins/ $1 $2 $3 $4 $5
ayourtch@ceehost:~/vpp$
ayourtch@ceehost:~/vpp$
ayourtch@ceehost:~/vpp$ run-vat
[sudo] password for ayourtch:
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//lb_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//dpdk_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//memif_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//acl_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//udp_ping_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//nat_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//flowprobe_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//ioam_vxlan_gpe_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//ioam_export_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//pppoe_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//vxlan_gpe_ioam_export_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//ioam_pot_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//ioam_trace_test_plugin.so
load_one_plugin:63: Loaded plugin: ./build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins//gtpu_test_plugin.so
vat#

=== Now, let's create a MACIP ACL:

vat# macip_acl_add_replace -1 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat#

=== Now on VPP we can inspect the result via the debug CLI

DBGvpp# show acl-plugin macip acl
MACIP acl_index: 0, count: 1 (true len 1) tag {} is free pool slot: 0
  ip4_table_index 3, ip6_table_index 3, l2_table_index 3
    rule 0: ipv4 action 1 ip 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
DBGvpp#
DBGvpp# show classify table
  TableIdx  Sessions   NextTbl  NextNode
         0         1        -1         0
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
         1         1         0        -1
  Heap: 3 objects, 236 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 3 flag 0 offset 0
  mask 00000000: 000000000000000000000000ffff0000ffff0000ffff00000000000000000000
       00000020: 00000000000000000000000000000000
  linear-search buckets 0
         2         1         1        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff0000ffff0000000000000000000000000000
  linear-search buckets 0
         3         1         2        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
DBGvpp#

=== notice the "_table_index" in acl-plugin output points to the head of the chain of the classifier tables used to inspect the traffic.

=== Let's apply the macip acl to an interface

vat# macip_acl_interface_add_del sw_if_index 0 add acl 0
vat#

=== since under the hood the MACIP is just a wrapper on top of VPP inacls, we can now inspect them on VPP side

DBGvpp# show inacl type l2
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip4
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip6
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp#

=== so, we can see the head of the chain of the classifier tables applied as an inacl. Let's do macip_acl_add_replace

vat# macip_acl_add_replace 0 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat#

=== Success, let's see what happened on the VPP side

DBGvpp# show acl-plugin macip acl
MACIP acl_index: 0, count: 1 (true len 1) tag {} is free pool slot: 0
  ip4_table_index 0, ip6_table_index 0, l2_table_index 0
    rule 0: ipv4 action 1 ip 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
DBGvpp# show classify tables
  TableIdx  Sessions   NextTbl  NextNode
         0         1         1        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
         1         1         2        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff0000ffff0000000000000000000000000000
  linear-search buckets 0
         2         1         3        -1
  Heap: 3 objects, 236 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 3 flag 0 offset 0
  mask 00000000: 000000000000000000000000ffff0000ffff0000ffff00000000000000000000
       00000020: 00000000000000000000000000000000
  linear-search buckets 0
         3         1        -1         0
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
DBGvpp# show inacl type l2
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip4
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip6
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp#

=== Few things come to mind - first, that the table number has changed. However, a curious reader will see it is only the indices of classify tables. The logical order is still the same.
=== So, it's the allocation/deallocation of the table indices that affects this order. Shrug. 
=== We have to delete and recreate the classifier tables, since the masks might change and we might have even a different set of tables.
=== More concerning, however, is the wrong inacl number - it is the "old" one. well, if we replace the tables and the order changes, then we'd expect this to become a problem...
=== Moreso, if we attempt to unapply the macip ACL, we will get a problem:

vat# macip_acl_interface_add_del sw_if_index 0 del acl 0
macip_acl_interface_add_del error: No such table
vat#

=== The first "naive" fix is to reset the inacl upon recreating the tables:

diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c
index dbb740ab..c32f8cf1 100644
--- a/src/plugins/acl/acl.c
+++ b/src/plugins/acl/acl.c
@@ -1503,6 +1503,25 @@ macip_destroy_classify_tables (acl_main_t * am, u32 macip_acl_index)
 }

 static int
+macip_maybe_apply_unapply_classifier_tables(acl_main_t *am, u32 acl_index, int is_apply)
+{
+  int rv = 0;
+  int rv0 = 0;
+  int i;
+  macip_acl_list_t *a = pool_elt_at_index (am->macip_acls, acl_index);
+
+  for(i = 0; i < vec_len(am->macip_acl_by_sw_if_index); i++)
+    if (vec_elt(am->macip_acl_by_sw_if_index, i) == acl_index)
+      {
+        rv0 = vnet_set_input_acl_intfc (am->vlib_main, i, a->ip4_table_index,
+                              a->ip6_table_index, a->l2_table_index, is_apply);
+        /* return the first unhappy outcome but make try to plough through. */
+        rv = rv || rv0;
+      }
+  return rv;
+}
+
+static int
 macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
                    u32 * acl_list_index, u8 * tag)
 {
@@ -1511,6 +1530,7 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
   macip_acl_rule_t *r;
   macip_acl_rule_t *acl_new_rules = 0;
   int i;
+  int rv = 0;

   if (*acl_list_index != ~0)
     {
@@ -1575,7 +1595,9 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
   /* Create and populate the classifer tables */
   macip_create_classify_tables (am, *acl_list_index);
   clib_mem_set_heap (oldheap);
-  return 0;
+  /* If the ACL was already applied somewhere, reapply the newly created tables */
+  rv = rv || macip_maybe_apply_unapply_classifier_tables(am, *acl_list_index, 1);
+  return rv;
 }


=== restarting VPP and VAT, let's redo the same testing sequence:

vat# macip_acl_add_replace -1 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat# macip_acl_interface_add_del sw_if_index 0 add acl 0
vat# macip_acl_add_replace 0 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat#

DBGvpp# show acl-plugin macip acl
MACIP acl_index: 0, count: 1 (true len 1) tag {} is free pool slot: 0
  ip4_table_index 0, ip6_table_index 0, l2_table_index 0
    rule 0: ipv4 action 1 ip 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
DBGvpp# show classify tables
  TableIdx  Sessions   NextTbl  NextNode
         0         1         1        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
         1         1         2        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff0000ffff0000000000000000000000000000
  linear-search buckets 0
         2         1         3        -1
  Heap: 3 objects, 236 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 3 flag 0 offset 0
  mask 00000000: 000000000000000000000000ffff0000ffff0000ffff00000000000000000000
       00000020: 00000000000000000000000000000000
  linear-search buckets 0
         3         1        -1         0
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
DBGvpp# show inacl type l2
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip4
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp# show inacl type ip6
 Intfc idx      Classify table		Interface name
         0                   3		local0
DBGvpp#

=== Uh-oh, all the new code and all for naughts ? To see what is going on, we need to take a look at the code of vnet_set_input_acl_intfc:

...
/* Return ok on ADD operaton if feature is already enabled */
      if (is_add &&
          am->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
        return 0;
...

=== So, if there is an inacl already applied and we are calling "set" operation, it will quietly do nothing.
=== One might say it is a bug in vnet_set_input_acl_intfc, but it is hard to argue about the semantics,
=== and it is cleaner to ensure that code is not triggered at all, hence we should probably tweak the code
=== to cleanly remove the inacl before destroying the tables.
=== So the final fix will look as follows:

diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c
index dbb740ab..4b950763 100644
--- a/src/plugins/acl/acl.c
+++ b/src/plugins/acl/acl.c
@@ -1503,6 +1503,25 @@ macip_destroy_classify_tables (acl_main_t * am, u32 macip_acl_index)
 }

 static int
+macip_maybe_apply_unapply_classifier_tables(acl_main_t *am, u32 acl_index, int is_apply)
+{
+  int rv = 0;
+  int rv0 = 0;
+  int i;
+  macip_acl_list_t *a = pool_elt_at_index (am->macip_acls, acl_index);
+
+  for(i = 0; i < vec_len(am->macip_acl_by_sw_if_index); i++)
+    if (vec_elt(am->macip_acl_by_sw_if_index, i) == acl_index)
+      {
+        rv0 = vnet_set_input_acl_intfc (am->vlib_main, i, a->ip4_table_index,
+                              a->ip6_table_index, a->l2_table_index, is_apply);
+        /* return the first unhappy outcome but make try to plough through. */
+        rv = rv || rv0;
+      }
+  return rv;
+}
+
+static int
 macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
                    u32 * acl_list_index, u8 * tag)
 {
@@ -1511,6 +1530,7 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
   macip_acl_rule_t *r;
   macip_acl_rule_t *acl_new_rules = 0;
   int i;
+  int rv = 0;

   if (*acl_list_index != ~0)
     {
@@ -1531,6 +1551,9 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
        ("acl-plugin-warning: Trying to create empty MACIP ACL (tag %s)",
         tag);
     }
+  /* if replacing the ACL, unapply the classifier tables first - they will be gone.. */
+  if (~0 != *acl_list_index)
+    rv = macip_maybe_apply_unapply_classifier_tables(am, *acl_list_index, 0);
   void *oldheap = acl_set_heap (am);
   /* Create and populate the rules */
   if (count > 0)
@@ -1575,7 +1598,9 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
   /* Create and populate the classifer tables */
   macip_create_classify_tables (am, *acl_list_index);
   clib_mem_set_heap (oldheap);
-  return 0;
+  /* If the ACL was already applied somewhere, reapply the newly created tables */
+  rv = rv || macip_maybe_apply_unapply_classifier_tables(am, *acl_list_index, 1);
+  return rv;
 }

=== Let's test it. Though this time, for fun, let us also inspect the API message trace on VPP:

DBGvpp# api trace on

=== now run the commands on the VAT

vat# macip_acl_add_replace -1 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat# macip_acl_interface_add_del sw_if_index 0 add acl 0
vat# macip_acl_add_replace 0 ipv4 permit 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
vl_api_macip_acl_add_replace_reply_t_handler:107: ACL index: 0
vat#

=== now we are ready to inspect the API trace dump on the VPP, and look at the outputs

DBGvpp# api trace save macip-trace
API trace saved to /tmp/macip-trace
DBGvpp# api trace custom-dump /tmp/macip-trace
SCRIPT: macip_acl_add_replace -1 count 1 count 1 \
  ipv4 permit \
    src mac 00:00:00:00:00:00 mask 00:00:00:00:00:00 \
    src ip 0.0.0.0/0, \

SCRIPT: macip_acl_interface_add_del sw_if_index 0 acl_index 0 add
SCRIPT: macip_acl_add_replace 0 count 1 count 1 \
  ipv4 permit \
    src mac 00:00:00:00:00:00 mask 00:00:00:00:00:00 \
    src ip 0.0.0.0/0, \

DBGvpp# show acl-plugin macip acl
MACIP acl_index: 0, count: 1 (true len 1) tag {} is free pool slot: 0
  ip4_table_index 0, ip6_table_index 0, l2_table_index 0
    rule 0: ipv4 action 1 ip 0.0.0.0/0 mac 00:00:00:00:00:00 mask 00:00:00:00:00:00
DBGvpp# show classify tables
  TableIdx  Sessions   NextTbl  NextNode
         0         1         1        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
         1         1         2        -1
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff0000ffff0000000000000000000000000000
  linear-search buckets 0
         2         1         3        -1
  Heap: 3 objects, 236 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 3 flag 0 offset 0
  mask 00000000: 000000000000000000000000ffff0000ffff0000ffff00000000000000000000
       00000020: 00000000000000000000000000000000
  linear-search buckets 0
         3         1        -1         0
  Heap: 3 objects, 204 of 2k used, 76 free, 0 reclaimed, 1k overhead, 8188k capacity
  nbuckets 32, skip 0 match 2 flag 0 offset 0
  mask 000000000000000000000000ffff000000000000000000000000000000000000
  linear-search buckets 0
DBGvpp# show inacl type l2
 Intfc idx      Classify table		Interface name
         0                   0		local0
DBGvpp# show inacl type ip4
 Intfc idx      Classify table		Interface name
         0                   0		local0
DBGvpp# show inacl type ip6
 Intfc idx      Classify table		Interface name
         0                   0		local0
DBGvpp#

=== This looks way better, so mow we can try to see if unapplying the ACL will work

vat# macip_acl_interface_add_del sw_if_index 0 del acl 0
vat#

=== yay! let's see what happened on VPP:

DBGvpp# show inacl type l2
 Intfc idx      Classify table		Interface name
DBGvpp# show inacl type ip4
 Intfc idx      Classify table		Interface name
DBGvpp# show inacl type ip6
 Intfc idx      Classify table		Interface name
DBGvpp#

=== Yes, we can indeed see that the inacl were correctly removed from interfaces.

The resulting fix is in change 9772.

Index of /blog/2017-12-09-Debugging-VPP-MACIP-ACLs/

NameLast ModifiedSizeType
Parent Directory/ -  Directory
lighttpd/1.4.33