fib: Table Replace
[vpp.git] / src / vnet / mfib / ip4_mfib.c
index eaa61c0..4da1be6 100644 (file)
@@ -210,7 +210,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 +224,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 +303,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
@@ -334,7 +366,7 @@ 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);
 
@@ -474,9 +506,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)