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,