PF with IPv6

Paul Mather paul at
Sat May 1 14:37:44 UTC 2021

On Fri, 30 Apr 2021 21:20:48 -0700, Doug Hardie <bc979 at <mailto:bc979 at>> wrote:

> Message: 3
> Date: Fri, 30 Apr 2021 21:20:48 -0700
> From: Doug Hardie <bc979 at <mailto:bc979 at>>
> To: FreeBSD Questions <freebsd-questions at <mailto:freebsd-questions at>>
> Subject: PF with IPv6
> Message-ID: <2CD4806C-F1A4-4DDE-8C2F-2B0A08EA2A18 at <mailto:2CD4806C-F1A4-4DDE-8C2F-2B0A08EA2A18 at>>
> Content-Type: text/plain;	charset=us-ascii
> FreeBSD 13-RELEASE.  I have a small test network setup and tried to block all IPv6 except those addressed to a specific address.  /etc/pf.conf contained:
> ext_if = "bge0"
> LAN3 = "2001:1000:0:3000::/64"
> pass in quick log on $ext_if proto ipv6 from $LAN3 to $LAN3
> block in log on $ext_if proto ipv6 from any to any
> Nothing got blocked.  pftop showed all zeros for both rules.  I then added at the end:
> pass in quick log on $ext_if proto icmp6 from $LAN3 to $LAN3
> block in log on $ext_if proto icmp6 from any to any
> A lot of stuff got blocked.  The log shows many entries like:
> 15:59:41.597632 rule 3/0(match): block in on bge0: (hlim 1, next-header Options (0) payload length: 32) fe80::120c:6bff:fe5d:4404 > ff02::1: HBH (rtalert: 0x0000) (pad1)(pad1) ICMP6, multicast listener query
> 	0x0000:  6000 0000 0020 0001 fe80 0000 0000 0000  `...............
> 	0x0010:  120c 6bff fe5d 4404 ff02 0000 0000 0000  ..k..]D.........
> 	0x0020:  0000 0000 0000 0001 3a00 0502 0000 0000  ........:.......
> 	0x0030:  8200 98aa                                ....
> Rule 3 is the block for ICMP6, but those are clearly IP6 packets that should have been blocked by rule 1. Is there a problem with IPv6 and pf?

It's not clear to me precisely what you are trying to achieve.  The "proto" keyword in PF rules refers to protocols in /etc/protocols.  Your rules appear to be targeting the specific case of filtering IPv6 encapsulated in IPv4.  I don't believe that is what you intend.

The more standard way in PF to block IPv6 vs IPv4 traffic is to use "inet" (IPv4) or "inet6" (IPv6) to target IPv4 or IPv6 packets.

Note, the last rule you added that you say did start blocking things is more typical of rules to block ICMP6.  Because you omit "inet" or "inet6" on the rule it will be applied to both IPv4 and IPv6 packets.  But, the "proto icmp6" part is specifically targeting ICMP6.

So, to summarise, use "inet" and "inet6" to select IPv4 and IPv6 and "proto" to select the protocol you want to target (e.g., "tcp", "udp", "icmp", "icmp6", etc.).  E.g., "pass in log quick on $ext_if inet6 from ..." to allow all IPv6 for the rule, or ""pass in log quick on $ext_if inet6 proto tcp from ..." to allow only IPv6 TCP traffic, etc.



More information about the freebsd-questions mailing list