Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: pf(4) is still overly strict in filtering MLD messages
To:
Kristof Provost <kp@freebsd.org>
Cc:
tech@openbsd.org
Date:
Thu, 3 Sep 2026 11:40:33 +0200

Download raw body.

Thread
On Thu, Sep 03, 2026 at 10:07:08AM +0200, Kristof Provost wrote:
> Hi,
> 
> I???ve gotten a bug report from a FreeBSD user that pf filters valid MLD messages.
> Specifically, messages with an unspecified source address.
> RFC 3590 explains that this can happen when doing duplicate address detection, and should be allowed for MLD Report and Done messages.
> 
> Specifically paragraph 4 MLD Source Address Selection Guidelines:
> 
> > MLD Query messages MUST be sent with a valid link-local address as
> > the IPv6 source address.  If a node (router or host) receives a query
> > message with an IPv6 source address set to the unspecified address
> > (::), it MUST silently discard the message and SHOULD log a warning.
> 
> > MLD Report and Done messages are sent with a link-local address as
> > the IPv6 source address, if a valid address is available on the
> > interface.  If a valid link-local address is not available (e.g., one
> > has not been configured), the message is sent with the unspecified
> > address (::) as the IPv6 source address.
> 
> I propose the following:

OK bluhm@

> diff --git a/sys/net/pf.c b/sys/net/pf.c
> index 130843a03a1..5daa5c14249 100644
> --- a/sys/net/pf.c
> +++ b/sys/net/pf.c
> @@ -7974,9 +7974,17 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
>                                  * local source address.  If either one is
>                                  * missing then MLD message is invalid and
>                                  * should be discarded.
> +                                * RFC 3590 clarifies that during initial
> +                                * duplicate address detection nodes may not
> +                                * have an address, so are permitted to use
> +                                * the unspecified address, but only for Report
> +                                * and Done messages.
>                                  */
>                                 if ((h->ip6_hlim != 1) ||
> -                                   !IN6_IS_ADDR_LINKLOCAL(&h->ip6_src)) {
> +                                   (!IN6_IS_ADDR_LINKLOCAL(&h->ip6_src) &&
> +                                    icmp6.icmp6_type == MLD_LISTENER_QUERY) ||
> +                                   (!IN6_IS_ADDR_LINKLOCAL(&h->ip6_src) &&
> +                                   !IN6_IS_ADDR_UNSPECIFIED(&h->ip6_src))) {
>                                         DPFPRINTF(LOG_NOTICE, "Invalid MLD");
>                                         REASON_SET(reason, PFRES_IPOPTIONS);
>                                         return (PF_DROP);
> 
> (Patch against OpenBSD, but I???ve only tested it on FreeBSD.)
> 
> ???
> Kristof
> 
>