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 */
&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
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))
{
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;
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;
},
};
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)))
{
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))
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))
{
/* 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))
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;
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 */
}
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;
}
}
{
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;
}
}
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;
}
}
}
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
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;
}
}
out:
- *p_value = sm0;
-out2:
- *p_proto = key0.protocol;
- *p_dont_translate = dont_translate;
return next0;
}
#endif
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;
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)
}
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,
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;
/* 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,
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;
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;
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:
{
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;
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;
}
}
- 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,
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;
}
}
- 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,
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;
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;
}
}
- 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))
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))
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];
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;
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);
}
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");
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);
&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;
}
}
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;
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;
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);
}
}
- 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)
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,
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);
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))
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,
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);
&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;
}
{
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
}
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))
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));
}
/* 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));
#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)
{
(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;
}
}
rx_fib_index,
thread_index)))
{
- dont_translate = 1;
+ *dont_translate = 1;
goto out;
}
}
if (!s)
{
- dont_translate = 1;
+ *dont_translate = 1;
goto out;
}
}
}
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
}
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))
{
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))
{
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;
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 =
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");
}
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))
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));
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;
{
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
{
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");
{
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;
}
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;
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");
&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");
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))
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
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;
}
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;
}
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)))
/* 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;
}
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");
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");
&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))
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);
}
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;
}
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;
}
{
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;
}
}
- 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
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;
}
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;
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) */
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,
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);
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);
{
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;
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
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 :
}
}
- 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");
({
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");
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);
{
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;
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);
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");
}
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");
}
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);
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;
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));
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 *
FIB_SOURCE_PRIORITY_LOW,
FIB_SOURCE_BH_SIMPLE);
- test_ed_make_split ();
+ test_key_calc_split ();
return error;
}
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;
}
a = addresses + address_index;
- switch (k->protocol)
+ switch (protocol)
{
#define _(N, i, n, s) \
case NAT_PROTOCOL_##N: \
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: \
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,
{
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);
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
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");
{
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:
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;
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: \
--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; \
} \
} \
if (ga)
{
a = ga;
- switch (k->protocol)
+ switch (proto)
{
#define _(N, j, n, s) \
case NAT_PROTOCOL_##N: \
++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;
}
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;
if (!vec_len (addresses))
goto exhausted;
- switch (k->protocol)
+ switch (proto)
{
#define _(N, i, n, s) \
case NAT_PROTOCOL_##N: \
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; \
} \
} \
}
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;
if (!vec_len (addresses))
goto exhausted;
- switch (k->protocol)
+ switch (proto)
{
#define _(N, i, n, s) \
case NAT_PROTOCOL_##N: \
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; \
} \
} \
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;
}
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;
}
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;
/* 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))
{
/* 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))
{
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)))
{
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)))
/* 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))
{
/* 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))
{
{
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;
},
};
- 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;
}
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;
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* */
{
if (fib_entry_get_resolving_interface (fei) != ~0)
{
- key.fib_index = outside_fib->fib_index;
+ s->out2in.fib_index = outside_fib->fib_index;
break;
}
}
/* *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");
}
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;
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;
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;
{
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 ();
},
};
- 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;
}
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* */
{
if (fib_entry_get_resolving_interface (fei) != ~0)
{
- key.fib_index = outside_fib->fib_index;
+ s->out2in.fib_index = outside_fib->fib_index;
break;
}
}
/* *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");
}
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;
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;
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;
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
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;
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))
{
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;
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
{
/* *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;
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,
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);
/* 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,
*
* @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
* @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
*
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
* @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,
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 */
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))
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))
{
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 */
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))
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))
{
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;
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))
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))
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))
{
if (now >= sess_timeout_time)
timed_out++;
- switch (s->in2out.protocol)
+ switch (s->nat_proto)
{
case NAT_PROTOCOL_ICMP:
icmp_sessions++;
if (now >= sess_timeout_time)
timed_out++;
- switch (s->in2out.protocol)
+ switch (s->nat_proto)
{
case NAT_PROTOCOL_ICMP:
icmp_sessions++;
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);
}
}
- 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)
{
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)
{
{
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)
}
/* *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;
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
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)
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;
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));
}
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;
}
}
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))
{
{
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) -
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;
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;
{
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;
}
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);
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)
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));
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);
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);
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);
{
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))
{
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);
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,
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;
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++;
}
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;
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;
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);
IP_PROTOCOL_ICMP,
rx_fib_index0)))
{
- dont_translate = 1;
+ *dont_translate = 1;
goto out;
}
next0 = NAT_DET_IN2OUT_NEXT_DROP;
IP_PROTOCOL_ICMP,
rx_fib_index0)))
{
- dont_translate = 1;
+ *dont_translate = 1;
goto out;
}
if (icmp0->type != ICMP4_echo_request)
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)
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;
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);
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",
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",
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)
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;
}
#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,
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;
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);
}
}
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;
}
}
}
-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;
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);
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;
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);
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;
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)
{
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");
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))
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;
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 */
}
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)
{
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];
}
else
{
- dont_translate = 1;
+ *dont_translate = 1;
goto out;
}
}
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)
{
}
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;
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];
}
out:
- *p_value = sm0;
-out2:
- *p_proto = key0.protocol;
- *p_dont_translate = dont_translate;
return next0;
}
#endif
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;
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)
}
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,
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;
}
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;
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;
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;
{
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;
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. */
{
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
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;
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))
/* 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
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;
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];
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))
/* 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
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;
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];
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;
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);
}
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;
}
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");
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);
&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;
+ // }
}
}
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;
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,
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
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];
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,
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))
{
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,
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);
&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;
}
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;
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))
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))
#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;
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)
{
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];
}
else
{
- dont_translate = 1;
+ *dont_translate = 1;
if (next_src_nat (sm, ip, l_port, r_port,
thread_index, rx_fib_index))
{
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)
{
}
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;
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))
{
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))
{
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");
}
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 */
(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 ==
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];
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))
{
/* 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
}
/* 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;