hs-test: more debug output in http3 test
[vpp.git] / src / vnet / mfib / mfib_entry.c
index f169dc0..244dd4f 100644 (file)
@@ -38,6 +38,7 @@ static mfib_path_ext_t *mfib_path_ext_pool;
  * String names for each source
  */
 static const char *mfib_source_names[] = MFIB_SOURCE_NAMES;
+static const char *mfib_src_attribute_names[] = MFIB_ENTRY_SRC_ATTRIBUTES;
 
 /*
  * Pool for all fib_entries
@@ -101,6 +102,26 @@ format_mfib_entry_path_ext (u8 * s, va_list * args)
                    format_mfib_itf_flags, path_ext->mfpe_flags));
 }
 
+u8 *
+format_mfib_entry_src_flags (u8 *s, va_list *args)
+{
+    mfib_entry_src_attribute_t sattr;
+    mfib_entry_src_flags_t flag = va_arg(*args, int);
+
+    if (!flag)
+    {
+        return format(s, "none");
+    }
+
+    FOR_EACH_MFIB_SRC_ATTRIBUTE(sattr) {
+        if ((1 << sattr) & flag) {
+            s = format (s, "%s,", mfib_src_attribute_names[sattr]);
+        }
+    }
+
+    return (s);
+}
+
 u8 *
 format_mfib_entry (u8 * s, va_list * args)
 {
@@ -127,14 +148,15 @@ format_mfib_entry (u8 * s, va_list * args)
         s = format (s, " locks:%d\n", mfib_entry->mfe_node.fn_locks);
         vec_foreach(msrc, mfib_entry->mfe_srcs)
         {
-            s = format (s, "  src:%s locks:%d:",
+            s = format (s, "  src:%s flags:%U locks:%d:",
                         mfib_source_names[msrc->mfes_src],
+                        format_mfib_entry_src_flags, msrc->mfes_flags,
                         msrc->mfes_ref_count);
             if (msrc->mfes_cover != FIB_NODE_INDEX_INVALID)
             {
                 s = format (s, " cover:%d", msrc->mfes_cover);
             }
-            s = format (s, " %U\n", format_mfib_entry_flags, msrc->mfes_flags);
+            s = format (s, " %U\n", format_mfib_entry_flags, msrc->mfes_route_flags);
             if (FIB_NODE_INDEX_INVALID != msrc->mfes_pl)
             {
                 s = fib_path_list_format(msrc->mfes_pl, s);
@@ -201,7 +223,7 @@ mfib_entry_src_init (mfib_entry_t *mfib_entry,
 {
     mfib_entry_src_t esrc = {
         .mfes_pl = FIB_NODE_INDEX_INVALID,
-        .mfes_flags = MFIB_ENTRY_FLAG_NONE,
+        .mfes_route_flags = MFIB_ENTRY_FLAG_NONE,
         .mfes_src = source,
         .mfes_cover = FIB_NODE_INDEX_INVALID,
         .mfes_sibling = FIB_NODE_INDEX_INVALID,
@@ -215,8 +237,8 @@ mfib_entry_src_init (mfib_entry_t *mfib_entry,
 
 static mfib_entry_src_t *
 mfib_entry_src_find (const mfib_entry_t *mfib_entry,
-                    mfib_source_t source,
-                    u32 *index)
+                     mfib_source_t source,
+                     u32 *index)
 
 {
     mfib_entry_src_t *esrc;
@@ -269,8 +291,9 @@ mfib_entry_src_update (mfib_entry_t *mfib_entry,
 
     msrc = mfib_entry_src_find_or_create(mfib_entry, source);
 
-    msrc->mfes_flags = entry_flags;
+    msrc->mfes_route_flags = entry_flags;
     msrc->mfes_rpf_id = rpf_id;
+    msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE;
 
     return (msrc);
 }
@@ -286,6 +309,7 @@ mfib_entry_src_update_and_lock (mfib_entry_t *mfib_entry,
     msrc = mfib_entry_src_update(mfib_entry, source, rpf_id, entry_flags);
 
     msrc->mfes_ref_count++;
+    msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE;
 
     return (msrc);
 }
@@ -331,6 +355,44 @@ mfib_entry_is_sourced (fib_node_index_t mfib_entry_index,
     return (NULL != mfib_entry_src_find(mfib_entry, source, NULL));
 }
 
+int
+mfib_entry_is_marked (fib_node_index_t mfib_entry_index,
+                      mfib_source_t source)
+{
+    mfib_entry_t *mfib_entry;
+    mfib_entry_src_t *esrc;
+
+    mfib_entry = mfib_entry_get(mfib_entry_index);
+
+    esrc = mfib_entry_src_find(mfib_entry, source, NULL);
+
+    if (NULL == esrc)
+    {
+        return (0);
+    }
+    else
+    {
+        return (!!(esrc->mfes_flags & MFIB_ENTRY_SRC_FLAG_STALE));
+    }
+}
+
+void
+mfib_entry_mark (fib_node_index_t fib_entry_index,
+                 mfib_source_t source)
+{
+    mfib_entry_t *mfib_entry;
+    mfib_entry_src_t *esrc;
+
+    mfib_entry = mfib_entry_get(fib_entry_index);
+
+    esrc = mfib_entry_src_find(mfib_entry, source, NULL);
+
+    if (NULL != esrc)
+    {
+        esrc->mfes_flags |= MFIB_ENTRY_SRC_FLAG_STALE;
+    }
+}
+
 int
 mfib_entry_is_host (fib_node_index_t mfib_entry_index)
 {
@@ -350,6 +412,8 @@ mfib_entry_src_flush (mfib_entry_src_t *msrc)
     }));
     hash_free(msrc->mfes_itfs);
     msrc->mfes_itfs = NULL;
+    hash_free(msrc->mfes_exts);
+    msrc->mfes_exts = NULL;
     fib_path_list_unlock(msrc->mfes_pl);
 }
 
@@ -435,7 +499,7 @@ mfib_entry_alloc (u32 fib_index,
 }
 
 static inline mfib_path_ext_t *
-mfib_entry_path_ext_find (mfib_path_ext_t *exts,
+mfib_entry_path_ext_find (uword *exts,
                           fib_node_index_t path_index)
 {
     uword *p;
@@ -485,6 +549,7 @@ typedef struct mfib_entry_collect_forwarding_ctx_t_
     load_balance_path_t * next_hops;
     fib_forward_chain_type_t fct;
     mfib_entry_src_t *msrc;
+    dpo_proto_t payload_proto;
 } mfib_entry_collect_forwarding_ctx_t;
 
 static fib_path_list_walk_rc_t
@@ -530,7 +595,8 @@ mfib_entry_src_collect_forwarding (fib_node_index_t pl_index,
 
         nh->path_index = path_index;
         nh->path_weight = fib_path_get_weight(path_index);
-        fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo);
+        fib_path_contribute_forwarding(path_index, ctx->fct,
+                                       ctx->payload_proto, &nh->path_dpo);
         break;
 
     case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
@@ -570,6 +636,7 @@ mfib_entry_stack (mfib_entry_t *mfib_entry,
             .next_hops = NULL,
             .fct = mfib_entry_get_default_chain_type(mfib_entry),
             .msrc = msrc,
+            .payload_proto = fib_proto_to_dpo(mfib_entry->mfe_prefix.fp_proto),
         };
 
         /*
@@ -578,7 +645,7 @@ mfib_entry_stack (mfib_entry_t *mfib_entry,
          * updates to recalculate forwarding.
          */
         mfib_entry->mfe_pl = msrc->mfes_pl;
-        mfib_entry->mfe_flags = msrc->mfes_flags;
+        mfib_entry->mfe_flags = msrc->mfes_route_flags;
         mfib_entry->mfe_itfs = msrc->mfes_itfs;
         mfib_entry->mfe_rpf_id = msrc->mfes_rpf_id;
 
@@ -677,7 +744,9 @@ static fib_node_index_t*
 mfib_entry_src_paths_add (mfib_entry_src_t *msrc,
                           const fib_route_path_t *rpaths)
 {
-    ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags));
+    ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_route_flags));
+
+    msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE;
 
     if (FIB_NODE_INDEX_INVALID == msrc->mfes_pl)
     {
@@ -694,7 +763,9 @@ static fib_node_index_t*
 mfib_entry_src_paths_remove (mfib_entry_src_t *msrc,
                              const fib_route_path_t *rpaths)
 {
-    ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags));
+    ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_route_flags));
+
+    msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE;
 
     return (fib_path_list_paths_remove(msrc->mfes_pl, rpaths));
 }
@@ -792,11 +863,11 @@ static int
 mfib_entry_src_ok_for_delete (const mfib_entry_src_t *msrc)
 {
     return ((INDEX_INVALID == msrc->mfes_cover &&
-             MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags &&
+             MFIB_ENTRY_FLAG_NONE == msrc->mfes_route_flags &&
              0 == fib_path_list_get_n_paths(msrc->mfes_pl)) &&
             (0 == hash_elts(msrc->mfes_itfs)));
 
-    /* return ((MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags) && */
+    /* return ((MFIB_ENTRY_FLAG_NONE == msrc->mfes_route_flags) && */
     /*         (0 == fib_path_list_get_n_paths(msrc->mfes_pl)) && */
     /*         (0 == hash_elts(msrc->mfes_itfs))); */
 }
@@ -926,12 +997,14 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index,
     const fib_route_path_t *rpath;
     mfib_source_t current_best;
     mfib_path_ext_t *path_ext;
+    const mfib_prefix_t *pfx;
     mfib_entry_t *mfib_entry;
     mfib_entry_src_t *msrc;
     mfib_itf_flags_t old;
     u32 ii;
 
     mfib_entry = mfib_entry_get(mfib_entry_index);
+    pfx = mfib_entry_get_prefix(mfib_entry_index);
     ASSERT(NULL != mfib_entry);
     current_best = mfib_entry_get_best_source(mfib_entry);
     msrc = mfib_entry_src_find_or_create(mfib_entry, source);
@@ -985,13 +1058,23 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index,
 
                 if (NULL == mfib_itf)
                 {
+                    index_t mfib_itf_i = mfib_itf_create(path_index,
+                                                         rpath->frp_mitf_flags);
                     mfib_entry_itf_add(msrc,
                                        rpath->frp_sw_if_index,
-                                       mfib_itf_create(path_index,
-                                                       rpath->frp_mitf_flags));
+                                       mfib_itf_i);
+
+                    if (MFIB_ITF_FLAG_ACCEPT & rpath->frp_mitf_flags)
+                    {
+                        /* new accepting interface - add the mac to the driver */
+                        mfib_itf_mac_add(mfib_itf_get(mfib_itf_i), pfx);
+                    }
                 }
                 else
                 {
+                    u8 was_accept = !!(old & MFIB_ITF_FLAG_ACCEPT);
+                    u8 is_accept = !!(rpath->frp_mitf_flags & MFIB_ITF_FLAG_ACCEPT);
+
                     if (mfib_itf_update(mfib_itf,
                                         path_index,
                                         rpath->frp_mitf_flags))
@@ -1000,8 +1083,32 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index,
                          * no more interface flags on this path, remove
                          * from the data-plane set
                          */
+                        if (was_accept)
+                        {
+                            mfib_itf_mac_del(mfib_itf, pfx);
+
+                        }
                         mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index);
                     }
+                    else
+                    {
+                        /*
+                         * is there a change to the ACCEPT flag that
+                         * requires us to update hte driver with the
+                         * MAC
+                         */
+                        if (is_accept != was_accept)
+                        {
+                            if (is_accept)
+                            {
+                                mfib_itf_mac_add(mfib_itf, pfx);
+                            }
+                            else if (was_accept)
+                            {
+                                mfib_itf_mac_del(mfib_itf, pfx);
+                            }
+                        }
+                    }
                 }
             }
         }
@@ -1025,11 +1132,13 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index,
     fib_node_index_t path_index, *path_indices;
     const fib_route_path_t *rpath;
     mfib_source_t current_best;
+    const mfib_prefix_t *pfx;
     mfib_entry_t *mfib_entry;
     mfib_entry_src_t *msrc;
     u32 ii;
 
     mfib_entry = mfib_entry_get(mfib_entry_index);
+    pfx = mfib_entry_get_prefix(mfib_entry_index);
     ASSERT(NULL != mfib_entry);
     current_best = mfib_entry_get_best_source(mfib_entry);
     msrc = mfib_entry_src_find(mfib_entry, source, NULL);
@@ -1062,34 +1171,50 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index,
         mfib_path_ext_remove(msrc, path_index);
         if (mfib_entry_path_itf_based(rpath))
         {
+            u8 was_accept, is_accept;
             mfib_itf_t *mfib_itf;
 
             mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs,
                                            rpath->frp_sw_if_index);
+            was_accept = !!(MFIB_ITF_FLAG_ACCEPT & mfib_itf->mfi_flags);
 
             if (mfib_itf_update(mfib_itf,
                                 path_index,
                                 MFIB_ITF_FLAG_NONE))
             {
+                if (was_accept)
+                {
+                    mfib_itf_mac_del(mfib_itf, pfx);                    
+                }
+
                 /*
                  * no more interface flags on this path, remove
                  * from the data-plane set
                  */
                 mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index);
             }
-        }
+            else
+            {
+                is_accept = !!(MFIB_ITF_FLAG_ACCEPT & mfib_itf->mfi_flags);
 
-        if (mfib_entry_src_ok_for_delete(msrc))
-        {
-            /*
-             * this source has no interfaces and no flags.
-             * it has nothing left to give - remove it
-             */
-            mfib_entry_src_remove(mfib_entry, source);
+                if (was_accept && !is_accept)
+                {
+                    mfib_itf_mac_del(mfib_itf, pfx);                    
+                }
+            }
         }
     }
     vec_free(path_indices);
 
+    if (mfib_entry_src_ok_for_delete(msrc))
+      {
+        /*
+         * this source has no interfaces and no flags.
+         * it has nothing left to give - remove it
+         */
+        mfib_entry_src_remove(mfib_entry, source);
+      }
+
     mfib_entry_recalculate_forwarding(mfib_entry, current_best);
 
     return (mfib_entry_ok_for_delete(mfib_entry));
@@ -1425,7 +1550,8 @@ mfib_entry_contribute_forwarding (fib_node_index_t mfib_entry_index,
             /*
              * caller does not want the local paths that the entry has
              */
-            dpo_set(dpo, DPO_REPLICATE, rep->rep_proto,
+            dpo_proto_t rep_proto = rep->rep_proto;
+            dpo_set(dpo, DPO_REPLICATE, rep_proto,
                     replicate_dup(REPLICATE_FLAGS_NONE,
                                   mfib_entry->mfe_rep.dpoi_index));
         }
@@ -1525,21 +1651,21 @@ show_mfib_entry_command (vlib_main_t * vm,
          * show all
          */
         vlib_cli_output (vm, "FIB Entries:");
-        pool_foreach_index(fei, mfib_entry_pool,
-        ({
+        pool_foreach_index (fei, mfib_entry_pool)
+         {
             vlib_cli_output (vm, "%d@%U",
                              fei,
                              format_mfib_entry, fei,
                              MFIB_ENTRY_FORMAT_BRIEF);
-        }));
+        }
     }
 
     return (NULL);
 }
 
 /*?
- * This commnad displays an entry, or all entries, in the mfib tables indexed by their unique
- * numerical indentifier.
+ * This command displays an entry, or all entries, in the mfib tables indexed
+ * by their unique numerical identifier.
  ?*/
 VLIB_CLI_COMMAND (show_mfib_entry, static) = {
   .path = "show mfib entry",