pfctl should not infer the af-to behavior from the af/naf
difference.  instead, we should be clear that this is an
af-to rule.  essentially this diff converts FOM_AFTO marker
into a rule flag PFRULE_AFTO so that we don't rely on
ambiguous checks (like r->af != r->naf) when setting things up.

also, naf should be figured out in the collapse_redirspec
by looking at the "filter_opts.nat.af" which is the only
deterministic value here.

the diff also reduces the difference between pre-nat64 version
and the in-tree version.

ok?

so far i've got a positive review from claudio.  bringing
this out so that it doesn't rot away.

Index: sys/net/pf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/pf.c,v
retrieving revision 1.787
diff -u -p -u -p -r1.787 pf.c
--- sys/net/pf.c        26 Nov 2011 03:28:46 -0000      1.787
+++ sys/net/pf.c        28 Nov 2011 13:06:15 -0000
@@ -3366,7 +3366,7 @@ pf_test_rule(struct pf_pdesc *pd, struct
                                /* order is irrelevant */
                                SLIST_INSERT_HEAD(&rules, ri, entry);
                                pf_rule_to_actions(r, &act);
-                               if (r->naf)
+                               if (r->rule_flag & PFRULE_AFTO)
                                        pd->naf = r->naf;
                                if (pf_get_transaddr(r, pd, sns, &nr) == -1) {
                                        REASON_SET(&reason, PFRES_MEMORY);
@@ -3401,7 +3401,7 @@ pf_test_rule(struct pf_pdesc *pd, struct
 
        /* apply actions for last matching pass/block rule */
        pf_rule_to_actions(r, &act);
-       if (r->naf)
+       if (r->rule_flag & PFRULE_AFTO)
                pd->naf = r->naf;
        if (pf_get_transaddr(r, pd, sns, &nr) == -1) {
                REASON_SET(&reason, PFRES_MEMORY);
Index: sys/net/pf_ioctl.c
===================================================================
RCS file: /home/ncvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.245
diff -u -p -u -p -r1.245 pf_ioctl.c
--- sys/net/pf_ioctl.c  25 Nov 2011 12:52:10 -0000      1.245
+++ sys/net/pf_ioctl.c  28 Nov 2011 13:06:15 -0000
@@ -2520,8 +2520,6 @@ pf_rule_copyin(struct pf_rule *from, str
        pf_pool_copyin(&from->rdr, &to->rdr);
        pf_pool_copyin(&from->route, &to->route);
 
-       to->naf = from->naf;
-
        if (pf_kif_setup(to->ifname, &to->kif))
                return (EINVAL);
        if (pf_kif_setup(to->rcv_ifname, &to->rcv_kif))
@@ -2604,6 +2602,7 @@ pf_rule_copyin(struct pf_rule *from, str
        to->match_tag_not = from->match_tag_not;
        to->keep_state = from->keep_state;
        to->af = from->af;
+       to->naf = from->naf;
        to->proto = from->proto;
        to->type = from->type;
        to->code = from->code;
Index: sys/net/pfvar.h
===================================================================
RCS file: /home/ncvs/src/sys/net/pfvar.h,v
retrieving revision 1.355
diff -u -p -u -p -r1.355 pfvar.h
--- sys/net/pfvar.h     26 Nov 2011 03:28:46 -0000      1.355
+++ sys/net/pfvar.h     28 Nov 2011 13:06:15 -0000
@@ -674,6 +674,7 @@ struct pf_rule {
 #define PFRULE_STATESLOPPY     0x00020000      /* sloppy state tracking */
 #define PFRULE_PFLOW           0x00040000
 #define PFRULE_ONCE            0x00100000      /* one shot rule */
+#define PFRULE_AFTO            0x00200000      /* af-to rule */
 
 #define PFSTATE_HIWAT          10000   /* default state table size */
 #define PFSTATE_ADAPT_START    6000    /* default adaptive timeout start */
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /home/ncvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.610
diff -u -p -u -p -r1.610 parse.y
--- sbin/pfctl/parse.y  13 Oct 2011 18:30:54 -0000      1.610
+++ sbin/pfctl/parse.y  28 Nov 2011 13:06:15 -0000
@@ -899,7 +899,6 @@ anchorrule  : ANCHOR anchorname dir quick
 
                        decide_address_family($8.src.host, &r.af);
                        decide_address_family($8.dst.host, &r.af);
-                       r.naf = r.af;
 
                        expand_rule(&r, 0, $5, NULL, NULL, NULL, $7, $8.src_os,
                            $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
@@ -1729,6 +1728,7 @@ pfrule            : action dir logquick interface 
                                            "translation");
                                        YYERROR;
                                }
+                               r.rule_flag |= PFRULE_AFTO;
                        }
                        r.af = $5;
 
@@ -2015,7 +2015,6 @@ pfrule            : action dir logquick interface 
 
                        decide_address_family($7.src.host, &r.af);
                        decide_address_family($7.dst.host, &r.af);
-                       r.naf = r.af;
 
                        if ($8.route.rt) {
                                if (!r.direction) {
@@ -4197,7 +4196,7 @@ rule_consistent(struct pf_rule *r, int a
                           "must not be used on match rules");
                        problems++;
                }
-               if (r->nat.addr.type != PF_ADDR_NONE && r->naf != r->af) {
+               if (r->rule_flag & PFRULE_AFTO) {
                        yyerror("af-to is not supported on match rules");
                        problems++;
                }
@@ -4700,21 +4699,22 @@ collapse_redirspec(struct pf_pool *rpool
        struct pf_rule_addr ra;
        int     i = 0;
 
-       if (rs && rs->af)
-               r->naf = rs->af;
-
        if (!rs || !rs->rdr || rs->rdr->host == NULL) {
                rpool->addr.type = PF_ADDR_NONE;
                return (0);
        }
 
+       if (r->rule_flag & PFRULE_AFTO)
+               r->naf = rs->af;
+
        /* count matching addresses */
        for (h = rs->rdr->host; h != NULL; h = h->next) {
                if (!r->af || !h->af || rs->af || h->af == r->af) {
                        i++;
                        if (h->af && !r->af)
                                r->af = h->af;
-               }
+               } else if (r->naf && h->af == r->naf)
+                       i++;
        }
 
        if (i == 0) {           /* no pool address */
@@ -4723,7 +4723,8 @@ collapse_redirspec(struct pf_pool *rpool
                return (1);
        } else if (i == 1) {    /* only one address */
                for (h = rs->rdr->host; h != NULL; h = h->next)
-                       if (!h->af || !r->af || rs->af || r->af == h->af)
+                       if (!h->af || !r->af || rs->af || r->af == h->af ||
+                           (r->naf && r->naf == h->af))
                                break;
                rpool->addr = h->addr;
                if (!allow_if && h->ifname) {
@@ -4892,7 +4893,7 @@ expand_rule(struct pf_rule *r, int keepr
        LOOP_THROUGH(struct node_uid, uid, uids,
        LOOP_THROUGH(struct node_gid, gid, gids,
 
-               r->af = af;
+               r->af = r->naf = af;
 
                error += collapse_redirspec(&r->rdr, r, rdr, 0);
                error += collapse_redirspec(&r->nat, r, nat, 0);
Index: sbin/pfctl/pfctl_parser.c
===================================================================
RCS file: /home/ncvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.283
diff -u -p -u -p -r1.283 pfctl_parser.c
--- sbin/pfctl/pfctl_parser.c   23 Nov 2011 10:24:37 -0000      1.283
+++ sbin/pfctl/pfctl_parser.c   28 Nov 2011 13:06:15 -0000
@@ -1058,7 +1058,7 @@ print_rule(struct pf_rule *r, const char
                printf(" divert-packet port %u", ntohs(r->divert_packet.port));
 
        if (!anchor_call[0] && r->nat.addr.type != PF_ADDR_NONE &&
-           r->naf != r->af) {
+           r->rule_flag & PFRULE_AFTO) {
                printf(" af-to %s from ", r->naf == AF_INET ? "inet" : "inet6");
                print_pool(&r->nat, r->nat.proxy_port[0],
                    r->nat.proxy_port[1], r->naf ? r->naf : r->af,

Reply via email to