interface configuration: --o<-- cxl3: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500 options=6ec07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,HWRXTSTMP,MEXTPG> ether 00:07:43:3f:e7:78 inet 81.2.96.162/28 broadcast 81.2.96.175 inet6 fe80::207:43ff:fe3f:e778%cxl3/64 scopeid 0x4 inet6 2001:8b0:aab5:c401::1:5/64 inet6 fd5b:a83:b06b:c401::1:5/64 media: Ethernet 10Gbase-Twinax <full-duplex,rxpause,txpause> status: active nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> --o<-- pf.conf: --o<-- set skip on lo set reassemble yes set state-policy floating block return in log block return in quick proto tcp flags /S pass out # + a few 'pass in on cxl3 ...' rules for services --o<-- with state-policy floating, traceroute works: # traceroute6 -I ns1.burble.dn42 traceroute6 to ns1.burble.dn42 (fd42:4242:2601:ac53::1) from fd5b:a83:b06b:c401::1:5, 64 hops max, 20 byte packets 1 vlan401.core-1.inet.eden.le-fay.dn42 (fd5b:a83:b06b:c401::1) 0.219 ms 0.144 ms 0.136 ms 2 ix0-3004.willow.eden.le-fay.org (2001:8b0:aab5:3004::2) 0.139 ms 0.081 ms 0.073 ms 3 yarrow.eden.le-fay.dn42 (fd5b:a83:b06b:10::1) 6.846 ms 7.246 ms 6.996 ms 4 uk-lon1.burble.dn42 (fd42:4242:2601:35::1) 8.576 ms 8.873 ms 8.756 ms 5 ns1.burble.dn42 (fd42:4242:2601:ac53::1) 8.445 ms 8.829 ms 8.325 ms with state-policy if-bound, traceroute doesn't work: # traceroute6 -I ns1.burble.dn42 traceroute6 to ns1.burble.dn42 (fd42:4242:2601:ac53::1) from fd5b:a83:b06b:c401::1:5, 64 hops max, 20 byte packets 1 * * * 2 * * * because the ICMP errors are blocked by pf: 21:53:39.119122 rule 0/0(match): block in on cxl3: fd5b:a83:b06b:c401::1 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 21:53:44.174904 rule 0/0(match): block in on cxl3: fd5b:a83:b06b:c401::1 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 21:53:49.724459 rule 0/0(match): block in on cxl3: fd5b:a83:b06b:c401::1 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 21:53:54.846427 rule 0/0(match): block in on cxl3: 2001:8b0:aab5:3004::2 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 21:54:00.869729 rule 0/0(match): block in on cxl3: 2001:8b0:aab5:3004::2 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 21:54:06.568530 rule 0/0(match): block in on cxl3: 2001:8b0:aab5:3004::2 > fd5b:a83:b06b:c401::1:5: ICMP6, time exceeded in-transit for fd42:4242:2601:ac53::1, length 68 using src f5aff1871d3273b3cd3621ea5d3e37cdd807e66f on amd64, pf is statically compiler with PF_DEFAULT_TO_DROP.
Try this: ``` diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 8bd6c72ce05f..f9715cd18166 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -7793,6 +7793,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, pd2.sidx = (pd->dir == PF_IN) ? 1 : 0; pd2.didx = (pd->dir == PF_IN) ? 0 : 1; pd2.m = pd->m; + pd2.kif = pd->kif; switch (pd->af) { #ifdef INET case AF_INET: ``` If that doesn't work re-try without PF_DEFAULT_TO_DROP, because that's know to be buggy in at least one other situation. Also gather state information and network captures.
the suggested patch seems to fix the problem, thanks.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=86f2641b99f01eb8e8191c4435f22c17433b0c2f commit 86f2641b99f01eb8e8191c4435f22c17433b0c2f Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2025-02-19 12:28:33 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2025-02-19 13:34:45 +0000 pf: fix icmp-in-icmp handling with if-bound states When we receive an ICMP packet containing another ICMP packet we look up the original ICMP state. This is done through a second struct pf_pdesc ('pd2'), containing relevant information (i.e. addresses, type, id, ..). pd2 did not contain the network interface ('kif'), leading to state lookup failures. This only affected if-bound mode, because floating states match all interfaces. Set kif in pd2. Extend the icmp.py:test_fragmentation_needed test case to use if-bound mode. It already checked that we handled icmp-in-icmp correctly. PR: 284866 MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") sys/netpfil/pf/pf.c | 1 + tests/sys/netpfil/pf/icmp.py | 1 + 2 files changed, 2 insertions(+)