untrusted comment: signature from openbsd 5.6 base private key
RWR0EANmo9nqhiT16rKFHRYbuSpK1vdiNmGBgywhcRvG8QJELUKpjap89kh8i2BHuX2w2GtE4hnAukUcSOUaHHAg743QKHqdGgc=

OpenBSD 5.6 errata 7, Nov 17, 2014:  A PF rule using an IPv4 address
followed by an IPv6 address and then a dynamic address, e.g. "pass
from {192.0.2.1 2001:db8::1} to (pppoe0)", will have an incorrect /32
mask applied to the dynamic address.

This is the 2nd version of this patch.

Apply patch using:

   signify -Vep /etc/signify/openbsd-56-base.pub -x 007_pfctl.patch.sig \
       -m - | (cd /usr/src && patch -p0)

Then build and install pfctl:
   cd /usr/src/sbin/pfctl
   make obj
   make
   make install

Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.636
retrieving revision 1.636.4.1
diff -u -p -r1.636 -r1.636.4.1
--- sbin/pfctl/parse.y  2 Jul 2014 13:03:41 -0000       1.636
+++ sbin/pfctl/parse.y  29 Oct 2014 15:29:33 -0000      1.636.4.1
@@ -4516,7 +4516,7 @@ expand_rule(struct pf_rule *r, int keepr
       char                     tagname[PF_TAG_NAME_SIZE];
       char                     match_tagname[PF_TAG_NAME_SIZE];
       u_int8_t                 flags, flagset, keep_state;
-       struct node_host        *srch, *dsth;
+       struct node_host        *srch, *dsth, *osrch, *odsth;
       struct redirspec         binat;
       struct pf_rule           rb;
       int                      dir = r->direction;
@@ -4607,6 +4607,18 @@ expand_rule(struct pf_rule *r, int keepr
                   r->af, src_host, src_port, dst_host, dst_port,
                   proto->proto);

+               osrch = odsth = NULL;
+               if (src_host->addr.type == PF_ADDR_DYNIFTL) {
+                       osrch = src_host;
+                       if ((src_host = gen_dynnode(src_host, r->af)) == NULL)
+                               err(1, "expand_rule: calloc");
+               }
+               if (dst_host->addr.type == PF_ADDR_DYNIFTL) {
+                       odsth = dst_host;
+                       if ((dst_host = gen_dynnode(dst_host, r->af)) == NULL)
+                               err(1, "expand_rule: calloc");
+               }
+
               error += check_netmask(src_host, r->af);
               error += check_netmask(dst_host, r->af);

@@ -4757,6 +4769,14 @@ expand_rule(struct pf_rule *r, int keepr
                           uid, gid, rcv, icmp_type, anchor_call);
               }

+               if (osrch && src_host->addr.type == PF_ADDR_DYNIFTL) {
+                       free(src_host);
+                       src_host = osrch;
+               }
+               if (odsth && dst_host->addr.type == PF_ADDR_DYNIFTL) {
+                       free(dst_host);
+                       dst_host = odsth;
+               }
       ))))))))));

       if (!keeprule) {
Index: sbin/pfctl/pfctl_parser.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.298
retrieving revision 1.298.6.1
diff -u -p -r1.298 -r1.298.6.1
--- sbin/pfctl/pfctl_parser.c   20 Jan 2014 02:59:13 -0000      1.298
+++ sbin/pfctl/pfctl_parser.c   29 Oct 2014 15:29:34 -0000      1.298.6.1
@@ -1244,16 +1244,12 @@ int
check_netmask(struct node_host *h, sa_family_t af)
{
       struct node_host        *n = NULL;
-       struct pf_addr  *m;
+       struct pf_addr          *m;

       for (n = h; n != NULL; n = n->next) {
               if (h->addr.type == PF_ADDR_TABLE)
                       continue;
               m = &h->addr.v.a.mask;
-               /* fix up netmask for dynaddr */
-               if (af == AF_INET && h->addr.type == PF_ADDR_DYNIFTL &&
-                   unmask(m, AF_INET6) > 32)
-                       set_ipmask(n, 32);
               /* netmasks > 32 bit are invalid on v4 */
               if (af == AF_INET &&
                   (m->addr32[1] || m->addr32[2] || m->addr32[3])) {
@@ -1263,6 +1259,30 @@ check_netmask(struct node_host *h, sa_fa
               }
       }
       return (0);
+}
+
+struct node_host *
+gen_dynnode(struct node_host *h, sa_family_t af)
+{
+       struct node_host        *n;
+       struct pf_addr          *m;
+
+       if (h->addr.type != PF_ADDR_DYNIFTL)
+               return (NULL);
+
+       if ((n = calloc(1, sizeof(*n))) == NULL)
+               return (NULL);
+       bcopy(h, n, sizeof(*n));
+       n->ifname = NULL;
+       n->next = NULL;
+       n->tail = NULL;
+
+       /* fix up netmask */
+       m = &n->addr.v.a.mask;
+       if (af == AF_INET && unmask(m, AF_INET6) > 32)
+               set_ipmask(n, 32);
+
+       return (n);
}

/* interface lookup routines */
Index: sbin/pfctl/pfctl_parser.h
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.h,v
retrieving revision 1.102
retrieving revision 1.102.4.1
diff -u -p -r1.102 -r1.102.4.1
--- sbin/pfctl/pfctl_parser.h   19 Apr 2014 14:22:32 -0000      1.102
+++ sbin/pfctl/pfctl_parser.h   29 Oct 2014 15:29:34 -0000      1.102.4.1
@@ -265,6 +265,7 @@ extern const struct pf_timeout pf_timeou
void                    set_ipmask(struct node_host *, u_int8_t);
int                     check_netmask(struct node_host *, sa_family_t);
int                     unmask(struct pf_addr *, sa_family_t);
+struct node_host       *gen_dynnode(struct node_host *, sa_family_t);
void                    ifa_load(void);
unsigned int            ifa_nametoindex(const char *);
char                   *ifa_indextoname(unsigned int, char *);