diff options
author | Matthew Smith <mgsmith@netgate.com> | 2021-08-10 12:22:14 -0500 |
---|---|---|
committer | Matthew Smith <mgsmith@netgate.com> | 2021-08-19 15:52:18 +0000 |
commit | ad51075029c59dc4100c1a416bed17870b9be1b7 (patch) | |
tree | 4e59261885d9089a1e0bc9fde43a0c7213e8ffcf /src/plugins/nat/nat44-ed/nat44_ed.c | |
parent | 1d342b9c8f515eabfb20fe8856ba311769870711 (diff) |
nat: handle ED in2out ICMP errors with workers
Type: fix
With endpoint dependent NAT44, When there are multiple workers we look
for a flow which matches the packet in order to figure out which worker
should handle the packet. If the packet is an ICMP error, it may be
associated with an existing flow by inspecting the L3/L4 headers that
are included in the message payload.
This was not being done for in2out packets in
nat44_ed_get_in2out_worker_index(), so some packets which were related
to an open session were not being associated with that session and were
being passed to a different thread than the one where the session was
created. Later on, when the packet was processed by the fast path in2out
node, the L3/L4 headers in the payload are inspected and the fast path
node finds the existing session. Since that session is owned by a
different thread than the one the packet is being processed by, the
in2out fast path node can potentially access the wrong session and/or
memory adjacent to the session pool. This can cause a SEGV.
Make nat44_ed_get_in2out_worker_index() look at the inner headers when
processing an ICMP error. THis is already done in
nat44_ed_get_out2in_worker_index() and in the fast path in2out node.
Change-Id: Icdc1abebcbce452ee7be7cb23fc563e09bf575f2
Signed-off-by: Matthew Smith <mgsmith@netgate.com>
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed.c')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index ad78dc2dd1f..b9dbe6ebeca 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -2854,6 +2854,28 @@ nat44_ed_get_in2out_worker_index (vlib_buffer_t *b, ip4_header_t *ip, } } + if (PREDICT_FALSE (ip->protocol == IP_PROTOCOL_ICMP)) + { + ip4_address_t lookup_saddr, lookup_daddr; + u16 lookup_sport, lookup_dport; + u8 lookup_protocol; + + if (!nat_get_icmp_session_lookup_values ( + b, ip, &lookup_saddr, &lookup_sport, &lookup_daddr, + &lookup_dport, &lookup_protocol)) + { + init_ed_k (&kv16, lookup_saddr, lookup_sport, lookup_daddr, + lookup_dport, rx_fib_index, lookup_protocol); + if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv16, &value16)) + { + next_worker_index = ed_value_get_thread_index (&value16); + vnet_buffer2 (b)->nat.cached_session_index = + ed_value_get_session_index (&value16); + goto out; + } + } + } + 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); |