Skip to content

nat44-ed: SIGSEGV in out2in slow path on ICMP error carrying GRE/IPIP inner packet (26.06) #3728

Description

@TeTecko

Summary

On VPP 26.06-release (nat44-ed, on-a-stick — one interface configured as both NAT in and out,
so the classification feature is active), a worker thread reliably SIGSEGVs in
nat44_ed_out2in_slowpath_node_fn
under normal CGNAT traffic. For ~39 s before the crash the log
floods with:

nat_6t_flow_icmp_translate:3955: unexpected NAT protocol value 47' nat_6t_flow_icmp_translate:3955: unexpected NAT protocol value 4'

i.e. an ICMP error message whose quoted inner packet is GRE (proto 47) or IPIP (proto 4)
generated naturally by subscribers running PPTP (GRE) / IP-in-IP tunnels.

Environment

  • VPP 26.06-release (x86_64-v4 build), vpp_plugins/nat_plugin.so
  • Debian 13 (trixie), kernel 6.12.94, Intel E810 via DPDK/vfio-pci, 16 worker threads
  • nat44-ed (endpoint-dependent), on-a-stick: both interfaces nat44 in out (classification feature)
  • CGNAT pool /24 + 375 address-only 1:1 static mappings, ~1.3–1.5M sessions, ~930k pps

Steps to reproduce

  1. nat44-ed on-a-stick (one interface configured as both in and out) with a NAT pool / static-mapped
    external address.
  2. From outside, send to that NATed external address an ICMP error (dest-unreachable / TTL-exceeded /
    frag-needed) whose quoted inner IPv4 header has protocol = 47 (GRE) or 4 (IPIP).
  3. Drive volume through the out2in slow path. The log floods with nat_6t_flow_icmp_translate:3955: unexpected NAT protocol value '47'/'4', then a worker SIGSEGVs in nat44_ed_out2in_slowpath_node_fn.

Crash details

Syslog:
received signal SIGSEGV, PC 0x..b957, faulting address 0x..
#0 nat44_ed_out2in_slowpath_node_fn_x86_64_v4 + 0x9e7 (nat_plugin.so)

Backtrace (gdb on core):
#6 nat44_ed_out2in_slowpath_node_fn_x86_64_v4 () nat_plugin.so
#7 dispatch_node () libvlib
#8 vlib_worker_thread_bootstrap_fn () libvlib

Faulting instruction:
nat44_ed_out2in_slowpath_node_fn_x86_64_v4+2535: mov %ebp,0x4(%rcx,%rbx,4)

followed by lea (%rbp,%rbp,2) (×3) and mov qword [..],-1 — the shape of clib_dlist
manipulation on the per-thread LRU pool (dlist_elt_t = {next,prev,value} = 3×u32, -1 = invalid-index
sentinel).

Source analysis

nat_6t_flow_icmp_translate() (nat44_ed.c) switches on the inner packet's protocol; for anything other
than TCP/UDP/ICMP (GRE 47, IPIP 4) it returns cleanly:

3954    default:
3955      clib_warning ("unexpected NAT protocol value `%d'", inner_proto);
3956      return NAT_ED_TRNSL_ERR_TRANSLATION_FAILED;
The node-fn callers handle that return correctly (next=DROP; b0->error; goto trace0), so this is not
a missing-drop bug.

Suspected mechanism (UNVERIFIEDstatic analysis + faulting-instruction shape only):
icmp_out2in_ed_slow_path() (nat44_ed_out2in.c) creates a session for the inbound ICMP error and links
it into the per-thread LRU dlist. Back in the node fn (~l.1122-1131) the follow-up
nat_6t_flow_buf_translate_o2i() then fails for the GRE/IPIP inner packet, so the packet is droppedbut
unlike the FLOW_MISMATCH path (~l.936-939, which does nat44_ed_free_session_data + nat_ed_session_delete)
this drop path does not delete the just-created session, leaking it in the LRU dlist. Accumulation
corrupts the dlistlater SIGSEGV in dlist code (consistent with the ~39 s warning flood beforehand).

Candidate fix (unverified): on that drop path, free_session_data + session_delete the just-created
s0 (mirroring l.936-939). Reproducing + verifying on a debug build; will follow up with a PR if confirmed.

Impact
Worker SIGSEGVVPP restart. Triggered by everyday GRE/IPIP tunnel traffic, so a nat44-ed node cannot
stay up reliably. The crash is in LRU clib_dlist code but the trigger differs from VPP-2117 / CSIT-1947
(not the eviction patha session leaked into the LRU on an ICMP-error translate failure).

Artifacts
A 12 GB core (VPP 26.06-release, core.vpp_wk_15.*) is available on request.

Question
Does this analysis match a known issue, or is it already fixed on master? Happy to test a patch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions