Dump routes (VPP-500)
[vpp.git] / vnet / vnet / fib / fib_entry.c
index 8b275c6..da2656e 100644 (file)
@@ -90,7 +90,8 @@ fib_entry_chain_type_fixup (const fib_entry_t *entry,
             * then use the payload-protocol field, that we stashed there
             * for just this purpose
             */
-           return (fib_proto_to_forw_chain_type(entry->fe_prefix.fp_payload_proto));
+           return (fib_forw_chain_type_from_dpo_proto(
+                       entry->fe_prefix.fp_payload_proto));
        }
        /*
         * else give them what this entry would be by default. i.e. if it's a v6
@@ -120,7 +121,8 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry)
             * then use the payload-protocol field, that we stashed there
             * for just this purpose
             */
-           return (fib_proto_to_forw_chain_type(fib_entry->fe_prefix.fp_payload_proto));
+           return (fib_forw_chain_type_from_dpo_proto(
+                       fib_entry->fe_prefix.fp_payload_proto));
        else
            return (FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS);
     }
@@ -209,7 +211,7 @@ format_fib_entry (u8 * s, va_list * args)
         if (level >= FIB_ENTRY_FORMAT_DETAIL2)
         {
 
-            FOR_EACH_FIB_FORW_CHAIN(fct)
+            FOR_EACH_FIB_FORW_MPLS_CHAIN(fct)
             {
                 s = format(s, "  %U-chain\n  %U",
                            format_fib_forw_chain_type, fct,
@@ -318,7 +320,7 @@ fib_entry_last_lock_gone (fib_node_t *node)
 
     fib_entry = fib_entry_from_fib_node(node);
 
-    FOR_EACH_FIB_FORW_CHAIN(fct)
+    FOR_EACH_FIB_FORW_MPLS_CHAIN(fct)
     {
        dpo_reset(&fib_entry->fe_lb[fct]);
     }
@@ -391,6 +393,7 @@ fib_entry_back_walk_notify (fib_node_t *node,
 
     if (FIB_NODE_BW_REASON_FLAG_EVALUATE & ctx->fnbw_reason        ||
         FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason      ||
+        FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason        ||
        FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason    ||
        FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason  ||
        FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason)
@@ -400,39 +403,58 @@ fib_entry_back_walk_notify (fib_node_t *node,
                                             fib_entry_get_index(fib_entry)));
     }
 
-    if (FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason)
-    {
-        /*
-         * ADJ updates (complete<->incomplete) do not need to propagate to
-         * recursive entries.
-         * The only reason its needed as far back as here, is that the adj
-         * and the incomplete adj are a different DPO type, so the LBs need
-         * to re-stack.
-         */
-        return (FIB_NODE_BACK_WALK_CONTINUE);
-    }
-    else
-    {
-        /*
-         * all other walk types can be reclassifed to a re-evaluate to
-         * all recursive dependents.
-         * By reclassifying we ensure that should any of these walk types meet
-         * they can be merged.
-         */
-        ctx->fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
-
-        /*
-         * propagate the backwalk further if we haven't already reached the
-         * maximum depth.
-         */
-        fib_walk_sync(FIB_NODE_TYPE_ENTRY,
-                      fib_entry_get_index(fib_entry),
-                      ctx);
-    }
+    /*
+     * all other walk types can be reclassifed to a re-evaluate to
+     * all recursive dependents.
+     * By reclassifying we ensure that should any of these walk types meet
+     * they can be merged.
+     */
+    ctx->fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
+
+    /*
+     * ... and nothing is forced sync from now on.
+     */
+    ctx->fnbw_flags &= ~FIB_NODE_BW_FLAG_FORCE_SYNC;
+
+    /*
+     * propagate the backwalk further if we haven't already reached the
+     * maximum depth.
+     */
+    fib_walk_sync(FIB_NODE_TYPE_ENTRY,
+                 fib_entry_get_index(fib_entry),
+                 ctx);
 
     return (FIB_NODE_BACK_WALK_CONTINUE);
 }
 
+static void
+fib_entry_show_memory (void)
+{
+    u32 n_srcs = 0, n_exts = 0;
+    fib_entry_src_t *esrc;
+    fib_entry_t *entry;
+
+    fib_show_memory_usage("Entry",
+                         pool_elts(fib_entry_pool),
+                         pool_len(fib_entry_pool),
+                         sizeof(fib_entry_t));
+
+    pool_foreach(entry, fib_entry_pool,
+    ({
+       n_srcs += vec_len(entry->fe_srcs);
+       vec_foreach(esrc, entry->fe_srcs)
+       {
+           n_exts += vec_len(esrc->fes_path_exts);
+       }
+    }));
+
+    fib_show_memory_usage("Entry Source",
+                         n_srcs, n_srcs, sizeof(fib_entry_src_t));
+    fib_show_memory_usage("Entry Path-Extensions",
+                         n_exts, n_exts,
+                         sizeof(fib_path_ext_t));
+}
+
 /*
  * The FIB path-list's graph node virtual function table
  */
@@ -440,8 +462,24 @@ static const fib_node_vft_t fib_entry_vft = {
     .fnv_get = fib_entry_get_node,
     .fnv_last_lock = fib_entry_last_lock_gone,
     .fnv_back_walk = fib_entry_back_walk_notify,
+    .fnv_mem_show = fib_entry_show_memory,
 };
 
+/**
+ * @brief Contribute the set of Adjacencies that this entry forwards with
+ * to build the uRPF list of its children
+ */
+void
+fib_entry_contribute_urpf (fib_node_index_t entry_index,
+                          index_t urpf)
+{
+    fib_entry_t *fib_entry;
+
+    fib_entry = fib_entry_get(entry_index);
+
+    return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf));
+}
+
 /*
  * fib_entry_contribute_forwarding
  *
@@ -514,14 +552,6 @@ fib_entry_get_path_list (fib_node_index_t fib_entry_index)
     return (fib_entry->fe_parent);
 }
 
-u32
-fib_entry_get_fib_table_id(fib_node_index_t fib_entry_index)
-{
-    
-
-    return (0);
-}
-
 u32
 fib_entry_child_add (fib_node_index_t fib_entry_index,
                     fib_node_type_t child_type,
@@ -567,7 +597,7 @@ fib_entry_alloc (u32 fib_index,
     fib_entry->fe_export = FIB_NODE_INDEX_INVALID;
     fib_entry->fe_import = FIB_NODE_INDEX_INVALID;
     fib_entry->fe_covered = FIB_NODE_INDEX_INVALID;
-    FOR_EACH_FIB_FORW_CHAIN(fct)
+    FOR_EACH_FIB_FORW_MPLS_CHAIN(fct)
     {
        dpo_reset(&fib_entry->fe_lb[fct]);
     }
@@ -729,39 +759,26 @@ fib_entry_post_update_actions (fib_entry_t *fib_entry,
     fib_entry_post_install_actions(fib_entry, source, old_flags);
 }
 
-void
-fib_entry_special_add (fib_node_index_t fib_entry_index,
-                      fib_source_t source,
-                      fib_entry_flag_t flags,
-                      const dpo_id_t *dpo)
+static void
+fib_entry_source_change (fib_entry_t *fib_entry,
+                        fib_source_t best_source,
+                        fib_source_t new_source,
+                        fib_entry_flag_t old_flags)
 {
-    fib_source_t best_source;
-    fib_entry_flag_t bflags;
-    fib_entry_t *fib_entry;
-    fib_entry_src_t *bsrc;
-
-    fib_entry = fib_entry_get(fib_entry_index);
-
-    bsrc = fib_entry_get_best_src_i(fib_entry);
-    best_source = fib_entry_src_get_source(bsrc);
-    bflags = fib_entry_src_get_flags(bsrc);
-
-    fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
-
     /*
      * if the path list for the source passed is invalid,
      * then we need to create a new one. else we are updating
      * an existing.
      */
-    if (source < best_source)
+    if (new_source < best_source)
     {
        /*
         * we have a new winning source.
         */
        fib_entry_src_action_deactivate(fib_entry, best_source);
-       fib_entry_src_action_activate(fib_entry, source);
+       fib_entry_src_action_activate(fib_entry, new_source);
     }
-    else if (source > best_source)
+    else if (new_source > best_source)
     {
        /*
         * the new source loses. nothing to do here.
@@ -776,13 +793,56 @@ fib_entry_special_add (fib_node_index_t fib_entry_index,
         * But the path-list was updated, which will contribute new forwarding,
         * so install it.
         */
-       fib_entry_src_action_deactivate(fib_entry, source);
-       fib_entry_src_action_activate(fib_entry, source);
+       fib_entry_src_action_deactivate(fib_entry, new_source);
+       fib_entry_src_action_activate(fib_entry, new_source);
     }
 
-    fib_entry_post_update_actions(fib_entry, source, bflags);
+    fib_entry_post_update_actions(fib_entry, new_source, old_flags);
+}
+
+void
+fib_entry_special_add (fib_node_index_t fib_entry_index,
+                      fib_source_t source,
+                      fib_entry_flag_t flags,
+                      const dpo_id_t *dpo)
+{
+    fib_source_t best_source;
+    fib_entry_flag_t bflags;
+    fib_entry_t *fib_entry;
+    fib_entry_src_t *bsrc;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+
+    bsrc = fib_entry_get_best_src_i(fib_entry);
+    best_source = fib_entry_src_get_source(bsrc);
+    bflags = fib_entry_src_get_flags(bsrc);
+
+    fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
+    fib_entry_source_change(fib_entry, best_source, source, bflags);
+}
+
+void
+fib_entry_special_update (fib_node_index_t fib_entry_index,
+                         fib_source_t source,
+                         fib_entry_flag_t flags,
+                         const dpo_id_t *dpo)
+{
+    fib_source_t best_source;
+    fib_entry_flag_t bflags;
+    fib_entry_t *fib_entry;
+    fib_entry_src_t *bsrc;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+
+    bsrc = fib_entry_get_best_src_i(fib_entry);
+    best_source = fib_entry_src_get_source(bsrc);
+    bflags = fib_entry_src_get_flags(bsrc);
+
+    fib_entry = fib_entry_src_action_update(fib_entry, source, flags, dpo);
+    fib_entry_source_change(fib_entry, best_source, source, bflags);
 }
 
+
 void
 fib_entry_path_add (fib_node_index_t fib_entry_index,
                    fib_source_t source,
@@ -1271,7 +1331,7 @@ fib_entry_recursive_loop_detect (fib_node_index_t entry_index,
             * re-evaluate all the entry's forwarding
             * NOTE: this is an inplace modify
             */
-           FOR_EACH_FIB_FORW_CHAIN(fct)
+           FOR_EACH_FIB_FORW_MPLS_CHAIN(fct)
            {
                if (dpo_id_is_valid(&fib_entry->fe_lb[fct]))
                {
@@ -1418,6 +1478,16 @@ fib_entry_module_init (void)
     fib_node_register_type (FIB_NODE_TYPE_ENTRY, &fib_entry_vft);
 }
 
+void
+fib_entry_encode (fib_node_index_t fib_entry_index,
+                 fib_route_path_encode_t **api_rpaths)
+{
+    fib_entry_t *fib_entry;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+    fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths);
+}
+
 void
 fib_entry_get_prefix (fib_node_index_t fib_entry_index,
                      fib_prefix_t *pfx)