diff options
author | Klement Sekera <ksekera@cisco.com> | 2020-05-19 17:47:23 +0000 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2020-06-08 13:46:35 +0000 |
commit | e3621518046ad7f37ccf77c549a93375ab89da19 (patch) | |
tree | aab4446172fe661f3a2eaa58c1fc4cc1d209219b /src/plugins | |
parent | c1f0d9c105c25c67d9ef86a53c10d43d40b61fe0 (diff) |
nat: more long read after short write optimization
Replace whitespread (mis)use of snat_session_key_t by proper function
arguments where applicable and inline functions to calculate hash keys
instead of using structs for that. Make all hash tables use same network
byte order port so that there is no longer a discrepancy between static
mappings using host byte order while in2out/out2in tables using network
byte order.
Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I80786d2f947c67824c101a13bb608f1fe1080f34
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/nat/in2out.c | 293 | ||||
-rw-r--r-- | src/plugins/nat/in2out_ed.c | 262 | ||||
-rw-r--r-- | src/plugins/nat/nat.c | 525 | ||||
-rw-r--r-- | src/plugins/nat/nat.h | 134 | ||||
-rw-r--r-- | src/plugins/nat/nat44_classify.c | 52 | ||||
-rw-r--r-- | src/plugins/nat/nat44_cli.c | 21 | ||||
-rw-r--r-- | src/plugins/nat/nat44_hairpinning.c | 83 | ||||
-rw-r--r-- | src/plugins/nat/nat64.c | 14 | ||||
-rw-r--r-- | src/plugins/nat/nat_api.c | 32 | ||||
-rw-r--r-- | src/plugins/nat/nat_det_in2out.c | 24 | ||||
-rw-r--r-- | src/plugins/nat/nat_det_out2in.c | 22 | ||||
-rw-r--r-- | src/plugins/nat/nat_format.c | 22 | ||||
-rw-r--r-- | src/plugins/nat/nat_inlines.h | 125 | ||||
-rw-r--r-- | src/plugins/nat/out2in.c | 283 | ||||
-rw-r--r-- | src/plugins/nat/out2in_ed.c | 219 |
15 files changed, 1051 insertions, 1060 deletions
diff --git a/src/plugins/nat/in2out.c b/src/plugins/nat/in2out.c index 0c52e50119d..0d702711ffd 100644 --- a/src/plugins/nat/in2out.c +++ b/src/plugins/nat/in2out.c @@ -126,14 +126,10 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node, u32 rx_fib_index0, u32 thread_index) { udp_header_t *udp0 = ip4_next_header (ip0); - snat_session_key_t key0, sm0; clib_bihash_kv_8_8_t kv0, value0; - key0.addr = ip0->dst_address; - key0.port = udp0->dst_port; - key0.protocol = proto0; - key0.fib_index = sm->outside_fib_index; - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, + proto0); /* NAT packet aimed at external address if */ /* has active sessions */ @@ -141,7 +137,13 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node, &value0)) { /* or is static mappings */ - if (!snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0)) + ip4_address_t dummy_addr; + u16 dummy_port; + u32 dummy_fib_index; + if (!snat_static_mapping_match + (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, + proto0, &dummy_addr, &dummy_port, &dummy_fib_index, 1, 0, 0, 0, 0, + 0)) return 0; } else @@ -159,26 +161,20 @@ nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0, u32 proto0, u16 src_port, u16 dst_port, u32 thread_index, u32 sw_if_index) { - snat_session_key_t key0; clib_bihash_kv_8_8_t kv0, value0; snat_interface_t *i; /* src NAT check */ - key0.addr = ip0->src_address; - key0.port = src_port; - key0.protocol = proto0; - key0.fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index); - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->src_address, src_port, + ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0); if (!clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) return 1; /* dst NAT check */ - key0.addr = ip0->dst_address; - key0.port = dst_port; - key0.protocol = proto0; - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, dst_port, + ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0); if (!clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, &value0)) { @@ -212,30 +208,30 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s); if (ctx->now >= sess_timeout_time) { - s_kv.key = s->out2in.as_u64; + init_nat_o2i_k (&s_kv, s); if (clib_bihash_add_del_8_8 (&tsm->out2in, &s_kv, 0)) nat_elog_warn ("out2in key del failed"); snat_ipfix_logging_nat44_ses_delete (ctx->thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index, &s->in2out.addr, s->in2out.port, - &s->out2in.addr, s->out2in.port, - s->in2out.protocol); + &s->out2in.addr, s->out2in.port, s->nat_proto); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, ctx->thread_index); if (!snat_is_session_static (s)) snat_free_outside_address_and_port (sm->addresses, ctx->thread_index, - &s->out2in); + &s->out2in.addr, + s->out2in.port, s->nat_proto); nat44_delete_session (sm, s, ctx->thread_index); return 1; @@ -248,15 +244,16 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) static u32 slow_path (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0, + ip4_address_t i2o_addr, + u16 i2o_port, u32 rx_fib_index0, - snat_session_key_t * key0, + nat_protocol_t nat_proto, snat_session_t ** sessionp, vlib_node_runtime_t * node, u32 next0, u32 thread_index, f64 now) { snat_user_t *u; snat_session_t *s = 0; clib_bihash_kv_8_8_t kv0; - snat_session_key_t key1; u8 is_sm = 0; nat_outside_fib_t *outside_fib; fib_node_index_t fei = FIB_NODE_INDEX_INVALID; @@ -269,6 +266,9 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, }, }; nat44_is_idle_session_ctx_t ctx0; + ip4_address_t sm_addr; + u16 sm_port; + u32 sm_fib_index; if (PREDICT_FALSE (nat44_maximum_sessions_exceeded (sm, thread_index))) { @@ -278,15 +278,16 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, return SNAT_IN2OUT_NEXT_DROP; } - key1.protocol = key0->protocol; - /* First try to match static mapping by local address and port */ if (snat_static_mapping_match - (sm, *key0, &key1, 0, 0, 0, 0, 0, &identity_nat)) + (sm, i2o_addr, i2o_port, rx_fib_index0, nat_proto, &sm_addr, + &sm_port, &sm_fib_index, 0, 0, 0, 0, 0, &identity_nat)) { /* Try to create dynamic translation */ if (snat_alloc_outside_address_and_port (sm->addresses, rx_fib_index0, - thread_index, &key1, + thread_index, + nat_proto, + &sm_addr, &sm_port, sm->port_per_thread, sm->per_thread_data [thread_index].snat_thread_index)) @@ -325,9 +326,12 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, if (is_sm) s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING; user_session_increment (sm, u, is_sm); - s->in2out = *key0; - s->out2in = key1; - s->out2in.protocol = key0->protocol; + s->in2out.addr = i2o_addr; + s->in2out.port = i2o_port; + s->in2out.fib_index = rx_fib_index0; + s->nat_proto = nat_proto; + s->out2in.addr = sm_addr; + s->out2in.port = sm_port; s->out2in.fib_index = sm->outside_fib_index; switch (vec_len (sm->outside_fibs)) { @@ -361,16 +365,13 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, /* Add to translation hashes */ ctx0.now = now; ctx0.thread_index = thread_index; - kv0.key = s->in2out.as_u64; - kv0.value = s - sm->per_thread_data[thread_index].sessions; + init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); if (clib_bihash_add_or_overwrite_stale_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0)) nat_elog_notice ("in2out key add failed"); - kv0.key = s->out2in.as_u64; - kv0.value = s - sm->per_thread_data[thread_index].sessions; - + init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); if (clib_bihash_add_or_overwrite_stale_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0)) @@ -380,30 +381,28 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, snat_ipfix_logging_nat44_ses_create (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index, &s->in2out.addr, s->in2out.port, &s->out2in.addr, - s->out2in.port, s->in2out.protocol); + s->out2in.port, s->nat_proto); nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, &s->ext_host_nat_addr, s->ext_host_nat_port, - s->in2out.protocol, s->in2out.fib_index, s->flags, - thread_index, 0); + s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0); return next0; } #ifndef CLIB_MARCH_VARIANT -static_always_inline - snat_in2out_error_t icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0, - snat_session_key_t * p_key0) +static_always_inline snat_in2out_error_t +icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0, + ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto) { icmp46_header_t *icmp0; - snat_session_key_t key0; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0 = 0; void *l4_header = 0; @@ -415,32 +414,31 @@ static_always_inline if (!icmp_type_is_error_message (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)) { - key0.protocol = NAT_PROTOCOL_ICMP; - key0.addr = ip0->src_address; - key0.port = vnet_buffer (b)->ip.reass.l4_src_port; + *nat_proto = NAT_PROTOCOL_ICMP; + *addr = ip0->src_address; + *port = vnet_buffer (b)->ip.reass.l4_src_port; } else { inner_ip0 = (ip4_header_t *) (echo0 + 1); l4_header = ip4_next_header (inner_ip0); - key0.protocol = ip_proto_to_nat_proto (inner_ip0->protocol); - key0.addr = inner_ip0->dst_address; - switch (key0.protocol) + *nat_proto = ip_proto_to_nat_proto (inner_ip0->protocol); + *addr = inner_ip0->dst_address; + switch (*nat_proto) { case NAT_PROTOCOL_ICMP: inner_icmp0 = (icmp46_header_t *) l4_header; inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1); - key0.port = inner_echo0->identifier; + *port = inner_echo0->identifier; break; case NAT_PROTOCOL_UDP: case NAT_PROTOCOL_TCP: - key0.port = ((tcp_udp_header_t *) l4_header)->dst_port; + *port = ((tcp_udp_header_t *) l4_header)->dst_port; break; default: return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL; } } - *p_key0 = key0; return -1; /* success */ } @@ -462,47 +460,40 @@ static_always_inline u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + ip4_header_t * ip0, ip4_address_t * addr, u16 * port, + u32 * fib_index, nat_protocol_t * proto, void *d, + void *e, u8 * dont_translate) { snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; u32 sw_if_index0; - u32 rx_fib_index0; - snat_session_key_t key0; snat_session_t *s0 = 0; - u8 dont_translate = 0; clib_bihash_kv_8_8_t kv0, value0; u32 next0 = ~0; int err; vlib_main_t *vm = vlib_get_main (); + *dont_translate = 0; sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); + *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); - err = icmp_get_key (b0, ip0, &key0); + err = icmp_get_key (b0, ip0, addr, port, proto); if (err != -1) { b0->error = node->errors[err]; next0 = SNAT_IN2OUT_NEXT_DROP; goto out; } - key0.fib_index = rx_fib_index0; - - kv0.key = key0.as_u64; + init_nat_k (&kv0, *addr, *port, *fib_index, *proto); if (clib_bihash_search_8_8 (&tsm->in2out, &kv0, &value0)) { if (vnet_buffer (b0)->sw_if_index[VLIB_TX] != ~0) { - if (PREDICT_FALSE (nat_not_translate_output_feature (sm, ip0, - key0.protocol, - key0.port, - key0.port, - thread_index, - sw_if_index0))) + if (PREDICT_FALSE + (nat_not_translate_output_feature + (sm, ip0, *proto, *port, *port, thread_index, sw_if_index0))) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -510,10 +501,9 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, { if (PREDICT_FALSE (snat_not_translate (sm, node, sw_if_index0, ip0, NAT_PROTOCOL_ICMP, - rx_fib_index0, - thread_index))) + *fib_index, thread_index))) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -527,15 +517,16 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, goto out; } - next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, &s0, node, next0, - thread_index, vlib_time_now (vm)); + next0 = + slow_path (sm, b0, ip0, *addr, *port, *fib_index, *proto, &s0, node, + next0, thread_index, vlib_time_now (vm)); if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP)) goto out; if (!s0) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -558,12 +549,14 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, } out: - *p_proto = key0.protocol; if (s0) - *p_value = s0->out2in; - *p_dont_translate = dont_translate; + { + *addr = s0->out2in.addr; + *port = s0->out2in.port; + *fib_index = s0->out2in.fib_index; + } if (d) - *(snat_session_t **) d = s0; + *(snat_session_t **) (d) = s0; return next0; } #endif @@ -586,39 +579,40 @@ out: u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + ip4_header_t * ip0, ip4_address_t * addr, u16 * port, + u32 * fib_index, nat_protocol_t * proto, void *d, + void *e, u8 * dont_translate) { u32 sw_if_index0; - u32 rx_fib_index0; - snat_session_key_t key0; - snat_session_key_t sm0; - u8 dont_translate = 0; u8 is_addr_only; u32 next0 = ~0; int err; + *dont_translate = 0; sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); + *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); - err = icmp_get_key (b0, ip0, &key0); + err = icmp_get_key (b0, ip0, addr, port, proto); if (err != -1) { b0->error = node->errors[err]; next0 = SNAT_IN2OUT_NEXT_DROP; - goto out2; + goto out; } - key0.fib_index = rx_fib_index0; + + ip4_address_t sm_addr; + u16 sm_port; + u32 sm_fib_index; if (snat_static_mapping_match - (sm, key0, &sm0, 0, &is_addr_only, 0, 0, 0, 0)) + (sm, *addr, *port, *fib_index, *proto, &sm_addr, &sm_port, + &sm_fib_index, 0, &is_addr_only, 0, 0, 0, 0)) { if (PREDICT_FALSE (snat_not_translate_fast (sm, node, sw_if_index0, ip0, IP_PROTOCOL_ICMP, - rx_fib_index0))) + *fib_index))) { - dont_translate = 1; + *dont_translate = 1; goto out; } @@ -647,10 +641,6 @@ icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node, } out: - *p_value = sm0; -out2: - *p_proto = key0.protocol; - *p_dont_translate = dont_translate; return next0; } #endif @@ -667,8 +657,10 @@ icmp_in2out (snat_main_t * sm, u32 next0, u32 thread_index, void *d, void *e) { vlib_main_t *vm = vlib_get_main (); - snat_session_key_t sm0; - u8 protocol; + ip4_address_t addr; + u16 port; + u32 fib_index; + nat_protocol_t protocol; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0; void *l4_header = 0; @@ -683,9 +675,9 @@ icmp_in2out (snat_main_t * sm, echo0 = (icmp_echo_header_t *) (icmp0 + 1); - next0_tmp = sm->icmp_match_in2out_cb (sm, node, thread_index, b0, ip0, - &protocol, &sm0, &dont_translate, d, - e); + next0_tmp = + sm->icmp_match_in2out_cb (sm, node, thread_index, b0, ip0, &addr, &port, + &fib_index, &protocol, d, e, &dont_translate); if (next0_tmp != ~0) next0 = next0_tmp; if (next0 == SNAT_IN2OUT_NEXT_DROP || dont_translate) @@ -708,7 +700,7 @@ icmp_in2out (snat_main_t * sm, } old_addr0 = ip0->src_address.as_u32; - new_addr0 = ip0->src_address.as_u32 = sm0.addr.as_u32; + new_addr0 = ip0->src_address.as_u32 = addr.as_u32; sum0 = ip0->checksum; sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, @@ -722,11 +714,11 @@ icmp_in2out (snat_main_t * sm, if (!icmp_type_is_error_message (icmp0->type)) { - new_id0 = sm0.port; + new_id0 = port; if (PREDICT_FALSE (new_id0 != echo0->identifier)) { old_id0 = echo0->identifier; - new_id0 = sm0.port; + new_id0 = port; echo0->identifier = new_id0; sum0 = icmp0->checksum; @@ -749,7 +741,7 @@ icmp_in2out (snat_main_t * sm, /* update inner destination IP address */ old_addr0 = inner_ip0->dst_address.as_u32; - inner_ip0->dst_address = sm0.addr; + inner_ip0->dst_address = addr; new_addr0 = inner_ip0->dst_address.as_u32; sum0 = icmp0->checksum; sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, @@ -776,7 +768,7 @@ icmp_in2out (snat_main_t * sm, inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1); old_id0 = inner_echo0->identifier; - new_id0 = sm0.port; + new_id0 = port; inner_echo0->identifier = new_id0; sum0 = icmp0->checksum; @@ -788,7 +780,7 @@ icmp_in2out (snat_main_t * sm, case NAT_PROTOCOL_UDP: case NAT_PROTOCOL_TCP: old_id0 = ((tcp_udp_header_t *) l4_header)->dst_port; - new_id0 = sm0.port; + new_id0 = port; ((tcp_udp_header_t *) l4_header)->dst_port = new_id0; sum0 = icmp0->checksum; @@ -807,7 +799,7 @@ icmp_in2out (snat_main_t * sm, if (sm->deterministic || 0 != snat_icmp_hairpinning (sm, b0, ip0, icmp0, sm->endpoint_dependent)) - vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index; } out: @@ -850,15 +842,10 @@ nat_in2out_sm_unknown_proto (snat_main_t * sm, { clib_bihash_kv_8_8_t kv, value; snat_static_mapping_t *m; - snat_session_key_t m_key; u32 old_addr, new_addr; ip_csum_t sum; - m_key.addr = ip->src_address; - m_key.port = 0; - m_key.protocol = 0; - m_key.fib_index = rx_fib_index; - kv.key = m_key.as_u64; + init_nat_k (&kv, ip->src_address, 0, rx_fib_index, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value)) return 1; @@ -923,7 +910,6 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, udp_header_t *udp0, *udp1; tcp_header_t *tcp0, *tcp1; icmp46_header_t *icmp0, *icmp1; - snat_session_key_t key0, key1; u32 rx_fib_index0, rx_fib_index1; u32 proto0, proto1; snat_session_t *s0 = 0, *s1 = 0; @@ -1023,13 +1009,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } - key0.addr = ip0->src_address; - key0.port = vnet_buffer (b0)->ip.reass.l4_src_port; - key0.protocol = proto0; - key0.fib_index = rx_fib_index0; - - kv0.key = key0.as_u64; - + init_nat_k (&kv0, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, + proto0); if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, @@ -1068,7 +1050,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, goto trace00; } - next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, + next0 = slow_path (sm, b0, ip0, + ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, + rx_fib_index0, + proto0, &s0, node, next0, thread_index, now); if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP)) goto trace00; @@ -1232,13 +1218,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } - key1.addr = ip1->src_address; - key1.port = vnet_buffer (b1)->ip.reass.l4_src_port; - key1.protocol = proto1; - key1.fib_index = rx_fib_index1; - - kv1.key = key1.as_u64; - + init_nat_k (&kv1, ip1->src_address, + vnet_buffer (b1)->ip.reass.l4_src_port, rx_fib_index1, + proto1); if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv1, @@ -1277,8 +1259,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, goto trace01; } - next1 = slow_path (sm, b1, ip1, rx_fib_index1, &key1, - &s1, node, next1, thread_index, now); + next1 = + slow_path (sm, b1, ip1, ip1->src_address, + vnet_buffer (b1)->ip.reass.l4_src_port, + rx_fib_index1, proto1, &s1, node, next1, + thread_index, now); if (PREDICT_FALSE (next1 == SNAT_IN2OUT_NEXT_DROP)) goto trace01; @@ -1392,7 +1377,6 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, udp_header_t *udp0; tcp_header_t *tcp0; icmp46_header_t *icmp0; - snat_session_key_t key0; u32 rx_fib_index0; u32 proto0; snat_session_t *s0 = 0; @@ -1476,12 +1460,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } - key0.addr = ip0->src_address; - key0.port = vnet_buffer (b0)->ip.reass.l4_src_port; - key0.protocol = proto0; - key0.fib_index = rx_fib_index0; - - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, + proto0); if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, &value0)) @@ -1519,7 +1500,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, goto trace0; } - next0 = slow_path (sm, b0, ip0, rx_fib_index0, &key0, + next0 = slow_path (sm, b0, ip0, + ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, + rx_fib_index0, + proto0, &s0, node, next0, thread_index, now); if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP)) @@ -1808,9 +1793,12 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm, udp_header_t *udp0; tcp_header_t *tcp0; icmp46_header_t *icmp0; - snat_session_key_t key0, sm0; u32 proto0; u32 rx_fib_index0; + ip4_address_t sm0_addr; + u16 sm0_port; + u32 sm0_fib_index; + /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -1854,21 +1842,18 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm, goto trace0; } - key0.addr = ip0->src_address; - key0.protocol = proto0; - key0.port = udp0->src_port; - key0.fib_index = rx_fib_index0; - - if (snat_static_mapping_match (sm, key0, &sm0, 0, 0, 0, 0, 0, 0)) + if (snat_static_mapping_match + (sm, ip0->src_address, udp0->src_port, rx_fib_index0, proto0, + &sm0_addr, &sm0_port, &sm0_fib_index, 0, 0, 0, 0, 0, 0)) { b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION]; next0 = SNAT_IN2OUT_NEXT_DROP; goto trace0; } - new_addr0 = sm0.addr.as_u32; - new_port0 = sm0.port; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index; + new_addr0 = sm0_addr.as_u32; + new_port0 = sm0_port; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0_fib_index; old_addr0 = ip0->src_address.as_u32; ip0->src_address.as_u32 = new_addr0; diff --git a/src/plugins/nat/in2out_ed.c b/src/plugins/nat/in2out_ed.c index 54c866be74a..2e316f59c3a 100644 --- a/src/plugins/nat/in2out_ed.c +++ b/src/plugins/nat/in2out_ed.c @@ -81,7 +81,6 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) clib_bihash_kv_16_8_t ed_kv; int i; snat_address_t *a; - snat_session_key_t key; snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data, ctx->thread_index); @@ -104,12 +103,11 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) } else { - proto = nat_proto_to_ip_proto (s->in2out.protocol); + proto = nat_proto_to_ip_proto (s->nat_proto); l_port = s->out2in.port; r_port = s->ext_host_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0)) nat_elog_warn ("out2in_ed key del failed"); @@ -119,7 +117,7 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) snat_ipfix_logging_nat44_ses_delete (ctx->thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); @@ -129,24 +127,26 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, is_twice_nat_session (s)); + s->nat_proto, is_twice_nat_session (s)); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, ctx->thread_index); if (is_twice_nat_session (s)) { for (i = 0; i < vec_len (sm->twice_nat_addresses); i++) { - key.protocol = s->in2out.protocol; - key.port = s->ext_host_nat_port; + // TODO FIXME this is obviously broken - which address should be + // freed here?! a = sm->twice_nat_addresses + i; if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32) { snat_free_outside_address_and_port (sm->twice_nat_addresses, ctx->thread_index, - &key); + &s->ext_host_nat_addr, + s->ext_host_nat_port, + s->nat_proto); break; } } @@ -156,7 +156,8 @@ nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) goto delete; snat_free_outside_address_and_port (sm->addresses, ctx->thread_index, - &s->out2in); + &s->out2in.addr, s->out2in.port, + s->nat_proto); delete: nat_ed_session_delete (sm, s, ctx->thread_index, 1); return 1; @@ -220,37 +221,38 @@ nat_ed_alloc_addr_and_port (snat_main_t * sm, u32 rx_fib_index, a = sm->addresses + i; switch (nat_proto) { -#define _(N, j, n, unused) \ +#define _(N, j, n, unused) \ case NAT_PROTOCOL_##N: \ - if (a->fib_index == rx_fib_index) \ - { \ - u16 port = snat_random_port (1, port_per_thread); \ - u16 attempts = port_per_thread; \ - while (attempts > 0) \ - { \ - --attempts; \ - portnum = port_thread_offset + port; \ - make_ed_kv (&a->addr, &r_addr, proto, s->out2in.fib_index, \ - clib_host_to_net_u16 (portnum), r_port, thread_index, \ - s - tsm->sessions, out2in_ed_kv); \ - int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv, \ - 2 /* is_add */); \ - if (0 == rv) \ - { \ - ++a->busy_##n##_port_refcounts[portnum]; \ - a->busy_##n##_ports_per_thread[thread_index]++; \ - a->busy_##n##_ports++; \ - *allocated_addr = a->addr; \ - *allocated_port = clib_host_to_net_u16 (portnum); \ - return 0; \ - } \ - port = (port + 1) % port_per_thread; \ - } \ - } \ - else if (a->fib_index == ~0) \ - { \ - ga = a; \ - } \ + if (a->fib_index == rx_fib_index) \ + { \ + u16 port = snat_random_port (1, port_per_thread); \ + u16 attempts = port_per_thread; \ + while (attempts > 0) \ + { \ + --attempts; \ + portnum = port_thread_offset + port; \ + init_ed_kv (out2in_ed_kv, a->addr, \ + clib_host_to_net_u16 (portnum), r_addr, r_port, \ + s->out2in.fib_index, proto, thread_index, \ + s - tsm->sessions); \ + int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv, \ + 2 /* is_add */); \ + if (0 == rv) \ + { \ + ++a->busy_##n##_port_refcounts[portnum]; \ + a->busy_##n##_ports_per_thread[thread_index]++; \ + a->busy_##n##_ports++; \ + *allocated_addr = a->addr; \ + *allocated_port = clib_host_to_net_u16 (portnum); \ + return 0; \ + } \ + port = (port + 1) % port_per_thread; \ + } \ + } \ + else if (a->fib_index == ~0) \ + { \ + ga = a; \ + } \ break; foreach_nat_protocol; @@ -321,14 +323,11 @@ slow_path_ed (snat_main_t * sm, snat_session_t ** sessionp, vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now) { - snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; clib_bihash_kv_16_8_t out2in_ed_kv; nat44_is_idle_session_ctx_t ctx; - snat_session_key_t key0, key1; ip4_address_t allocated_addr; u16 allocated_port; - u32 tx_fib_index; u8 identity_nat; u32 nat_proto = ip_proto_to_nat_proto (proto); @@ -358,16 +357,13 @@ slow_path_ed (snat_main_t * sm, } } - key0.addr = l_addr; - key0.port = l_port; - key1.protocol = key0.protocol = nat_proto; - key0.fib_index = rx_fib_index; - key1.fib_index = sm->outside_fib_index; - tx_fib_index = sm->outside_fib_index; - + ip4_address_t sm_addr; + u16 sm_port; + u32 sm_fib_index; /* First try to match static mapping by local address and port */ if (snat_static_mapping_match - (sm, key0, &key1, 0, 0, 0, &lb, 0, &identity_nat)) + (sm, l_addr, l_port, rx_fib_index, nat_proto, &sm_addr, &sm_port, + &sm_fib_index, 0, 0, 0, &lb, 0, &identity_nat)) { s = nat_ed_session_alloc (sm, thread_index, now, proto); if (!s) @@ -376,20 +372,25 @@ slow_path_ed (snat_main_t * sm, b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED]; return NAT_NEXT_DROP; } + s->in2out.addr = l_addr; + s->in2out.port = l_port; + s->nat_proto = nat_proto; + s->in2out.fib_index = rx_fib_index; + s->out2in.fib_index = sm->outside_fib_index; + switch (vec_len (sm->outside_fibs)) { case 0: - tx_fib_index = sm->outside_fib_index; + s->out2in.fib_index = sm->outside_fib_index; break; case 1: - tx_fib_index = sm->outside_fibs[0].fib_index; + s->out2in.fib_index = sm->outside_fibs[0].fib_index; break; default: - tx_fib_index = nat_outside_fib_index_lookup (sm, r_addr); + s->out2in.fib_index = nat_outside_fib_index_lookup (sm, r_addr); break; } - s->out2in.fib_index = tx_fib_index; /* Try to create dynamic translation */ if (nat_ed_alloc_addr_and_port (sm, rx_fib_index, nat_proto, thread_index, r_addr, r_port, proto, @@ -403,14 +404,14 @@ slow_path_ed (snat_main_t * sm, nat_ed_session_delete (sm, s, thread_index, 1); return NAT_NEXT_DROP; } - key1.addr = allocated_addr; - key1.port = allocated_port; + s->out2in.addr = allocated_addr; + s->out2in.port = allocated_port; } else { if (PREDICT_FALSE (identity_nat)) { - *sessionp = s; + *sessionp = NULL; return next; } s = nat_ed_session_alloc (sm, thread_index, now, proto); @@ -420,25 +421,31 @@ slow_path_ed (snat_main_t * sm, b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED]; return NAT_NEXT_DROP; } + s->out2in.addr = sm_addr; + s->out2in.port = sm_port; + s->in2out.addr = l_addr; + s->in2out.port = l_port; + s->nat_proto = nat_proto; + s->in2out.fib_index = rx_fib_index; + s->out2in.fib_index = sm->outside_fib_index; switch (vec_len (sm->outside_fibs)) { case 0: - tx_fib_index = sm->outside_fib_index; + s->out2in.fib_index = sm->outside_fib_index; break; case 1: - tx_fib_index = sm->outside_fibs[0].fib_index; + s->out2in.fib_index = sm->outside_fibs[0].fib_index; break; default: - tx_fib_index = nat_outside_fib_index_lookup (sm, r_addr); + s->out2in.fib_index = nat_outside_fib_index_lookup (sm, r_addr); break; } - s->out2in.fib_index = tx_fib_index; s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING; - make_ed_kv (&key1.addr, &r_addr, proto, - s->out2in.fib_index, key1.port, r_port, thread_index, - s - tsm->sessions, &out2in_ed_kv); + init_ed_kv (&out2in_ed_kv, sm_addr, sm_port, r_addr, r_port, + s->out2in.fib_index, proto, thread_index, + s - tsm->sessions); if (clib_bihash_add_or_overwrite_stale_16_8 (&sm->out2in_ed, &out2in_ed_kv, nat44_o2i_ed_is_idle_session_cb, &ctx)) @@ -450,14 +457,10 @@ slow_path_ed (snat_main_t * sm, s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT; s->ext_host_addr = r_addr; s->ext_host_port = r_port; - s->in2out = key0; - s->out2in = key1; - s->out2in.fib_index = tx_fib_index; - s->out2in.protocol = key0.protocol; clib_bihash_kv_16_8_t in2out_ed_kv; - make_ed_kv (&l_addr, &r_addr, proto, rx_fib_index, l_port, r_port, - thread_index, s - tsm->sessions, &in2out_ed_kv); + init_ed_kv (&in2out_ed_kv, l_addr, l_port, r_addr, r_port, rx_fib_index, + proto, thread_index, s - tsm->sessions); ctx.now = now; ctx.thread_index = thread_index; if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &in2out_ed_kv, @@ -471,7 +474,7 @@ slow_path_ed (snat_main_t * sm, snat_ipfix_logging_nat44_ses_create (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); @@ -479,14 +482,13 @@ slow_path_ed (snat_main_t * sm, &s->in2out.addr, s->in2out.port, &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, - &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, 0); + &s->ext_host_addr, s->ext_host_port, s->nat_proto, + 0); nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, &s->ext_host_nat_addr, s->ext_host_nat_port, - s->in2out.protocol, s->in2out.fib_index, s->flags, - thread_index, 0); + s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0); return next; } @@ -498,21 +500,20 @@ nat44_ed_not_translate (snat_main_t * sm, vlib_node_runtime_t * node, { udp_header_t *udp = ip4_next_header (ip); clib_bihash_kv_16_8_t kv, value; - snat_session_key_t key0, key1; - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, - sm->outside_fib_index, udp->dst_port, udp->src_port, ~0, ~0, - &kv); + init_ed_k (&kv, ip->dst_address, udp->dst_port, ip->src_address, + udp->src_port, sm->outside_fib_index, ip->protocol); /* NAT packet aimed at external address if has active sessions */ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value)) { - key0.addr = ip->dst_address; - key0.port = udp->dst_port; - key0.protocol = proto; - key0.fib_index = sm->outside_fib_index; /* or is static mappings */ - if (!snat_static_mapping_match (sm, key0, &key1, 1, 0, 0, 0, 0, 0)) + ip4_address_t dummy_addr; + u16 dummy_port; + u32 dummy_fib_index; + if (!snat_static_mapping_match + (sm, ip->dst_address, udp->dst_port, sm->outside_fib_index, proto, + &dummy_addr, &dummy_port, &dummy_fib_index, 1, 0, 0, 0, 0, 0)) return 0; } else @@ -544,14 +545,14 @@ nat_not_translate_output_feature_fwd (snat_main_t * sm, ip4_header_t * ip, } else if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP) { - make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0, - vnet_buffer (b)->ip.reass.l4_src_port, - vnet_buffer (b)->ip.reass.l4_dst_port, ~0, ~0, &kv); + init_ed_k (&kv, ip->src_address, vnet_buffer (b)->ip.reass.l4_src_port, + ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port, 0, + ip->protocol); } else { - make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0, 0, - 0, ~0, ~0, &kv); + init_ed_k (&kv, ip->src_address, 0, ip->dst_address, 0, 0, + ip->protocol); } if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value)) @@ -597,8 +598,8 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip, u32 tx_fib_index = ip4_fib_table_get_index_for_sw_if_index (tx_sw_if_index); /* src NAT check */ - make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, - tx_fib_index, src_port, dst_port, ~0, ~0, &kv); + init_ed_k (&kv, ip->src_address, src_port, ip->dst_address, dst_port, + tx_fib_index, ip->protocol); if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value)) { ASSERT (thread_index == ed_value_get_thread_index (&value)); @@ -616,8 +617,8 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip, } /* dst NAT check */ - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, - rx_fib_index, dst_port, src_port, ~0, ~0, &kv); + init_ed_k (&kv, ip->dst_address, dst_port, ip->src_address, src_port, + rx_fib_index, ip->protocol); if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value)) { ASSERT (thread_index == ed_value_get_thread_index (&value)); @@ -644,26 +645,27 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip, #ifndef CLIB_MARCH_VARIANT u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, - u32 thread_index, vlib_buffer_t * b, ip4_header_t * ip, - u8 * p_proto, snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + u32 thread_index, vlib_buffer_t * b, + ip4_header_t * ip, ip4_address_t * addr, + u16 * port, u32 * fib_index, nat_protocol_t * proto, + void *d, void *e, u8 * dont_translate) { u32 sw_if_index; u32 rx_fib_index; - snat_session_t *s = 0; - u8 dont_translate = 0; clib_bihash_kv_16_8_t kv, value; u32 next = ~0; int err; + snat_session_t *s = NULL; u16 l_port = 0, r_port = 0; // initialize to workaround gcc warning vlib_main_t *vm = vlib_get_main (); snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; + *dont_translate = 0; sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index); err = - get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port, + get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0, ~0, proto, &l_port, &r_port, &kv); if (err != 0) { @@ -681,7 +683,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, (sm, ip, l_port, r_port, thread_index, sw_if_index, vnet_buffer (b)->sw_if_index[VLIB_TX]))) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -692,7 +694,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, rx_fib_index, thread_index))) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -716,7 +718,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, if (!s) { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -742,10 +744,15 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, } out: if (s) - *p_value = s->out2in; - *p_dont_translate = dont_translate; + { + *addr = s->out2in.addr; + *port = s->out2in.port; + *fib_index = s->out2in.fib_index; + } if (d) - *(snat_session_t **) d = s; + { + *(snat_session_t **) d = s; + } return next; } #endif @@ -784,8 +791,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, } old_addr = ip->src_address.as_u32; - make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, - rx_fib_index, 0, 0, ~0, ~0, &s_kv); + init_ed_k (&s_kv, ip->src_address, 0, ip->dst_address, 0, rx_fib_index, + ip->protocol); if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &s_kv, &s_value)) { @@ -807,7 +814,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, return 0; } - make_sm_kv (&kv, &ip->src_address, 0, rx_fib_index, 0); + init_nat_k (&kv, ip->src_address, 0, rx_fib_index, 0); /* Try to find static mapping first */ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value)) @@ -825,8 +832,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, { new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32; - make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol, - outside_fib_index, 0, 0, ~0, ~0, &s_kv); + init_ed_k(&s_kv, s->out2in.addr, 0, ip->dst_address, 0, outside_fib_index, ip->protocol); if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value)) goto create_ses; @@ -837,9 +843,8 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, for (i = 0; i < vec_len (sm->addresses); i++) { - make_ed_kv (&sm->addresses[i].addr, &ip->dst_address, - ip->protocol, outside_fib_index, 0, 0, ~0, ~0, - &s_kv); + init_ed_k (&s_kv, sm->addresses[i].addr, 0, ip->dst_address, 0, + outside_fib_index, ip->protocol); if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value)) { new_addr = ip->src_address.as_u32 = @@ -871,14 +876,14 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING; /* Add to lookup tables */ - make_ed_kv (&s->in2out.addr, &ip->dst_address, ip->protocol, - rx_fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv); + init_ed_kv (&s_kv, s->in2out.addr, 0, ip->dst_address, 0, rx_fib_index, + ip->protocol, thread_index, s - tsm->sessions); if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1)) nat_elog_notice ("in2out key add failed"); - make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol, - outside_fib_index, 0, 0, thread_index, s - tsm->sessions, - &s_kv); + init_ed_kv (&s_kv, s->out2in.addr, 0, ip->dst_address, 0, + outside_fib_index, ip->protocol, thread_index, + s - tsm->sessions); if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1)) nat_elog_notice ("out2in key add failed"); } @@ -1007,10 +1012,10 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm, goto trace0; } - make_ed_kv (&ip0->src_address, &ip0->dst_address, - ip0->protocol, rx_fib_index0, - vnet_buffer (b0)->ip.reass.l4_src_port, - vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0); + init_ed_k (&kv0, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + ip0->protocol); // lookup for session if (clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0)) @@ -1295,11 +1300,10 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm, goto trace0; } - make_ed_kv (&ip0->src_address, &ip0->dst_address, - ip0->protocol, rx_fib_index0, - vnet_buffer (b0)->ip.reass.l4_src_port, - vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0); - + init_ed_k (&kv0, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + ip0->protocol); if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0)) { ASSERT (thread_index == ed_value_get_thread_index (&value0)); diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 55664564e0b..ed01bb4df80 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -198,7 +198,6 @@ void nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, u8 is_ha) { - snat_session_key_t key; clib_bihash_kv_8_8_t kv; u8 proto; u16 r_port, l_port; @@ -212,8 +211,8 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, { if (snat_is_unk_proto_session (s)) { - make_ed_kv (&s->in2out.addr, &s->ext_host_addr, s->in2out.port, 0, - 0, 0, ~0, ~0, &ed_kv); + init_ed_k (&ed_kv, s->in2out.addr, 0, s->ext_host_addr, 0, 0, + s->in2out.port); } else { @@ -221,9 +220,9 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, r_port = s->ext_host_port; l_addr = &s->in2out.addr; r_addr = &s->ext_host_addr; - proto = nat_proto_to_ip_proto (s->in2out.protocol); - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, - ~0, &ed_kv); + proto = nat_proto_to_ip_proto (s->nat_proto); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, + proto); } if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)) nat_elog_warn ("in2out_ed key del failed"); @@ -235,7 +234,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, { if (is_affinity_sessions (s)) nat_affinity_unlock (s->ext_host_addr, s->out2in.addr, - s->in2out.protocol, s->out2in.port); + s->nat_proto, s->out2in.port); l_addr = &s->out2in.addr; r_addr = &s->ext_host_addr; fib_index = s->out2in.fib_index; @@ -247,12 +246,11 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, } else { - proto = nat_proto_to_ip_proto (s->in2out.protocol); + proto = nat_proto_to_ip_proto (s->nat_proto); l_port = s->out2in.port; r_port = s->ext_host_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0)) nat_elog_warn ("out2in_ed key del failed"); l_addr = &s->in2out.addr; @@ -264,8 +262,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, r_addr = &s->ext_host_nat_addr; r_port = s->ext_host_nat_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)) nat_elog_warn ("in2out_ed key del failed"); @@ -275,14 +272,14 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, is_twice_nat_session (s)); + s->nat_proto, is_twice_nat_session (s)); } else { - kv.key = s->in2out.as_u64; + init_nat_i2o_k (&kv, s); if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0)) nat_elog_warn ("in2out key del failed"); - kv.key = s->out2in.as_u64; + init_nat_o2i_k (&kv, s); if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0)) nat_elog_warn ("out2in key del failed"); @@ -290,7 +287,7 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index, &s->in2out.addr, s->in2out.port, &s->out2in.addr, s->out2in.port, - s->in2out.protocol); + s->nat_proto); } if (snat_is_unk_proto_session (s)) @@ -302,31 +299,31 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, snat_ipfix_logging_nat44_ses_delete (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, thread_index); } /* Twice NAT address and port for external host */ if (is_twice_nat_session (s)) { - key.protocol = s->in2out.protocol; - key.port = s->ext_host_nat_port; - key.addr.as_u32 = s->ext_host_nat_addr.as_u32; snat_free_outside_address_and_port (sm->twice_nat_addresses, - thread_index, &key); + thread_index, + &s->ext_host_nat_addr, + s->ext_host_nat_port, s->nat_proto); } if (snat_is_session_static (s)) return; snat_free_outside_address_and_port (sm->addresses, thread_index, - &s->out2in); + &s->out2in.addr, s->out2in.port, + s->nat_proto); } int @@ -352,7 +349,6 @@ void nat44_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, u8 is_ha) { - snat_session_key_t key; u8 proto; u16 r_port, l_port; ip4_address_t *l_addr, *r_addr; @@ -371,7 +367,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, } else { - proto = nat_proto_to_ip_proto (s->in2out.protocol); + proto = nat_proto_to_ip_proto (s->nat_proto); l_port = s->in2out.port; r_port = s->ext_host_port; } @@ -379,8 +375,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, l_addr = &s->in2out.addr; r_addr = &s->ext_host_addr; fib_index = 0; - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))) @@ -391,7 +386,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, /* session lookup tables */ if (is_affinity_sessions (s)) nat_affinity_unlock (s->ext_host_addr, s->out2in.addr, - s->in2out.protocol, s->out2in.port); + s->nat_proto, s->out2in.port); l_addr = &s->out2in.addr; r_addr = &s->ext_host_addr; fib_index = s->out2in.fib_index; @@ -403,12 +398,11 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, } else { - proto = nat_proto_to_ip_proto (s->in2out.protocol); + proto = nat_proto_to_ip_proto (s->nat_proto); l_port = s->out2in.port; r_port = s->ext_host_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))) nat_elog_warn ("out2in_ed key del failed"); @@ -424,8 +418,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, r_addr = &s->ext_host_nat_addr; r_port = s->ext_host_nat_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))) nat_elog_warn ("in2out_ed key del failed"); @@ -437,7 +430,7 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, is_twice_nat_session (s)); + s->nat_proto, is_twice_nat_session (s)); } if (snat_is_unk_proto_session (s)) @@ -448,30 +441,30 @@ nat44_free_session_data (snat_main_t * sm, snat_session_t * s, snat_ipfix_logging_nat44_ses_delete (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, thread_index); } /* Twice NAT address and port for external host */ if (is_twice_nat_session (s)) { - key.protocol = s->in2out.protocol; - key.port = s->ext_host_nat_port; - key.addr.as_u32 = s->ext_host_nat_addr.as_u32; snat_free_outside_address_and_port (sm->twice_nat_addresses, - thread_index, &key); + thread_index, + &s->ext_host_nat_addr, + s->ext_host_nat_port, s->nat_proto); } if (snat_is_session_static (s)) return; snat_free_outside_address_and_port (sm->addresses, thread_index, - &s->out2in); + &s->out2in.addr, s->out2in.port, + s->nat_proto); } @@ -790,7 +783,7 @@ snat_static_mapping_del_sessions (snat_main_t * sm, if (!addr_only) { if ((s->out2in.addr.as_u32 != e_addr.as_u32) || - (clib_net_to_host_u16 (s->out2in.port) != e_port)) + (s->out2in.port != e_port)) continue; } @@ -831,9 +824,9 @@ snat_ed_static_mapping_del_sessions (snat_main_t * sm, if (!addr_only) { if ((s->out2in.addr.as_u32 != e_addr.as_u32) || - (clib_net_to_host_u16 (s->out2in.port) != e_port) || - clib_net_to_host_u16 (s->in2out.port) != l_port || - s->in2out.protocol != protocol) + s->out2in.port != e_port || + s->in2out.port != l_port || + s->nat_proto != protocol) continue; } @@ -865,7 +858,6 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, { snat_main_t *sm = &snat_main; snat_static_mapping_t *m; - snat_session_key_t m_key; clib_bihash_kv_8_8_t kv, value; snat_address_t *a = 0; u32 fib_index = ~0; @@ -958,11 +950,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, } } - m_key.addr = e_addr; - m_key.port = addr_only ? 0 : e_port; - m_key.protocol = addr_only ? 0 : proto; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 : proto); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) m = 0; else @@ -986,12 +974,9 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, local->fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, nat_fib_src_low); - m_key.addr = m->local_addr; - m_key.port = m->local_port; - m_key.protocol = m->proto; - m_key.fib_index = local->fib_index; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, m->local_addr, m->local_port, + local->fib_index, m->proto, + m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); return 0; } @@ -1017,11 +1002,8 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, if (!(out2in_only || identity_nat)) { - m_key.addr = l_addr; - m_key.port = addr_only ? 0 : l_port; - m_key.protocol = addr_only ? 0 : proto; - m_key.fib_index = fib_index; - kv.key = m_key.as_u64; + init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index, + addr_only ? 0 : proto); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value)) return VNET_API_ERROR_VALUE_EXIST; @@ -1123,20 +1105,13 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, else tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); - m_key.addr = m->local_addr; - m_key.port = m->local_port; - m_key.protocol = m->proto; - m_key.fib_index = fib_index; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, + m - sm->static_mappings); if (!out2in_only) clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); - m_key.addr = m->external_addr; - m_key.port = m->external_port; - m_key.fib_index = 0; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, + m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1); /* Delete dynamic sessions matching local address (+ local port) */ @@ -1165,9 +1140,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, if (snat_is_session_static (s)) continue; - if (!addr_only - && (clib_net_to_host_u16 (s->in2out.port) != - m->local_port)) + if (!addr_only && s->in2out.port != m->local_port) continue; nat_free_session_data (sm, s, @@ -1248,11 +1221,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, else tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); - m_key.addr = m->local_addr; - m_key.port = m->local_port; - m_key.protocol = m->proto; - m_key.fib_index = fib_index; - kv.key = m_key.as_u64; + init_nat_k (&kv, m->local_addr, m->local_port, fib_index, m->proto); if (!out2in_only) clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0); @@ -1281,10 +1250,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, if (pool_elts (m->locals)) return 0; - m_key.addr = m->external_addr; - m_key.port = m->external_port; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto); clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0); vec_free (m->tag); @@ -1328,7 +1294,6 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, { snat_main_t *sm = &snat_main; snat_static_mapping_t *m; - snat_session_key_t m_key; clib_bihash_kv_8_8_t kv, value; snat_address_t *a = 0; int i; @@ -1340,11 +1305,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, if (!sm->endpoint_dependent) return VNET_API_ERROR_FEATURE_DISABLED; - m_key.addr = e_addr; - m_key.port = e_port; - m_key.protocol = proto; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, e_addr, e_port, 0, proto); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) m = 0; else @@ -1413,32 +1374,25 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, else m->affinity_per_service_list_head_index = ~0; - m_key.addr = m->external_addr; - m_key.port = m->external_port; - m_key.protocol = m->proto; - m_key.fib_index = 0; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, + m - sm->static_mappings); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1)) { nat_elog_err ("static_mapping_by_external key add failed"); return VNET_API_ERROR_UNSPECIFIED; } - m_key.fib_index = m->fib_index; for (i = 0; i < vec_len (locals); i++) { locals[i].fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, locals[i].vrf_id, nat_fib_src_low); - m_key.addr = locals[i].addr; - m_key.fib_index = locals[i].fib_index; if (!out2in_only) { - m_key.port = locals[i].port; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, locals[i].addr, locals[i].port, + locals[i].fib_index, m->proto, + m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); } locals[i].prefix = (i == 0) ? locals[i].probability : @@ -1506,11 +1460,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, } } - m_key.addr = m->external_addr; - m_key.port = m->external_port; - m_key.protocol = m->proto; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0)) { nat_elog_err ("static_mapping_by_external key del failed"); @@ -1522,12 +1472,9 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, ({ fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4, nat_fib_src_low); - m_key.addr = local->addr; if (!out2in_only) { - m_key.port = local->port; - m_key.fib_index = local->fib_index; - kv.key = m_key.as_u64; +init_nat_k(& kv, local->addr, local->port, local->fib_index, m->proto); if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0)) { nat_elog_err ("static_mapping_by_local key del failed"); @@ -1552,7 +1499,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, continue; if ((s->in2out.addr.as_u32 != local->addr.as_u32) || - (clib_net_to_host_u16 (s->in2out.port) != local->port)) + s->in2out.port != local->port) continue; nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0); @@ -1580,7 +1527,6 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, { snat_main_t *sm = &snat_main; snat_static_mapping_t *m = 0; - snat_session_key_t m_key; clib_bihash_kv_8_8_t kv, value; nat44_lb_addr_port_t *local, *prev_local, *match_local = 0; snat_main_per_thread_data_t *tsm; @@ -1592,11 +1538,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, if (!sm->endpoint_dependent) return VNET_API_ERROR_FEATURE_DISABLED; - m_key.addr = e_addr; - m_key.port = e_port; - m_key.protocol = proto; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, e_addr, e_port, 0, proto); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) m = pool_elt_at_index (sm->static_mappings, value.value); @@ -1635,11 +1577,8 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, if (!is_out2in_only_static_mapping (m)) { - m_key.addr = l_addr; - m_key.port = l_port; - m_key.fib_index = local->fib_index; - kv.key = m_key.as_u64; - kv.value = m - sm->static_mappings; + init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto, + m - sm->static_mappings); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1)) nat_elog_err ("static_mapping_by_local key add failed"); } @@ -1657,10 +1596,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, if (!is_out2in_only_static_mapping (m)) { - m_key.addr = l_addr; - m_key.port = l_port; - m_key.fib_index = match_local->fib_index; - kv.key = m_key.as_u64; + init_nat_k (&kv, l_addr, l_port, match_local->fib_index, proto); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0)) nat_elog_err ("static_mapping_by_local key del failed"); } @@ -1684,7 +1620,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, continue; if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) || - (clib_net_to_host_u16 (s->in2out.port) != match_local->port)) + s->in2out.port != match_local->port) continue; nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0); @@ -2441,14 +2377,13 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, u32 if_address_index, u32 is_delete); static int -nat_alloc_addr_and_port_default (snat_address_t * addresses, - u32 fib_index, - u32 thread_index, - snat_session_key_t * k, +nat_alloc_addr_and_port_default (snat_address_t * addresses, u32 fib_index, + u32 thread_index, nat_protocol_t proto, + ip4_address_t * addr, u16 * port, u16 port_per_thread, u32 snat_thread_index); void -test_ed_make_split () +test_key_calc_split () { ip4_address_t l_addr; l_addr.as_u8[0] = 1; @@ -2467,8 +2402,8 @@ test_ed_make_split () u32 thread_index = 3000000001; u32 session_index = 3000000221; clib_bihash_kv_16_8_t kv; - make_ed_kv (&l_addr, &r_addr, proto, fib_index, l_port, r_port, - thread_index, session_index, &kv); + init_ed_kv (&kv, l_addr, l_port, r_addr, r_port, fib_index, proto, + thread_index, session_index); ip4_address_t l_addr2; ip4_address_t r_addr2; clib_memset (&l_addr2, 0, sizeof (l_addr2)); @@ -2487,6 +2422,16 @@ test_ed_make_split () ASSERT (fib_index == fib_index2); ASSERT (thread_index == ed_value_get_thread_index (&kv)); ASSERT (session_index == ed_value_get_session_index (&kv)); + + fib_index = 7001; + proto = 5; + nat_protocol_t proto3 = ~0; + u64 key = calc_nat_key (l_addr, l_port, fib_index, proto); + split_nat_key (key, &l_addr2, &l_port2, &fib_index2, &proto3); + ASSERT (l_addr.as_u32 == l_addr2.as_u32); + ASSERT (l_port == l_port2); + ASSERT (proto == proto3); + ASSERT (fib_index == fib_index2); } static clib_error_t * @@ -2656,7 +2601,7 @@ snat_init (vlib_main_t * vm) FIB_SOURCE_PRIORITY_LOW, FIB_SOURCE_BH_SIMPLE); - test_ed_make_split (); + test_key_calc_split (); return error; } @@ -2664,16 +2609,18 @@ VLIB_INIT_FUNCTION (snat_init); void snat_free_outside_address_and_port (snat_address_t * addresses, - u32 thread_index, snat_session_key_t * k) + u32 thread_index, + ip4_address_t * addr, + u16 port, nat_protocol_t protocol) { snat_address_t *a; u32 address_index; - u16 port_host_byte_order = clib_net_to_host_u16 (k->port); + u16 port_host_byte_order = clib_net_to_host_u16 (port); for (address_index = 0; address_index < vec_len (addresses); address_index++) { - if (addresses[address_index].addr.as_u32 == k->addr.as_u32) + if (addresses[address_index].addr.as_u32 == addr->as_u32) break; } @@ -2681,7 +2628,7 @@ snat_free_outside_address_and_port (snat_address_t * addresses, a = addresses + address_index; - switch (k->protocol) + switch (protocol) { #define _(N, i, n, s) \ case NAT_PROTOCOL_##N: \ @@ -2700,20 +2647,21 @@ snat_free_outside_address_and_port (snat_address_t * addresses, static int nat_set_outside_address_and_port (snat_address_t * addresses, - u32 thread_index, snat_session_key_t * k) + u32 thread_index, ip4_address_t addr, + u16 port, nat_protocol_t protocol) { snat_address_t *a = 0; u32 address_index; - u16 port_host_byte_order = clib_net_to_host_u16 (k->port); + u16 port_host_byte_order = clib_net_to_host_u16 (port); for (address_index = 0; address_index < vec_len (addresses); address_index++) { - if (addresses[address_index].addr.as_u32 != k->addr.as_u32) + if (addresses[address_index].addr.as_u32 != addr.as_u32) continue; a = addresses + address_index; - switch (k->protocol) + switch (protocol) { #define _(N, j, n, s) \ case NAT_PROTOCOL_##N: \ @@ -2736,8 +2684,13 @@ nat_set_outside_address_and_port (snat_address_t * addresses, int snat_static_mapping_match (snat_main_t * sm, - snat_session_key_t match, - snat_session_key_t * mapping, + ip4_address_t match_addr, + u16 match_port, + u32 match_fib_index, + nat_protocol_t match_protocol, + ip4_address_t * mapping_addr, + u16 * mapping_port, + u32 * mapping_fib_index, u8 by_external, u8 * is_addr_only, twice_nat_type_t * twice_nat, @@ -2746,33 +2699,36 @@ snat_static_mapping_match (snat_main_t * sm, { clib_bihash_kv_8_8_t kv, value; snat_static_mapping_t *m; - snat_session_key_t m_key; clib_bihash_8_8_t *mapping_hash = &sm->static_mapping_by_local; u32 rand, lo = 0, hi, mid, *tmp = 0, i; u8 backend_index; nat44_lb_addr_port_t *local; - m_key.fib_index = match.fib_index; if (by_external) { mapping_hash = &sm->static_mapping_by_external; - m_key.fib_index = 0; - } - - m_key.addr = match.addr; - m_key.port = clib_net_to_host_u16 (match.port); - m_key.protocol = match.protocol; - - kv.key = m_key.as_u64; + init_nat_k (&kv, match_addr, match_port, 0, match_protocol); + if (clib_bihash_search_8_8 (mapping_hash, &kv, &value)) + { + /* Try address only mapping */ + init_nat_k (&kv, match_addr, 0, 0, 0); + if (clib_bihash_search_8_8 (mapping_hash, &kv, &value)) + return 1; + } - if (clib_bihash_search_8_8 (mapping_hash, &kv, &value)) + } + else { - /* Try address only mapping */ - m_key.port = 0; - m_key.protocol = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, match_addr, match_port, match_fib_index, + match_protocol); if (clib_bihash_search_8_8 (mapping_hash, &kv, &value)) - return 1; + { + /* Try address only mapping */ + init_nat_k (&kv, match_addr, 0, match_fib_index, 0); + if (clib_bihash_search_8_8 (mapping_hash, &kv, &value)) + return 1; + } + } m = pool_elt_at_index (sm->static_mappings, value.value); @@ -2784,15 +2740,15 @@ snat_static_mapping_match (snat_main_t * sm, if (PREDICT_FALSE (lb != 0)) *lb = m->affinity ? AFFINITY_LB_NAT : LB_NAT; if (m->affinity && !nat_affinity_find_and_lock (ext_host_addr[0], - match.addr, - match.protocol, - match.port, + match_addr, + match_protocol, + match_port, &backend_index)) { local = pool_elt_at_index (m->locals, backend_index); - mapping->addr = local->addr; - mapping->port = clib_host_to_net_u16 (local->port); - mapping->fib_index = local->fib_index; + *mapping_addr = local->addr; + *mapping_port = local->port; + *mapping_fib_index = local->fib_index; goto end; } // pick locals matching this worker @@ -2838,13 +2794,13 @@ snat_static_mapping_match (snat_main_t * sm, local = pool_elt_at_index (m->locals, tmp[lo]); if (!(local->prefix >= rand)) return 1; - mapping->addr = local->addr; - mapping->port = clib_host_to_net_u16 (local->port); - mapping->fib_index = local->fib_index; + *mapping_addr = local->addr; + *mapping_port = local->port; + *mapping_fib_index = local->fib_index; if (m->affinity) { - if (nat_affinity_create_and_lock (ext_host_addr[0], match.addr, - match.protocol, match.port, + if (nat_affinity_create_and_lock (ext_host_addr[0], match_addr, + match_protocol, match_port, tmp[lo], m->affinity, m->affinity_per_service_list_head_index)) nat_elog_info ("create affinity record failed"); @@ -2855,21 +2811,20 @@ snat_static_mapping_match (snat_main_t * sm, { if (PREDICT_FALSE (lb != 0)) *lb = NO_LB_NAT; - mapping->fib_index = m->fib_index; - mapping->addr = m->local_addr; + *mapping_fib_index = m->fib_index; + *mapping_addr = m->local_addr; /* Address only mapping doesn't change port */ - mapping->port = is_addr_only_static_mapping (m) ? match.port - : clib_host_to_net_u16 (m->local_port); + *mapping_port = is_addr_only_static_mapping (m) ? match_port + : m->local_port; } - mapping->protocol = m->proto; } else { - mapping->addr = m->external_addr; + *mapping_addr = m->external_addr; /* Address only mapping doesn't change port */ - mapping->port = is_addr_only_static_mapping (m) ? match.port - : clib_host_to_net_u16 (m->external_port); - mapping->fib_index = sm->outside_fib_index; + *mapping_port = is_addr_only_static_mapping (m) ? match_port + : m->external_port; + *mapping_fib_index = sm->outside_fib_index; } end: @@ -2897,21 +2852,26 @@ int snat_alloc_outside_address_and_port (snat_address_t * addresses, u32 fib_index, u32 thread_index, - snat_session_key_t * k, + nat_protocol_t proto, + ip4_address_t * addr, + u16 * port, u16 port_per_thread, u32 snat_thread_index) { snat_main_t *sm = &snat_main; - return sm->alloc_addr_and_port (addresses, fib_index, thread_index, k, - port_per_thread, snat_thread_index); + return sm->alloc_addr_and_port (addresses, fib_index, thread_index, proto, + addr, port, port_per_thread, + snat_thread_index); } static int nat_alloc_addr_and_port_default (snat_address_t * addresses, u32 fib_index, u32 thread_index, - snat_session_key_t * k, + nat_protocol_t proto, + ip4_address_t * addr, + u16 * port, u16 port_per_thread, u32 snat_thread_index) { int i; @@ -2921,7 +2881,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, for (i = 0; i < vec_len (addresses); i++) { a = addresses + i; - switch (k->protocol) + switch (proto) { #define _(N, j, n, s) \ case NAT_PROTOCOL_##N: \ @@ -2939,8 +2899,8 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, --a->busy_##n##_port_refcounts[portnum]; \ a->busy_##n##_ports_per_thread[thread_index]++; \ a->busy_##n##_ports++; \ - k->addr = a->addr; \ - k->port = clib_host_to_net_u16(portnum); \ + *addr = a->addr; \ + *port = clib_host_to_net_u16(portnum); \ return 0; \ } \ } \ @@ -2962,7 +2922,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, if (ga) { a = ga; - switch (k->protocol) + switch (proto) { #define _(N, j, n, s) \ case NAT_PROTOCOL_##N: \ @@ -2976,8 +2936,8 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, ++a->busy_##n##_port_refcounts[portnum]; \ a->busy_##n##_ports_per_thread[thread_index]++; \ a->busy_##n##_ports++; \ - k->addr = a->addr; \ - k->port = clib_host_to_net_u16(portnum); \ + *addr = a->addr; \ + *port = clib_host_to_net_u16(portnum); \ return 0; \ } break; @@ -2995,10 +2955,9 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, } static int -nat_alloc_addr_and_port_mape (snat_address_t * addresses, - u32 fib_index, - u32 thread_index, - snat_session_key_t * k, +nat_alloc_addr_and_port_mape (snat_address_t * addresses, u32 fib_index, + u32 thread_index, nat_protocol_t proto, + ip4_address_t * addr, u16 * port, u16 port_per_thread, u32 snat_thread_index) { snat_main_t *sm = &snat_main; @@ -3010,7 +2969,7 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses, if (!vec_len (addresses)) goto exhausted; - switch (k->protocol) + switch (proto) { #define _(N, i, n, s) \ case NAT_PROTOCOL_##N: \ @@ -3025,8 +2984,8 @@ nat_alloc_addr_and_port_mape (snat_address_t * addresses, continue; \ ++a->busy_##n##_port_refcounts[portnum]; \ a->busy_##n##_ports++; \ - k->addr = a->addr; \ - k->port = clib_host_to_net_u16 (portnum); \ + *addr = a->addr; \ + *port = clib_host_to_net_u16 (portnum); \ return 0; \ } \ } \ @@ -3045,10 +3004,9 @@ exhausted: } static int -nat_alloc_addr_and_port_range (snat_address_t * addresses, - u32 fib_index, - u32 thread_index, - snat_session_key_t * k, +nat_alloc_addr_and_port_range (snat_address_t * addresses, u32 fib_index, + u32 thread_index, nat_protocol_t proto, + ip4_address_t * addr, u16 * port, u16 port_per_thread, u32 snat_thread_index) { snat_main_t *sm = &snat_main; @@ -3060,7 +3018,7 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses, if (!vec_len (addresses)) goto exhausted; - switch (k->protocol) + switch (proto) { #define _(N, i, n, s) \ case NAT_PROTOCOL_##N: \ @@ -3073,8 +3031,8 @@ nat_alloc_addr_and_port_range (snat_address_t * addresses, continue; \ ++a->busy_##n##_port_refcounts[portnum]; \ a->busy_##n##_ports++; \ - k->addr = a->addr; \ - k->port = clib_host_to_net_u16 (portnum); \ + *addr = a->addr; \ + *port = clib_host_to_net_u16 (portnum); \ return 0; \ } \ } \ @@ -3119,11 +3077,8 @@ u8 * format_session_kvp (u8 * s, va_list * args) { clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *); - snat_session_key_t k; - k.as_u64 = v->key; - - s = format (s, "%U session-index %llu", format_snat_key, &k, v->value); + s = format (s, "%U session-index %llu", format_snat_key, v->key, v->value); return s; } @@ -3132,12 +3087,9 @@ u8 * format_static_mapping_kvp (u8 * s, va_list * args) { clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *); - snat_session_key_t k; - - k.as_u64 = v->key; s = format (s, "%U static-mapping-index %llu", - format_static_mapping_key, &k, v->value); + format_snat_key, v->key, v->value); return s; } @@ -3205,7 +3157,6 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0, snat_main_t *sm = &snat_main; udp_header_t *udp; u16 port; - snat_session_key_t m_key; clib_bihash_kv_8_8_t kv, value; snat_static_mapping_t *m; u32 proto; @@ -3214,11 +3165,7 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0, /* first try static mappings without port */ if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - m_key.addr = ip0->dst_address; - m_key.port = 0; - m_key.protocol = 0; - m_key.fib_index = rx_fib_index0; - kv.key = m_key.as_u64; + init_nat_k (&kv, ip0->dst_address, 0, rx_fib_index0, 0); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { @@ -3271,11 +3218,7 @@ snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0, /* try static mappings with port */ if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - m_key.addr = ip0->dst_address; - m_key.port = clib_net_to_host_u16 (port); - m_key.protocol = proto; - m_key.fib_index = rx_fib_index0; - kv.key = m_key.as_u64; + init_nat_k (&kv, ip0->dst_address, port, rx_fib_index0, proto); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { @@ -3345,9 +3288,8 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t * ip, u32 rx_fib_index, break; } - make_ed_kv (&ip->src_address, &ip->dst_address, - ip->protocol, fib_index, udp->src_port, udp->dst_port, - ~0, ~0, &kv16); + init_ed_k (&kv16, ip->src_address, udp->src_port, ip->dst_address, + udp->dst_port, fib_index, ip->protocol); if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv16, &value16))) @@ -3415,9 +3357,8 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip, { udp = ip4_next_header (ip); - make_ed_kv (&ip->dst_address, &ip->src_address, - ip->protocol, rx_fib_index, udp->dst_port, udp->src_port, - ~0, ~0, &kv16); + init_ed_k (&kv16, ip->dst_address, udp->dst_port, ip->src_address, + udp->src_port, rx_fib_index, ip->protocol); if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv16, &value16))) @@ -3462,7 +3403,7 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip, /* first try static mappings without port */ if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - make_sm_kv (&kv, &ip->dst_address, 0, 0, 0); + init_nat_k (&kv, ip->dst_address, 0, 0, 0); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { @@ -3517,8 +3458,7 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip, /* try static mappings with port */ if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - make_sm_kv (&kv, &ip->dst_address, proto, 0, - clib_net_to_host_u16 (port)); + init_nat_k (&kv, ip->dst_address, proto, 0, port); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { @@ -3562,7 +3502,6 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, { snat_main_t *sm = &snat_main; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; - snat_session_key_t key; snat_user_t *u; snat_session_t *s; clib_bihash_kv_8_8_t kv; @@ -3578,14 +3517,10 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, }, }; - key.addr.as_u32 = out_addr->as_u32; - key.port = out_port; - key.protocol = proto; - if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING)) { if (nat_set_outside_address_and_port - (sm->addresses, thread_index, &key)) + (sm->addresses, thread_index, *out_addr, out_port, proto)) return; } @@ -3599,9 +3534,12 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, if (sm->endpoint_dependent) { - nat_ed_lru_insert (tsm, s, now, proto); + nat_ed_lru_insert (tsm, s, now, nat_proto_to_ip_proto (proto)); } + s->out2in.addr.as_u32 = out_addr->as_u32; + s->out2in.port = out_port; + s->nat_proto = proto; s->last_heard = now; s->flags = flags; s->ext_host_addr.as_u32 = eh_addr->as_u32; @@ -3610,10 +3548,10 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, switch (vec_len (sm->outside_fibs)) { case 0: - key.fib_index = sm->outside_fib_index; + s->out2in.fib_index = sm->outside_fib_index; break; case 1: - key.fib_index = sm->outside_fibs[0].fib_index; + s->out2in.fib_index = sm->outside_fibs[0].fib_index; break; default: /* *INDENT-OFF* */ @@ -3624,7 +3562,7 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, { if (fib_entry_get_resolving_interface (fei) != ~0) { - key.fib_index = outside_fib->fib_index; + s->out2in.fib_index = outside_fib->fib_index; break; } } @@ -3632,17 +3570,14 @@ nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port, /* *INDENT-ON* */ break; } - s->out2in = key; - kv.key = key.as_u64; - kv.value = s - tsm->sessions; + init_nat_o2i_kv (&kv, s, s - tsm->sessions); if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 1)) nat_elog_warn ("out2in key add failed"); - key.addr.as_u32 = in_addr->as_u32; - key.port = in_port; - key.fib_index = fib_index; - s->in2out = key; - kv.key = key.as_u64; + s->in2out.addr.as_u32 = in_addr->as_u32; + s->in2out.port = in_port; + s->in2out.fib_index = fib_index; + init_nat_i2o_kv (&kv, s, s - tsm->sessions); if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 1)) nat_elog_warn ("in2out key add failed"); } @@ -3653,7 +3588,6 @@ nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port, u32 ti) { snat_main_t *sm = &snat_main; - snat_session_key_t key; clib_bihash_kv_8_8_t kv, value; u32 thread_index; snat_session_t *s; @@ -3668,11 +3602,7 @@ nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port, thread_index = sm->num_workers; tsm = vec_elt_at_index (sm->per_thread_data, thread_index); - key.addr.as_u32 = out_addr->as_u32; - key.port = out_port; - key.protocol = proto; - key.fib_index = fib_index; - kv.key = key.as_u64; + init_nat_k (&kv, *out_addr, out_port, fib_index, proto); if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value)) return; @@ -3687,18 +3617,13 @@ nat_ha_sref_cb (ip4_address_t * out_addr, u16 out_port, u32 total_pkts, u64 total_bytes, u32 thread_index) { snat_main_t *sm = &snat_main; - snat_session_key_t key; clib_bihash_kv_8_8_t kv, value; snat_session_t *s; snat_main_per_thread_data_t *tsm; tsm = vec_elt_at_index (sm->per_thread_data, thread_index); - key.addr.as_u32 = out_addr->as_u32; - key.port = out_port; - key.protocol = proto; - key.fib_index = fib_index; - kv.key = key.as_u64; + init_nat_k (&kv, *out_addr, out_port, fib_index, proto); if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value)) return; @@ -3716,7 +3641,6 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port, { snat_main_t *sm = &snat_main; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; - snat_session_key_t key; snat_session_t *s; clib_bihash_kv_16_8_t kv; vlib_main_t *vm = vlib_get_main (); @@ -3731,23 +3655,18 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port, }, }; - key.addr.as_u32 = out_addr->as_u32; - key.port = out_port; - key.protocol = proto; if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING)) { if (nat_set_outside_address_and_port - (sm->addresses, thread_index, &key)) + (sm->addresses, thread_index, *out_addr, out_port, proto)) return; } - key.addr.as_u32 = ehn_addr->as_u32; - key.port = ehn_port; if (flags & SNAT_SESSION_FLAG_TWICE_NAT) { if (nat_set_outside_address_and_port - (sm->twice_nat_addresses, thread_index, &key)) + (sm->addresses, thread_index, *ehn_addr, ehn_port, proto)) return; } @@ -3767,10 +3686,10 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port, switch (vec_len (sm->outside_fibs)) { case 0: - key.fib_index = sm->outside_fib_index; + s->out2in.fib_index = sm->outside_fib_index; break; case 1: - key.fib_index = sm->outside_fibs[0].fib_index; + s->out2in.fib_index = sm->outside_fibs[0].fib_index; break; default: /* *INDENT-OFF* */ @@ -3781,7 +3700,7 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port, { if (fib_entry_get_resolving_interface (fei) != ~0) { - key.fib_index = outside_fib->fib_index; + s->out2in.fib_index = outside_fib->fib_index; break; } } @@ -3789,25 +3708,23 @@ nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port, /* *INDENT-ON* */ break; } - key.addr.as_u32 = out_addr->as_u32; - key.port = out_port; - s->out2in = key; - kv.value = s - tsm->sessions; - - key.addr.as_u32 = in_addr->as_u32; - key.port = in_port; - key.fib_index = fib_index; - s->in2out = key; - - make_ed_kv (in_addr, &s->ext_host_nat_addr, - nat_proto_to_ip_proto (proto), fib_index, in_port, - s->ext_host_nat_port, thread_index, s - tsm->sessions, &kv); + s->nat_proto = proto; + s->out2in.addr.as_u32 = out_addr->as_u32; + s->out2in.port = out_port; + + s->in2out.addr.as_u32 = in_addr->as_u32; + s->in2out.port = in_port; + s->in2out.fib_index = fib_index; + + init_ed_kv (&kv, *in_addr, in_port, s->ext_host_nat_addr, + s->ext_host_nat_port, fib_index, nat_proto_to_ip_proto (proto), + thread_index, s - tsm->sessions); if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1)) nat_elog_warn ("in2out key add failed"); - make_ed_kv (out_addr, eh_addr, nat_proto_to_ip_proto (proto), - s->out2in.fib_index, out_port, eh_port, thread_index, - s - tsm->sessions, &kv); + init_ed_kv (&kv, *out_addr, out_port, *eh_addr, eh_port, + s->out2in.fib_index, nat_proto_to_ip_proto (proto), + thread_index, s - tsm->sessions); if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &kv, 1)) nat_elog_warn ("out2in key add failed"); } @@ -3832,8 +3749,7 @@ nat_ha_sdel_ed_cb (ip4_address_t * out_addr, u16 out_port, thread_index = sm->num_workers; tsm = vec_elt_at_index (sm->per_thread_data, thread_index); - make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0, - &kv); + init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto); if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value)) return; @@ -3855,8 +3771,7 @@ nat_ha_sref_ed_cb (ip4_address_t * out_addr, u16 out_port, tsm = vec_elt_at_index (sm->per_thread_data, thread_index); - make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0, - &kv); + init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto); if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value)) return; @@ -4210,7 +4125,6 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, snat_main_t *sm = &snat_main; snat_static_map_resolve_t *rp; snat_static_mapping_t *m; - snat_session_key_t m_key; clib_bihash_kv_8_8_t kv, value; int i, rv; ip4_address_t l_addr; @@ -4227,11 +4141,8 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, return; match: - m_key.addr.as_u32 = address->as_u32; - m_key.port = rp->addr_only ? 0 : rp->e_port; - m_key.protocol = rp->addr_only ? 0 : rp->proto; - m_key.fib_index = sm->outside_fib_index; - kv.key = m_key.as_u64; + init_nat_k (&kv, *address, rp->addr_only ? 0 : rp->e_port, + sm->outside_fib_index, rp->addr_only ? 0 : rp->proto); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) m = 0; else @@ -4425,7 +4336,6 @@ nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port, clib_bihash_kv_8_8_t kv, value; ip4_header_t ip; u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id); - snat_session_key_t key; snat_session_t *s; clib_bihash_8_8_t *t; @@ -4440,11 +4350,7 @@ nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port, else tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); - key.addr.as_u32 = addr->as_u32; - key.port = clib_host_to_net_u16 (port); - key.protocol = proto; - key.fib_index = fib_index; - kv.key = key.as_u64; + init_nat_k (&kv, *addr, port, fib_index, proto); t = is_in ? &tsm->in2out : &tsm->out2in; if (!clib_bihash_search_8_8 (t, &kv, &value)) { @@ -4484,8 +4390,7 @@ nat44_del_ed_session (snat_main_t * sm, ip4_address_t * addr, u16 port, tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); t = is_in ? &tsm->in2out_ed : &sm->out2in_ed; - make_ed_kv (addr, eh_addr, proto, fib_index, clib_host_to_net_u16 (port), - clib_host_to_net_u16 (eh_port), ~0, ~0, &kv); + init_ed_k (&kv, *addr, port, *eh_addr, eh_port, fib_index, proto); if (clib_bihash_search_16_8 (t, &kv, &value)) { return VNET_API_ERROR_NO_SUCH_ENTRY; diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index fbf2105dea3..8b04e18b18b 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -68,21 +68,6 @@ typedef struct u32 arc_next_index; } nat_pre_trace_t; -/* session key (4-tuple) */ -typedef struct -{ - union - { - struct - { - ip4_address_t addr; - u16 port; - u16 protocol:3, fib_index:13; - }; - u64 as_u64; - }; -} snat_session_key_t; - /* deterministic session outside key */ typedef struct { @@ -251,11 +236,23 @@ typedef enum /* *INDENT-OFF* */ typedef CLIB_PACKED(struct { - /* Outside network key */ - snat_session_key_t out2in; + /* Outside network tuple */ + struct + { + ip4_address_t addr; + u32 fib_index; + u16 port; + } out2in; - /* Inside network key */ - snat_session_key_t in2out; + /* Inside network tuple */ + struct + { + ip4_address_t addr; + u32 fib_index; + u16 port; + } in2out; + + nat_protocol_t nat_proto; /* Flags */ u32 flags; @@ -491,10 +488,13 @@ typedef u32 (snat_icmp_match_function_t) (struct snat_main_s * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, - void *e); + ip4_header_t * ip0, + ip4_address_t * addr, + u16 * port, + u32 * fib_index, + nat_protocol_t * proto, + void *d, void *e, + u8 * dont_translate); /* Return worker thread index for given packet */ typedef u32 (snat_get_worker_in2out_function_t) (ip4_header_t * ip, @@ -511,7 +511,9 @@ typedef int (nat_alloc_out_addr_and_port_function_t) (snat_address_t * addresses, u32 fib_index, u32 thread_index, - snat_session_key_t * k, + nat_protocol_t proto, + ip4_address_t * addr, + u16 * port, u16 port_per_thread, u32 snat_thread_index); @@ -1008,48 +1010,54 @@ do \ /* ICMP session match functions */ u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); /* ICMP deterministic NAT session match functions */ u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate); /* ICMP endpoint-dependent session match functions */ u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, nat_protocol_t * proto, + void *d, void *e, u8 * dont_translate); u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e); + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, nat_protocol_t * proto, + void *d, void *e, u8 * dont_translate); u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0, icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0, @@ -1348,11 +1356,13 @@ void nat_set_alloc_addr_and_port_default (void); * * @param addresses vector of outside addresses * @param thread_index thread index - * @param k address, port and protocol + * @param key address, port and protocol */ -void snat_free_outside_address_and_port (snat_address_t * addresses, - u32 thread_index, - snat_session_key_t * k); +void +snat_free_outside_address_and_port (snat_address_t * addresses, + u32 thread_index, + ip4_address_t * addr, + u16 port, nat_protocol_t protocol); /** * @brief Alloc outside address and port @@ -1360,7 +1370,6 @@ void snat_free_outside_address_and_port (snat_address_t * addresses, * @param addresses vector of outside addresses * @param fib_index FIB table index * @param thread_index thread index - * @param k allocated address and port pair * @param port_per_thread number of ports per thread * @param snat_thread_index NAT thread index * @@ -1369,15 +1378,19 @@ void snat_free_outside_address_and_port (snat_address_t * addresses, int snat_alloc_outside_address_and_port (snat_address_t * addresses, u32 fib_index, u32 thread_index, - snat_session_key_t * k, + nat_protocol_t proto, + ip4_address_t * addr, + u16 * port, u16 port_per_thread, u32 snat_thread_index); /** * @brief Match NAT44 static mapping. * - * @param match address and port to match - * @param mapping external/local address and port of the matched mapping + * @param key address and port to match + * @param addr external/local address of the matched mapping + * @param port port of the matched mapping + * @param fib_index fib index of the matched mapping * @param by_external if 0 match by local address otherwise match by external * address * @param is_addr_only 1 if matched mapping is address only @@ -1388,8 +1401,13 @@ int snat_alloc_outside_address_and_port (snat_address_t * addresses, * @returns 0 if match found otherwise 1. */ int snat_static_mapping_match (snat_main_t * sm, - snat_session_key_t match, - snat_session_key_t * mapping, + ip4_address_t match_addr, + u16 match_port, + u32 match_fib_index, + nat_protocol_t match_protocol, + ip4_address_t * mapping_addr, + u16 * mapping_port, + u32 * mapping_fib_index, u8 by_external, u8 * is_addr_only, twice_nat_type_t * twice_nat, diff --git a/src/plugins/nat/nat44_classify.c b/src/plugins/nat/nat44_classify.c index bb3584e8a72..54c52e3ee4b 100644 --- a/src/plugins/nat/nat44_classify.c +++ b/src/plugins/nat/nat44_classify.c @@ -104,7 +104,6 @@ nat44_classify_node_fn_inline (vlib_main_t * vm, u32 next0 = NAT44_CLASSIFY_NEXT_IN2OUT; ip4_header_t *ip0; snat_address_t *ap; - snat_session_key_t m_key0; clib_bihash_kv_8_8_t kv0, value0; /* speculatively enqueue b0 to the current next frame */ @@ -131,11 +130,7 @@ nat44_classify_node_fn_inline (vlib_main_t * vm, if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - m_key0.addr = ip0->dst_address; - m_key0.port = 0; - m_key0.protocol = 0; - m_key0.fib_index = 0; - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, 0, 0, 0); /* try to classify the fragment based on IP header alone */ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) @@ -145,10 +140,9 @@ nat44_classify_node_fn_inline (vlib_main_t * vm, next0 = NAT44_CLASSIFY_NEXT_OUT2IN; goto enqueue0; } - m_key0.port = - clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port); - m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol); - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, 0, + ip_proto_to_nat_proto (ip0->protocol)); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) { @@ -221,7 +215,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm, u32 next0 = NAT_NEXT_IN2OUT_CLASSIFY; ip4_header_t *ip0; snat_address_t *ap; - snat_session_key_t m_key0; clib_bihash_kv_8_8_t kv0, value0; /* speculatively enqueue b0 to the current next frame */ @@ -248,11 +241,7 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm, if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - m_key0.addr = ip0->dst_address; - m_key0.port = 0; - m_key0.protocol = 0; - m_key0.fib_index = 0; - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, 0, 0, 0); /* try to classify the fragment based on IP header alone */ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) @@ -262,10 +251,9 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm, next0 = NAT_NEXT_OUT2IN_CLASSIFY; goto enqueue0; } - m_key0.port = - clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port); - m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol); - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, 0, + ip_proto_to_nat_proto (ip0->protocol)); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) { @@ -340,7 +328,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm, u32 sw_if_index0, rx_fib_index0; ip4_header_t *ip0; snat_address_t *ap; - snat_session_key_t m_key0; clib_bihash_kv_8_8_t kv0, value0; clib_bihash_kv_16_8_t ed_kv0, ed_value0; @@ -366,11 +353,11 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm, rx_fib_index0 = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index0); - make_ed_kv (&ip0->src_address, &ip0->dst_address, - ip0->protocol, rx_fib_index0, - vnet_buffer (b0)->ip.reass.l4_src_port, - vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, - &ed_kv0); + init_ed_k (&ed_kv0, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, + ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, + rx_fib_index0, ip0->protocol); /* process whole packet */ if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &ed_kv0, &ed_value0)) @@ -391,11 +378,7 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm, if (PREDICT_FALSE (pool_elts (sm->static_mappings))) { - m_key0.addr = ip0->dst_address; - m_key0.port = 0; - m_key0.protocol = 0; - m_key0.fib_index = 0; - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, 0, 0, 0); /* try to classify the fragment based on IP header alone */ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) @@ -405,10 +388,9 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm, next0 = NAT_NEXT_OUT2IN_ED_FAST_PATH; goto enqueue0; } - m_key0.port = - clib_net_to_host_u16 (vnet_buffer (b0)->ip.reass.l4_dst_port); - m_key0.protocol = ip_proto_to_nat_proto (ip0->protocol); - kv0.key = m_key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, 0, + ip_proto_to_nat_proto (ip0->protocol)); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) { diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c index 68ed0cb7207..ffc5fd43618 100644 --- a/src/plugins/nat/nat44_cli.c +++ b/src/plugins/nat/nat44_cli.c @@ -674,7 +674,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input, if (now >= sess_timeout_time) timed_out++; - switch (s->in2out.protocol) + switch (s->nat_proto) { case NAT_PROTOCOL_ICMP: icmp_sessions++; @@ -720,7 +720,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input, if (now >= sess_timeout_time) timed_out++; - switch (s->in2out.protocol) + switch (s->nat_proto) { case NAT_PROTOCOL_ICMP: icmp_sessions++; @@ -1071,7 +1071,8 @@ add_static_mapping_command_fn (vlib_main_t * vm, goto done; } - rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port, + rv = snat_add_static_mapping (l_addr, e_addr, clib_host_to_net_u16 (l_port), + clib_host_to_net_u16 (e_port), vrf_id, addr_only, sw_if_index, proto, is_add, twice_nat, out2in_only, 0, 0); @@ -1155,9 +1156,10 @@ add_identity_mapping_command_fn (vlib_main_t * vm, } } - rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port, - vrf_id, addr_only, sw_if_index, proto, is_add, - 0, 0, 0, 1); + rv = + snat_add_static_mapping (addr, addr, clib_host_to_net_u16 (port), + clib_host_to_net_u16 (port), vrf_id, addr_only, + sw_if_index, proto, is_add, 0, 0, 0, 1); switch (rv) { @@ -1730,10 +1732,13 @@ nat44_del_session_command_fn (vlib_main_t * vm, if (is_ed) rv = - nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port, + nat44_del_ed_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr, + clib_host_to_net_u16 (eh_port), nat_proto_to_ip_proto (proto), vrf_id, is_in); else - rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in); + rv = + nat44_del_session (sm, &addr, clib_host_to_net_u16 (port), proto, + vrf_id, is_in); switch (rv) { diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44_hairpinning.c index 1c91bd77e04..f15de9530da 100644 --- a/src/plugins/nat/nat44_hairpinning.c +++ b/src/plugins/nat/nat44_hairpinning.c @@ -93,7 +93,6 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr) { snat_address_t *ap; clib_bihash_kv_8_8_t kv, value; - snat_session_key_t m_key; /* *INDENT-OFF* */ vec_foreach (ap, sm->addresses) @@ -103,11 +102,7 @@ is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr) } /* *INDENT-ON* */ - m_key.addr.as_u32 = dst_addr->as_u32; - m_key.fib_index = 0; - m_key.port = 0; - m_key.protocol = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, *dst_addr, 0, 0, 0); if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) return 1; @@ -121,26 +116,23 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, udp_header_t * udp0, tcp_header_t * tcp0, u32 proto0, int is_ed, int do_trace) { - snat_session_key_t key0, sm0; snat_session_t *s0 = NULL; clib_bihash_kv_8_8_t kv0, value0; ip_csum_t sum0; u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si = ~0; u16 new_dst_port0 = ~0, old_dst_port0; int rv; - - key0.addr = ip0->dst_address; - key0.port = udp0->dst_port; - key0.protocol = proto0; - key0.fib_index = sm->outside_fib_index; - kv0.key = key0.as_u64; - + ip4_address_t sm0_addr; + u16 sm0_port; + u32 sm0_fib_index; /* Check if destination is static mappings */ - if (!snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0)) + if (!snat_static_mapping_match + (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, proto0, + &sm0_addr, &sm0_port, &sm0_fib_index, 1, 0, 0, 0, 0, 0)) { - new_dst_addr0 = sm0.addr.as_u32; - new_dst_port0 = sm0.port; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index; + new_dst_addr0 = sm0_addr.as_u32; + new_dst_port0 = sm0_port; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0_fib_index; } /* or active session */ else @@ -155,17 +147,21 @@ snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node, if (is_ed) { clib_bihash_kv_16_8_t ed_kv, ed_value; - make_ed_kv (&ip0->dst_address, &ip0->src_address, - ip0->protocol, sm->outside_fib_index, udp0->dst_port, - udp0->src_port, ~0, ~0, &ed_kv); + init_ed_k (&ed_kv, ip0->dst_address, udp0->dst_port, + ip0->src_address, udp0->src_port, sm->outside_fib_index, + ip0->protocol); rv = clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value); ASSERT (ti == ed_value_get_thread_index (&ed_value)); si = ed_value_get_session_index (&ed_value); } else { - rv = clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0, - &value0); + + init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, + sm->outside_fib_index, proto0); + rv = + clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0, + &value0); si = value0.value; } if (rv) @@ -250,7 +246,6 @@ snat_icmp_hairpinning (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0, icmp46_header_t * icmp0, int is_ed) { - snat_session_key_t key0; clib_bihash_kv_8_8_t kv0, value0; u32 old_dst_addr0, new_dst_addr0; u32 old_addr0, new_addr0; @@ -277,10 +272,9 @@ snat_icmp_hairpinning (snat_main_t * sm, if (is_ed) { clib_bihash_kv_16_8_t ed_kv, ed_value; - make_ed_kv (&ip0->dst_address, &ip0->src_address, - inner_ip0->protocol, sm->outside_fib_index, - l4_header->src_port, l4_header->dst_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, ip0->dst_address, l4_header->src_port, + ip0->src_address, l4_header->dst_port, + sm->outside_fib_index, inner_ip0->protocol); if (clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value)) return 1; ASSERT (ti == ed_value_get_thread_index (&ed_value)); @@ -288,13 +282,10 @@ snat_icmp_hairpinning (snat_main_t * sm, } else { - key0.addr = ip0->dst_address; - key0.port = l4_header->src_port; - key0.protocol = protocol; - key0.fib_index = sm->outside_fib_index; - kv0.key = key0.as_u64; - if (clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0, - &value0)) + init_nat_k (&kv0, ip0->dst_address, l4_header->src_port, + sm->outside_fib_index, protocol); + if (clib_bihash_search_8_8 + (&sm->per_thread_data[ti].out2in, &kv0, &value0)) return 1; si = value0.value; } @@ -334,12 +325,7 @@ snat_icmp_hairpinning (snat_main_t * sm, } else { - key0.addr = ip0->dst_address; - key0.port = 0; - key0.protocol = 0; - key0.fib_index = sm->outside_fib_index; - kv0.key = key0.as_u64; - + init_nat_k (&kv0, ip0->dst_address, 0, sm->outside_fib_index, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, &value0)) { @@ -347,11 +333,8 @@ snat_icmp_hairpinning (snat_main_t * sm, { icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1); u16 icmp_id0 = echo0->identifier; - key0.addr = ip0->dst_address; - key0.port = icmp_id0; - key0.protocol = NAT_PROTOCOL_ICMP; - key0.fib_index = sm->outside_fib_index; - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, icmp_id0, + sm->outside_fib_index, NAT_PROTOCOL_ICMP); if (sm->num_workers > 1) ti = (clib_net_to_host_u16 (icmp_id0) - @@ -412,7 +395,7 @@ nat_hairpinning_sm_unknown_proto (snat_main_t * sm, u32 old_addr, new_addr; ip_csum_t sum; - make_sm_kv (&kv, &ip->dst_address, 0, 0, 0); + init_nat_k (&kv, ip->dst_address, 0, 0, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) return; @@ -447,11 +430,11 @@ nat44_ed_hairpinning_unknown_proto (snat_main_t * sm, ti = sm->num_workers; old_addr = ip->dst_address.as_u32; - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, - sm->outside_fib_index, 0, 0, ~0, ~0, &s_kv); + init_ed_k (&s_kv, ip->dst_address, 0, ip->src_address, 0, + sm->outside_fib_index, ip->protocol); if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value)) { - make_sm_kv (&kv, &ip->dst_address, 0, 0, 0); + init_nat_k (&kv, ip->dst_address, 0, 0, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) return; diff --git a/src/plugins/nat/nat64.c b/src/plugins/nat/nat64.c index 6c5bfc15196..9fc3344f015 100644 --- a/src/plugins/nat/nat64.c +++ b/src/plugins/nat/nat64.c @@ -530,24 +530,16 @@ nat64_alloc_out_addr_and_port (u32 fib_index, nat_protocol_t proto, { nat64_main_t *nm = &nat64_main; snat_main_t *sm = nm->sm; - snat_session_key_t k; u32 worker_index = 0; int rv; - k.protocol = proto; - if (sm->num_workers > 1) worker_index = thread_index - sm->first_worker_index; rv = - sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index, &k, - sm->port_per_thread, worker_index); - - if (!rv) - { - *port = k.port; - addr->as_u32 = k.addr.as_u32; - } + sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index, + proto, addr, port, sm->port_per_thread, + worker_index); return rv; } diff --git a/src/plugins/nat/nat_api.c b/src/plugins/nat/nat_api.c index abd1d867c47..9d1ed1bd9a9 100644 --- a/src/plugins/nat/nat_api.c +++ b/src/plugins/nat/nat_api.c @@ -1110,8 +1110,8 @@ static void if (!(mp->flags & NAT_API_IS_ADDR_ONLY)) { - local_port = clib_net_to_host_u16 (mp->local_port); - external_port = clib_net_to_host_u16 (mp->external_port); + local_port = mp->local_port; + external_port = mp->external_port; } vrf_id = clib_net_to_host_u32 (mp->vrf_id); @@ -1201,8 +1201,8 @@ send_nat44_static_mapping_details (snat_static_mapping_t * m, else { rmp->protocol = nat_proto_to_ip_proto (m->proto); - rmp->external_port = htons (m->external_port); - rmp->local_port = htons (m->local_port); + rmp->external_port = m->external_port; + rmp->local_port = m->local_port; } if (m->tag) @@ -1238,8 +1238,8 @@ send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m, else { rmp->protocol = nat_proto_to_ip_proto (m->proto); - rmp->external_port = htons (m->e_port); - rmp->local_port = htons (m->l_port); + rmp->external_port = m->e_port; + rmp->local_port = m->l_port; } if (m->tag) strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag)); @@ -1312,7 +1312,7 @@ static void if (!(mp->flags & NAT_API_IS_ADDR_ONLY)) { - port = clib_net_to_host_u16 (mp->port); + port = mp->port; proto = ip_proto_to_nat_proto (mp->protocol); } vrf_id = clib_net_to_host_u32 (mp->vrf_id); @@ -1374,7 +1374,7 @@ send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index, rmp->flags |= NAT_API_IS_ADDR_ONLY; clib_memcpy (rmp->ip_address, &(m->local_addr), 4); - rmp->port = htons (m->local_port); + rmp->port = m->local_port; rmp->sw_if_index = ~0; rmp->vrf_id = htonl (local->vrf_id); rmp->protocol = nat_proto_to_ip_proto (m->proto); @@ -1401,7 +1401,7 @@ send_nat44_identity_map_resolve_details (snat_static_map_resolve_t * m, if (m->addr_only) rmp->flags = (vl_api_nat_config_flags_t) NAT_API_IS_ADDR_ONLY; - rmp->port = htons (m->l_port); + rmp->port = m->l_port; rmp->sw_if_index = htonl (m->sw_if_index); rmp->vrf_id = htonl (m->vrf_id); rmp->protocol = nat_proto_to_ip_proto (m->proto); @@ -1719,7 +1719,7 @@ send_nat44_user_session_details (snat_session_t * s, { rmp->outside_port = s->out2in.port; rmp->inside_port = s->in2out.port; - rmp->protocol = ntohs (nat_proto_to_ip_proto (s->in2out.protocol)); + rmp->protocol = ntohs (nat_proto_to_ip_proto (s->nat_proto)); } if (is_ed_session (s) || is_fwd_bypass_session (s)) { @@ -1831,7 +1831,7 @@ unformat_nat44_lb_addr_port (vl_api_nat44_lb_addr_port_t * addr_port_pairs, ap = &addr_port_pairs[i]; clib_memset (&lb_addr_port, 0, sizeof (lb_addr_port)); clib_memcpy (&lb_addr_port.addr, ap->addr, 4); - lb_addr_port.port = clib_net_to_host_u16 (ap->port); + lb_addr_port.port = ap->port; lb_addr_port.probability = ap->probability; lb_addr_port.vrf_id = clib_net_to_host_u32 (ap->vrf_id); vec_add1 (lb_addr_port_pairs, lb_addr_port); @@ -1875,7 +1875,7 @@ static void rv = nat44_add_del_lb_static_mapping (e_addr, - clib_net_to_host_u16 (mp->external_port), + mp->external_port, proto, locals, mp->is_add, twice_nat, mp->flags & NAT_API_IS_OUT2IN_ONLY, tag, @@ -1968,7 +1968,7 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m, ntohs (VL_API_NAT44_LB_STATIC_MAPPING_DETAILS + sm->msg_id_base); clib_memcpy (rmp->external_addr, &(m->external_addr), 4); - rmp->external_port = ntohs (m->external_port); + rmp->external_port = m->external_port; rmp->protocol = nat_proto_to_ip_proto (m->proto); rmp->context = context; @@ -1986,7 +1986,7 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m, pool_foreach (ap, m->locals, ({ clib_memcpy (locals->addr, &(ap->addr), 4); - locals->port = htons (ap->port); + locals->port = ap->port; locals->probability = ap->probability; locals->vrf_id = ntohl (ap->vrf_id); locals++; @@ -2051,11 +2051,11 @@ vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp) } memcpy (&addr.as_u8, mp->address, 4); - port = clib_net_to_host_u16 (mp->port); + port = mp->port; vrf_id = clib_net_to_host_u32 (mp->vrf_id); proto = ip_proto_to_nat_proto (mp->protocol); memcpy (&eh_addr.as_u8, mp->ext_host_address, 4); - eh_port = clib_net_to_host_u16 (mp->ext_host_port); + eh_port = mp->ext_host_port; is_in = mp->flags & NAT_API_IS_INSIDE; diff --git a/src/plugins/nat/nat_det_in2out.c b/src/plugins/nat/nat_det_in2out.c index 8628fcc42f7..b9b940559b6 100644 --- a/src/plugins/nat/nat_det_in2out.c +++ b/src/plugins/nat/nat_det_in2out.c @@ -96,17 +96,17 @@ format_nat_det_in2out_trace (u8 * s, va_list * args) u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, u8 * p_dont_translate, - void *d, void *e) + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate) { vlib_main_t *vm = vlib_get_main (); icmp46_header_t *icmp0; u32 sw_if_index0; u32 rx_fib_index0; - u8 protocol; + nat_protocol_t protocol; snat_det_out_key_t key0; - u8 dont_translate = 0; u32 next0 = ~0; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0; @@ -118,6 +118,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, snat_det_session_t *ses0 = 0; ip4_address_t in_addr; u16 in_port; + *dont_translate = 0; icmp0 = (icmp46_header_t *) ip4_next_header (ip0); echo0 = (icmp_echo_header_t *) (icmp0 + 1); @@ -165,7 +166,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, IP_PROTOCOL_ICMP, rx_fib_index0))) { - dont_translate = 1; + *dont_translate = 1; goto out; } next0 = NAT_DET_IN2OUT_NEXT_DROP; @@ -185,7 +186,7 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, IP_PROTOCOL_ICMP, rx_fib_index0))) { - dont_translate = 1; + *dont_translate = 1; goto out; } if (icmp0->type != ICMP4_echo_request) @@ -234,14 +235,13 @@ icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node, ses0->expire = now + sm->icmp_timeout; out: - *p_proto = protocol; + *proto = protocol; if (ses0) { - p_value->addr = new_addr0; - p_value->fib_index = sm->outside_fib_index; - p_value->port = ses0->out.out_port; + *addr = new_addr0; + *fib_index = sm->outside_fib_index; + *port = ses0->out.out_port; } - *p_dont_translate = dont_translate; if (d) *(snat_det_session_t **) d = ses0; if (e) diff --git a/src/plugins/nat/nat_det_out2in.c b/src/plugins/nat/nat_det_out2in.c index 80d9b39b2bb..5ca2afb1b82 100644 --- a/src/plugins/nat/nat_det_out2in.c +++ b/src/plugins/nat/nat_det_out2in.c @@ -95,15 +95,15 @@ format_nat_det_out2in_trace (u8 * s, va_list * args) u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate) { icmp46_header_t *icmp0; u32 sw_if_index0; u8 protocol; snat_det_out_key_t key0; - u8 dont_translate = 0; u32 next0 = ~0; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0; @@ -113,6 +113,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, ip4_address_t new_addr0 = { {0} }; snat_det_session_t *ses0 = 0; ip4_address_t out_addr; + *dont_translate = 0; icmp0 = (icmp46_header_t *) ip4_next_header (ip0); echo0 = (icmp_echo_header_t *) (icmp0 + 1); @@ -162,7 +163,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))) { - dont_translate = 1; + *dont_translate = 1; goto out; } nat_log_info ("unknown dst address: %U", @@ -180,7 +181,7 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))) { - dont_translate = 1; + *dont_translate = 1; goto out; } nat_log_info ("no match src %U:%d dst %U:%d for user %U", @@ -207,14 +208,13 @@ icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node, goto out; out: - *p_proto = protocol; + *proto = protocol; if (ses0) { - p_value->addr = new_addr0; - p_value->fib_index = sm->inside_fib_index; - p_value->port = ses0->in_port; + *addr = new_addr0; + *fib_index = sm->inside_fib_index; + *port = ses0->in_port; } - *p_dont_translate = dont_translate; if (d) *(snat_det_session_t **) d = ses0; if (e) diff --git a/src/plugins/nat/nat_format.c b/src/plugins/nat/nat_format.c index 33e9655dc4e..8287968e029 100644 --- a/src/plugins/nat/nat_format.c +++ b/src/plugins/nat/nat_format.c @@ -76,23 +76,19 @@ format_nat_addr_and_port_alloc_alg (u8 * s, va_list * args) u8 * format_snat_key (u8 * s, va_list * args) { - snat_session_key_t *key = va_arg (*args, snat_session_key_t *); + u64 key = va_arg (*args, u64); - s = format (s, "%U proto %U port %d fib %d", - format_ip4_address, &key->addr, - format_nat_protocol, key->protocol, - clib_net_to_host_u16 (key->port), key->fib_index); - return s; -} + ip4_address_t addr; + u16 port; + nat_protocol_t protocol; + u32 fib_index; -u8 * -format_static_mapping_key (u8 * s, va_list * args) -{ - snat_session_key_t *key = va_arg (*args, snat_session_key_t *); + split_nat_key (key, &addr, &port, &fib_index, &protocol); s = format (s, "%U proto %U port %d fib %d", - format_ip4_address, &key->addr, - format_nat_protocol, key->protocol, key->port, key->fib_index); + format_ip4_address, &addr, + format_nat_protocol, protocol, + clib_net_to_host_u16 (port), fib_index); return s; } diff --git a/src/plugins/nat/nat_inlines.h b/src/plugins/nat/nat_inlines.h index 7c28919f781..76dd9a70002 100644 --- a/src/plugins/nat/nat_inlines.h +++ b/src/plugins/nat/nat_inlines.h @@ -23,6 +23,83 @@ #include <nat/nat.h> #include <nat/nat_ha.h> +always_inline u64 +calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto) +{ + ASSERT (fib_index <= (1 << 14) - 1); + ASSERT (proto <= (1 << 3) - 1); + return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 | + (proto & 0x7); +} + +always_inline void +split_nat_key (u64 key, ip4_address_t * addr, u16 * port, + u32 * fib_index, nat_protocol_t * proto) +{ + if (addr) + { + addr->as_u32 = key >> 32; + } + if (port) + { + *port = (key >> 16) & (u16) ~ 0; + } + if (fib_index) + { + *fib_index = key >> 3 & ((1 << 13) - 1); + } + if (proto) + { + *proto = key & 0x7; + } +} + +always_inline void +init_nat_k (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port, + u32 fib_index, nat_protocol_t proto) +{ + kv->key = calc_nat_key (addr, port, fib_index, proto); + kv->value = ~0ULL; +} + +always_inline void +init_nat_kv (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port, + u32 fib_index, nat_protocol_t proto, u64 value) +{ + init_nat_k (kv, addr, port, fib_index, proto); + kv->value = value; +} + +always_inline void +init_nat_i2o_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s) +{ + return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index, + s->nat_proto); +} + +always_inline void +init_nat_i2o_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value) +{ + init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index, + s->nat_proto); + kv->value = value; +} + +always_inline void +init_nat_o2i_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s) +{ + return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index, + s->nat_proto); +} + +always_inline void +init_nat_o2i_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value) +{ + init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index, + s->nat_proto); + kv->value = value; +} + static inline uword nat_pre_node_fn_inline (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -384,7 +461,7 @@ nat44_set_tcp_session_state_o2i (snat_main_t * sm, f64 now, always_inline u32 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s) { - switch (s->in2out.protocol) + switch (s->nat_proto) { case NAT_PROTOCOL_ICMP: return sm->icmp_timeout; @@ -412,7 +489,7 @@ nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes, s->total_pkts++; s->total_bytes += bytes; nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, s->total_pkts, s->total_bytes, thread_index, &s->ha_last_refreshed, now); } @@ -444,13 +521,20 @@ nat44_session_update_lru (snat_main_t * sm, snat_session_t * s, } always_inline void -make_ed_kv (ip4_address_t * l_addr, ip4_address_t * r_addr, u8 proto, - u32 fib_index, u16 l_port, u16 r_port, u32 thread_index, - u32 session_index, clib_bihash_kv_16_8_t * kv) +init_ed_k (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port, + ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto) { - kv->key[0] = (u64) r_addr->as_u32 << 32 | l_addr->as_u32; + kv->key[0] = (u64) r_addr.as_u32 << 32 | l_addr.as_u32; kv->key[1] = (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto; +} + +always_inline void +init_ed_kv (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port, + ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto, + u32 thread_index, u32 session_index) +{ + init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto); kv->value = (u64) thread_index << 32 | session_index; } @@ -511,20 +595,11 @@ split_ed_kv (clib_bihash_kv_16_8_t * kv, } } -always_inline void -make_sm_kv (clib_bihash_kv_8_8_t * kv, ip4_address_t * addr, u8 proto, - u32 fib_index, u16 port) -{ - kv->key = (u64) fib_index << 51 | (u64) proto << 48 | (u64) port << 32 | - addr->as_u32; - - kv->value = ~0ULL; -} - static_always_inline int get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index, - u32 thread_index, u32 session_index, u8 * nat_proto, - u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv) + u32 thread_index, u32 session_index, + nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port, + clib_bihash_kv_16_8_t * kv) { u8 proto; u16 _l_port, _r_port; @@ -572,8 +647,8 @@ get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index, return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL; } } - make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port, - thread_index, session_index, kv); + init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto, + thread_index, session_index); if (nat_proto) { *nat_proto = ip_proto_to_nat_proto (proto); @@ -589,11 +664,11 @@ get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index, return 0; } - static_always_inline int get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index, - u32 thread_index, u32 session_index, u8 * nat_proto, - u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv) + u32 thread_index, u32 session_index, + nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port, + clib_bihash_kv_16_8_t * kv) { icmp46_header_t *icmp0; u8 proto; @@ -640,8 +715,8 @@ get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index, return -1; } } - make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port, - thread_index, session_index, kv); + init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto, + thread_index, session_index); if (nat_proto) { *nat_proto = ip_proto_to_nat_proto (proto); diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c index 44f7dcf34f6..faf5d7315f4 100644 --- a/src/plugins/nat/out2in.c +++ b/src/plugins/nat/out2in.c @@ -126,30 +126,30 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s); if (ctx->now >= sess_timeout_time) { - s_kv.key = s->in2out.as_u64; + init_nat_i2o_k (&s_kv, s); if (clib_bihash_add_del_8_8 (&tsm->in2out, &s_kv, 0)) nat_elog_warn ("out2in key del failed"); snat_ipfix_logging_nat44_ses_delete (ctx->thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index, &s->in2out.addr, s->in2out.port, - &s->out2in.addr, s->out2in.port, - s->in2out.protocol); + &s->out2in.addr, s->out2in.port, s->nat_proto); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, ctx->thread_index); if (!snat_is_session_static (s)) snat_free_outside_address_and_port (sm->addresses, ctx->thread_index, - &s->out2in); + &s->out2in.addr, s->out2in.port, + s->nat_proto); nat44_delete_session (sm, s, ctx->thread_index); return 1; @@ -176,8 +176,13 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) static inline snat_session_t * create_session_for_static_mapping (snat_main_t * sm, vlib_buffer_t * b0, - snat_session_key_t in2out, - snat_session_key_t out2in, + ip4_address_t i2o_addr, + u16 i2o_port, + u32 i2o_fib_index, + ip4_address_t o2i_addr, + u16 o2i_port, + u32 o2i_fib_index, + nat_protocol_t proto, vlib_node_runtime_t * node, u32 thread_index, f64 now) { @@ -198,8 +203,7 @@ create_session_for_static_mapping (snat_main_t * sm, ip0 = vlib_buffer_get_current (b0); udp0 = ip4_next_header (ip0); - u = - nat_user_get_or_create (sm, &in2out.addr, in2out.fib_index, thread_index); + u = nat_user_get_or_create (sm, &i2o_addr, i2o_fib_index, thread_index); if (!u) { nat_elog_warn ("create NAT user failed"); @@ -218,22 +222,24 @@ create_session_for_static_mapping (snat_main_t * sm, s->ext_host_addr.as_u32 = ip0->src_address.as_u32; s->ext_host_port = udp0->src_port; user_session_increment (sm, u, 1 /* static */ ); - s->in2out = in2out; - s->out2in = out2in; - s->in2out.protocol = out2in.protocol; + s->in2out.addr = i2o_addr; + s->in2out.port = i2o_port; + s->in2out.fib_index = i2o_fib_index; + s->out2in.addr = o2i_addr; + s->out2in.port = o2i_port; + s->out2in.fib_index = o2i_fib_index; + s->nat_proto = proto; /* Add to translation hashes */ ctx0.now = now; ctx0.thread_index = thread_index; - kv0.key = s->in2out.as_u64; - kv0.value = s - sm->per_thread_data[thread_index].sessions; + init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); if (clib_bihash_add_or_overwrite_stale_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0)) nat_elog_notice ("in2out key add failed"); - kv0.key = s->out2in.as_u64; - + init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); if (clib_bihash_add_or_overwrite_stale_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0)) @@ -243,30 +249,28 @@ create_session_for_static_mapping (snat_main_t * sm, snat_ipfix_logging_nat44_ses_create (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index, &s->in2out.addr, s->in2out.port, &s->out2in.addr, - s->out2in.port, s->in2out.protocol); + s->out2in.port, s->nat_proto); nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, &s->ext_host_nat_addr, s->ext_host_nat_port, - s->in2out.protocol, s->in2out.fib_index, s->flags, - thread_index, 0); + s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0); return s; } #ifndef CLIB_MARCH_VARIANT -static_always_inline - snat_out2in_error_t icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0, - snat_session_key_t * p_key0) +static_always_inline snat_out2in_error_t +icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0, + ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto) { icmp46_header_t *icmp0; - snat_session_key_t key0; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0; void *l4_header = 0; @@ -278,32 +282,31 @@ static_always_inline if (!icmp_type_is_error_message (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)) { - key0.protocol = NAT_PROTOCOL_ICMP; - key0.addr = ip0->dst_address; - key0.port = vnet_buffer (b)->ip.reass.l4_src_port; + *nat_proto = NAT_PROTOCOL_ICMP; + *addr = ip0->dst_address; + *port = vnet_buffer (b)->ip.reass.l4_src_port; } else { inner_ip0 = (ip4_header_t *) (echo0 + 1); l4_header = ip4_next_header (inner_ip0); - key0.protocol = ip_proto_to_nat_proto (inner_ip0->protocol); - key0.addr = inner_ip0->src_address; - switch (key0.protocol) + *nat_proto = ip_proto_to_nat_proto (inner_ip0->protocol); + *addr = inner_ip0->src_address; + switch (*nat_proto) { case NAT_PROTOCOL_ICMP: inner_icmp0 = (icmp46_header_t *) l4_header; inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1); - key0.port = inner_echo0->identifier; + *port = inner_echo0->identifier; break; case NAT_PROTOCOL_UDP: case NAT_PROTOCOL_TCP: - key0.port = ((tcp_udp_header_t *) l4_header)->src_port; + *port = ((tcp_udp_header_t *) l4_header)->src_port; break; default: return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL; } } - *p_key0 = key0; return -1; /* success */ } @@ -325,46 +328,48 @@ static_always_inline u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + ip4_header_t * ip0, ip4_address_t * addr, + u16 * port, u32 * fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate) { snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; u32 sw_if_index0; - u32 rx_fib_index0; - snat_session_key_t key0; - snat_session_key_t sm0; snat_session_t *s0 = 0; - u8 dont_translate = 0; clib_bihash_kv_8_8_t kv0, value0; u8 is_addr_only; u32 next0 = ~0; int err; u8 identity_nat; vlib_main_t *vm = vlib_get_main (); + *dont_translate = 0; sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); + *fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); - key0.protocol = 0; + *proto = 0; - err = icmp_get_key (b0, ip0, &key0); + err = icmp_get_key (b0, ip0, addr, port, proto); if (err != -1) { b0->error = node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL]; next0 = SNAT_OUT2IN_NEXT_DROP; goto out; } - key0.fib_index = rx_fib_index0; - kv0.key = key0.as_u64; + ip4_address_t mapping_addr; + u16 mapping_port; + u32 mapping_fib_index; + init_nat_k (&kv0, *addr, *port, *fib_index, *proto); if (clib_bihash_search_8_8 (&tsm->out2in, &kv0, &value0)) { /* Try to match static mapping by external address and port, destination address and port in packet */ if (snat_static_mapping_match - (sm, key0, &sm0, 1, &is_addr_only, 0, 0, 0, &identity_nat)) + (sm, *addr, *port, *fib_index, *proto, + &mapping_addr, &mapping_port, &mapping_fib_index, 1, &is_addr_only, + 0, 0, 0, &identity_nat)) { if (!sm->forwarding_enabled) { @@ -372,7 +377,7 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))) { - dont_translate = 1; + *dont_translate = 1; goto out; } b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION]; @@ -381,7 +386,7 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, } else { - dont_translate = 1; + *dont_translate = 1; goto out; } } @@ -399,13 +404,15 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (identity_nat)) { - dont_translate = 1; + *dont_translate = 1; goto out; } /* Create session initiated by host from external network */ - s0 = create_session_for_static_mapping (sm, b0, sm0, key0, - node, thread_index, - vlib_time_now (vm)); + s0 = + create_session_for_static_mapping (sm, b0, mapping_addr, mapping_port, + mapping_fib_index, *addr, *port, + *fib_index, *proto, node, + thread_index, vlib_time_now (vm)); if (!s0) { @@ -432,10 +439,12 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, } out: - *p_proto = key0.protocol; if (s0) - *p_value = s0->in2out; - *p_dont_translate = dont_translate; + { + *addr = s0->in2out.addr; + *port = s0->in2out.port; + *fib_index = s0->in2out.fib_index; + } if (d) *(snat_session_t **) d = s0; return next0; @@ -460,38 +469,38 @@ out: u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0, - ip4_header_t * ip0, u8 * p_proto, - snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + ip4_header_t * ip0, ip4_address_t * mapping_addr, + u16 * mapping_port, u32 * mapping_fib_index, + nat_protocol_t * proto, void *d, void *e, + u8 * dont_translate) { u32 sw_if_index0; u32 rx_fib_index0; - snat_session_key_t key0; - snat_session_key_t sm0; - u8 dont_translate = 0; u8 is_addr_only; u32 next0 = ~0; int err; + ip4_address_t addr; + u16 port; + *dont_translate = 0; sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0); - err = icmp_get_key (b0, ip0, &key0); + err = icmp_get_key (b0, ip0, &addr, &port, proto); if (err != -1) { b0->error = node->errors[err]; next0 = SNAT_OUT2IN_NEXT_DROP; - goto out2; + goto out; } - key0.fib_index = rx_fib_index0; - if (snat_static_mapping_match - (sm, key0, &sm0, 1, &is_addr_only, 0, 0, 0, 0)) + (sm, addr, port, rx_fib_index0, *proto, mapping_addr, mapping_port, + mapping_fib_index, 1, &is_addr_only, 0, 0, 0, 0)) { /* Don't NAT packet aimed at the intfc address */ if (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32)) { - dont_translate = 1; + *dont_translate = 1; goto out; } b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION]; @@ -512,10 +521,6 @@ icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node, } out: - *p_value = sm0; -out2: - *p_proto = key0.protocol; - *p_dont_translate = dont_translate; return next0; } #endif @@ -531,8 +536,6 @@ icmp_out2in (snat_main_t * sm, vlib_node_runtime_t * node, u32 next0, u32 thread_index, void *d, void *e) { - snat_session_key_t sm0; - u8 protocol; icmp_echo_header_t *echo0, *inner_echo0 = 0; ip4_header_t *inner_ip0 = 0; void *l4_header = 0; @@ -544,12 +547,16 @@ icmp_out2in (snat_main_t * sm, u16 checksum0; u32 next0_tmp; vlib_main_t *vm = vlib_get_main (); + ip4_address_t addr; + u16 port; + u32 fib_index; + nat_protocol_t proto; echo0 = (icmp_echo_header_t *) (icmp0 + 1); next0_tmp = sm->icmp_match_out2in_cb (sm, node, thread_index, b0, ip0, - &protocol, &sm0, &dont_translate, d, - e); + &addr, &port, &fib_index, &proto, + d, e, &dont_translate); if (next0_tmp != ~0) next0 = next0_tmp; if (next0 == SNAT_OUT2IN_NEXT_DROP || dont_translate) @@ -572,8 +579,8 @@ icmp_out2in (snat_main_t * sm, } old_addr0 = ip0->dst_address.as_u32; - new_addr0 = ip0->dst_address.as_u32 = sm0.addr.as_u32; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index; + new_addr0 = ip0->dst_address.as_u32 = addr.as_u32; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index; sum0 = ip0->checksum; sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, @@ -588,11 +595,11 @@ icmp_out2in (snat_main_t * sm, if (!icmp_type_is_error_message (icmp0->type)) { - new_id0 = sm0.port; + new_id0 = port; if (PREDICT_FALSE (new_id0 != echo0->identifier)) { old_id0 = echo0->identifier; - new_id0 = sm0.port; + new_id0 = port; echo0->identifier = new_id0; sum0 = icmp0->checksum; @@ -614,7 +621,7 @@ icmp_out2in (snat_main_t * sm, } old_addr0 = inner_ip0->src_address.as_u32; - inner_ip0->src_address = sm0.addr; + inner_ip0->src_address = addr; new_addr0 = inner_ip0->src_address.as_u32; sum0 = icmp0->checksum; @@ -622,14 +629,14 @@ icmp_out2in (snat_main_t * sm, src_address /* changed member */ ); icmp0->checksum = ip_csum_fold (sum0); - switch (protocol) + switch (proto) { case NAT_PROTOCOL_ICMP: inner_icmp0 = (icmp46_header_t *) l4_header; inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1); old_id0 = inner_echo0->identifier; - new_id0 = sm0.port; + new_id0 = port; inner_echo0->identifier = new_id0; sum0 = icmp0->checksum; @@ -641,7 +648,7 @@ icmp_out2in (snat_main_t * sm, case NAT_PROTOCOL_UDP: case NAT_PROTOCOL_TCP: old_id0 = ((tcp_udp_header_t *) l4_header)->src_port; - new_id0 = sm0.port; + new_id0 = port; ((tcp_udp_header_t *) l4_header)->src_port = new_id0; sum0 = icmp0->checksum; @@ -695,15 +702,10 @@ nat_out2in_sm_unknown_proto (snat_main_t * sm, { clib_bihash_kv_8_8_t kv, value; snat_static_mapping_t *m; - snat_session_key_t m_key; u32 old_addr, new_addr; ip_csum_t sum; - m_key.addr = ip->dst_address; - m_key.port = 0; - m_key.protocol = 0; - m_key.fib_index = 0; - kv.key = m_key.as_u64; + init_nat_k (&kv, ip->dst_address, 0, 0, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) return 1; @@ -759,12 +761,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, udp_header_t *udp0, *udp1; tcp_header_t *tcp0, *tcp1; icmp46_header_t *icmp0, *icmp1; - snat_session_key_t key0, key1, sm0, sm1; u32 rx_fib_index0, rx_fib_index1; u32 proto0, proto1; snat_session_t *s0 = 0, *s1 = 0; clib_bihash_kv_8_8_t kv0, kv1, value0, value1; u8 identity_nat0, identity_nat1; + ip4_address_t sm_addr0, sm_addr1; + u16 sm_port0, sm_port1; + u32 sm_fib_index0, sm_fib_index1; /* Prefetch next iteration. */ { @@ -839,20 +843,19 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace0; } - key0.addr = ip0->dst_address; - key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port; - key0.protocol = proto0; - key0.fib_index = rx_fib_index0; - - kv0.key = key0.as_u64; - + init_nat_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + proto0); if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) { /* Try to match static mapping by external address and port, destination address and port in packet */ if (snat_static_mapping_match - (sm, key0, &sm0, 1, 0, 0, 0, 0, &identity_nat0)) + (sm, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + proto0, &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0, + 0, &identity_nat0)) { /* * Send DHCP packets to the ipv4 stack, or we won't @@ -881,8 +884,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace0; /* Create session initiated by host from external network */ - s0 = create_session_for_static_mapping (sm, b0, sm0, key0, node, - thread_index, now); + s0 = create_session_for_static_mapping (sm, b0, + sm_addr0, sm_port0, + sm_fib_index0, + ip0->dst_address, + vnet_buffer (b0)-> + ip.reass.l4_dst_port, + rx_fib_index0, proto0, + node, thread_index, + now); if (!s0) { next0 = SNAT_OUT2IN_NEXT_DROP; @@ -1011,12 +1021,9 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace1; } - key1.addr = ip1->dst_address; - key1.port = vnet_buffer (b1)->ip.reass.l4_dst_port; - key1.protocol = proto1; - key1.fib_index = rx_fib_index1; - - kv1.key = key1.as_u64; + init_nat_k (&kv1, ip1->dst_address, + vnet_buffer (b1)->ip.reass.l4_dst_port, rx_fib_index1, + proto1); if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv1, &value1)) @@ -1024,7 +1031,10 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, /* Try to match static mapping by external address and port, destination address and port in packet */ if (snat_static_mapping_match - (sm, key1, &sm1, 1, 0, 0, 0, 0, &identity_nat1)) + (sm, ip1->dst_address, + vnet_buffer (b1)->ip.reass.l4_dst_port, proto1, + rx_fib_index1, &sm_addr1, &sm_port1, &sm_fib_index1, 1, 0, + 0, 0, 0, &identity_nat1)) { /* * Send DHCP packets to the ipv4 stack, or we won't @@ -1053,8 +1063,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace1; /* Create session initiated by host from external network */ - s1 = create_session_for_static_mapping (sm, b1, sm1, key1, node, - thread_index, now); + s1 = + create_session_for_static_mapping (sm, b1, sm_addr1, sm_port1, + sm_fib_index1, + ip1->dst_address, + vnet_buffer (b1)->ip. + reass.l4_dst_port, + rx_fib_index1, proto1, + node, thread_index, now); if (!s1) { next1 = SNAT_OUT2IN_NEXT_DROP; @@ -1162,12 +1178,14 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, udp_header_t *udp0; tcp_header_t *tcp0; icmp46_header_t *icmp0; - snat_session_key_t key0, sm0; u32 rx_fib_index0; u32 proto0; snat_session_t *s0 = 0; clib_bihash_kv_8_8_t kv0, value0; u8 identity_nat0; + ip4_address_t sm_addr0; + u16 sm_port0; + u32 sm_fib_index0; /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -1226,12 +1244,9 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace00; } - key0.addr = ip0->dst_address; - key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port; - key0.protocol = proto0; - key0.fib_index = rx_fib_index0; - - kv0.key = key0.as_u64; + init_nat_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + proto0); if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) @@ -1239,7 +1254,10 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, /* Try to match static mapping by external address and port, destination address and port in packet */ if (snat_static_mapping_match - (sm, key0, &sm0, 1, 0, 0, 0, 0, &identity_nat0)) + (sm, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + proto0, &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0, + 0, &identity_nat0)) { /* * Send DHCP packets to the ipv4 stack, or we won't @@ -1268,8 +1286,15 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, goto trace00; /* Create session initiated by host from external network */ - s0 = create_session_for_static_mapping (sm, b0, sm0, key0, node, - thread_index, now); + s0 = create_session_for_static_mapping (sm, b0, + sm_addr0, sm_port0, + sm_fib_index0, + ip0->dst_address, + vnet_buffer (b0)-> + ip.reass.l4_dst_port, + rx_fib_index0, proto0, + node, thread_index, + now); if (!s0) { next0 = SNAT_OUT2IN_NEXT_DROP; @@ -1437,9 +1462,11 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm, udp_header_t *udp0; tcp_header_t *tcp0; icmp46_header_t *icmp0; - snat_session_key_t key0, sm0; u32 proto0; u32 rx_fib_index0; + ip4_address_t sm_addr0; + u16 sm_port0; + u32 sm_fib_index0; /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -1484,19 +1511,17 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm, goto trace00; } - key0.addr = ip0->dst_address; - key0.port = udp0->dst_port; - key0.fib_index = rx_fib_index0; - - if (snat_static_mapping_match (sm, key0, &sm0, 1, 0, 0, 0, 0, 0)) + if (snat_static_mapping_match + (sm, ip0->dst_address, udp0->dst_port, rx_fib_index0, proto0, + &sm_addr0, &sm_port0, &sm_fib_index0, 1, 0, 0, 0, 0, 0)) { b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION]; goto trace00; } - new_addr0 = sm0.addr.as_u32; - new_port0 = sm0.port; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm0.fib_index; + new_addr0 = sm_addr0.as_u32; + new_port0 = sm_port0; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = sm_fib_index0; old_addr0 = ip0->dst_address.as_u32; ip0->dst_address.as_u32 = new_addr0; diff --git a/src/plugins/nat/out2in_ed.c b/src/plugins/nat/out2in_ed.c index 5d759fbfad5..3d081e15313 100644 --- a/src/plugins/nat/out2in_ed.c +++ b/src/plugins/nat/out2in_ed.c @@ -103,8 +103,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) u32 fib_index; clib_bihash_kv_16_8_t ed_kv; int i; - snat_address_t *a; - snat_session_key_t key; + //snat_address_t *a; snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data, ctx->thread_index); @@ -123,7 +122,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) } else { - proto = nat_proto_to_ip_proto (s->in2out.protocol); + proto = nat_proto_to_ip_proto (s->nat_proto); l_port = s->in2out.port; r_port = s->ext_host_port; } @@ -132,8 +131,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) r_addr = &s->ext_host_nat_addr; r_port = s->ext_host_nat_port; } - make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0, - &ed_kv); + init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto); if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)) nat_elog_warn ("in2out_ed key del failed"); @@ -143,7 +141,7 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) snat_ipfix_logging_nat44_ses_delete (ctx->thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); @@ -153,26 +151,27 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, is_twice_nat_session (s)); + s->nat_proto, is_twice_nat_session (s)); nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr, - s->ext_host_port, s->out2in.protocol, s->out2in.fib_index, + s->ext_host_port, s->nat_proto, s->out2in.fib_index, ctx->thread_index); if (is_twice_nat_session (s)) { for (i = 0; i < vec_len (sm->twice_nat_addresses); i++) { - key.protocol = s->in2out.protocol; - key.port = s->ext_host_nat_port; - a = sm->twice_nat_addresses + i; - if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32) - { - snat_free_outside_address_and_port (sm->twice_nat_addresses, - ctx->thread_index, - &key); - break; - } + // FIXME TODO this is obviously wrong code ... needs fix! + // key.protocol = s->nat_proto; + // key.port = s->ext_host_nat_port; + // a = sm->twice_nat_addresses + i; + // if (a->addr.as_u32 == s->ext_host_nat_addr.as_u32) + // { + // snat_free_outside_address_and_port (sm->twice_nat_addresses, + // ctx->thread_index, + // &key); + // break; + // } } } @@ -180,7 +179,8 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) goto delete; snat_free_outside_address_and_port (sm->addresses, ctx->thread_index, - &s->out2in); + &s->out2in.addr, s->out2in.port, + s->nat_proto); delete: nat_ed_session_delete (sm, s, ctx->thread_index, 1); return 1; @@ -193,8 +193,13 @@ nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg) static snat_session_t * create_session_for_static_mapping_ed (snat_main_t * sm, vlib_buffer_t * b, - snat_session_key_t l_key, - snat_session_key_t e_key, + ip4_address_t i2o_addr, + u16 i2o_port, + u32 i2o_fib_index, + ip4_address_t o2i_addr, + u16 o2i_port, + u32 o2i_fib_index, + nat_protocol_t nat_proto, vlib_node_runtime_t * node, u32 rx_fib_index, u32 thread_index, @@ -206,7 +211,6 @@ create_session_for_static_mapping_ed (snat_main_t * sm, udp_header_t *udp; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; clib_bihash_kv_16_8_t kv; - snat_session_key_t eh_key; nat44_is_idle_session_ctx_t ctx; if (PREDICT_FALSE @@ -217,7 +221,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm, return 0; } - s = nat_ed_session_alloc (sm, thread_index, now, e_key.protocol); + s = nat_ed_session_alloc (sm, thread_index, now, nat_proto); if (!s) { b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED]; @@ -229,21 +233,24 @@ create_session_for_static_mapping_ed (snat_main_t * sm, udp = ip4_next_header (ip); s->ext_host_addr.as_u32 = ip->src_address.as_u32; - s->ext_host_port = e_key.protocol == NAT_PROTOCOL_ICMP ? 0 : udp->src_port; + s->ext_host_port = nat_proto == NAT_PROTOCOL_ICMP ? 0 : udp->src_port; s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING; if (lb_nat) s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING; if (lb_nat == AFFINITY_LB_NAT) s->flags |= SNAT_SESSION_FLAG_AFFINITY; s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT; - s->out2in = e_key; - s->in2out = l_key; - s->in2out.protocol = s->out2in.protocol; + s->out2in.addr = o2i_addr; + s->out2in.port = o2i_port; + s->out2in.fib_index = o2i_fib_index; + s->in2out.addr = i2o_addr; + s->in2out.port = i2o_port; + s->in2out.fib_index = i2o_fib_index; + s->nat_proto = nat_proto; /* Add to lookup tables */ - make_ed_kv (&e_key.addr, &s->ext_host_addr, ip->protocol, - e_key.fib_index, e_key.port, s->ext_host_port, thread_index, - s - tsm->sessions, &kv); + init_ed_kv (&kv, o2i_addr, o2i_port, s->ext_host_addr, s->ext_host_port, + o2i_fib_index, ip->protocol, thread_index, s - tsm->sessions); ctx.now = now; ctx.thread_index = thread_index; if (clib_bihash_add_or_overwrite_stale_16_8 (&sm->out2in_ed, &kv, @@ -252,11 +259,13 @@ create_session_for_static_mapping_ed (snat_main_t * sm, nat_elog_notice ("out2in-ed key add failed"); if (twice_nat == TWICE_NAT || (twice_nat == TWICE_NAT_SELF && - ip->src_address.as_u32 == l_key.addr.as_u32)) + ip->src_address.as_u32 == i2o_addr.as_u32)) { - eh_key.protocol = e_key.protocol; if (snat_alloc_outside_address_and_port (sm->twice_nat_addresses, 0, - thread_index, &eh_key, + thread_index, + nat_proto, + &s->ext_host_nat_addr, + &s->ext_host_nat_port, sm->port_per_thread, tsm->snat_thread_index)) { @@ -266,18 +275,16 @@ create_session_for_static_mapping_ed (snat_main_t * sm, nat_elog_notice ("out2in-ed key del failed"); return 0; } - s->ext_host_nat_addr.as_u32 = eh_key.addr.as_u32; - s->ext_host_nat_port = eh_key.port; s->flags |= SNAT_SESSION_FLAG_TWICE_NAT; - make_ed_kv (&l_key.addr, &s->ext_host_nat_addr, ip->protocol, - l_key.fib_index, l_key.port, s->ext_host_nat_port, - thread_index, s - tsm->sessions, &kv); + init_ed_kv (&kv, i2o_addr, i2o_port, s->ext_host_nat_addr, + s->ext_host_nat_port, i2o_fib_index, ip->protocol, + thread_index, s - tsm->sessions); } else { - make_ed_kv (&l_key.addr, &s->ext_host_addr, ip->protocol, - l_key.fib_index, l_key.port, s->ext_host_port, thread_index, - s - tsm->sessions, &kv); + init_ed_kv (&kv, i2o_addr, i2o_port, s->ext_host_addr, + s->ext_host_port, i2o_fib_index, ip->protocol, + thread_index, s - tsm->sessions); } if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &kv, nat44_i2o_ed_is_idle_session_cb, @@ -287,7 +294,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm, snat_ipfix_logging_nat44_ses_create (thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, - s->in2out.protocol, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); @@ -296,13 +303,12 @@ create_session_for_static_mapping_ed (snat_main_t * sm, &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, - s->in2out.protocol, is_twice_nat_session (s)); + s->nat_proto, is_twice_nat_session (s)); nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr, s->out2in.port, &s->ext_host_addr, s->ext_host_port, &s->ext_host_nat_addr, s->ext_host_nat_port, - s->in2out.protocol, s->in2out.fib_index, s->flags, - thread_index, 0); + s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0); return s; } @@ -314,8 +320,8 @@ next_src_nat (snat_main_t * sm, ip4_header_t * ip, u16 src_port, clib_bihash_kv_16_8_t kv, value; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; - make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, - rx_fib_index, src_port, dst_port, ~0, ~0, &kv); + init_ed_k (&kv, ip->src_address, src_port, ip->dst_address, dst_port, + rx_fib_index, ip->protocol); if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value)) return 1; @@ -353,8 +359,8 @@ create_bypass_for_fwd (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip, l_port = 0; r_port = 0; } - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, - rx_fib_index, l_port, r_port, ~0, ~0, &kv); + init_ed_k (&kv, ip->dst_address, l_port, ip->src_address, r_port, + rx_fib_index, ip->protocol); } if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value)) @@ -387,14 +393,16 @@ create_bypass_for_fwd (snat_main_t * sm, vlib_buffer_t * b, ip4_header_t * ip, s->flags |= SNAT_SESSION_FLAG_FWD_BYPASS; s->out2in.addr = ip->dst_address; s->out2in.port = l_port; - s->out2in.protocol = proto; + s->nat_proto = proto; if (proto == NAT_PROTOCOL_OTHER) { s->flags |= SNAT_SESSION_FLAG_UNKNOWN_PROTO; s->out2in.port = ip->protocol; } s->out2in.fib_index = 0; - s->in2out = s->out2in; + s->in2out.addr = s->out2in.addr; + s->in2out.port = s->out2in.port; + s->in2out.fib_index = s->out2in.fib_index; kv.value = s - tsm->sessions; if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1)) @@ -431,24 +439,28 @@ create_bypass_for_fwd_worker (snat_main_t * sm, vlib_buffer_t * b, #ifndef CLIB_MARCH_VARIANT u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, - u32 thread_index, vlib_buffer_t * b, ip4_header_t * ip, - u8 * p_proto, snat_session_key_t * p_value, - u8 * p_dont_translate, void *d, void *e) + u32 thread_index, vlib_buffer_t * b, + ip4_header_t * ip, ip4_address_t * addr, + u16 * port, u32 * fib_index, nat_protocol_t * proto, + void *d, void *e, u8 * dont_translate) { u32 next = ~0, sw_if_index, rx_fib_index; clib_bihash_kv_16_8_t kv, value; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; snat_session_t *s = 0; - u8 dont_translate = 0, is_addr_only, identity_nat; - snat_session_key_t e_key, l_key; + u8 is_addr_only, identity_nat; u16 l_port, r_port; vlib_main_t *vm = vlib_get_main (); + ip4_address_t sm_addr; + u16 sm_port; + u32 sm_fib_index; + *dont_translate = 0; sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index); if (get_icmp_o2i_ed_key - (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port, &r_port, &kv)) + (b, ip, rx_fib_index, ~0, ~0, proto, &l_port, &r_port, &kv)) { b->error = node->errors[NAT_OUT2IN_ED_ERROR_UNSUPPORTED_PROTOCOL]; next = NAT_NEXT_DROP; @@ -458,12 +470,10 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value)) { /* Try to match static mapping */ - e_key.addr = ip->dst_address; - e_key.port = l_port; - e_key.protocol = ip_proto_to_nat_proto (ip->protocol); - e_key.fib_index = rx_fib_index; if (snat_static_mapping_match - (sm, e_key, &l_key, 1, &is_addr_only, 0, 0, 0, &identity_nat)) + (sm, ip->dst_address, l_port, rx_fib_index, + ip_proto_to_nat_proto (ip->protocol), &sm_addr, &sm_port, + &sm_fib_index, 1, &is_addr_only, 0, 0, 0, &identity_nat)) { if (!sm->forwarding_enabled) { @@ -471,7 +481,7 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index, ip->dst_address.as_u32))) { - dont_translate = 1; + *dont_translate = 1; goto out; } b->error = node->errors[NAT_OUT2IN_ED_ERROR_NO_TRANSLATION]; @@ -480,7 +490,7 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, } else { - dont_translate = 1; + *dont_translate = 1; if (next_src_nat (sm, ip, l_port, r_port, thread_index, rx_fib_index)) { @@ -508,14 +518,18 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, if (PREDICT_FALSE (identity_nat)) { - dont_translate = 1; + *dont_translate = 1; goto out; } /* Create session initiated by host from external network */ - s = create_session_for_static_mapping_ed (sm, b, l_key, e_key, node, - rx_fib_index, thread_index, 0, - 0, vlib_time_now (vm)); + s = + create_session_for_static_mapping_ed (sm, b, sm_addr, sm_port, + sm_fib_index, ip->dst_address, + l_port, rx_fib_index, *proto, + node, rx_fib_index, + thread_index, 0, 0, + vlib_time_now (vm)); if (!s) { @@ -545,8 +559,11 @@ icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node, } out: if (s) - *p_value = s->in2out; - *p_dont_translate = dont_translate; + { + *addr = s->in2out.addr; + *port = s->in2out.port; + *fib_index = s->in2out.fib_index; + } if (d) *(snat_session_t **) d = s; return next; @@ -572,8 +589,8 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm, old_addr = ip->dst_address.as_u32; - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, rx_fib_index, - 0, 0, ~0, ~0, &s_kv); + init_ed_k (&s_kv, ip->dst_address, 0, ip->src_address, 0, rx_fib_index, + ip->protocol); if (!clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value)) { @@ -594,7 +611,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm, return 0; } - make_sm_kv (&kv, &ip->dst_address, 0, 0, 0); + init_nat_k (&kv, ip->dst_address, 0, 0, 0); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { @@ -630,8 +647,8 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm, if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1)) nat_elog_notice ("out2in key add failed"); - make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, - m->fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv); + init_ed_kv (&s_kv, ip->dst_address, 0, ip->src_address, 0, m->fib_index, + ip->protocol, thread_index, s - tsm->sessions); if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1)) nat_elog_notice ("in2out key add failed"); } @@ -738,10 +755,10 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm, goto trace0; } - make_ed_kv (&ip0->dst_address, &ip0->src_address, - ip0->protocol, rx_fib_index0, - vnet_buffer (b0)->ip.reass.l4_dst_port, - vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0); + init_ed_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, + ip0->protocol); /* there is a stashed index in vnet_buffer2 from handoff node, * see if we can use it */ @@ -757,8 +774,7 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm, (s0->out2in.addr.as_u32 == ip0->dst_address.as_u32 && s0->out2in.port == vnet_buffer (b0)->ip.reass.l4_dst_port - && s0->out2in.protocol == - ip_proto_to_nat_proto (ip0->protocol) + && s0->nat_proto == ip_proto_to_nat_proto (ip0->protocol) && s0->out2in.fib_index == rx_fib_index0 && s0->ext_host_addr.as_u32 == ip0->src_address.as_u32 && s0->ext_host_port == @@ -991,10 +1007,12 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm, snat_session_t *s0 = 0; clib_bihash_kv_16_8_t kv0, value0; ip_csum_t sum0; - snat_session_key_t e_key0, l_key0; lb_nat_type_t lb_nat0; twice_nat_type_t twice_nat0; u8 identity_nat0; + ip4_address_t sm_addr; + u16 sm_port; + u32 sm_fib_index; /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -1053,10 +1071,10 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm, goto trace0; } - make_ed_kv (&ip0->dst_address, &ip0->src_address, - ip0->protocol, rx_fib_index0, - vnet_buffer (b0)->ip.reass.l4_dst_port, - vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0); + init_ed_k (&kv0, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, ip0->src_address, + vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, + ip0->protocol); s0 = NULL; if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv0, &value0)) @@ -1078,15 +1096,12 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm, { /* Try to match static mapping by external address and port, destination address and port in packet */ - e_key0.addr = ip0->dst_address; - e_key0.port = vnet_buffer (b0)->ip.reass.l4_dst_port; - e_key0.protocol = proto0; - e_key0.fib_index = rx_fib_index0; - - if (snat_static_mapping_match (sm, e_key0, &l_key0, 1, 0, - &twice_nat0, &lb_nat0, - &ip0->src_address, - &identity_nat0)) + + if (snat_static_mapping_match + (sm, ip0->dst_address, + vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, + proto0, &sm_addr, &sm_port, &sm_fib_index, 1, 0, + &twice_nat0, &lb_nat0, &ip0->src_address, &identity_nat0)) { /* * Send DHCP packets to the ipv4 stack, or we won't @@ -1140,12 +1155,18 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm, } /* Create session initiated by host from external network */ - s0 = create_session_for_static_mapping_ed (sm, b0, l_key0, - e_key0, node, + s0 = create_session_for_static_mapping_ed (sm, b0, + sm_addr, sm_port, + sm_fib_index, + ip0->dst_address, + vnet_buffer (b0)-> + ip.reass.l4_dst_port, + rx_fib_index0, + proto0, node, rx_fib_index0, thread_index, - twice_nat0, - lb_nat0, now); + twice_nat0, lb_nat0, + now); if (!s0) { next0 = NAT_NEXT_DROP; |