mfib_table_t *mfib_table;
pool_get_aligned(ip4_main.mfibs, mfib_table, CLIB_CACHE_LINE_BYTES);
- memset(mfib_table, 0, sizeof(*mfib_table));
+ clib_memset(mfib_table, 0, sizeof(*mfib_table));
mfib_table->mft_proto = FIB_PROTOCOL_IP4;
mfib_table->mft_index =
}
}
- 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);
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,
}
else if (unformat (input, "%U/%d", unformat_ip4_address, &grp, &mask))
{
- memset(&src, 0, sizeof(src));
+ clib_memset(&src, 0, sizeof(src));
matching = 1;
}
else if (unformat (input, "%U", unformat_ip4_address, &grp))
{
- memset(&src, 0, sizeof(src));
+ clib_memset(&src, 0, sizeof(src));
matching = 1;
mask = 32;
}