From 5599fc2dae024bcf150fa4b3b4584e19419f8079 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Wed, 17 Feb 2021 18:48:35 +0100 Subject: nat: optimize flow matching in ED NAT This saves 6 clocks in nat44-ed-in2out node. (112->106 per packet) Type: improvement Signed-off-by: Klement Sekera Change-Id: I48e757e7f4b6b0d250a432a4659fe6955fc52a07 --- src/plugins/nat/nat44-ed/nat44_ed_in2out.c | 69 ++++++++++++++++-------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'src/plugins/nat/nat44-ed/nat44_ed_in2out.c') diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c index 784dea0faf6..b99b3367329 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c @@ -918,10 +918,11 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, } static inline uword -nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - int is_output_feature) +nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t *vm, + vlib_node_runtime_t *node, + vlib_frame_t *frame, + int is_output_feature, + int is_multi_worker) { u32 n_left_from, *from; snat_main_t *sm = &snat_main; @@ -948,9 +949,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, clib_bihash_kv_16_8_t kv0, value0; nat_translation_error_e translation_error = NAT_ED_TRNSL_ERR_SUCCESS; nat_6t_flow_t *f = 0; - ip4_address_t lookup_saddr, lookup_daddr; - u16 lookup_sport, lookup_dport; - u8 lookup_protocol; + nat_6t_t lookup; int lookup_skipped = 0; b0 = *b; @@ -981,6 +980,7 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; rx_fib_index0 = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0); + lookup.fib_index = rx_fib_index0; if (PREDICT_FALSE (ip0->ttl == 1)) { @@ -1016,8 +1016,8 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, goto trace0; } int err = nat_get_icmp_session_lookup_values ( - b0, ip0, &lookup_saddr, &lookup_sport, &lookup_daddr, - &lookup_dport, &lookup_protocol); + b0, ip0, &lookup.saddr, &lookup.sport, &lookup.daddr, + &lookup.dport, &lookup.proto); if (err != 0) { b0->error = node->errors[err]; @@ -1027,30 +1027,27 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, } else { - lookup_protocol = ip0->protocol; - lookup_saddr = ip0->src_address; - lookup_daddr = ip0->dst_address; - lookup_sport = vnet_buffer (b0)->ip.reass.l4_src_port; - lookup_dport = vnet_buffer (b0)->ip.reass.l4_dst_port; + lookup.proto = ip0->protocol; + lookup.saddr.as_u32 = ip0->src_address.as_u32; + lookup.daddr.as_u32 = ip0->dst_address.as_u32; + lookup.sport = vnet_buffer (b0)->ip.reass.l4_src_port; + lookup.dport = vnet_buffer (b0)->ip.reass.l4_dst_port; } /* there might be a stashed index in vnet_buffer2 from handoff or * classify node, see if it can be used */ - if (!pool_is_free_index (tsm->sessions, + if (is_multi_worker && + !pool_is_free_index (tsm->sessions, vnet_buffer2 (b0)->nat.cached_session_index)) { s0 = pool_elt_at_index (tsm->sessions, vnet_buffer2 (b0)->nat.cached_session_index); if (PREDICT_TRUE ( - nat_6t_flow_match (&s0->i2o, b0, lookup_saddr, lookup_sport, - lookup_daddr, lookup_dport, lookup_protocol, - rx_fib_index0) + nat_6t_t_eq (&s0->i2o.match, &lookup) // for some hairpinning cases there are two "i2i" flows instead // of i2o and o2i as both hosts are on inside || (s0->flags & SNAT_SESSION_FLAG_HAIRPINNING && - nat_6t_flow_match ( - &s0->o2i, b0, lookup_saddr, lookup_sport, lookup_daddr, - lookup_dport, lookup_protocol, rx_fib_index0)))) + nat_6t_t_eq (&s0->o2i.match, &lookup)))) { /* yes, this is the droid we're looking for */ lookup_skipped = 1; @@ -1059,8 +1056,8 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, s0 = NULL; } - init_ed_k (&kv0, ip0->src_address, lookup_sport, ip0->dst_address, - lookup_dport, rx_fib_index0, lookup_protocol); + init_ed_k (&kv0, lookup.saddr, lookup.sport, lookup.daddr, lookup.dport, + lookup.fib_index, lookup.proto); // lookup flow if (clib_bihash_search_16_8 (&sm->flow_hash, &kv0, &value0)) @@ -1117,16 +1114,12 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, b0->flags |= VNET_BUFFER_F_IS_NATED; - if (nat_6t_flow_match (&s0->i2o, b0, lookup_saddr, lookup_sport, - lookup_daddr, lookup_dport, lookup_protocol, - rx_fib_index0)) + if (nat_6t_t_eq (&s0->i2o.match, &lookup)) { f = &s0->i2o; } else if (s0->flags & SNAT_SESSION_FLAG_HAIRPINNING && - nat_6t_flow_match (&s0->o2i, b0, lookup_saddr, lookup_sport, - lookup_daddr, lookup_dport, lookup_protocol, - rx_fib_index0)) + nat_6t_t_eq (&s0->o2i.match, &lookup)) { f = &s0->o2i; } @@ -1459,7 +1452,14 @@ VLIB_NODE_FN (nat44_ed_in2out_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 0); + if (snat_main.num_workers > 1) + { + return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 0, 1); + } + else + { + return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 0, 0); + } } VLIB_REGISTER_NODE (nat44_ed_in2out_node) = { @@ -1477,7 +1477,14 @@ VLIB_NODE_FN (nat44_ed_in2out_output_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 1); + if (snat_main.num_workers > 1) + { + return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 1, 1); + } + else + { + return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 1, 0); + } } VLIB_REGISTER_NODE (nat44_ed_in2out_output_node) = { -- cgit 1.2.3-korg