aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2021-03-03 22:14:55 +0100
committerOle Tr�an <otroan@employees.org>2021-03-07 17:57:32 +0000
commit76401c5767ecdf701f4c77beee0b721c485321d5 (patch)
tree0c0c80f4362aabdb6a3565f77e6395724a6cb2fc
parente79bbe918b2afa12943ea99b8323dd8f3aef73ab (diff)
nat: fix worker selection
Use correct ports from SVR. Perform lookup of existing session for all cases to pick any created bypasses and derive correct thread indexes. Type: fix Change-Id: I1e3814c9e13cd4d9b8d65f514f7e9ab42df3c22e Signed-off-by: Klement Sekera <ksekera@cisco.com>
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.c98
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.h9
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_api.c5
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_handoff.c10
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_in2out.c27
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_out2in.c11
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.c2
7 files changed, 73 insertions, 89 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c
index 6f2cd11e695..0d62e788ec1 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed.c
@@ -182,9 +182,8 @@ static u32
nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
u32 rx_fib_index, u8 is_output);
-static u32
-nat44_ed_get_worker_in2out_cb (ip4_header_t * ip, u32 rx_fib_index,
- u8 is_output);
+static u32 nat44_ed_get_worker_in2out_cb (vlib_buffer_t *b, ip4_header_t *ip,
+ u32 rx_fib_index, u8 is_output);
u32 nat_calc_bihash_buckets (u32 n_elts);
@@ -738,7 +737,8 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
ip4_header_t ip = {
.src_address = m->local_addr,
};
- vec_add1 (m->workers, sm->worker_in2out_cb (&ip, m->fib_index, 0));
+ vec_add1 (m->workers,
+ sm->worker_in2out_cb (0, &ip, m->fib_index, 0));
tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
}
else
@@ -988,10 +988,8 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
ip4_header_t ip = {
.src_address = locals[i].addr,
};
- bitmap =
- clib_bitmap_set (bitmap,
- sm->worker_in2out_cb (&ip, m->fib_index, 0),
- 1);
+ bitmap = clib_bitmap_set (
+ bitmap, sm->worker_in2out_cb (0, &ip, m->fib_index, 0), 1);
}
}
@@ -1057,9 +1055,11 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
sm->fib_src_low);
if (!out2in_only)
{
-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))
- {
+ 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 (sm, "static_mapping_by_local key del failed");
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1070,9 +1070,9 @@ init_nat_k(& kv, local->addr, local->port, local->fib_index, m->pro
ip4_header_t ip = {
.src_address = local->addr,
};
- tsm =
- vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, m->fib_index, 0));
+ tsm = vec_elt_at_index (
+ sm->per_thread_data,
+ sm->worker_in2out_cb (0, &ip, m->fib_index, 0));
}
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
@@ -1188,9 +1188,9 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
ip4_header_t ip = {
.src_address = local->addr,
};
- tsm = vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, m->fib_index,
- 0));
+ tsm =
+ vec_elt_at_index (sm->per_thread_data,
+ sm->worker_in2out_cb (0, &ip, m->fib_index, 0));
}
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
@@ -1222,10 +1222,9 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
if (sm->num_workers > 1)
{
ip4_header_t ip;
- ip.src_address.as_u32 = local->addr.as_u32,
- bitmap = clib_bitmap_set (bitmap,
- sm->worker_in2out_cb (&ip, local->fib_index, 0),
- 1);
+ ip.src_address.as_u32 = local->addr.as_u32,
+ bitmap = clib_bitmap_set (
+ bitmap, sm->worker_in2out_cb (0, &ip, local->fib_index, 0), 1);
}
}
/* *INDENT-ON* */
@@ -2485,12 +2484,12 @@ snat_static_mapping_match (snat_main_t * sm,
.src_address = local->addr,
};
- if (sm->worker_in2out_cb (&ip, m->fib_index, 0) ==
+ if (sm->worker_in2out_cb (0, &ip, m->fib_index, 0) ==
thread_index)
- {
- vec_add1 (tmp, i);
- }
- }
+ {
+ vec_add1 (tmp, i);
+ }
+ }
ASSERT (vec_len (tmp) != 0);
}
else
@@ -2562,20 +2561,19 @@ end:
}
static u32
-nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
- u8 is_output)
+nat44_ed_get_worker_in2out_cb (vlib_buffer_t *b, ip4_header_t *ip,
+ u32 rx_fib_index, u8 is_output)
{
snat_main_t *sm = &snat_main;
u32 next_worker_index = sm->first_worker_index;
u32 hash;
clib_bihash_kv_16_8_t kv16, value16;
- snat_main_per_thread_data_t *tsm;
- udp_header_t *udp;
+ u32 fib_index = rx_fib_index;
if (PREDICT_FALSE (is_output))
{
- u32 fib_index = sm->outside_fib_index;
+ fib_index = sm->outside_fib_index;
nat_outside_fib_t *outside_fib;
fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
fib_prefix_t pfx = {
@@ -2587,8 +2585,6 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
,
};
- udp = ip4_next_header (ip);
-
switch (vec_len (sm->outside_fibs))
{
case 0:
@@ -2614,24 +2610,21 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
/* *INDENT-ON* */
break;
}
+ }
- init_ed_k (&kv16, ip->src_address, udp->src_port, ip->dst_address,
- udp->dst_port, fib_index, ip->protocol);
+ if (b)
+ {
+ init_ed_k (&kv16, ip->src_address, vnet_buffer (b)->ip.reass.l4_src_port,
+ ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port,
+ fib_index, ip->protocol);
if (PREDICT_TRUE (
!clib_bihash_search_16_8 (&sm->flow_hash, &kv16, &value16)))
{
- tsm =
- vec_elt_at_index (sm->per_thread_data,
- ed_value_get_thread_index (&value16));
- next_worker_index += tsm->thread_index;
-
- nat_elog_debug_handoff (
- sm, "HANDOFF IN2OUT-OUTPUT-FEATURE (session)", next_worker_index,
- fib_index, clib_net_to_host_u32 (ip->src_address.as_u32),
- clib_net_to_host_u32 (ip->dst_address.as_u32));
-
- return next_worker_index;
+ next_worker_index = ed_value_get_thread_index (&value16);
+ vnet_buffer2 (b)->nat.cached_session_index =
+ ed_value_get_session_index (&value16);
+ goto out;
}
}
@@ -2643,6 +2636,7 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
else
next_worker_index += sm->workers[hash % _vec_len (sm->workers)];
+out:
if (PREDICT_TRUE (!is_output))
{
nat_elog_debug_handoff (sm, "HANDOFF IN2OUT", next_worker_index,
@@ -2682,8 +2676,9 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
{
udp = ip4_next_header (ip);
- init_ed_k (&kv16, ip->dst_address, udp->dst_port, ip->src_address,
- udp->src_port, rx_fib_index, ip->protocol);
+ init_ed_k (&kv16, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port,
+ ip->src_address, vnet_buffer (b)->ip.reass.l4_src_port,
+ rx_fib_index, ip->protocol);
if (PREDICT_TRUE (
!clib_bihash_search_16_8 (&sm->flow_hash, &kv16, &value16)))
@@ -2750,7 +2745,7 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
}
udp = ip4_next_header (ip);
- port = udp->dst_port;
+ port = vnet_buffer (b)->ip.reass.l4_dst_port;
if (PREDICT_FALSE (ip->protocol == IP_PROTOCOL_ICMP))
{
@@ -3220,9 +3215,8 @@ nat44_del_ed_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
ip.dst_address.as_u32 = ip.src_address.as_u32 = addr->as_u32;
if (sm->num_workers > 1)
- tsm =
- vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, fib_index, 0));
+ tsm = vec_elt_at_index (sm->per_thread_data,
+ sm->worker_in2out_cb (0, &ip, fib_index, 0));
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h
index 902e5e34b14..c6bccd9f492 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed.h
@@ -190,7 +190,6 @@ typedef enum
#define NAT_STATIC_MAPPING_FLAG_LB 8
#define NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS 16
-/* *INDENT-OFF* */
typedef CLIB_PACKED(struct
{
// number of sessions in this vrf
@@ -202,7 +201,6 @@ typedef CLIB_PACKED(struct
// is this vrf expired
u8 expired;
}) per_vrf_sessions_t;
-/* *INDENT-ON* */
typedef union
{
@@ -287,7 +285,6 @@ nat_6t_flow_icmp_id_rewrite_set (nat_6t_flow_t *f, u16 id)
f->rewrite.icmp_id = id;
}
-/* *INDENT-OFF* */
typedef CLIB_PACKED(struct
{
/* Outside network tuple */
@@ -348,20 +345,17 @@ typedef CLIB_PACKED(struct
u32 per_vrf_sessions_index;
}) snat_session_t;
-/* *INDENT-ON* */
typedef struct
{
ip4_address_t addr;
u32 fib_index;
-/* *INDENT-OFF* */
#define _(N, i, n, s) \
u32 busy_##n##_ports; \
u32 * busy_##n##_ports_per_thread; \
u32 busy_##n##_port_refcounts[65535];
foreach_nat_protocol
#undef _
-/* *INDENT-ON* */
} snat_address_t;
typedef struct
@@ -496,7 +490,8 @@ typedef struct
struct snat_main_s;
/* Return worker thread index for given packet */
-typedef u32 (snat_get_worker_in2out_function_t) (ip4_header_t * ip,
+typedef u32 (snat_get_worker_in2out_function_t) (vlib_buffer_t *b,
+ ip4_header_t *ip,
u32 rx_fib_index,
u8 is_output);
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c
index c6c505e0daf..3089f68950f 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_api.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c
@@ -1529,9 +1529,8 @@ vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
ip.src_address.as_u32 = ukey.addr.as_u32;
ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
if (sm->num_workers > 1)
- tsm =
- vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, ukey.fib_index, 0));
+ tsm = vec_elt_at_index (sm->per_thread_data,
+ sm->worker_in2out_cb (0, &ip, ukey.fib_index, 0));
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_handoff.c b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
index 6715ce2f2c4..e286df93a6e 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
@@ -157,10 +157,10 @@ nat44_worker_handoff_fn_inline (vlib_main_t * vm,
if (is_in2out)
{
- ti[0] = sm->worker_in2out_cb (ip0, rx_fib_index0, is_output);
- ti[1] = sm->worker_in2out_cb (ip1, rx_fib_index1, is_output);
- ti[2] = sm->worker_in2out_cb (ip2, rx_fib_index2, is_output);
- ti[3] = sm->worker_in2out_cb (ip3, rx_fib_index3, is_output);
+ ti[0] = sm->worker_in2out_cb (b[0], ip0, rx_fib_index0, is_output);
+ ti[1] = sm->worker_in2out_cb (b[1], ip1, rx_fib_index1, is_output);
+ ti[2] = sm->worker_in2out_cb (b[2], ip2, rx_fib_index2, is_output);
+ ti[3] = sm->worker_in2out_cb (b[3], ip3, rx_fib_index3, is_output);
}
else
{
@@ -218,7 +218,7 @@ nat44_worker_handoff_fn_inline (vlib_main_t * vm,
if (is_in2out)
{
- ti[0] = sm->worker_in2out_cb (ip0, rx_fib_index0, is_output);
+ ti[0] = sm->worker_in2out_cb (b[0], ip0, rx_fib_index0, is_output);
}
else
{
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
index 59355e49ccd..885851c46b6 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
@@ -554,15 +554,15 @@ error:
}
static_always_inline int
-nat44_ed_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 sw_if_index, ip4_header_t * ip, u32 proto,
- u32 rx_fib_index, u32 thread_index)
+nat44_ed_not_translate (snat_main_t *sm, vlib_node_runtime_t *node,
+ u32 sw_if_index, vlib_buffer_t *b, ip4_header_t *ip,
+ u32 proto, u32 rx_fib_index, u32 thread_index)
{
- udp_header_t *udp = ip4_next_header (ip);
clib_bihash_kv_16_8_t kv, value;
- init_ed_k (&kv, ip->dst_address, udp->dst_port, ip->src_address,
- udp->src_port, sm->outside_fib_index, ip->protocol);
+ init_ed_k (&kv, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port,
+ ip->src_address, vnet_buffer (b)->ip.reass.l4_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->flow_hash, &kv, &value))
@@ -571,10 +571,10 @@ nat44_ed_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
ip4_address_t placeholder_addr;
u16 placeholder_port;
u32 placeholder_fib_index;
- if (!snat_static_mapping_match
- (sm, ip->dst_address, udp->dst_port, sm->outside_fib_index, proto,
- &placeholder_addr, &placeholder_port, &placeholder_fib_index, 1, 0,
- 0, 0, 0, 0, 0))
+ if (!snat_static_mapping_match (
+ sm, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port,
+ sm->outside_fib_index, proto, &placeholder_addr, &placeholder_port,
+ &placeholder_fib_index, 1, 0, 0, 0, 0, 0, 0))
return 0;
}
else
@@ -742,7 +742,7 @@ icmp_in2out_ed_slow_path (snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip,
}
else
{
- if (PREDICT_FALSE (nat44_ed_not_translate (sm, node, sw_if_index, ip,
+ if (PREDICT_FALSE (nat44_ed_not_translate (sm, node, sw_if_index, b, ip,
NAT_PROTOCOL_ICMP,
rx_fib_index, thread_index)))
{
@@ -1373,9 +1373,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
}
else
{
- if (PREDICT_FALSE
- (nat44_ed_not_translate
- (sm, node, sw_if_index0, ip0, proto0, rx_fib_index0,
+ if (PREDICT_FALSE (nat44_ed_not_translate (
+ sm, node, sw_if_index0, b0, ip0, proto0, rx_fib_index0,
thread_index)))
goto trace0;
}
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
index 90f2ec32155..d3fd50953e0 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
@@ -372,7 +372,6 @@ create_session_for_static_mapping_ed (
{
snat_session_t *s;
ip4_header_t *ip;
- udp_header_t *udp;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
if (PREDICT_FALSE
@@ -392,10 +391,10 @@ create_session_for_static_mapping_ed (
}
ip = vlib_buffer_get_current (b);
- udp = ip4_next_header (ip);
s->ext_host_addr.as_u32 = ip->src_address.as_u32;
- s->ext_host_port = nat_proto == NAT_PROTOCOL_ICMP ? 0 : udp->src_port;
+ s->ext_host_port =
+ nat_proto == NAT_PROTOCOL_ICMP ? 0 : vnet_buffer (b)->ip.reass.l4_src_port;
s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
if (lb_nat)
s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
@@ -574,7 +573,6 @@ create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b, snat_session_t *s,
ip4_header_t *ip, u32 rx_fib_index, u32 thread_index)
{
clib_bihash_kv_16_8_t kv, value;
- udp_header_t *udp;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
vlib_main_t *vm = vlib_get_main ();
f64 now = vlib_time_now (vm);
@@ -593,9 +591,8 @@ create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b, snat_session_t *s,
{
if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP)
{
- udp = ip4_next_header (ip);
- lookup_sport = udp->dst_port;
- lookup_dport = udp->src_port;
+ lookup_sport = vnet_buffer (b)->ip.reass.l4_dst_port;
+ lookup_dport = vnet_buffer (b)->ip.reass.l4_src_port;
}
else
{
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c
index d361060a42e..67757015b1d 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei.c
@@ -1407,7 +1407,7 @@ nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
proto = ip_proto_to_nat_proto (ip0->protocol);
udp = ip4_next_header (ip0);
- port = udp->dst_port;
+ port = vnet_buffer (b)->ip.reass.l4_dst_port;
/* unknown protocol */
if (PREDICT_FALSE (proto == NAT_PROTOCOL_OTHER))