From 3a0325f9cab7838c21b19698b89cfc65e3236085 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 1 Jun 2018 12:22:23 -0700 Subject: [PATCH] ip: save fib index for buffer in ip lookup Avoids recomputing the fib index in ip local for locally delivered packets and should incur no extra cost when forwarding packets. Change-Id: Id826ffa8206392087327f154337eabc8a801b4d7 Signed-off-by: Florin Coras --- src/vnet/ip/ip4_forward.c | 41 ++++++++++++++++------------------ src/vnet/ip/ip4_forward.h | 57 ++++++++++------------------------------------- src/vnet/ip/ip6_forward.c | 30 ++++++++----------------- src/vnet/ip/ip6_forward.h | 39 +++++++++++--------------------- src/vnet/ip/lookup.h | 12 ++++++++++ 5 files changed, 65 insertions(+), 114 deletions(-) diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 40fe9dc447e..04cfac0d6be 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -1202,8 +1202,8 @@ ip4_local_inline (vlib_main_t * vm, ip4_fib_mtrie_leaf_t leaf0, leaf1; const dpo_id_t *dpo0, *dpo1; const load_balance_t *lb0, *lb1; - u32 pi0, next0, fib_index0, lbi0; - u32 pi1, next1, fib_index1, lbi1; + u32 pi0, next0, lbi0; + u32 pi1, next1, lbi1; u8 error0, is_udp0, is_tcp_udp0, good_tcp_udp0, proto0; u8 error1, is_udp1, is_tcp_udp1, good_tcp_udp1, proto1; u32 sw_if_index0, sw_if_index1; @@ -1268,22 +1268,19 @@ ip4_local_inline (vlib_main_t * vm, error1 = (is_tcp_udp1 && !good_tcp_udp1 ? IP4_ERROR_TCP_CHECKSUM + is_udp1 : error1); - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, sw_if_index0); - fib_index0 = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + vnet_buffer (p0)->ip.fib_index = + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; - fib_index1 = vec_elt (im->fib_index_by_sw_if_index, sw_if_index1); - fib_index1 = - (vnet_buffer (p1)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX]; + vnet_buffer (p1)->ip.fib_index = + vnet_buffer (p1)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p1)->sw_if_index[VLIB_TX] : + vnet_buffer (p1)->ip.fib_index; - /* TODO maybe move to lookup? */ - vnet_buffer (p0)->ip.fib_index = fib_index0; - vnet_buffer (p1)->ip.fib_index = fib_index1; - mtrie0 = &ip4_fib_get (fib_index0)->mtrie; - mtrie1 = &ip4_fib_get (fib_index1)->mtrie; + mtrie0 = &ip4_fib_get (vnet_buffer (p0)->ip.fib_index)->mtrie; + mtrie1 = &ip4_fib_get (vnet_buffer (p1)->ip.fib_index)->mtrie; leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address); leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, &ip1->src_address); @@ -1374,7 +1371,7 @@ ip4_local_inline (vlib_main_t * vm, ip4_header_t *ip0; ip4_fib_mtrie_t *mtrie0; ip4_fib_mtrie_leaf_t leaf0; - u32 pi0, next0, fib_index0, lbi0; + u32 pi0, next0, lbi0; u8 error0, is_udp0, is_tcp_udp0, good_tcp_udp0, proto0; load_balance_t *lb0; const dpo_id_t *dpo0; @@ -1417,12 +1414,12 @@ ip4_local_inline (vlib_main_t * vm, error0 = (is_tcp_udp0 && !good_tcp_udp0 ? IP4_ERROR_TCP_CHECKSUM + is_udp0 : error0); - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, sw_if_index0); - fib_index0 = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; - vnet_buffer (p0)->ip.fib_index = fib_index0; - mtrie0 = &ip4_fib_get (fib_index0)->mtrie; + vnet_buffer (p0)->ip.fib_index = + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; + + mtrie0 = &ip4_fib_get (vnet_buffer (p0)->ip.fib_index)->mtrie; leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address); leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 2); diff --git a/src/vnet/ip/ip4_forward.h b/src/vnet/ip/ip4_forward.h index 71f58f14e6d..553a0536c6c 100644 --- a/src/vnet/ip/ip4_forward.h +++ b/src/vnet/ip/ip4_forward.h @@ -79,10 +79,7 @@ ip4_lookup_inline (vlib_main_t * vm, ip4_fib_mtrie_t *mtrie0, *mtrie1, *mtrie2, *mtrie3; ip4_fib_mtrie_leaf_t leaf0, leaf1, leaf2, leaf3; ip4_address_t *dst_addr0, *dst_addr1, *dst_addr2, *dst_addr3; - u32 pi0, fib_index0, lb_index0; - u32 pi1, fib_index1, lb_index1; - u32 pi2, fib_index2, lb_index2; - u32 pi3, fib_index3, lb_index3; + u32 pi0, pi1, pi2, pi3, lb_index0, lb_index1, lb_index2, lb_index3; flow_hash_config_t flow_hash_config0, flow_hash_config1; flow_hash_config_t flow_hash_config2, flow_hash_config3; u32 hash_c0, hash_c1, hash_c2, hash_c3; @@ -133,38 +130,17 @@ ip4_lookup_inline (vlib_main_t * vm, dst_addr2 = &ip2->dst_address; dst_addr3 = &ip3->dst_address; - fib_index0 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - fib_index1 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p1)->sw_if_index[VLIB_RX]); - fib_index2 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p2)->sw_if_index[VLIB_RX]); - fib_index3 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p3)->sw_if_index[VLIB_RX]); - fib_index0 = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; - fib_index1 = - (vnet_buffer (p1)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX]; - fib_index2 = - (vnet_buffer (p2)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index2 : vnet_buffer (p2)->sw_if_index[VLIB_TX]; - fib_index3 = - (vnet_buffer (p3)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index3 : vnet_buffer (p3)->sw_if_index[VLIB_TX]; - + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p1); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p2); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p3); if (!lookup_for_responses_to_locally_received_packets) { - mtrie0 = &ip4_fib_get (fib_index0)->mtrie; - mtrie1 = &ip4_fib_get (fib_index1)->mtrie; - mtrie2 = &ip4_fib_get (fib_index2)->mtrie; - mtrie3 = &ip4_fib_get (fib_index3)->mtrie; + mtrie0 = &ip4_fib_get (vnet_buffer (p0)->ip.fib_index)->mtrie; + mtrie1 = &ip4_fib_get (vnet_buffer (p1)->ip.fib_index)->mtrie; + mtrie2 = &ip4_fib_get (vnet_buffer (p2)->ip.fib_index)->mtrie; + mtrie3 = &ip4_fib_get (vnet_buffer (p3)->ip.fib_index)->mtrie; leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, dst_addr0); leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, dst_addr1); @@ -317,7 +293,7 @@ ip4_lookup_inline (vlib_main_t * vm, ip4_fib_mtrie_t *mtrie0; ip4_fib_mtrie_leaf_t leaf0; ip4_address_t *dst_addr0; - u32 pi0, fib_index0, lbi0; + u32 pi0, lbi0; flow_hash_config_t flow_hash_config0; const dpo_id_t *dpo0; u32 hash_c0; @@ -326,22 +302,13 @@ ip4_lookup_inline (vlib_main_t * vm, to_next[0] = pi0; p0 = vlib_get_buffer (vm, pi0); - ip0 = vlib_buffer_get_current (p0); - dst_addr0 = &ip0->dst_address; - - fib_index0 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - fib_index0 = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); if (!lookup_for_responses_to_locally_received_packets) { - mtrie0 = &ip4_fib_get (fib_index0)->mtrie; - + mtrie0 = &ip4_fib_get (vnet_buffer (p0)->ip.fib_index)->mtrie; leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, dst_addr0); } diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index f4c51e22bfc..275bcc67b69 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -1213,23 +1213,15 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node, ? IP6_ERROR_SRC_LOOKUP_MISS : error1); } - /* TODO maybe move to lookup? */ vnet_buffer (p0)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - vnet_buffer (p0)->ip.fib_index = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p0)->ip. - fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; vnet_buffer (p1)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p1)->sw_if_index[VLIB_RX]); - vnet_buffer (p1)->ip.fib_index = - (vnet_buffer (p1)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p1)->ip. - fib_index : vnet_buffer (p1)->sw_if_index[VLIB_TX]; - + vnet_buffer (p1)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p1)->sw_if_index[VLIB_TX] : + vnet_buffer (p1)->ip.fib_index; skip_checks: @@ -1343,14 +1335,10 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node, error0 = (!ip6_urpf_loose_check (im, p0, ip0) ? IP6_ERROR_SRC_LOOKUP_MISS : error0); } - - vnet_buffer (p0)->ip.fib_index = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); vnet_buffer (p0)->ip.fib_index = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? vnet_buffer (p0)->ip. - fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX]; + vnet_buffer (p0)->sw_if_index[VLIB_TX] != ~0 ? + vnet_buffer (p0)->sw_if_index[VLIB_TX] : + vnet_buffer (p0)->ip.fib_index; skip_check: diff --git a/src/vnet/ip/ip6_forward.h b/src/vnet/ip/ip6_forward.h index 790a2bb1ac1..fcdcabd1e00 100644 --- a/src/vnet/ip/ip6_forward.h +++ b/src/vnet/ip/ip6_forward.h @@ -76,7 +76,6 @@ ip6_lookup_inline (vlib_main_t * vm, ip_lookup_next_t next0, next1; ip6_header_t *ip0, *ip1; ip6_address_t *dst_addr0, *dst_addr1; - u32 fib_index0, fib_index1; u32 flow_hash_config0, flow_hash_config1; const dpo_id_t *dpo0, *dpo1; const load_balance_t *lb0, *lb1; @@ -106,20 +105,15 @@ ip6_lookup_inline (vlib_main_t * vm, dst_addr0 = &ip0->dst_address; dst_addr1 = &ip1->dst_address; - fib_index0 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - fib_index1 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p1)->sw_if_index[VLIB_RX]); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p1); - fib_index0 = (vnet_buffer (p0)->sw_if_index[VLIB_TX] == (u32) ~ 0) ? - fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; - fib_index1 = (vnet_buffer (p1)->sw_if_index[VLIB_TX] == (u32) ~ 0) ? - fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX]; - - lbi0 = ip6_fib_table_fwding_lookup (im, fib_index0, dst_addr0); - lbi1 = ip6_fib_table_fwding_lookup (im, fib_index1, dst_addr1); + lbi0 = ip6_fib_table_fwding_lookup (im, + vnet_buffer (p0)->ip.fib_index, + dst_addr0); + lbi1 = ip6_fib_table_fwding_lookup (im, + vnet_buffer (p1)->ip.fib_index, + dst_addr1); lb0 = load_balance_get (lbi0); lb1 = load_balance_get (lbi1); @@ -233,26 +227,19 @@ ip6_lookup_inline (vlib_main_t * vm, ip_lookup_next_t next0; load_balance_t *lb0; ip6_address_t *dst_addr0; - u32 fib_index0, flow_hash_config0; + u32 flow_hash_config0; const dpo_id_t *dpo0; pi0 = from[0]; to_next[0] = pi0; p0 = vlib_get_buffer (vm, pi0); - ip0 = vlib_buffer_get_current (p0); - dst_addr0 = &ip0->dst_address; - - fib_index0 = - vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - fib_index0 = - (vnet_buffer (p0)->sw_if_index[VLIB_TX] == - (u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX]; - - lbi0 = ip6_fib_table_fwding_lookup (im, fib_index0, dst_addr0); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); + lbi0 = ip6_fib_table_fwding_lookup (im, + vnet_buffer (p0)->ip.fib_index, + dst_addr0); lb0 = load_balance_get (lbi0); flow_hash_config0 = lb0->lb_hash_config; diff --git a/src/vnet/ip/lookup.h b/src/vnet/ip/lookup.h index a89546f5d92..ecabd817a00 100644 --- a/src/vnet/ip/lookup.h +++ b/src/vnet/ip/lookup.h @@ -211,6 +211,18 @@ do { \ } while (0) /* *INDENT-ON* */ +always_inline void +ip_lookup_set_buffer_fib_index (u32 * fib_index_by_sw_if_index, + vlib_buffer_t * b) +{ + vnet_buffer (b)->ip.fib_index = + vec_elt (fib_index_by_sw_if_index, vnet_buffer (b)->sw_if_index[VLIB_RX]); + vnet_buffer (b)->ip.fib_index = + (vnet_buffer (b)->sw_if_index[VLIB_TX] == + (u32) ~ 0) ? vnet_buffer (b)->ip. + fib_index : vnet_buffer (b)->sw_if_index[VLIB_TX]; +} + typedef struct _vnet_ip_container_proxy_args { fib_prefix_t prefix; -- 2.16.6