mirror of
https://github.com/opnsense/src.git
synced 2026-06-12 18:20:49 -04:00
pfctl: change for af-to / NAT64 support.
The general syntax is:
pass in inet from any to 192.168.1.1 af-to inet6 from 2001::1 to 2001::2
In the NAT64 case the "to" is not needed in af-to and the IP is extraced
from the IPv6 dst (assuming a /64 prefix).
Again most work by sperreault@, mikeb@ and reyk@
OK mcbride@, put it in deraadt@
Obtained from: OpenBSD, claudio <claudio@openbsd.org>, 0cde32ce3f
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D47790
This commit is contained in:
parent
b8e5384438
commit
aa69fdf154
9 changed files with 225 additions and 65 deletions
|
|
@ -1285,6 +1285,7 @@ snl_add_msg_attr_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfct
|
|||
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 @@ static struct snl_attr_parser ap_getrule[] = {
|
|||
{ .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_RPOOL_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 @@ 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 __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 @@ pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int whic
|
|||
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 @@ SNL_DECLARE_PARSER(get_addrs_parser, struct genlmsghdr, fp_get_addrs, ap_get_add
|
|||
|
||||
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 @@ pfctl_get_addrs(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
|
|||
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 @@ SNL_DECLARE_PARSER(get_addr_parser, struct genlmsghdr, fp_get_addr, ap_get_addr)
|
|||
|
||||
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 @@ pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t 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_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 @@ static struct snl_attr_parser ap_srcnode[] = {
|
|||
{ .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
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ struct pfctl_rule {
|
|||
uint8_t flush;
|
||||
uint8_t prio;
|
||||
uint8_t set_prio[2];
|
||||
sa_family_t naf;
|
||||
|
||||
struct {
|
||||
struct pf_addr addr;
|
||||
|
|
@ -407,6 +408,7 @@ struct pfctl_src_node {
|
|||
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_get_limit(struct pfctl_handle *h, const int index, uint *limit);
|
|||
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 *);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,34 @@ struct node_qassign {
|
|||
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 @@ static struct filter_opts {
|
|||
#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 @@ static struct filter_opts {
|
|||
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 @@ static struct table_opts {
|
|||
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 @@ void expand_eth_rule(struct pfctl_eth_rule *,
|
|||
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 @@ typedef struct {
|
|||
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 @@ typedef struct {
|
|||
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 @@ int parseport(char *, struct range *r, int);
|
|||
%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 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
|
|||
|
||||
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 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
|
|||
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 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
|
|||
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 @@ scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts
|
|||
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 @@ antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
|
|||
}
|
||||
|
||||
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 @@ antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
|
|||
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 @@ pfrule : action dir logquick interface route af proto fromto
|
|||
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 @@ pfrule : action dir logquick interface route af proto fromto
|
|||
|
||||
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,14 @@ pfrule : action dir logquick interface route af proto fromto
|
|||
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;
|
||||
|
||||
r.nat.opts = $9.nat.pool_opts.type;
|
||||
r.nat.opts |= $9.nat.pool_opts.opts;
|
||||
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 +3048,64 @@ filter_opt : USER uids {
|
|||
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 +4980,7 @@ natrule : nataction interface af proto fromto tag tagged rtable
|
|||
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 +5496,10 @@ filter_consistent(struct pfctl_rule *r, int anchor_call)
|
|||
"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 +6134,8 @@ expand_eth_rule(struct pfctl_eth_rule *r,
|
|||
|
||||
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 +6280,8 @@ expand_rule(struct pfctl_rule *r,
|
|||
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 +6295,24 @@ expand_rule(struct pfctl_rule *r,
|
|||
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 +6343,8 @@ expand_rule(struct pfctl_rule *r,
|
|||
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 +6418,7 @@ lookup(char *s)
|
|||
{
|
||||
/* this has to be sorted always */
|
||||
static const struct keywords keywords[] = {
|
||||
{ "af-to", AFTO},
|
||||
{ "all", ALL},
|
||||
{ "allow-opts", ALLOWOPTS},
|
||||
{ "altq", ALTQ},
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ print_state(struct pfctl_state *s, int opts)
|
|||
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 @@ print_state(struct pfctl_state *s, int opts)
|
|||
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(")");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ int pfctl_load_hostid(struct pfctl *, u_int32_t);
|
|||
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 @@ pfctl_id_kill_states(int dev, const char *iface, int opts)
|
|||
|
||||
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 @@ pfctl_get_pool(int dev, struct pfctl_pool *pool, u_int32_t nr,
|
|||
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 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
|||
}
|
||||
|
||||
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 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
|||
}
|
||||
|
||||
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 @@ pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth,
|
|||
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 @@ pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af, int which
|
|||
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 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ print_src_node(struct pfctl_src_node *sn, int opts)
|
|||
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);
|
||||
|
|
@ -1237,8 +1237,21 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer
|
|||
}
|
||||
#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);
|
||||
|
|
|
|||
|
|
@ -901,6 +901,7 @@ struct pf_ksrc_node {
|
|||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
sa_family_t af;
|
||||
sa_family_t naf;
|
||||
u_int8_t ruletype;
|
||||
struct mtx *lock;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1796,6 +1796,7 @@ pf_handle_get_srcnodes(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ enum pf_srcnodes_types_t {
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue