X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fmfib%2Fip4_mfib.c;h=4da1be611135a07d38b71fb7c463fe9e732d4d2c;hb=9db6ada77;hp=3e7bdd81bbfab8b12b3bd4167c6918d22c0d8dc1;hpb=c756c1c7903feca20194bf3ba88863307668106a;p=vpp.git diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c index 3e7bdd81bbf..4da1be61113 100644 --- a/src/vnet/mfib/ip4_mfib.c +++ b/src/vnet/mfib/ip4_mfib.c @@ -33,12 +33,13 @@ static const mfib_prefix_t ip4_specials[] = { }; static u32 -ip4_create_mfib_with_table_id (u32 table_id) +ip4_create_mfib_with_table_id (u32 table_id, + mfib_source_t src) { 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 = @@ -53,7 +54,7 @@ ip4_create_mfib_with_table_id (u32 table_id) mfib_table->v4.table_id = table_id; - mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4); + mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4, src); /* * add the special entries into the new FIB @@ -72,6 +73,7 @@ ip4_create_mfib_with_table_id (u32 table_id) mfib_table_entry_update(mfib_table->mft_index, &prefix, MFIB_SOURCE_DEFAULT_ROUTE, + MFIB_RPF_ID_NONE, MFIB_ENTRY_FLAG_DROP); } @@ -112,14 +114,15 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib) } u32 -ip4_mfib_table_find_or_create_and_lock (u32 table_id) +ip4_mfib_table_find_or_create_and_lock (u32 table_id, + mfib_source_t src) { u32 index; index = ip4_mfib_index_from_table_id(table_id); if (~0 == index) - return ip4_create_mfib_with_table_id(table_id); - mfib_table_lock(index, FIB_PROTOCOL_IP4); + return ip4_create_mfib_with_table_id(table_id, src); + mfib_table_lock(index, FIB_PROTOCOL_IP4, src); return (index); } @@ -207,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); @@ -221,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, @@ -268,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 @@ -279,6 +314,65 @@ ip4_mfib_table_entry_remove (ip4_mfib_t *mfib, mfib->fib_entry_by_dst_address[len] = hash; } +void +ip4_mfib_table_walk (ip4_mfib_t *mfib, + mfib_table_walk_fn_t fn, + void *ctx) +{ + int i; + + for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) + { + uword * hash = mfib->fib_entry_by_dst_address[i]; + + if (NULL != hash) + { + hash_pair_t * p; + + hash_foreach_pair (p, hash, + ({ + fn(p->value[0], ctx); + })); + } + } +} + +u8 * +format_ip4_mfib_table_memory (u8 * s, va_list * args) +{ + mfib_table_t *mfib_table; + u64 total_memory; + + total_memory = 0; + + pool_foreach (mfib_table, ip4_main.mfibs, + ({ + ip4_mfib_t *mfib = &mfib_table->v4; + uword mfib_size; + int i; + + mfib_size = 0; + + for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) + { + uword * hash = mfib->fib_entry_by_dst_address[i]; + + if (NULL != hash) + { + mfib_size += hash_bytes(hash); + } + } + + total_memory += mfib_size; + })); + + s = format(s, "%=30s %=6d %=12ld\n", + "IPv4 multicast", + pool_elts(ip4_main.mfibs), total_memory); + + return (s); +} + static void ip4_mfib_table_show_all (ip4_mfib_t *mfib, vlib_main_t * vm) @@ -337,20 +431,23 @@ ip4_show_mfib (vlib_main_t * vm, { ip4_main_t * im4 = &ip4_main; mfib_table_t *mfib_table; - int verbose, matching; + int verbose, matching, memory; ip4_address_t grp, src = {{0}}; u32 mask = 32; + u64 total_hash_memory; int i, table_id = -1, fib_index = ~0; verbose = 1; - matching = 0; + memory = matching = 0; + total_hash_memory = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "brief") || unformat (input, "summary") || unformat (input, "sum")) verbose = 0; - + else if (unformat (input, "mem") || unformat (input, "memory")) + memory = 1; else if (unformat (input, "%U %U", unformat_ip4_address, &src, unformat_ip4_address, &grp)) @@ -358,14 +455,17 @@ ip4_show_mfib (vlib_main_t * vm, matching = 1; mask = 64; } + else if (unformat (input, "%U/%d", unformat_ip4_address, &grp, &mask)) + { + clib_memset(&src, 0, sizeof(src)); + matching = 1; + } else if (unformat (input, "%U", unformat_ip4_address, &grp)) { + clib_memset(&src, 0, sizeof(src)); matching = 1; mask = 32; } - else if (unformat (input, "%U/%d", - unformat_ip4_address, &grp, &mask)) - matching = 1; else if (unformat (input, "table %d", &table_id)) ; else if (unformat (input, "index %d", &fib_index)) @@ -383,9 +483,33 @@ ip4_show_mfib (vlib_main_t * vm, if (fib_index != ~0 && fib_index != (int)mfib->index) continue; - vlib_cli_output (vm, "%U, fib_index %d", + if (memory) + { + uword hash_size; + + hash_size = 0; + + for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) + { + uword * hash = mfib->fib_entry_by_dst_address[i]; + if (NULL != hash) + { + hash_size += hash_bytes(hash); + } + } + if (verbose) + vlib_cli_output (vm, "%U hash:%d", + format_mfib_table_name, mfib->index, + FIB_PROTOCOL_IP4, + hash_size); + total_hash_memory += hash_size; + continue; + } + + 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) @@ -410,6 +534,8 @@ ip4_show_mfib (vlib_main_t * vm, ip4_mfib_table_show_one(mfib, vm, &src, &grp, mask); } })); + if (memory) + vlib_cli_output (vm, "totals: hash:%ld", total_hash_memory); return 0; }