Hi,

IGMP and ICMP6 for multicast packets have router alert options.
Per default pf drops all IP packets with options.  Usually people
ask what is wrong until someone points out that they have to use a
pf rule with allow-opts.

As this is normal behavior and our kernel generates such packets,
the pf default is bad.

Diff is untested, but otto@ and florian@ could try it.

Currently it allows all options.  Should I make it specific to
router alert with IGMP or ICMP6?

bluhm

Index: net/pf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
retrieving revision 1.1126
diff -u -p -r1.1126 pf.c
--- net/pf.c    17 Mar 2022 18:27:55 -0000      1.1126
+++ net/pf.c    21 Apr 2022 16:30:18 -0000
@@ -6398,6 +6398,9 @@ pf_walk_header(struct pf_pdesc *pd, stru
        end = pd->off + ntohs(h->ip_len);
        pd->off += hlen;
        pd->proto = h->ip_p;
+       /* IGMP packets have router alert options, allow them */
+       if (pd->proto == IPPROTO_IGMP)
+               pd->badopts = 0;
        /* stop walking over non initial fragments */
        if ((h->ip_off & htons(IP_OFFMASK)) != 0)
                return (PF_PASS);
@@ -6494,6 +6497,7 @@ pf_walk_header6(struct pf_pdesc *pd, str
 {
        struct ip6_frag          frag;
        struct ip6_ext           ext;
+       struct icmp6_hdr         icmp6;
        struct ip6_rthdr         rthdr;
        u_int32_t                end;
        int                      hdr_cnt, fraghdr_cnt = 0, rthdr_cnt = 0;
@@ -6607,9 +6611,23 @@ pf_walk_header6(struct pf_pdesc *pd, str
                                pd->off += (ext.ip6e_len + 1) * 8;
                        pd->proto = ext.ip6e_nxt;
                        break;
+               case IPPROTO_ICMPV6:
+                       if (!pf_pull_hdr(pd->m, pd->off, &icmp6, sizeof(icmp6),
+                           NULL, reason, AF_INET6)) {
+                               DPFPRINTF(LOG_NOTICE, "IPv6 short icmp6hdr");
+                               return (PF_DROP);
+                       }
+                       /* ICMP multicast packets have router alert options */
+                       switch (icmp6.icmp6_type) {
+                       case MLD_LISTENER_QUERY:
+                       case MLD_LISTENER_REPORT:
+                       case MLD_LISTENER_DONE:
+                               pd->badopts = 0;
+                               break;
+                       }
+                       /* FALLTHROUGH */
                case IPPROTO_TCP:
                case IPPROTO_UDP:
-               case IPPROTO_ICMPV6:
                        /* fragments may be short, ignore inner header then */
                        if (pd->fragoff != 0 && end < pd->off +
                            (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) :

Reply via email to