X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fmfib%2Fip6_mfib.c;h=690f4ed9dfdb46770d7ddd6a90c322322e5f3055;hb=9db6ada77;hp=554a932844f2f00f54430b24fe2696411d8f469a;hpb=ae8098350cb7b96f7495fa4d4180238064256e14;p=vpp.git diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c index 554a932844f..690f4ed9dfd 100644 --- a/src/vnet/mfib/ip6_mfib.c +++ b/src/vnet/mfib/ip6_mfib.c @@ -141,8 +141,9 @@ ip6_create_mfib_with_table_id (u32 table_id, .frp_addr = zero_addr, .frp_sw_if_index = 0xffffffff, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = FIB_ROUTE_PATH_LOCAL, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; pool_get_aligned(ip6_main.mfibs, mfib_table, CLIB_CACHE_LINE_BYTES); @@ -180,8 +181,7 @@ ip6_create_mfib_with_table_id (u32 table_id, mfib_table_entry_path_update(mfib_table->mft_index, &pfx, MFIB_SOURCE_SPECIAL, - &path_for_us, - MFIB_ITF_FLAG_FORWARD); + &path_for_us); })); return (mfib_table->mft_index); @@ -200,7 +200,7 @@ ip6_mfib_table_destroy (ip6_mfib_t *mfib) .frp_addr = zero_addr, .frp_sw_if_index = 0xffffffff, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = FIB_ROUTE_PATH_LOCAL, }; @@ -236,7 +236,8 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable) .frp_addr = zero_addr, .frp_sw_if_index = sw_if_index, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, + .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT, }; mfib_prefix_t pfx = { .fp_proto = FIB_PROTOCOL_IP6, @@ -253,8 +254,7 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable) mfib_table_entry_path_update(mfib_index, &pfx, MFIB_SOURCE_SPECIAL, - &path, - MFIB_ITF_FLAG_ACCEPT); + &path); }); } else @@ -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 * @@ -406,7 +438,7 @@ ip6_mfib_table_lookup (const ip6_mfib_t *mfib, { len = table->prefix_lengths_in_search_order[i]; - ASSERT(len >= 0 && len <= 256); + ASSERT(len <= 256); IP6_MFIB_MK_KEY(mfib, grp, src, len, key); rv = clib_bihash_search_inline_2_40_8(&table->ip6_mhash, &key, &value); @@ -489,9 +521,14 @@ VLIB_INIT_FUNCTION(ip6_mfib_module_init); u8 * format_ip6_mfib_table_memory (u8 * s, va_list * args) { - s = format(s, "%=30s %=6d %=8s\n", + u64 bytes_inuse; + + bytes_inuse = alloc_arena_next(&(ip6_main.ip6_mtable.ip6_mhash)); + + s = format(s, "%=30s %=6d %=12ld\n", "IPv6 multicast", - pool_elts(ip6_main.mfibs), "???"); + pool_elts(ip6_main.mfibs), + bytes_inuse); return (s); } @@ -501,12 +538,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_ { @@ -514,14 +562,14 @@ typedef struct ip6_mfib_show_ctx_t_ { } ip6_mfib_show_ctx_t; -static int +static walk_rc_t ip6_mfib_table_collect_entries (fib_node_index_t mfei, void *arg) { ip6_mfib_show_ctx_t *ctx = arg; vec_add1(ctx->entries, mfei); - return (0); + return (WALK_CONTINUE); } static void @@ -561,7 +609,7 @@ typedef struct ip6_mfib_walk_ctx_t_ void *i6w_ctx; } ip6_mfib_walk_ctx_t; -static int +static void ip6_mfib_walk_cb (clib_bihash_kv_40_8_t * kvp, void *arg) { @@ -569,9 +617,8 @@ ip6_mfib_walk_cb (clib_bihash_kv_40_8_t * kvp, if ((kvp->key[4] >> 32) == ctx->i6w_mfib_index) { - return (ctx->i6w_fn(kvp->value, ctx->i6w_ctx)); + ctx->i6w_fn(kvp->value, ctx->i6w_ctx); } - return (FIB_TABLE_WALK_CONTINUE); } void @@ -600,11 +647,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 +682,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 +721,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); } }));