Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111345416
D47790.id147049.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D47790.id147049.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -256,6 +256,7 @@
uint8_t flush;
uint8_t prio;
uint8_t set_prio[2];
+ sa_family_t naf;
struct {
struct pf_addr addr;
@@ -407,6 +408,7 @@
uint32_t states;
uint32_t conn;
sa_family_t af;
+ sa_family_t naf;
uint8_t ruletype;
uint64_t creation;
uint64_t expire;
@@ -528,9 +530,10 @@
int pfctl_begin_addrs(struct pfctl_handle *h, uint32_t *ticket);
int pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int which);
int pfctl_get_addrs(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
- uint8_t r_action, const char *anchor, uint32_t *nr);
+ uint8_t r_action, const char *anchor, uint32_t *nr, int which);
int pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
- uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa);
+ uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa,
+ int which);
int pfctl_get_rulesets(struct pfctl_handle *h, const char *path, uint32_t *nr);
int pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct pfioc_ruleset *rs);
typedef int (*pfctl_get_srcnode_fn)(struct pfctl_src_node*, void *);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1285,6 +1285,7 @@
snl_add_msg_attr_u8(nw, PF_RT_PRIO, r->prio);
snl_add_msg_attr_u8(nw, PF_RT_SET_PRIO, r->set_prio[0]);
snl_add_msg_attr_u8(nw, PF_RT_SET_PRIO_REPLY, r->set_prio[1]);
+ snl_add_msg_attr_u8(nw, PF_RT_NAF, r->naf);
snl_add_msg_attr_ip6(nw, PF_RT_DIVERT_ADDRESS, &r->divert.addr.v6);
snl_add_msg_attr_u16(nw, PF_RT_DIVERT_PORT, r->divert.port);
@@ -1662,6 +1663,7 @@
{ .type = PF_RT_RCV_IFNAME, .off = _OUT(r.rcv_ifname), .arg = (void*)IFNAMSIZ, .cb = snl_attr_copy_string },
{ .type = PF_RT_MAX_SRC_CONN, .off = _OUT(r.max_src_conn), .cb = snl_attr_get_uint32 },
{ .type = PF_RT_NAT, .off = _OUT(r.nat), .arg = &pool_parser, .cb = snl_attr_get_nested },
+ { .type = PF_RT_NAF, .off = _OUT(r.naf), .cb = snl_attr_get_uint8 },
};
static struct snl_field_parser fp_getrule[] = {};
#undef _OUT
@@ -2770,7 +2772,7 @@
}
int
-pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int which __unused)
+pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int which)
{
struct snl_writer nw;
struct snl_errmsg_data e = {};
@@ -2794,6 +2796,7 @@
snl_add_msg_attr_u8(&nw, PF_AA_AF, pa->af);
snl_add_msg_attr_string(&nw, PF_AA_ANCHOR, pa->anchor);
snl_add_msg_attr_pool_addr(&nw, PF_AA_ADDR, &pa->addr);
+ snl_add_msg_attr_u32(&nw, PF_AA_WHICH, which);
if ((hdr = snl_finalize_msg(&nw)) == NULL)
return (ENXIO);
@@ -2817,7 +2820,7 @@
int
pfctl_get_addrs(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
- uint8_t r_action, const char *anchor, uint32_t *nr)
+ uint8_t r_action, const char *anchor, uint32_t *nr, int which)
{
struct snl_writer nw;
struct snl_errmsg_data e = {};
@@ -2836,6 +2839,7 @@
snl_add_msg_attr_u32(&nw, PF_AA_R_NUM, r_num);
snl_add_msg_attr_u8(&nw, PF_AA_R_ACTION, r_action);
snl_add_msg_attr_string(&nw, PF_AA_ANCHOR, anchor);
+ snl_add_msg_attr_u32(&nw, PF_AA_WHICH, which);
if ((hdr = snl_finalize_msg(&nw)) == NULL)
return (ENXIO);
@@ -2879,7 +2883,8 @@
int
pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
- uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa)
+ uint8_t r_action, const char *anchor, uint32_t nr, struct pfioc_pooladdr *pa,
+ int which)
{
struct snl_writer nw;
struct snl_errmsg_data e = {};
@@ -2899,6 +2904,7 @@
snl_add_msg_attr_u8(&nw, PF_AA_R_ACTION, r_action);
snl_add_msg_attr_string(&nw, PF_AA_ANCHOR, anchor);
snl_add_msg_attr_u32(&nw, PF_AA_NR, nr);
+ snl_add_msg_attr_u32(&nw, PF_AA_WHICH, which);
if ((hdr = snl_finalize_msg(&nw)) == NULL)
return (ENXIO);
@@ -3023,6 +3029,7 @@
{ .type = PF_SN_CREATION, .off = _OUT(creation), .cb = snl_attr_get_uint64 },
{ .type = PF_SN_EXPIRE, .off = _OUT(expire), .cb = snl_attr_get_uint64 },
{ .type = PF_SN_CONNECTION_RATE, .off = _OUT(conn_rate), .arg = &pfctl_threshold_parser, .cb = snl_attr_get_nested },
+ { .type = PF_SN_NAF, .off = _OUT(naf), .cb = snl_attr_get_uint8 },
};
static struct snl_field_parser fp_srcnode[] = {};
#undef _OUT
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -222,6 +222,34 @@
char *pqname;
};
+struct range {
+ int a;
+ int b;
+ int t;
+};
+struct redirection {
+ struct node_host *host;
+ struct range rport;
+};
+
+static struct pool_opts {
+ int marker;
+#define POM_TYPE 0x01
+#define POM_STICKYADDRESS 0x02
+#define POM_ENDPI 0x04
+ u_int8_t opts;
+ int type;
+ int staticport;
+ struct pf_poolhashkey *key;
+ struct pf_mape_portset mape;
+} pool_opts;
+
+struct redirspec {
+ struct redirection *rdr;
+ struct pool_opts pool_opts;
+ int af;
+};
+
static struct filter_opts {
int marker;
#define FOM_FLAGS 0x0001
@@ -231,7 +259,7 @@
#define FOM_SRCTRACK 0x0010
#define FOM_MINTTL 0x0020
#define FOM_MAXMSS 0x0040
-#define FOM_AFTO 0x0080 /* not yet implemmented */
+#define FOM_AFTO 0x0080
#define FOM_SETTOS 0x0100
#define FOM_SCRUB_TCP 0x0200
#define FOM_SETPRIO 0x0400
@@ -274,6 +302,8 @@
struct node_host *addr;
u_int16_t port;
} divert;
+ struct redirspec nat;
+ struct redirspec rdr;
/* new-style scrub opts */
int nodf;
int minttl;
@@ -323,19 +353,6 @@
struct node_tinithead init_nodes;
} table_opts;
-static struct pool_opts {
- int marker;
-#define POM_TYPE 0x01
-#define POM_STICKYADDRESS 0x02
-#define POM_ENDPI 0x04
- u_int8_t opts;
- int type;
- int staticport;
- struct pf_poolhashkey *key;
- struct pf_mape_portset mape;
-
-} pool_opts;
-
static struct codel_opts codel_opts;
static struct node_hfsc_opts hfsc_opts;
static struct node_fairq_opts fairq_opts;
@@ -365,6 +382,7 @@
struct node_host *, struct node_host *, const char *,
const char *);
void expand_rule(struct pfctl_rule *, struct node_if *,
+ struct node_host *,
struct node_host *, struct node_proto *, struct node_os *,
struct node_host *, struct node_port *, struct node_host *,
struct node_port *, struct node_uid *, struct node_gid *,
@@ -417,11 +435,7 @@
u_int16_t w;
u_int16_t w2;
} b;
- struct range {
- int a;
- int b;
- int t;
- } range;
+ struct range range;
struct node_if *interface;
struct node_proto *proto;
struct node_etherproto *etherproto;
@@ -453,10 +467,7 @@
sa_family_t af;
struct pf_poolhashkey *key;
} route;
- struct redirection {
- struct node_host *host;
- struct range rport;
- } *redirection;
+ struct redirection *redirection;
struct {
int action;
struct node_state_opt *options;
@@ -517,7 +528,7 @@
%token STICKYADDRESS ENDPI MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
-%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE
+%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE AFTO
%token <v.string> STRING
%token <v.number> NUMBER
%token <v.i> PORTBINARY
@@ -1071,8 +1082,9 @@
decide_address_family($8.src.host, &r.af);
decide_address_family($8.dst.host, &r.af);
+ r.naf = r.af;
- expand_rule(&r, $5, NULL, $7, $8.src_os,
+ expand_rule(&r, $5, NULL, NULL, $7, $8.src_os,
$8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
$9.uid, $9.gid, $9.rcv, $9.icmpspec,
pf->astack[pf->asd + 1] ? pf->alast->name : $2);
@@ -1095,7 +1107,7 @@
decide_address_family($6.src.host, &r.af);
decide_address_family($6.dst.host, &r.af);
- expand_rule(&r, $3, NULL, $5, $6.src_os,
+ expand_rule(&r, $3, NULL, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
0, 0, 0, 0, $2);
free($2);
@@ -1137,7 +1149,7 @@
r.dst.port_op = $6.dst.port->op;
}
- expand_rule(&r, $3, NULL, $5, $6.src_os,
+ expand_rule(&r, $3, NULL, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
0, 0, 0, 0, $2);
free($2);
@@ -1460,7 +1472,7 @@
r.match_tag_not = $8.match_tag_not;
r.rtableid = $8.rtableid;
- expand_rule(&r, $4, NULL, $6, $7.src_os,
+ expand_rule(&r, $4, NULL, NULL, $6, $7.src_os,
$7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
NULL, NULL, NULL, NULL, "");
}
@@ -1625,7 +1637,7 @@
}
if (h != NULL)
- expand_rule(&r, j, NULL, NULL, NULL, h,
+ expand_rule(&r, j, NULL, NULL, NULL, NULL, h,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, "");
@@ -1647,7 +1659,7 @@
else
h = ifa_lookup(i->ifname, 0);
if (h != NULL)
- expand_rule(&r, NULL, NULL,
+ expand_rule(&r, NULL, NULL, NULL,
NULL, NULL, h, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, "");
} else
@@ -2414,6 +2426,19 @@
r.scrub_flags |= PFSTATE_SETPRIO;
}
+ if ($9.marker & FOM_AFTO) {
+ if (!$6) {
+ yyerror("must indicate source address "
+ "family with af-to");
+ YYERROR;
+ }
+ if ($6 == $9.nat.af) {
+ yyerror("incorrect address family "
+ "translation");
+ YYERROR;
+ }
+ }
+
r.af = $6;
if ($9.tag)
if (strlcpy(r.tagname, $9.tag,
@@ -2699,6 +2724,7 @@
decide_address_family($8.src.host, &r.af);
decide_address_family($8.dst.host, &r.af);
+ r.naf = r.af;
if ($5.rt) {
if (!r.direction) {
@@ -2801,9 +2827,12 @@
r.free_flags |= PFRULE_DN_IS_QUEUE;
}
- expand_rule(&r, $4, $5.host, $7, $8.src_os,
- $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
- $9.uid, $9.gid, $9.rcv, $9.icmpspec, "");
+ if ($9.marker & FOM_AFTO)
+ r.naf = $9.nat.af;
+
+ expand_rule(&r, $4, $5.host, $9.nat.rdr ? $9.nat.rdr->host : NULL,
+ $7, $8.src_os, $8.src.host, $8.src.port, $8.dst.host,
+ $8.dst.port, $9.uid, $9.gid, $9.rcv, $9.icmpspec, "");
}
;
@@ -3017,6 +3046,64 @@
filter_opts.marker |= FOM_SCRUB_TCP;
filter_opts.marker |= $3.marker;
}
+ | AFTO af FROM redirspec pool_opts {
+ if (filter_opts.nat.rdr) {
+ yyerror("cannot respecify af-to");
+ YYERROR;
+ }
+ if ($2 == 0) {
+ yyerror("no address family specified");
+ YYERROR;
+ }
+ if ($4->af && $4->af != $2) {
+ yyerror("af-to addresses must be in the "
+ "target address family");
+ YYERROR;
+ }
+ filter_opts.nat.af = $2;
+ filter_opts.nat.rdr = calloc(1, sizeof(struct redirection));
+ if (filter_opts.nat.rdr == NULL)
+ err(1, "af-to: calloc");
+ filter_opts.nat.rdr->host = $4;
+ memcpy(&filter_opts.nat.pool_opts, &$5,
+ sizeof(filter_opts.nat.pool_opts));
+ filter_opts.rdr.rdr =
+ calloc(1, sizeof(struct redirection));
+ bzero(&filter_opts.rdr.pool_opts,
+ sizeof(filter_opts.rdr.pool_opts));
+ filter_opts.marker |= FOM_AFTO;
+ }
+ | AFTO af FROM redirspec pool_opts TO redirspec pool_opts {
+ if (filter_opts.nat.rdr) {
+ yyerror("cannot respecify af-to");
+ YYERROR;
+ }
+ if ($2 == 0) {
+ yyerror("no address family specified");
+ YYERROR;
+ }
+ if (($4->af && $4->af != $2) ||
+ ($7->af && $7->af != $2)) {
+ yyerror("af-to addresses must be in the "
+ "target address family");
+ YYERROR;
+ }
+ filter_opts.nat.af = $2;
+ filter_opts.nat.rdr = calloc(1, sizeof(struct redirection));
+ if (filter_opts.nat.rdr == NULL)
+ err(1, "af-to: calloc");
+ filter_opts.nat.rdr->host = $4;
+ memcpy(&filter_opts.nat.pool_opts, &$5,
+ sizeof(filter_opts.nat.pool_opts));
+ filter_opts.rdr.af = $2;
+ filter_opts.rdr.rdr = calloc(1, sizeof(struct redirection));
+ if (filter_opts.rdr.rdr == NULL)
+ err(1, "af-to: calloc");
+ filter_opts.rdr.rdr->host = $7;
+ memcpy(&filter_opts.nat.pool_opts, &$8,
+ sizeof(filter_opts.nat.pool_opts));
+ filter_opts.marker |= FOM_AFTO;
+ }
| filter_sets
;
@@ -4891,7 +4978,7 @@
o = o->next;
}
- expand_rule(&r, $2, $9 == NULL ? NULL : $9->host, $4,
+ expand_rule(&r, $2, $9 == NULL ? NULL : $9->host, NULL, $4,
$5.src_os, $5.src.host, $5.src.port, $5.dst.host,
$5.dst.port, 0, 0, 0, 0, "");
free($9);
@@ -5407,6 +5494,10 @@
"must not be used on match rules");
problems++;
}
+ if (r->naf != r->af) {
+ yyerror("af-to is not supported on match rules");
+ problems++;
+ }
}
if (r->rpool.opts & PF_POOL_STICKYADDR && !r->keep_state) {
yyerror("'sticky-address' requires 'keep state'");
@@ -6041,7 +6132,8 @@
void
expand_rule(struct pfctl_rule *r,
- struct node_if *interfaces, struct node_host *rpool_hosts,
+ struct node_if *interfaces, struct node_host *rdr_hosts,
+ struct node_host *nat_hosts,
struct node_proto *protos, struct node_os *src_oses,
struct node_host *src_hosts, struct node_port *src_ports,
struct node_host *dst_hosts, struct node_port *dst_ports,
@@ -6186,8 +6278,8 @@
r->os_fingerprint = PF_OSFP_ANY;
}
- TAILQ_INIT(&r->rpool.list);
- for (h = rpool_hosts; h != NULL; h = h->next) {
+ TAILQ_INIT(&r->rdr.list);
+ for (h = rdr_hosts; h != NULL; h = h->next) {
pa = calloc(1, sizeof(struct pf_pooladdr));
if (pa == NULL)
err(1, "expand_rule: calloc");
@@ -6201,6 +6293,24 @@
pa->ifname[0] = 0;
TAILQ_INSERT_TAIL(&r->rpool.list, pa, entries);
}
+ TAILQ_INIT(&r->nat.list);
+ for (h = nat_hosts; h != NULL; h = h->next) {
+ pa = calloc(1, sizeof(struct pf_pooladdr));
+ if (pa == NULL)
+ err(1, "expand_rule: calloc");
+ pa->addr = h->addr;
+ if (h->ifname != NULL) {
+ if (strlcpy(pa->ifname, h->ifname,
+ sizeof(pa->ifname)) >=
+ sizeof(pa->ifname))
+ errx(1, "expand_rule: strlcpy");
+ } else
+ pa->ifname[0] = 0;
+ TAILQ_INSERT_TAIL(&r->nat.list, pa, entries);
+ }
+
+ r->nat.proxy_port[0] = PF_NAT_PROXY_PORT_LOW;
+ r->nat.proxy_port[1] = PF_NAT_PROXY_PORT_HIGH;
if (rule_consistent(r, anchor_call[0]) < 0 || error)
yyerror("skipping rule due to errors");
@@ -6231,7 +6341,8 @@
FREE_LIST(struct node_uid, uids);
FREE_LIST(struct node_gid, gids);
FREE_LIST(struct node_icmp, icmp_types);
- FREE_LIST(struct node_host, rpool_hosts);
+ FREE_LIST(struct node_host, rdr_hosts);
+ FREE_LIST(struct node_host, nat_hosts);
if (!added)
yyerror("rule expands to no valid combination");
@@ -6305,6 +6416,7 @@
{
/* this has to be sorted always */
static const struct keywords keywords[] = {
+ { "af-to", AFTO},
{ "all", ALL},
{ "allow-opts", ALLOWOPTS},
{ "altq", ALTQ},
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -243,6 +243,8 @@
int min, sec;
sa_family_t af;
uint8_t proto;
+ int afto = (s->key[PF_SK_STACK].af != s->key[PF_SK_WIRE].af);
+ int idx;
#ifndef __NO_STRICT_ALIGNMENT
struct pfctl_state_key aligned_key[2];
@@ -276,22 +278,26 @@
else
printf("%u ", proto);
- print_host(&nk->addr[1], nk->port[1], af, opts);
- if (PF_ANEQ(&nk->addr[1], &sk->addr[1], af) ||
+ print_host(&nk->addr[1], nk->port[1], nk->af, opts);
+ if (nk->af != sk->af || PF_ANEQ(&nk->addr[1], &sk->addr[1], nk->af) ||
nk->port[1] != sk->port[1]) {
+ idx = afto ? 0 : 1;
printf(" (");
- print_host(&sk->addr[1], sk->port[1], af, opts);
+ print_host(&sk->addr[idx], sk->port[idx], sk->af,
+ opts);
printf(")");
}
- if (s->direction == PF_OUT)
+ if (s->direction == PF_OUT || (afto && s->direction == PF_IN))
printf(" -> ");
else
printf(" <- ");
- print_host(&nk->addr[0], nk->port[0], af, opts);
- if (PF_ANEQ(&nk->addr[0], &sk->addr[0], af) ||
+ print_host(&nk->addr[0], nk->port[0], nk->af, opts);
+ if (nk->af != sk->af || PF_ANEQ(&nk->addr[0], &sk->addr[0], nk->af) ||
nk->port[0] != sk->port[0]) {
+ idx = afto ? 1 : 0;
printf(" (");
- print_host(&sk->addr[0], sk->port[0], af, opts);
+ print_host(&sk->addr[idx], sk->port[idx], sk->af,
+ opts);
printf(")");
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -93,7 +93,7 @@
int pfctl_load_reassembly(struct pfctl *, u_int32_t);
int pfctl_load_syncookies(struct pfctl *, u_int8_t);
int pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int,
- char *);
+ char *, int);
void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int);
void pfctl_print_rule_counters(struct pfctl_rule *, int);
int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, int, int);
@@ -956,7 +956,7 @@
int
pfctl_get_pool(int dev, struct pfctl_pool *pool, u_int32_t nr,
- u_int32_t ticket, int r_action, char *anchorname)
+ u_int32_t ticket, int r_action, char *anchorname, int which)
{
struct pfioc_pooladdr pp;
struct pf_pooladdr *pa;
@@ -964,14 +964,14 @@
int ret;
memset(&pp, 0, sizeof(pp));
- if ((ret = pfctl_get_addrs(pfh, ticket, nr, r_action, anchorname, &mpnr)) != 0) {
+ if ((ret = pfctl_get_addrs(pfh, ticket, nr, r_action, anchorname, &mpnr, which)) != 0) {
warnc(ret, "DIOCGETADDRS");
return (-1);
}
TAILQ_INIT(&pool->list);
for (pnr = 0; pnr < mpnr; ++pnr) {
- if ((ret = pfctl_get_addr(pfh, ticket, nr, r_action, anchorname, pnr, &pp)) != 0) {
+ if ((ret = pfctl_get_addr(pfh, ticket, nr, r_action, anchorname, pnr, &pp, which)) != 0) {
warnc(ret, "DIOCGETADDR");
return (-1);
}
@@ -1303,7 +1303,11 @@
}
if (pfctl_get_pool(dev, &rule.rpool,
- nr, ri.ticket, PF_SCRUB, path) != 0)
+ nr, ri.ticket, PF_SCRUB, path, PF_RDR) != 0)
+ goto error;
+
+ if (pfctl_get_pool(dev, &rule.nat,
+ nr, ri.ticket, PF_SCRUB, path, PF_NAT) != 0)
goto error;
switch (format) {
@@ -1334,7 +1338,11 @@
}
if (pfctl_get_pool(dev, &rule.rpool,
- nr, ri.ticket, PF_PASS, path) != 0)
+ nr, ri.ticket, PF_PASS, path, PF_RDR) != 0)
+ goto error;
+
+ if (pfctl_get_pool(dev, &rule.nat,
+ nr, ri.ticket, PF_PASS, path, PF_NAT) != 0)
goto error;
switch (format) {
@@ -1491,7 +1499,10 @@
return (-1);
}
if (pfctl_get_pool(dev, &rule.rpool, nr,
- ri.ticket, nattype[i], path) != 0)
+ ri.ticket, nattype[i], path, PF_RDR) != 0)
+ return (-1);
+ if (pfctl_get_pool(dev, &rule.nat, nr,
+ ri.ticket, nattype[i], path, PF_NAT) != 0)
return (-1);
if (dotitle) {
@@ -1692,11 +1703,6 @@
struct pf_pooladdr *pa;
int ret;
- if ((pf->opts & PF_OPT_NOACTION) == 0) {
- if ((ret = pfctl_begin_addrs(pf->h, &pf->paddr.ticket)) != 0)
- errc(1, ret, "DIOCBEGINADDRS");
- }
-
pf->paddr.af = af;
TAILQ_FOREACH(pa, &p->list, entries) {
memcpy(&pf->paddr.addr, pa, sizeof(struct pf_pooladdr));
@@ -2045,8 +2051,16 @@
was_present = false;
if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if ((error = pfctl_begin_addrs(pf->h,
+ &pf->paddr.ticket)) != 0)
+ errc(1, error, "DIOCBEGINADDRS");
+ }
+
if (pfctl_add_pool(pf, &r->rpool, r->af, PF_RDR))
return (1);
+ if (pfctl_add_pool(pf, &r->nat, r->naf ? r->naf : r->af, PF_NAT))
+ return (1);
error = pfctl_add_rule_h(pf->h, r, anchor, name, ticket,
pf->paddr.ticket);
switch (error) {
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -664,7 +664,7 @@
print_addr(&aw, sn->af, opts & PF_OPT_VERBOSE2);
printf(" -> ");
aw.v.a.addr = sn->raddr;
- print_addr(&aw, sn->af, opts & PF_OPT_VERBOSE2);
+ print_addr(&aw, sn->naf ? sn->naf : sn->af, opts & PF_OPT_VERBOSE2);
printf(" ( states %u, connections %u, rate %u.%u/%us )\n", sn->states,
sn->conn, sn->conn_rate.count / 1000,
(sn->conn_rate.count % 1000) / 100, sn->conn_rate.seconds);
@@ -1236,8 +1236,21 @@
}
#endif
}
- if (!anchor_call[0] && (r->action == PF_NAT ||
- r->action == PF_BINAT || r->action == PF_RDR)) {
+ if (!anchor_call[0] && ! TAILQ_EMPTY(&r->nat.list) &&
+ r->naf != r->af) {
+ 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, PF_NAT);
+ if (r->rdr.cur != NULL && !TAILQ_EMPTY(&r->rdr.list)) {
+ printf(" to ");
+ print_pool(&r->rdr, r->rdr.proxy_port[0],
+ r->rdr.proxy_port[1], r->naf ? r->naf : r->af,
+ PF_RDR);
+ }
+ }
+ if (!anchor_call[0] &&
+ (r->action == PF_NAT || r->action == PF_BINAT ||
+ r->action == PF_RDR)) {
printf(" -> ");
print_pool(&r->rpool, r->rpool.proxy_port[0],
r->rpool.proxy_port[1], r->af, r->action);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -898,6 +898,7 @@
u_int32_t creation;
u_int32_t expire;
sa_family_t af;
+ sa_family_t naf;
u_int8_t ruletype;
struct mtx *lock;
};
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -419,6 +419,7 @@
PF_SN_CREATION = 12, /* u64 */
PF_SN_EXPIRE = 13, /* u64 */
PF_SN_CONNECTION_RATE = 14, /* nested, pf_threshold */
+ PF_SN_NAF = 15, /* u8 */
};
#ifdef _KERNEL
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1796,6 +1796,7 @@
nlattr_add_u32(nw, PF_SN_STATES, n->states);
nlattr_add_u32(nw, PF_SN_CONNECTIONS, n->conn);
nlattr_add_u8(nw, PF_SN_AF, n->af);
+ nlattr_add_u8(nw, PF_SN_NAF, n->naf);
nlattr_add_u8(nw, PF_SN_RULE_TYPE, n->ruletype);
nlattr_add_u64(nw, PF_SN_CREATION, secs - n->creation);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 3, 3:57 PM (4 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16948204
Default Alt Text
D47790.id147049.diff (21 KB)
Attached To
Mode
D47790: pfctl: change for af-to / NAT64 support.
Attached
Detach File
Event Timeline
Log In to Comment