fib: doc nitfixes
[vpp.git] / src / vnet / mfib / ip4_mfib.c
index eaa61c0..206e451 100644 (file)
 #include <vnet/mfib/mfib_table.h>
 #include <vnet/mfib/mfib_entry.h>
 
-static const mfib_prefix_t ip4_specials[] = {
+static const mfib_prefix_t all_zeros =
+{
+    .fp_proto = FIB_PROTOCOL_IP4,
+};
+static const mfib_prefix_t ip4_specials[] =
+{
+    /* ALL prefixes are in network order */
     {
-        /* (*,*)/0 */
-        .fp_src_addr = {
-            .ip4.data_u32 = 0,
+        /* (*,224.0.0.1)/32 - all hosts */
+        .fp_grp_addr = {
+            .ip4.data_u32 = 0x010000e0,
         },
+        .fp_len = 32,
+        .fp_proto = FIB_PROTOCOL_IP4,
+    },
+    {
+        /* (*,224.0.0.2)/32 - all routers */
         .fp_grp_addr = {
-            .ip4.data_u32 = 0,
+            .ip4.data_u32 = 0x020000e0,
         },
-        .fp_len  = 0,
+        .fp_len = 32,
         .fp_proto = FIB_PROTOCOL_IP4,
     },
 };
@@ -57,24 +68,31 @@ ip4_create_mfib_with_table_id (u32 table_id,
     mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4, src);
 
     /*
-     * add the special entries into the new FIB
+     * add the default route into the new FIB
      */
+    mfib_table_entry_update(mfib_table->mft_index,
+                            &all_zeros,
+                            MFIB_SOURCE_DEFAULT_ROUTE,
+                            MFIB_RPF_ID_NONE,
+                            MFIB_ENTRY_FLAG_DROP);
+
+    const fib_route_path_t path = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_addr = zero_addr,
+        .frp_sw_if_index = ~0,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_flags = FIB_ROUTE_PATH_LOCAL,
+        .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
+    };
     int ii;
 
     for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++)
     {
-        mfib_prefix_t prefix = ip4_specials[ii];
-
-        prefix.fp_src_addr.ip4.data_u32 =
-            clib_host_to_net_u32(prefix.fp_src_addr.ip4.data_u32);
-        prefix.fp_grp_addr.ip4.data_u32 =
-            clib_host_to_net_u32(prefix.fp_grp_addr.ip4.data_u32);
-
-        mfib_table_entry_update(mfib_table->mft_index,
-                                &prefix,
-                                MFIB_SOURCE_DEFAULT_ROUTE,
-                                MFIB_RPF_ID_NONE,
-                                MFIB_ENTRY_FLAG_DROP);
+        mfib_table_entry_path_update(mfib_table->mft_index,
+                                     &ip4_specials[ii],
+                                     MFIB_SOURCE_SPECIAL,
+                                     &path);
     }
 
     return (mfib_table->mft_index);
@@ -89,18 +107,15 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib)
     /*
      * remove all the specials we added when the table was created.
      */
+    mfib_table_entry_delete(mfib_table->mft_index,
+                            &all_zeros,
+                            MFIB_SOURCE_DEFAULT_ROUTE);
+
     for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++)
     {
-        fib_node_index_t mfei;
-        mfib_prefix_t prefix = ip4_specials[ii];
-
-        prefix.fp_src_addr.ip4.data_u32 =
-            clib_host_to_net_u32(prefix.fp_src_addr.ip4.data_u32);
-        prefix.fp_grp_addr.ip4.data_u32 =
-            clib_host_to_net_u32(prefix.fp_grp_addr.ip4.data_u32);
-
-        mfei = mfib_table_lookup(mfib_table->mft_index, &prefix);
-        mfib_table_entry_delete_index(mfei, MFIB_SOURCE_DEFAULT_ROUTE);
+        mfib_table_entry_delete(mfib_table->mft_index,
+                                &ip4_specials[ii],
+                                MFIB_SOURCE_SPECIAL);
     }
 
     /*
@@ -113,6 +128,41 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib)
     pool_put(ip4_main.mfibs, mfib_table);
 }
 
+void
+ip4_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
+{
+    const fib_route_path_t path = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_addr = zero_addr,
+        .frp_sw_if_index = sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
+    };
+    u32 mfib_index;
+    int ii;
+
+    mfib_index = ip4_mfib_table_get_index_for_sw_if_index(sw_if_index);
+
+    for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++)
+    {
+        if (is_enable)
+        {
+            mfib_table_entry_path_update(mfib_index,
+                                         &ip4_specials[ii],
+                                         MFIB_SOURCE_SPECIAL,
+                                         &path);
+        }
+        else
+        {
+            mfib_table_entry_path_remove(mfib_index,
+                                         &ip4_specials[ii],
+                                         MFIB_SOURCE_SPECIAL,
+                                         &path);
+        }
+    }
+}
+
 u32
 ip4_mfib_table_find_or_create_and_lock (u32 table_id,
                                         mfib_source_t src)
@@ -210,7 +260,7 @@ ip4_mfib_table_lookup (const ip4_mfib_t *mfib,
         }
     }
 
-    for (mask_len = 32; mask_len >= 0; mask_len--)
+    for (mask_len = (len == 64 ? 32 : len); mask_len >= 0; mask_len--)
     {
         hash = mfib->fib_entry_by_dst_address[mask_len];
         IP4_MFIB_MK_GRP_KEY(grp, mask_len, key);
@@ -224,6 +274,38 @@ ip4_mfib_table_lookup (const ip4_mfib_t *mfib,
     return (FIB_NODE_INDEX_INVALID);
 }
 
+fib_node_index_t
+ip4_mfib_table_get_less_specific (const ip4_mfib_t *mfib,
+                                  const ip4_address_t *src,
+                                  const ip4_address_t *grp,
+                                  u32 len)
+{
+    u32 mask_len;
+
+    /*
+     * in the absence of a tree structure for the table that allows for an O(1)
+     * parent get, a cheeky way to find the cover is to LPM for the prefix with
+     * mask-1.
+     * there should always be a cover, though it may be the default route. the
+     * default route's cover is the default route.
+     */
+    if (len == 64)
+    {
+        /* go from (S,G) to (*,G*) */
+        mask_len = 32;
+    }
+    else if (len != 0)
+    {
+       mask_len = len - 1;
+    }
+    else
+    {
+        mask_len = len;
+    }
+
+    return (ip4_mfib_table_lookup(mfib, src, grp, mask_len));
+}
+
 void
 ip4_mfib_table_entry_insert (ip4_mfib_t *mfib,
                              const ip4_address_t *grp,
@@ -271,7 +353,7 @@ ip4_mfib_table_entry_remove (ip4_mfib_t *mfib,
     if (NULL == result)
     {
         /*
-         * removing a non-existant entry. i'll allow it.
+         * removing a non-existent entry. i'll allow it.
          */
     }
     else
@@ -313,8 +395,8 @@ format_ip4_mfib_table_memory (u8 * s, va_list * args)
 
     total_memory = 0;
 
-    pool_foreach (mfib_table, ip4_main.mfibs,
-    ({
+    pool_foreach (mfib_table, ip4_main.mfibs)
+     {
         ip4_mfib_t *mfib = &mfib_table->v4;
         uword mfib_size;
         int i;
@@ -332,9 +414,9 @@ format_ip4_mfib_table_memory (u8 * s, va_list * args)
         }
 
         total_memory += mfib_size;
-    }));
+    }
 
-    s = format(s, "%=30s %=6d %=8ld\n",
+    s = format(s, "%=30s %=6d %=12ld\n",
                "IPv4 multicast",
                pool_elts(ip4_main.mfibs), total_memory);
 
@@ -442,8 +524,8 @@ ip4_show_mfib (vlib_main_t * vm,
             break;
     }
 
-    pool_foreach (mfib_table, im4->mfibs,
-    ({
+    pool_foreach (mfib_table, im4->mfibs)
+     {
         ip4_mfib_t *mfib = &mfib_table->v4;
 
         if (table_id >= 0 && table_id != (int)mfib->table_id)
@@ -474,9 +556,10 @@ ip4_show_mfib (vlib_main_t * vm,
             continue;
         }
 
-        vlib_cli_output (vm, "%U, fib_index %d",
+        vlib_cli_output (vm, "%U, fib_index:%d flags:%U",
                          format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP4,
-                         mfib->index);
+                         mfib->index,
+                         format_mfib_table_flags, mfib_table->mft_flags);
 
         /* Show summary? */
         if (! verbose)
@@ -500,19 +583,20 @@ ip4_show_mfib (vlib_main_t * vm,
         {
             ip4_mfib_table_show_one(mfib, vm, &src, &grp, mask);
         }
-    }));
+    }
     if (memory)
         vlib_cli_output (vm, "totals: hash:%ld", total_hash_memory);
 
     return 0;
 }
 
+/* clang-format off */
 /*?
  * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and
  * the route entries for each table.
  *
  * @note This command will run for a long time when the FIB tables are
- * comprised of millions of entries. For those senarios, consider displaying
+ * comprised of millions of entries. For those scenarios, consider displaying
  * a single table or summary mode.
  *
  * @cliexpar
@@ -549,10 +633,9 @@ ip4_show_mfib (vlib_main_t * vm,
  *                   32               4
  * @cliexend
  ?*/
-/* *INDENT-OFF* */
+/* clang-format on */
 VLIB_CLI_COMMAND (ip4_show_mfib_command, static) = {
     .path = "show ip mfib",
     .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
     .function = ip4_show_mfib,
 };
-/* *INDENT-ON* */