X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip4_forward.c;h=332c483aa9df94648619f8c8f6986813dafe9d12;hb=f2984bbb0;hp=4691e27c3e3af10556640a22d0cf46cd7f192291;hpb=dbd366b239c0506b0d9984e7481967e038f10a23;p=vpp.git diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 4691e27c3e3..332c483aa9d 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -380,28 +380,28 @@ ip4_add_interface_prefix_routes (ip4_main_t *im, mhash_set (&lm->prefix_to_if_prefix_index, &key, if_prefix - lm->if_prefix_pool, 0 /* old value */); + pfx_special.fp_len = a->address_length; + pfx_special.fp_addr.ip4.as_u32 = address->as_u32; + + /* set the glean route for the prefix */ + fib_table_entry_update_one_path (fib_index, &pfx_special, + FIB_SOURCE_INTERFACE, + (FIB_ENTRY_FLAG_CONNECTED | + FIB_ENTRY_FLAG_ATTACHED), + DPO_PROTO_IP4, + /* No next-hop address */ + NULL, + sw_if_index, + /* invalid FIB index */ + ~0, + 1, + /* no out-label stack */ + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + /* length <= 30 - add glean, drop first address, maybe drop bcast address */ if (a->address_length <= 30) { - pfx_special.fp_len = a->address_length; - pfx_special.fp_addr.ip4.as_u32 = address->as_u32; - - /* set the glean route for the prefix */ - fib_table_entry_update_one_path (fib_index, &pfx_special, - FIB_SOURCE_INTERFACE, - (FIB_ENTRY_FLAG_CONNECTED | - FIB_ENTRY_FLAG_ATTACHED), - DPO_PROTO_IP4, - /* No next-hop address */ - NULL, - sw_if_index, - /* invalid FIB index */ - ~0, - 1, - /* no out-label stack */ - NULL, - FIB_ROUTE_PATH_FLAG_NONE); - /* set a drop route for the base address of the prefix */ pfx_special.fp_len = 32; pfx_special.fp_addr.ip4.as_u32 = @@ -528,90 +528,52 @@ ip4_del_interface_prefix_routes (ip4_main_t * im, if_prefix->ref_count -= 1; /* - * Routes need to be adjusted if: - * - deleting last intf addr in prefix - * - deleting intf addr used as default source address in glean adjacency + * Routes need to be adjusted if deleting last intf addr in prefix * * We're done now otherwise */ - if ((if_prefix->ref_count > 0) && - !pool_is_free_index (lm->if_address_pool, if_prefix->src_ia_index)) + if (if_prefix->ref_count > 0) return; /* length <= 30, delete glean route, first address, last address */ if (address_length <= 30) { + /* Less work to do in FIB if we remove the covered /32s first */ - /* remove glean route for prefix */ - pfx_special.fp_addr.ip4 = *address; - pfx_special.fp_len = address_length; - fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE); - - /* if no more intf addresses in prefix, remove other special routes */ - if (!if_prefix->ref_count) - { - /* first address in prefix */ - pfx_special.fp_addr.ip4.as_u32 = - address->as_u32 & im->fib_masks[address_length]; - pfx_special.fp_len = 32; + /* first address in prefix */ + pfx_special.fp_addr.ip4.as_u32 = + address->as_u32 & im->fib_masks[address_length]; + pfx_special.fp_len = 32; - if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32) - fib_table_entry_special_remove (fib_index, - &pfx_special, - FIB_SOURCE_INTERFACE); + if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32) + fib_table_entry_special_remove (fib_index, + &pfx_special, + FIB_SOURCE_INTERFACE); - /* prefix broadcast address */ - pfx_special.fp_addr.ip4.as_u32 = - address->as_u32 | ~im->fib_masks[address_length]; - pfx_special.fp_len = 32; + /* prefix broadcast address */ + pfx_special.fp_addr.ip4.as_u32 = + address->as_u32 | ~im->fib_masks[address_length]; + pfx_special.fp_len = 32; - if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32) - fib_table_entry_special_remove (fib_index, - &pfx_special, - FIB_SOURCE_INTERFACE); - } - else - /* default source addr just got deleted, find another */ - { - ip_interface_address_t *new_src_ia = NULL; - ip4_address_t *new_src_addr = NULL; - - new_src_addr = - ip4_interface_address_matching_destination - (im, address, sw_if_index, &new_src_ia); - - if_prefix->src_ia_index = new_src_ia - lm->if_address_pool; - - pfx_special.fp_len = address_length; - pfx_special.fp_addr.ip4 = *new_src_addr; - - /* set new glean route for the prefix */ - fib_table_entry_update_one_path (fib_index, &pfx_special, - FIB_SOURCE_INTERFACE, - (FIB_ENTRY_FLAG_CONNECTED | - FIB_ENTRY_FLAG_ATTACHED), - DPO_PROTO_IP4, - /* No next-hop address */ - NULL, - sw_if_index, - /* invalid FIB index */ - ~0, - 1, - /* no out-label stack */ - NULL, - FIB_ROUTE_PATH_FLAG_NONE); - return; - } + if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32) + fib_table_entry_special_remove (fib_index, + &pfx_special, + FIB_SOURCE_INTERFACE); } - /* length == 31, delete attached route for the other address */ else if (address_length == 31) { + /* length == 31, delete attached route for the other address */ pfx_special.fp_addr.ip4.as_u32 = address->as_u32 ^ clib_host_to_net_u32(1); fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE); } + /* remove glean route for prefix */ + pfx_special.fp_addr.ip4 = *address; + pfx_special.fp_len = address_length; + fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE); + mhash_unset (&lm->prefix_to_if_prefix_index, &key, 0 /* old_value */); pool_put (lm->if_prefix_pool, if_prefix); } @@ -623,16 +585,15 @@ ip4_del_interface_routes (u32 sw_if_index, ip4_address_t * address, u32 address_length) { fib_prefix_t pfx = { - .fp_len = address_length, + .fp_len = 32, .fp_proto = FIB_PROTOCOL_IP4, .fp_addr.ip4 = *address, }; + fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE); + ip4_del_interface_prefix_routes (im, sw_if_index, fib_index, address, address_length); - - pfx.fp_len = 32; - fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE); } #ifndef CLIB_MARCH_VARIANT @@ -640,6 +601,8 @@ void ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable) { ip4_main_t *im = &ip4_main; + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); vec_validate_init_empty (im->ip_enabled_by_sw_if_index, sw_if_index, 0); @@ -664,6 +627,11 @@ ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable) vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled", sw_if_index, !is_enable, 0, 0); + if (is_enable) + hi->l3_if_count++; + else if (hi->l3_if_count) + hi->l3_if_count--; + { ip4_enable_disable_interface_callback_t *cb; vec_foreach (cb, im->enable_disable_interface_callbacks) @@ -709,8 +677,8 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm, ip_interface_address_t *ia; vnet_sw_interface_t *sif; - pool_foreach(sif, vnm->interface_main.sw_interfaces, - ({ + pool_foreach (sif, vnm->interface_main.sw_interfaces) + { if (im->fib_index_by_sw_if_index[sw_if_index] == im->fib_index_by_sw_if_index[sif->sw_if_index]) { @@ -760,7 +728,7 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm, } })); } - })); + } } /* *INDENT-ON* */ @@ -2056,7 +2024,7 @@ ip4_ttl_inc (vlib_buffer_t * b, ip4_header_t * ip) ttl += 1; ip->ttl = ttl; - ASSERT (ip->checksum == ip4_header_checksum (ip)); + ASSERT (ip4_header_checksum_is_valid (ip)); } /* Decrement TTL & update checksum. @@ -2097,7 +2065,7 @@ ip4_ttl_and_checksum_check (vlib_buffer_t * b, ip4_header_t * ip, u16 * next, } /* Verify checksum. */ - ASSERT ((ip->checksum == ip4_header_checksum (ip)) || + ASSERT (ip4_header_checksum_is_valid (ip) || (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM)); } @@ -2141,8 +2109,11 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, u32 tx_sw_if_index0, tx_sw_if_index1; u8 *p; - vlib_prefetch_buffer_header (b[6], LOAD); - vlib_prefetch_buffer_header (b[7], LOAD); + if (is_midchain) + { + vlib_prefetch_buffer_header (b[6], LOAD); + vlib_prefetch_buffer_header (b[7], LOAD); + } adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX]; adj_index1 = vnet_buffer (b[1])->ip.adj_index[VLIB_TX]; @@ -2234,8 +2205,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, next[0] = next_index; if (is_midchain) vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ , - 0 /* is_ip6 */ , - 0 /* with gso */ ); + 0 /* is_ip6 */ ); } else { @@ -2259,9 +2229,8 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, adj1->ia_cfg_index); next[1] = next_index; if (is_midchain) - vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ , - 0 /* is_ip6 */ , - 0 /* with gso */ ); + vnet_calc_checksums_inline (vm, b[1], 1 /* is_ip4 */ , + 0 /* is_ip6 */ ); } else { @@ -2299,9 +2268,9 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, if (is_midchain) { if (error0 == IP4_ERROR_NONE) - adj_midchain_fixup (vm, adj0, b[0]); + adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4); if (error1 == IP4_ERROR_NONE) - adj_midchain_fixup (vm, adj1, b[1]); + adj_midchain_fixup (vm, adj1, b[1], VNET_LINK_IP4); } if (is_mcast) @@ -2412,8 +2381,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, if (is_midchain) { vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ , - 0 /* is_ip6 */ , - 0 /* with gso */ ); + 0 /* is_ip6 */ ); /* Guess we are only writing on ipv4 header. */ vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t)); @@ -2434,7 +2402,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, b[0]) + rw_len0); if (is_midchain) - adj_midchain_fixup (vm, adj0, b[0]); + adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4); if (is_mcast) /* copy bytes from the IP address into the MAC rewrite */ @@ -2520,8 +2488,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, { /* this acts on the packet that is about to be encapped */ vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ , - 0 /* is_ip6 */ , - 0 /* with gso */ ); + 0 /* is_ip6 */ ); /* Guess we are only writing on ipv4 header. */ vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t)); @@ -2537,9 +2504,8 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm, thread_index, adj_index0, 1, vlib_buffer_length_in_chain (vm, b[0]) + rw_len0); - if (is_midchain && adj0->sub_type.midchain.fixup_func) - adj0->sub_type.midchain.fixup_func - (vm, adj0, b[0], adj0->sub_type.midchain.fixup_data); + if (is_midchain) + adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4); if (is_mcast) /* copy bytes from the IP address into the MAC rewrite */ @@ -2805,24 +2771,6 @@ VLIB_CLI_COMMAND (lookup_test_command, static) = }; /* *INDENT-ON* */ -#ifndef CLIB_MARCH_VARIANT -int -vnet_set_ip4_flow_hash (u32 table_id, u32 flow_hash_config) -{ - u32 fib_index; - - fib_index = fib_table_find (FIB_PROTOCOL_IP4, table_id); - - if (~0 == fib_index) - return VNET_API_ERROR_NO_SUCH_FIB; - - fib_table_set_flow_hash_config (fib_index, FIB_PROTOCOL_IP4, - flow_hash_config); - - return 0; -} -#endif - static clib_error_t * set_ip_flow_hash_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -2837,8 +2785,12 @@ set_ip_flow_hash_command_fn (vlib_main_t * vm, { if (unformat (input, "table %d", &table_id)) matched = 1; -#define _(a,v) \ - else if (unformat (input, #a)) { flow_hash_config |= v; matched=1;} +#define _(a, b, v) \ + else if (unformat (input, #a)) \ + { \ + flow_hash_config |= v; \ + matched = 1; \ + } foreach_flow_hash_bit #undef _ else @@ -2849,7 +2801,7 @@ set_ip_flow_hash_command_fn (vlib_main_t * vm, return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); - rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config); + rv = ip_flow_hash_set (AF_IP4, table_id, flow_hash_config); switch (rv) { case 0: @@ -3084,29 +3036,6 @@ VLIB_CLI_COMMAND (set_ip_classify_command, static) = }; /* *INDENT-ON* */ -static clib_error_t * -ip4_config (vlib_main_t * vm, unformat_input_t * input) -{ - ip4_main_t *im = &ip4_main; - uword heapsize = 0; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "heap-size %U", unformat_memory_size, &heapsize)) - ; - else - return clib_error_return (0, - "invalid heap-size parameter `%U'", - format_unformat_error, input); - } - - im->mtrie_heap_size = heapsize; - - return 0; -} - -VLIB_EARLY_CONFIG_FUNCTION (ip4_config, "ip"); - /* * fd.io coding-style-patch-verification: ON *