fib: adjacency midchain teardown (VPP-1841) 01/25301/2
authorNeale Ranns <nranns@cisco.com>
Tue, 18 Feb 2020 13:56:24 +0000 (13:56 +0000)
committerNeale Ranns <nranns@cisco.com>
Thu, 20 Feb 2020 14:01:47 +0000 (14:01 +0000)
Type: fix

Change-Id: I57f8bfbce4feed9d2775875cb8b1b729a47900a4
Signed-off-by: Neale Ranns <nranns@cisco.com>
(cherry picked from commit 24064d02aa9810ebc64c16dc778a179bb0ef5483)

src/vnet/adj/adj.c
src/vnet/adj/adj_internal.h
src/vnet/adj/adj_midchain.c

index c758ebe..3a2b2dd 100644 (file)
@@ -249,7 +249,7 @@ adj_last_lock_gone (ip_adjacency_t *adj)
     switch (adj->lookup_next_index)
     {
     case IP_LOOKUP_NEXT_MIDCHAIN:
-        dpo_reset(&adj->sub_type.midchain.next_dpo);
+        adj_midchain_teardown(adj);
         /* FALL THROUGH */
     case IP_LOOKUP_NEXT_ARP:
     case IP_LOOKUP_NEXT_REWRITE:
@@ -267,8 +267,10 @@ adj_last_lock_gone (ip_adjacency_t *adj)
        adj_glean_remove(adj->ia_nh_proto,
                         adj->rewrite_header.sw_if_index);
        break;
-    case IP_LOOKUP_NEXT_MCAST:
     case IP_LOOKUP_NEXT_MCAST_MIDCHAIN:
+        adj_midchain_teardown(adj);
+        /* FALL THROUGH */
+    case IP_LOOKUP_NEXT_MCAST:
        adj_mcast_remove(adj->ia_nh_proto,
                         adj->rewrite_header.sw_if_index);
        break;
index adb7a32..c4dda51 100644 (file)
@@ -124,6 +124,7 @@ extern void adj_glean_remove(fib_protocol_t proto,
                             u32 sw_if_index);
 extern void adj_mcast_remove(fib_protocol_t proto,
                             u32 sw_if_index);
+extern void adj_midchain_teardown(ip_adjacency_t *adj);
 
 extern u32 adj_dpo_get_urpf(const dpo_id_t *dpo);
 
index fcd6993..88648fe 100644 (file)
@@ -30,6 +30,8 @@
 static u32 adj_midchain_tx_feature_node[VNET_LINK_NUM];
 static u32 adj_midchain_tx_no_count_feature_node[VNET_LINK_NUM];
 
+static u32 *adj_midchain_feat_count_per_sw_if_index[VNET_LINK_NUM];
+
 /**
  * @brief Trace data for packets traversing the midchain tx node
  */
@@ -445,6 +447,30 @@ adj_nbr_midchain_get_feature_node (ip_adjacency_t *adj)
     return (adj_midchain_tx_feature_node[adj->ia_link]);
 }
 
+/**
+ * adj_midchain_setup
+ *
+ * Setup the adj as a mid-chain
+ */
+void
+adj_midchain_teardown (ip_adjacency_t *adj)
+{
+    u32 feature_index;
+    u8 arc_index;
+
+    dpo_reset(&adj->sub_type.midchain.next_dpo);
+
+    arc_index = adj_midchain_get_feature_arc_index_for_link_type (adj);
+    feature_index = adj_nbr_midchain_get_feature_node(adj);
+
+    if (0 == --adj_midchain_feat_count_per_sw_if_index[adj->ia_link][adj->rewrite_header.sw_if_index])
+    {
+        vnet_feature_enable_disable_with_index (arc_index, feature_index,
+                                                adj->rewrite_header.sw_if_index,
+                                                0, 0, 0);
+    }
+}
+
 /**
  * adj_midchain_setup
  *
@@ -473,9 +499,15 @@ adj_midchain_setup (adj_index_t adj_index,
     feature_index = adj_nbr_midchain_get_feature_node(adj);
     tx_node = adj_nbr_midchain_get_tx_node(adj);
 
-    vnet_feature_enable_disable_with_index (arc_index, feature_index,
-                                           adj->rewrite_header.sw_if_index,
-                                           1 /* enable */, 0, 0);
+    vec_validate (adj_midchain_feat_count_per_sw_if_index[adj->ia_link],
+                  adj->rewrite_header.sw_if_index);
+
+    if (0 == adj_midchain_feat_count_per_sw_if_index[adj->ia_link][adj->rewrite_header.sw_if_index]++)
+    {
+        vnet_feature_enable_disable_with_index (arc_index, feature_index,
+                                                adj->rewrite_header.sw_if_index,
+                                                1 /* enable */, 0, 0);
+    }
 
     /*
      * stack the midchain on the drop so it's ready to forward in the adj-midchain-tx.