summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2025-12-10 17:27:51 +0100
committerKristof Provost <kp@FreeBSD.org>2025-12-11 10:25:33 +0100
commitac4fb06d096d6308b9522f454b68fbfc45bb8531 (patch)
tree5f9d5cc452537522af2d5ae294f066d3ef813c89 /tests
parenta35545ee02680cee04c354b50182dd94d4489666 (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.py36
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