diff options
-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; |