diff options
author | Neale Ranns <nranns@cisco.com> | 2018-12-17 05:50:32 -0800 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-12-18 12:52:56 +0000 |
commit | 9e829a856fdf88b3ea5770048ea20dcd50d1b4eb (patch) | |
tree | 48506b15a4550b5f766248378d5aea03510ce0f8 /src/vnet/mfib/ip6_mfib.c | |
parent | 05b5d1b3a6663c0366e863adc845d7ee4facc1e3 (diff) |
MFIB: recurse resolution through an MFIB entry
Change-Id: I8dc261e40b8398c5c8ab6bb69ecebbd0176055d9
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/mfib/ip6_mfib.c')
-rw-r--r-- | src/vnet/mfib/ip6_mfib.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c index 554a932844f..d47887be699 100644 --- a/src/vnet/mfib/ip6_mfib.c +++ b/src/vnet/mfib/ip6_mfib.c @@ -365,7 +365,6 @@ ip6_mfib_table_fwd_lookup (const ip6_mfib_t *mfib, ASSERT(len >= 0 && len <= 256); IP6_MFIB_MK_KEY(mfib, grp, src, len, key); - rv = clib_bihash_search_inline_2_40_8(&table->ip6_mhash, &key, &value); if (rv == 0) return value.value; @@ -374,6 +373,39 @@ ip6_mfib_table_fwd_lookup (const ip6_mfib_t *mfib, return (FIB_NODE_INDEX_INVALID); } + +fib_node_index_t +ip6_mfib_table_get_less_specific (const ip6_mfib_t *mfib, + const ip6_address_t *src, + const ip6_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 == 256) + { + /* go from (S,G) to (*,G*) */ + mask_len = 128; + } + else if (len != 0) + { + mask_len = len - 1; + } + else + { + mask_len = len; + } + + return (ip6_mfib_table_lookup(mfib, src, grp, mask_len)); +} + /* * ip6_fib_table_lookup * @@ -501,12 +533,23 @@ ip6_mfib_table_show_one (ip6_mfib_t *mfib, vlib_main_t * vm, ip6_address_t *src, ip6_address_t *grp, - u32 mask_len) + u32 mask_len, + u32 cover) { - vlib_cli_output(vm, "%U", - format_mfib_entry, - ip6_mfib_table_lookup(mfib, src, grp, mask_len), - MFIB_ENTRY_FORMAT_DETAIL); + if (cover) + { + vlib_cli_output(vm, "%U", + format_mfib_entry, + ip6_mfib_table_get_less_specific(mfib, src, grp, mask_len), + MFIB_ENTRY_FORMAT_DETAIL); + } + else + { + vlib_cli_output(vm, "%U", + format_mfib_entry, + ip6_mfib_table_lookup(mfib, src, grp, mask_len), + MFIB_ENTRY_FORMAT_DETAIL); + } } typedef struct ip6_mfib_show_ctx_t_ { @@ -600,11 +643,12 @@ ip6_show_mfib (vlib_main_t * vm, mfib_table_t *mfib_table; int verbose, matching; ip6_address_t grp, src = {{0}}; - u32 mask = 32; + u32 mask = 128, cover; int table_id = -1, fib_index = ~0; verbose = 1; matching = 0; + cover = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -634,6 +678,8 @@ ip6_show_mfib (vlib_main_t * vm, ; else if (unformat (input, "index %d", &fib_index)) ; + else if (unformat (input, "cover")) + cover = 1; else break; } @@ -671,7 +717,7 @@ ip6_show_mfib (vlib_main_t * vm, } else { - ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask); + ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask, cover); } })); |