fib: Adjacency walk fix for IPv6
[vpp.git] / src / vnet / adj / adj_nbr.c
index cbd6691..28ee53e 100644 (file)
@@ -221,12 +221,12 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto,
                     u32 sw_if_index)
 {
     adj_index_t adj_index;
-    ip_adjacency_t *adj;
 
     adj_index = adj_nbr_find(nh_proto, link_type, nh_addr, sw_if_index);
 
     if (ADJ_INDEX_INVALID == adj_index)
     {
+        ip_adjacency_t *adj;
        vnet_main_t *vnm;
 
        vnm = vnet_get_main();
@@ -256,6 +256,7 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto,
        adj_lock(adj_index);
     }
 
+    adj_delegate_adj_created(adj_get(adj_index));
     return (adj_index);
 }
 
@@ -284,6 +285,8 @@ adj_nbr_add_or_lock_w_rewrite (fib_protocol_t nh_proto,
                           ADJ_NBR_REWRITE_FLAG_COMPLETE,
                           rewrite);
 
+    adj_delegate_adj_created(adj_get(adj_index));
+
     return (adj_index);
 }
 
@@ -518,12 +521,13 @@ typedef struct adj_db_count_ctx_t_ {
     u64 count;
 } adj_db_count_ctx_t;
 
-static void
+static int
 adj_db_count (BVT(clib_bihash_kv) * kvp,
              void *arg)
 {
     adj_db_count_ctx_t * ctx = arg;
     ctx->count++;
+    return (BIHASH_WALK_CONTINUE);
 }
 
 u32
@@ -560,14 +564,16 @@ typedef struct adj_walk_ctx_t_
     void *awc_ctx;
 } adj_walk_ctx_t;
 
-static void
+static int
 adj_nbr_walk_cb (BVT(clib_bihash_kv) * kvp,
                 void *arg)
 {
     adj_walk_ctx_t *ctx = arg;
 
     // FIXME: can't stop early...
-    ctx->awc_cb(kvp->value, ctx->awc_ctx);
+    if (ADJ_WALK_RC_STOP == ctx->awc_cb(kvp->value, ctx->awc_ctx))
+        return (BIHASH_WALK_STOP);
+    return (BIHASH_WALK_CONTINUE);
 }
 
 void
@@ -665,7 +671,7 @@ adj_nbr_walk_nh (u32 sw_if_index,
 
     FOR_EACH_VNET_LINK(linkt)
     {
-        ai = adj_nbr_find (FIB_PROTOCOL_IP4, linkt, nh, sw_if_index);
+        ai = adj_nbr_find (adj_nh_proto, linkt, nh, sw_if_index);
 
         if (INDEX_INVALID != ai)
             cb(ai, ctx);
@@ -823,12 +829,15 @@ adj_nbr_interface_delete_one (adj_index_t ai,
     };
     ip_adjacency_t *adj;
 
+    adj_lock(ai);
+
     adj = adj_get(ai);
 
     adj->ia_flags |= ADJ_FLAG_SYNC_WALK_ACTIVE;
     fib_walk_sync(FIB_NODE_TYPE_ADJ, ai, &bw_ctx);
     adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE;
 
+    adj_unlock(ai);
     return (ADJ_WALK_RC_CONTINUE);
 }