ITADN

pf blocks IPv6 packets with source :: (unspecified) to ff02::16 regardless of matching pass/block rules with allow-opts (FreeBSD 15.1 / OPNsense 26.7)

#10616Openruibastos1 创建于 2026-07-26
support
R
ruibastos1commented
### Environment - OPNsense 26.7 (Xenial Xenops), FreeBSD 15.1 base - Issue appeared immediately after upgrading from a prior release to 26.7 - Interface: VLAN-tagged interface (vlan02), IPv6 enabled via SLAAC/RA on that segment ### Description IPv6 packets with source address `::` (unspecified) destined to `ff02::16` (MLDv2-capable routers multicast address) are being blocked by the implicit default-deny rule, with filter log reason `ip-option`, even though: 1. An explicit `pass` rule exists matching this exact traffic (interface, direction, protocol ipv6-icmp, source ::, destination ff02::16) with `allow-opts` and `keep state` enabled. 2. An explicit `block` rule (which per pf.conf(5) does not require `allow-opts` to match packets containing IP options / IPv6 hop-by-hop headers) was also tested in the same position, and also does not match. 3. `pfctl -vvsr` shows the rule being evaluated (`Evaluations` counter increments) but never actually matched (`Packets: 0`). 4. The filter log entry for the blocked packet shows an empty `rulenr` and `rid`, indicating the packet is falling through to the implicit default deny without matching any user-defined rule at all — pass or block. Other MLDv2 reports on the same interface, identical in every respect except that they use a `fe80::...` link-local source instead of `::`, are correctly matched by the same rules and pass without issue. This isolates the problem specifically to the unspecified source address `::` in combination with the IPv6 Hop-by-Hop Options header (Router Alert) used by MLDv2. This traffic is generated by hosts on the segment sending MLDv2 Listener Reports during Duplicate Address Detection (RFC 4862), before a link-local address is available — a normal and expected part of IPv6 address configuration, not malicious or malformed traffic. ### Steps to reproduce 1. On an IPv6-enabled interface, observe a host performing address configuration (e.g. reboot a client, or bring up a new VLAN client). 2. Capture with: `tcpdump -ne -i pflog0 ip6 and dst ff02::16` 3. Observe blocked packets with source `::`, reason `ip-option`, alongside passed packets with `fe80::...` source, both using the same rule. 4. Attempt to explicitly permit or explicitly block source `::` traffic to `ff02::16` with a dedicated quick rule — the packet still bypasses the rule and hits the implicit block. ### Expected behavior A pass or block rule matching interface, protocol, source `::`, and destination `ff02::16` should be evaluated as matching, the same way it is for `fe80::...` source packets, regardless of the presence of an IPv6 Hop-by-Hop Options header. ### Actual behavior Packets with source `::` bypass all user-defined rules (pass and block alike) and fall through to the implicit default-deny, logged with an empty rule number and reason `ip-option`. ### Supporting data - `pfctl -vvsr` output showing the relevant rule with Evaluations > 0 but Packets: 0 - Filter log entry (JSON) showing `rid`/`rulenr` empty, `reason: ip-option`, `src: ::`, `dst: ff02::16` - tcpdump on pflog0 showing side-by-side pass (fe80::) vs block (::) for identical MLDv2 report traffic
1 条评论