X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fmfib%2Fip4_mfib.c;h=206e451e95c6f5f63ae5283cf61ba26ef1b11e6c;hb=da3310597;hp=eaa61c0f86c7ff53da150a8dc0686c53f3b40882;hpb=b7b929931a07fbb27b43d5cd105f366c3e29807e;p=vpp.git diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c index eaa61c0f86c..206e451e95c 100644 --- a/src/vnet/mfib/ip4_mfib.c +++ b/src/vnet/mfib/ip4_mfib.c @@ -18,16 +18,27 @@ #include #include -static const mfib_prefix_t ip4_specials[] = { +static const mfib_prefix_t all_zeros = +{ + .fp_proto = FIB_PROTOCOL_IP4, +}; +static const mfib_prefix_t ip4_specials[] = +{ + /* ALL prefixes are in network order */ { - /* (*,*)/0 */ - .fp_src_addr = { - .ip4.data_u32 = 0, + /* (*,224.0.0.1)/32 - all hosts */ + .fp_grp_addr = { + .ip4.data_u32 = 0x010000e0, }, + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + }, + { + /* (*,224.0.0.2)/32 - all routers */ .fp_grp_addr = { - .ip4.data_u32 = 0, + .ip4.data_u32 = 0x020000e0, }, - .fp_len = 0, + .fp_len = 32, .fp_proto = FIB_PROTOCOL_IP4, }, }; @@ -57,24 +68,31 @@ ip4_create_mfib_with_table_id (u32 table_id, mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4, src); /* - * add the special entries into the new FIB + * add the default route into the new FIB */ + mfib_table_entry_update(mfib_table->mft_index, + &all_zeros, + MFIB_SOURCE_DEFAULT_ROUTE, + MFIB_RPF_ID_NONE, + MFIB_ENTRY_FLAG_DROP); + + const fib_route_path_t path = { + .frp_proto = DPO_PROTO_IP4, + .frp_addr = zero_addr, + .frp_sw_if_index = ~0, + .frp_fib_index = ~0, + .frp_weight = 1, + .frp_flags = FIB_ROUTE_PATH_LOCAL, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, + }; int ii; for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++) { - mfib_prefix_t prefix = ip4_specials[ii]; - - prefix.fp_src_addr.ip4.data_u32 = - clib_host_to_net_u32(prefix.fp_src_addr.ip4.data_u32); - prefix.fp_grp_addr.ip4.data_u32 = - clib_host_to_net_u32(prefix.fp_grp_addr.ip4.data_u32); - - mfib_table_entry_update(mfib_table->mft_index, - &prefix, - MFIB_SOURCE_DEFAULT_ROUTE, - MFIB_RPF_ID_NONE, - MFIB_ENTRY_FLAG_DROP); + mfib_table_entry_path_update(mfib_table->mft_index, + &ip4_specials[ii], + MFIB_SOURCE_SPECIAL, + &path); } return (mfib_table->mft_index); @@ -89,18 +107,15 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib) /* * remove all the specials we added when the table was created. */ + mfib_table_entry_delete(mfib_table->mft_index, + &all_zeros, + MFIB_SOURCE_DEFAULT_ROUTE); + for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++) { - fib_node_index_t mfei; - mfib_prefix_t prefix = ip4_specials[ii]; - - prefix.fp_src_addr.ip4.data_u32 = - clib_host_to_net_u32(prefix.fp_src_addr.ip4.data_u32); - prefix.fp_grp_addr.ip4.data_u32 = - clib_host_to_net_u32(prefix.fp_grp_addr.ip4.data_u32); - - mfei = mfib_table_lookup(mfib_table->mft_index, &prefix); - mfib_table_entry_delete_index(mfei, MFIB_SOURCE_DEFAULT_ROUTE); + mfib_table_entry_delete(mfib_table->mft_index, + &ip4_specials[ii], + MFIB_SOURCE_SPECIAL); } /* @@ -113,6 +128,41 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib) pool_put(ip4_main.mfibs, mfib_table); } +void +ip4_mfib_interface_enable_disable (u32 sw_if_index, int is_enable) +{ + const fib_route_path_t path = { + .frp_proto = DPO_PROTO_IP4, + .frp_addr = zero_addr, + .frp_sw_if_index = sw_if_index, + .frp_fib_index = ~0, + .frp_weight = 1, + .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT, + }; + u32 mfib_index; + int ii; + + mfib_index = ip4_mfib_table_get_index_for_sw_if_index(sw_if_index); + + for (ii = 0; ii < ARRAY_LEN(ip4_specials); ii++) + { + if (is_enable) + { + mfib_table_entry_path_update(mfib_index, + &ip4_specials[ii], + MFIB_SOURCE_SPECIAL, + &path); + } + else + { + mfib_table_entry_path_remove(mfib_index, + &ip4_specials[ii], + MFIB_SOURCE_SPECIAL, + &path); + } + } +} + u32 ip4_mfib_table_find_or_create_and_lock (u32 table_id, mfib_source_t src) @@ -210,7 +260,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 +274,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, @@ -271,7 +353,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 @@ -313,8 +395,8 @@ format_ip4_mfib_table_memory (u8 * s, va_list * args) total_memory = 0; - pool_foreach (mfib_table, ip4_main.mfibs, - ({ + pool_foreach (mfib_table, ip4_main.mfibs) + { ip4_mfib_t *mfib = &mfib_table->v4; uword mfib_size; int i; @@ -332,9 +414,9 @@ format_ip4_mfib_table_memory (u8 * s, va_list * args) } total_memory += mfib_size; - })); + } - s = format(s, "%=30s %=6d %=8ld\n", + s = format(s, "%=30s %=6d %=12ld\n", "IPv4 multicast", pool_elts(ip4_main.mfibs), total_memory); @@ -442,8 +524,8 @@ ip4_show_mfib (vlib_main_t * vm, break; } - pool_foreach (mfib_table, im4->mfibs, - ({ + pool_foreach (mfib_table, im4->mfibs) + { ip4_mfib_t *mfib = &mfib_table->v4; if (table_id >= 0 && table_id != (int)mfib->table_id) @@ -474,9 +556,10 @@ ip4_show_mfib (vlib_main_t * vm, continue; } - vlib_cli_output (vm, "%U, fib_index %d", + 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) @@ -500,19 +583,20 @@ 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; } +/* clang-format off */ /*? * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and * the route entries for each table. * * @note This command will run for a long time when the FIB tables are - * comprised of millions of entries. For those senarios, consider displaying + * comprised of millions of entries. For those scenarios, consider displaying * a single table or summary mode. * * @cliexpar @@ -549,10 +633,9 @@ ip4_show_mfib (vlib_main_t * vm, * 32 4 * @cliexend ?*/ -/* *INDENT-OFF* */ +/* clang-format on */ VLIB_CLI_COMMAND (ip4_show_mfib_command, static) = { .path = "show ip mfib", .short_help = "show ip mfib [summary] [table ] [index ] [[/]] [] [ ]", .function = ip4_show_mfib, }; -/* *INDENT-ON* */