X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvnet%2Fmfib%2Fip4_mfib.c;h=d20d1f6c2b9784c1d003c893aee0835c2b9bc301;hb=775f73c;hp=7040fa71764779a2eb6277f2fc563b7f0bfdd7a6;hpb=c87aafad759f92ae630fec52079a08ace607410b;p=vpp.git diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c index 7040fa71764..d20d1f6c2b9 100644 --- a/src/vnet/mfib/ip4_mfib.c +++ b/src/vnet/mfib/ip4_mfib.c @@ -39,7 +39,7 @@ ip4_create_mfib_with_table_id (u32 table_id, 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 = @@ -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, @@ -425,12 +457,12 @@ ip4_show_mfib (vlib_main_t * vm, } 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; }