fib: make sure dpo is valid even when path pool expands 44/32644/1
authorBenoît Ganne <bganne@cisco.com>
Tue, 8 Jun 2021 16:44:37 +0000 (18:44 +0200)
committerBenoît Ganne <bganne@cisco.com>
Tue, 8 Jun 2021 16:53:01 +0000 (18:53 +0200)
The path pool can expand during in fib_path_attached_next_hop_get_adj()
when calling adj_nbr_add_or_lock(). If dpo points to a path->fp_dpo, its
reference becomes stale.
Use a temporary copy instead.

Type: fix

Change-Id: Ie966cb5f3f7b416425964dca12f1f586bfc2010c
Signed-off-by: Benoît Ganne <bganne@cisco.com>
src/vnet/fib/fib_path.c

index c580045..209cf40 100644 (file)
@@ -664,14 +664,18 @@ fib_path_attached_next_hop_get_adj (fib_path_t *path,
 static void
 fib_path_attached_next_hop_set (fib_path_t *path)
 {
+    dpo_id_t tmp = DPO_INVALID;
+
     /*
      * resolve directly via the adjacency discribed by the
      * interface and next-hop
      */
+    dpo_copy (&tmp, &path->fp_dpo);
     path = fib_path_attached_next_hop_get_adj(path,
                                               dpo_proto_to_link(path->fp_nh_proto),
-                                              &path->fp_dpo);
-
+                                              &tmp);
+    dpo_copy(&path->fp_dpo, &tmp);
+    dpo_reset(&tmp);
     ASSERT(dpo_is_adj(&path->fp_dpo));
 
     /*
@@ -1089,16 +1093,20 @@ FIXME comment
             /*
              * restack the DPO to pick up the correct DPO sub-type
              */
+            dpo_id_t tmp = DPO_INVALID;
             uword if_is_up;
 
             if_is_up = vnet_sw_interface_is_up(
                            vnet_get_main(),
                            path->attached_next_hop.fp_interface);
 
+            dpo_copy (&tmp, &path->fp_dpo);
             path = fib_path_attached_next_hop_get_adj(
                 path,
                 dpo_proto_to_link(path->fp_nh_proto),
-                &path->fp_dpo);
+                &tmp);
+            dpo_copy(&path->fp_dpo, &tmp);
+            dpo_reset(&tmp);
 
             path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
             if (if_is_up && adj_is_up(path->fp_dpo.dpoi_index))
@@ -2441,11 +2449,17 @@ fib_path_contribute_forwarding (fib_node_index_t path_index,
            case FIB_FORW_CHAIN_TYPE_NSH:
            case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
            case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
-               path = fib_path_attached_next_hop_get_adj(
-                    path,
-                    fib_forw_chain_type_to_link_type(fct),
-                    dpo);
-               break;
+                {
+                    dpo_id_t tmp = DPO_INVALID;
+                    dpo_copy (&tmp, dpo);
+                    path = fib_path_attached_next_hop_get_adj(
+                           path,
+                           fib_forw_chain_type_to_link_type(fct),
+                           &tmp);
+                    dpo_copy (dpo, &tmp);
+                    dpo_reset(&tmp);
+                    break;
+                }
            case FIB_FORW_CHAIN_TYPE_BIER:
                break;
            }