diff options
| author | Kristof Provost <kp@FreeBSD.org> | 2025-12-10 17:27:51 +0100 |
|---|---|---|
| committer | Kristof Provost <kp@FreeBSD.org> | 2025-12-11 10:25:33 +0100 |
| commit | ac4fb06d096d6308b9522f454b68fbfc45bb8531 (patch) | |
| tree | 5f9d5cc452537522af2d5ae294f066d3ef813c89 /tests | |
| parent | a35545ee02680cee04c354b50182dd94d4489666 (diff) | |
pf: handle TTL expired during nat64
If the TTL (or hop limit) expires during nat64 translation we may
need to send the error message in the original address family (i.e.
pre-translation).
We'd usually handle this in pf_route()/pf_route6(), but at that point we
have already translated the packet, making it difficult to include it in
the generated ICMP message.
Check for this case in pf_translate_af() and send icmp errors directly
from it.
PR: 291527
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D54166
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/sys/netpfil/pf/nat64.py | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py index 705de72f5bc4..ba0d2ae01a9e 100644 --- a/tests/sys/netpfil/pf/nat64.py +++ b/tests/sys/netpfil/pf/nat64.py @@ -331,6 +331,42 @@ class TestNAT64(VnetTestTemplate): @pytest.mark.require_user("root") @pytest.mark.require_progs(["scapy"]) + def test_ttl_one(self): + """ + PR 291527: invalid ICMP error generated by nat64 router + """ + ifname = self.vnet.iface_alias_map["if1"].name + gw_mac = self.vnet.iface_alias_map["if1"].epairb.ether + ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1") + + import scapy.all as sp + + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::198.51.100.2", hlim=1) \ + / sp.SCTP(sport=1111, dport=2222) \ + / sp.SCTPChunkInit(init_tag=1, n_in_streams=1, n_out_streams=1, \ + a_rwnd=1500, params=[]) + s = DelayedSend(pkt, sendif=ifname) + + found = False + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + print("Reply packet:") + r.show() + + ip6 = r.getlayer(sp.IPv6) + icmp6 = r.getlayer(sp.ICMPv6TimeExceeded) + if not ip6 or not icmp6: + continue + assert ip6.src == "2001:db8::1" + assert ip6.dst == "2001:db8::2" + assert icmp6.type == 3 # Time exceeded + assert icmp6.code == 0 # hop limit exceeded in transit + found = True + assert found + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) def test_ttl_zero(self): """ PR 288274: we can use an mbuf after free on TTL = 0 |
