Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148373156
D49218.1786505635.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
56 KB
Referenced Files
None
Subscribers
None
D49218.1786505635.diff
View Options
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -227,10 +227,6 @@
int b;
int t;
};
-struct redirection {
- struct node_host *host;
- struct range rport;
-};
static struct pool_opts {
int marker;
@@ -245,9 +241,10 @@
} pool_opts;
struct redirspec {
- struct redirection *rdr;
+ struct node_host *host;
+ struct range rport;
struct pool_opts pool_opts;
- int af;
+ int af;
};
static struct filter_opts {
@@ -302,9 +299,8 @@
struct node_host *addr;
u_int16_t port;
} divert;
- struct redirspec nat;
- struct redirspec rdr;
- struct redirspec rroute;
+ struct redirspec *nat;
+ struct redirspec *rdr;
/* new-style scrub opts */
int nodf;
int minttl;
@@ -382,9 +378,11 @@
struct node_mac *, struct node_mac *,
struct node_host *, struct node_host *, const char *,
const char *);
+int apply_rdr_ports(struct pfctl_rule *r, struct pfctl_pool *, struct redirspec *);
+int apply_nat_ports(struct pfctl_pool *, struct redirspec *);
+int apply_redirspec(struct pfctl_pool *, struct redirspec *);
void expand_rule(struct pfctl_rule *, struct node_if *,
struct redirspec *, struct redirspec *, struct redirspec *,
- struct node_host *, 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 *, struct node_if *,
@@ -463,13 +461,10 @@
} etheraddr;
char *bridge_to;
struct {
- struct node_host *host;
+ struct redirspec *redirspec;
u_int8_t rt;
- u_int8_t pool_opts;
- sa_family_t af;
- struct pf_poolhashkey *key;
} route;
- struct redirection *redirection;
+ struct redirspec *redirspec;
struct {
int action;
struct node_state_opt *options;
@@ -554,14 +549,15 @@
%type <v.fromto> fromto l3fromto
%type <v.peer> ipportspec from to
%type <v.host> ipspec toipspec xhost host dynaddr host_list
-%type <v.host> redir_host_list redirspec
-%type <v.host> route_host route_host_list routespec
+%type <v.host> redir_host redir_host_list routespec
+%type <v.host> route_host route_host_list
%type <v.os> os xos os_list
%type <v.port> portspec port_list port_item
%type <v.uid> uids uid_list uid_item
%type <v.gid> gids gid_list gid_item
%type <v.route> route
-%type <v.redirection> redirection redirpool
+%type <v.redirspec> no_port_redirspec port_redirspec route_redirspec
+%type <v.redirspec> binat_redirspec nat_redirspec
%type <v.string> label stringall tag anchorname
%type <v.string> string varstring numberstring
%type <v.keep_state> keep
@@ -965,7 +961,8 @@
YYERROR;
}
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
+
if (pf->astack[pf->asd + 1]) {
if ($2 && strchr($2, '/') != NULL) {
free($2);
@@ -978,7 +975,7 @@
pfctl_anchor_setup(&r,
&pf->astack[pf->asd]->ruleset,
$2 ? $2 : pf->alast->name);
-
+
if (r.anchor == NULL)
err(1, "anchorrule: unable to "
"create ruleset");
@@ -1082,7 +1079,7 @@
decide_address_family($8.src.host, &r.af);
decide_address_family($8.dst.host, &r.af);
- expand_rule(&r, $5, NULL, NULL, NULL, NULL, NULL, NULL,
+ expand_rule(&r, $5, NULL, 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);
@@ -1097,7 +1094,8 @@
YYERROR;
}
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
+
r.action = PF_NAT;
r.af = $4;
r.rtableid = $7;
@@ -1105,7 +1103,7 @@
decide_address_family($6.src.host, &r.af);
decide_address_family($6.dst.host, &r.af);
- expand_rule(&r, $3, NULL, NULL, NULL, NULL, NULL, NULL,
+ expand_rule(&r, $3, NULL, 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);
@@ -1118,7 +1116,8 @@
YYERROR;
}
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
+
r.action = PF_RDR;
r.af = $4;
r.rtableid = $7;
@@ -1147,7 +1146,7 @@
r.dst.port_op = $6.dst.port->op;
}
- expand_rule(&r, $3, NULL, NULL, NULL, NULL, NULL, NULL,
+ expand_rule(&r, $3, NULL, 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);
@@ -1160,7 +1159,8 @@
YYERROR;
}
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
+
r.action = PF_BINAT;
r.af = $4;
r.rtableid = $7;
@@ -1425,7 +1425,7 @@
if (check_rulestate(PFCTL_STATE_SCRUB))
YYERROR;
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
r.action = $1.b1;
r.direction = $2;
@@ -1470,7 +1470,7 @@
r.match_tag_not = $8.match_tag_not;
r.rtableid = $8.rtableid;
- expand_rule(&r, $4, NULL, NULL, NULL, NULL, NULL, NULL,
+ expand_rule(&r, $4, NULL, NULL, NULL,
$6, $7.src_os, $7.src.host, $7.src.port, $7.dst.host,
$7.dst.port, NULL, NULL, NULL, NULL, "");
}
@@ -1587,7 +1587,7 @@
YYERROR;
for (i = $3; i; i = i->next) {
- bzero(&r, sizeof(r));
+ pfctl_init_rule(&r);
r.action = PF_DROP;
r.direction = PF_IN;
@@ -1635,9 +1635,9 @@
}
if (h != NULL)
- expand_rule(&r, j, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, h, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, "");
+ expand_rule(&r, j, NULL, NULL, NULL,
+ NULL, NULL, h, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, "");
if ((i->ifa_flags & IFF_LOOPBACK) == 0) {
bzero(&r, sizeof(r));
@@ -1657,9 +1657,10 @@
else
h = ifa_lookup(i->ifname, 0);
if (h != NULL)
- expand_rule(&r, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, h, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, "");
+ expand_rule(&r, NULL, NULL,
+ NULL, NULL, NULL, NULL, h,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "");
} else
free(hh);
}
@@ -2371,7 +2372,7 @@
if (check_rulestate(PFCTL_STATE_FILTER))
YYERROR;
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
r.action = $1.b1;
switch ($1.b2) {
@@ -2728,44 +2729,14 @@
YYERROR;
}
r.rt = $5.rt;
- r.route.opts = $5.pool_opts;
- if ($5.key != NULL)
- memcpy(&r.route.key, $5.key,
- sizeof(struct pf_poolhashkey));
- }
- if (r.rt) {
- decide_address_family($5.host, &r.af);
+ decide_address_family($5.redirspec->host, &r.af);
if (!(r.rule_flag & PFRULE_AFTO))
- remove_invalid_hosts(&$5.host, &r.af);
- if ($5.host == NULL) {
+ remove_invalid_hosts(&($5.redirspec->host), &r.af);
+ if ($5.redirspec->host == NULL) {
yyerror("no routing address with "
"matching address family found.");
YYERROR;
}
- if ((r.route.opts & PF_POOL_TYPEMASK) ==
- PF_POOL_NONE && ($5.host->next != NULL ||
- $5.host->addr.type == PF_ADDR_TABLE ||
- DYNIF_MULTIADDR($5.host->addr)))
- r.route.opts |= PF_POOL_ROUNDROBIN;
- if ($5.host->next != NULL &&
- !PF_POOL_DYNTYPE(r.route.opts)) {
- yyerror("address pool option "
- "not supported by type");
- }
- if (!PF_POOL_DYNTYPE(r.route.opts) &&
- (disallow_table($5.host,
- "tables are not supported by pool type") ||
- disallow_alias($5.host,
- "interface (%s) is not supported by pool type")))
- YYERROR;
- if ($5.host->next != NULL) {
- if ((r.route.opts & PF_POOL_TYPEMASK) !=
- PF_POOL_ROUNDROBIN) {
- yyerror("r.route.opts must "
- "be PF_POOL_ROUNDROBIN");
- YYERROR;
- }
- }
}
if ($9.queues.qname != NULL) {
if (strlcpy(r.qname, $9.queues.qname,
@@ -2824,19 +2795,10 @@
}
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;
-
- if (!PF_POOL_DYNTYPE(r.nat.opts) &&
- disallow_table($9.nat.rdr->host, "tables are not "
- "supported by pool type"))
- YYERROR;
+ r.naf = $9.nat->af;
}
- expand_rule(&r, $4, &$9.nat, &$9.rdr, &$9.rroute,
- NULL, $9.nat.rdr ? $9.nat.rdr->host : NULL, $5.host,
+ expand_rule(&r, $4, $9.nat, $9.rdr, $5.redirspec,
$7, $8.src_os, $8.src.host, $8.src.port, $8.dst.host,
$8.dst.port, $9.uid, $9.gid, $9.rcv, $9.icmpspec, "");
}
@@ -3053,8 +3015,8 @@
filter_opts.marker |= FOM_SCRUB_TCP;
filter_opts.marker |= $3.marker;
}
- | AFTO af FROM redirspec pool_opts {
- if (filter_opts.nat.rdr) {
+ | AFTO af FROM port_redirspec {
+ if (filter_opts.nat) {
yyerror("cannot respecify af-to");
YYERROR;
}
@@ -3062,26 +3024,18 @@
yyerror("no address family specified");
YYERROR;
}
+
+ filter_opts.nat = $4;
+ filter_opts.nat->af = $2;
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) {
+ | AFTO af FROM port_redirspec TO port_redirspec {
+ if (filter_opts.nat) {
yyerror("cannot respecify af-to");
YYERROR;
}
@@ -3089,26 +3043,16 @@
yyerror("no address family specified");
YYERROR;
}
- if (($4->af && $4->af != $2) ||
- ($7->af && $7->af != $2)) {
+ filter_opts.nat = $4;
+ filter_opts.nat->af = $2;
+ filter_opts.rdr = $6;
+ filter_opts.rdr->af = $2;
+ if (($4->af && $4->host->af != $2) ||
+ ($6->af && $6->host->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
@@ -4580,7 +4524,7 @@
}
;
-redirspec : host { $$ = $1; }
+redir_host : host { $$ = $1; }
| '{' optnl redir_host_list '}' { $$ = $3; }
;
@@ -4592,20 +4536,41 @@
}
;
-redirpool : /* empty */ { $$ = NULL; }
- | ARROW redirspec {
- $$ = calloc(1, sizeof(struct redirection));
+/* Redirection without port */
+no_port_redirspec: redir_host pool_opts {
+ $$ = calloc(1, sizeof(struct redirspec));
if ($$ == NULL)
- err(1, "redirection: calloc");
- $$->host = $2;
+ err(1, "redirspec: calloc");
+ $$->host = $1;
+ $$->pool_opts = $2;
$$->rport.a = $$->rport.b = $$->rport.t = 0;
}
- | ARROW redirspec PORT portstar {
- $$ = calloc(1, sizeof(struct redirection));
+ ;
+
+/* Redirection with optional port */
+port_redirspec : no_port_redirspec;
+ | redir_host PORT portstar pool_opts {
+ $$ = calloc(1, sizeof(struct redirspec));
if ($$ == NULL)
- err(1, "redirection: calloc");
- $$->host = $2;
- $$->rport = $4;
+ err(1, "redirspec: calloc");
+ $$->host = $1;
+ $$->rport = $3;
+ $$->pool_opts = $4;
+ }
+
+/* Redirection with an arrow and an optional port: FreeBSD NAT rules */
+nat_redirspec : ARROW port_redirspec {
+ $$ = $2;
+ }
+ ;
+
+/* Redirection with interfaces and without ports: route-to rules */
+route_redirspec : routespec pool_opts {
+ $$ = calloc(1, sizeof(struct redirspec));
+ if ($$ == NULL)
+ err(1, "redirspec: calloc");
+ $$->host = $1;
+ $$->pool_opts = $2;
}
;
@@ -4756,18 +4721,18 @@
}
;
-redirection : /* empty */ { $$ = NULL; }
+binat_redirspec : /* empty */ { $$ = NULL; }
| ARROW host {
- $$ = calloc(1, sizeof(struct redirection));
+ $$ = calloc(1, sizeof(struct redirspec));
if ($$ == NULL)
- err(1, "redirection: calloc");
+ err(1, "redirspec: calloc");
$$->host = $2;
$$->rport.a = $$->rport.b = $$->rport.t = 0;
}
| ARROW host PORT portstar {
- $$ = calloc(1, sizeof(struct redirection));
+ $$ = calloc(1, sizeof(struct redirspec));
if ($$ == NULL)
- err(1, "redirection: calloc");
+ err(1, "redirspec: calloc");
$$->host = $2;
$$->rport = $4;
}
@@ -4808,7 +4773,7 @@
;
natrule : nataction interface af proto fromto tag tagged rtable
- redirpool pool_opts
+ nat_redirspec
{
struct pfctl_rule r;
struct node_state_opt *o;
@@ -4816,7 +4781,7 @@
if (check_rulestate(PFCTL_STATE_NAT))
YYERROR;
- memset(&r, 0, sizeof(r));
+ pfctl_init_rule(&r);
r.action = $1.b1;
r.natpass = $1.b2;
@@ -4875,110 +4840,6 @@
}
if (check_netmask($9->host, r.af))
YYERROR;
-
- r.rdr.proxy_port[0] = ntohs($9->rport.a);
-
- switch (r.action) {
- case PF_RDR:
- if (!$9->rport.b && $9->rport.t &&
- $5.dst.port != NULL) {
- r.rdr.proxy_port[1] =
- ntohs($9->rport.a) +
- (ntohs(
- $5.dst.port->port[1]) -
- ntohs(
- $5.dst.port->port[0]));
- } else
- r.rdr.proxy_port[1] =
- ntohs($9->rport.b);
- break;
- case PF_NAT:
- r.rdr.proxy_port[1] =
- ntohs($9->rport.b);
- if (!r.rdr.proxy_port[0] &&
- !r.rdr.proxy_port[1]) {
- r.rdr.proxy_port[0] =
- PF_NAT_PROXY_PORT_LOW;
- r.rdr.proxy_port[1] =
- PF_NAT_PROXY_PORT_HIGH;
- } else if (!r.rdr.proxy_port[1])
- r.rdr.proxy_port[1] =
- r.rdr.proxy_port[0];
- break;
- default:
- break;
- }
-
- r.rdr.opts = $10.type;
- if ((r.rdr.opts & PF_POOL_TYPEMASK) ==
- PF_POOL_NONE && ($9->host->next != NULL ||
- $9->host->addr.type == PF_ADDR_TABLE ||
- DYNIF_MULTIADDR($9->host->addr)))
- r.rdr.opts = PF_POOL_ROUNDROBIN;
- if (!PF_POOL_DYNTYPE(r.rdr.opts) &&
- (disallow_table($9->host,
- "tables are not supported by pool type") ||
- disallow_alias($9->host,
- "interface (%s) is not supported by pool type")))
- YYERROR;
- if ($9->host->next != NULL) {
- if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
- PF_POOL_ROUNDROBIN) {
- yyerror("only round-robin "
- "valid for multiple "
- "redirection addresses");
- YYERROR;
- }
- }
- }
-
- if ($10.key != NULL)
- memcpy(&r.rdr.key, $10.key,
- sizeof(struct pf_poolhashkey));
-
- if ($10.opts)
- r.rdr.opts |= $10.opts;
-
- if ($10.staticport) {
- if (r.action != PF_NAT) {
- yyerror("the 'static-port' option is "
- "only valid with nat rules");
- YYERROR;
- }
- if (r.rdr.proxy_port[0] !=
- PF_NAT_PROXY_PORT_LOW &&
- r.rdr.proxy_port[1] !=
- PF_NAT_PROXY_PORT_HIGH) {
- yyerror("the 'static-port' option can't"
- " be used when specifying a port"
- " range");
- YYERROR;
- }
- r.rdr.proxy_port[0] = 0;
- r.rdr.proxy_port[1] = 0;
- }
-
- if ($10.mape.offset) {
- if (r.action != PF_NAT) {
- yyerror("the 'map-e-portset' option is"
- " only valid with nat rules");
- YYERROR;
- }
- if ($10.staticport) {
- yyerror("the 'map-e-portset' option"
- " can't be used 'static-port'");
- YYERROR;
- }
- if (r.rdr.proxy_port[0] !=
- PF_NAT_PROXY_PORT_LOW &&
- r.rdr.proxy_port[1] !=
- PF_NAT_PROXY_PORT_HIGH) {
- yyerror("the 'map-e-portset' option"
- " can't be used when specifying"
- " a port range");
- YYERROR;
- }
- r.rdr.mape = $10.mape;
}
o = keep_state_defaults;
@@ -4996,16 +4857,14 @@
o = o->next;
}
- expand_rule(&r, $2, NULL, NULL, NULL,
- $9 == NULL ? NULL : $9->host, NULL, NULL, $4,
+ expand_rule(&r, $2, NULL, $9, NULL, $4,
$5.src_os, $5.src.host, $5.src.port, $5.dst.host,
$5.dst.port, 0, 0, 0, 0, "");
- free($9);
}
;
binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag
- tagged rtable redirection
+ tagged rtable binat_redirspec
{
struct pfctl_rule binat;
struct pf_pooladdr *pa;
@@ -5016,7 +4875,7 @@
"permitted as a binat destination"))
YYERROR;
- memset(&binat, 0, sizeof(binat));
+ pfctl_init_rule(&binat);
if ($1 && $3.b1) {
yyerror("\"pass\" not valid with \"no\"");
@@ -5249,36 +5108,23 @@
;
route : /* empty */ {
- $$.host = NULL;
- $$.rt = 0;
- $$.pool_opts = 0;
+ $$.rt = PF_NOPFROUTE;
}
| FASTROUTE {
/* backwards-compat */
- $$.host = NULL;
- $$.rt = 0;
- $$.pool_opts = 0;
+ $$.rt = PF_NOPFROUTE;
}
- | ROUTETO routespec pool_opts {
- $$.host = $2;
+ | ROUTETO route_redirspec {
$$.rt = PF_ROUTETO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
+ $$.redirspec = $2;
}
- | REPLYTO routespec pool_opts {
- $$.host = $2;
+ | REPLYTO route_redirspec {
$$.rt = PF_REPLYTO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
+ $$.redirspec = $2;
}
- | DUPTO routespec pool_opts {
- $$.host = $2;
+ | DUPTO route_redirspec {
$$.rt = PF_DUPTO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
+ $$.redirspec = $2;
}
;
@@ -6161,12 +6007,144 @@
FREE_LIST(struct node_host, ipdsts);
}
+int
+apply_rdr_ports(struct pfctl_rule *r, struct pfctl_pool *rpool, struct redirspec *rs)
+{
+ if (rs == NULL)
+ return 0;
+
+ rpool->proxy_port[0] = ntohs(rs->rport.a);
+
+ if (!rs->rport.b && rs->rport.t && r->dst.port != NULL) {
+ rpool->proxy_port[1] = ntohs(rs->rport.a) +
+ (ntohs(r->dst.port[1]) - ntohs(r->dst.port[0]));
+ } else
+ r->rdr.proxy_port[1] = ntohs(rs->rport.b);
+
+ if (rs->pool_opts.staticport) {
+ yyerror("the 'static-port' option is only valid with nat rules");
+ return 1;
+ }
+
+ if (rs->pool_opts.mape.offset) {
+ yyerror("the 'map-e-portset' option is only valid with nat rules");
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+apply_nat_ports(struct pfctl_pool *rpool, struct redirspec *rs)
+{
+ if (rs == NULL)
+ return 0;
+
+ rpool->proxy_port[0] = ntohs(rs->rport.a);
+ rpool->proxy_port[1] = ntohs(rs->rport.b);
+ if (!rpool->proxy_port[0] && !rpool->proxy_port[1]) {
+ rpool->proxy_port[0] = PF_NAT_PROXY_PORT_LOW;
+ rpool->proxy_port[1] = PF_NAT_PROXY_PORT_HIGH;
+ } else if (!rpool->proxy_port[1])
+ rpool->proxy_port[1] = rpool->proxy_port[0];
+
+ if (rs->pool_opts.staticport) {
+ if (rpool->proxy_port[0] != PF_NAT_PROXY_PORT_LOW &&
+ rpool->proxy_port[1] != PF_NAT_PROXY_PORT_HIGH) {
+ yyerror("the 'static-port' option can't"
+ " be used when specifying a port"
+ " range");
+ return 1;
+ }
+ rpool->proxy_port[0] = 0;
+ rpool->proxy_port[1] = 0;
+ }
+
+ if (rs->pool_opts.mape.offset) {
+ if (rs->pool_opts.staticport) {
+ yyerror("the 'map-e-portset' option"
+ " can't be used 'static-port'");
+ return 1;
+ }
+ if (rpool->proxy_port[0] != PF_NAT_PROXY_PORT_LOW &&
+ rpool->proxy_port[1] != PF_NAT_PROXY_PORT_HIGH) {
+ yyerror("the 'map-e-portset' option"
+ " can't be used when specifying"
+ " a port range");
+ return 1;
+ }
+ rpool->mape = rs->pool_opts.mape;
+ }
+
+ return 0;
+}
+
+int
+apply_redirspec(struct pfctl_pool *rpool, struct redirspec *rs)
+{
+ struct node_host *h;
+ struct pf_pooladdr *pa;
+
+ if (rs == NULL)
+ return 0;
+
+ rpool->opts = rs->pool_opts.type;
+
+ if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_NONE &&
+ (rs->host->next != NULL ||
+ rs->host->addr.type == PF_ADDR_TABLE ||
+ DYNIF_MULTIADDR(rs->host->addr)))
+ rpool->opts = PF_POOL_ROUNDROBIN;
+
+ if (!PF_POOL_DYNTYPE(rpool->opts) &&
+ (disallow_table(rs->host, "tables are not supported by pool type") ||
+ disallow_alias(rs->host, "interface (%s) is not supported by pool type")))
+ return 1;
+
+ if (rs->host->next != NULL &&
+ ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)) {
+ yyerror("r.route.opts must be PF_POOL_ROUNDROBIN");
+ return 1;
+ }
+
+ if (rs->host->next != NULL) {
+ if ((rpool->opts & PF_POOL_TYPEMASK) !=
+ PF_POOL_ROUNDROBIN) {
+ yyerror("only round-robin valid for multiple "
+ "redirection addresses");
+ return 1;
+ }
+ }
+
+ rpool->opts |= rs->pool_opts.opts;
+
+ if (rs->pool_opts.key != NULL)
+ memcpy(&(rpool->key), rs->pool_opts.key,
+ sizeof(struct pf_poolhashkey));
+
+ TAILQ_INIT(&(rpool->list));
+ for (h = rs->host; 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(&(rpool->list), pa, entries);
+ }
+
+ return 0;
+}
+
void
expand_rule(struct pfctl_rule *r,
struct node_if *interfaces, struct redirspec *nat,
struct redirspec *rdr, struct redirspec *route,
- struct node_host *rdr_hosts, struct node_host *nat_hosts,
- struct node_host *route_hosts, struct node_proto *protos,
+ 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, struct node_uid *uids, struct node_gid *gids,
@@ -6178,8 +6156,7 @@
char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
- struct pf_pooladdr *pa;
- struct node_host *h, *osrch, *odsth;
+ struct node_host *osrch, *odsth;
u_int8_t flags, flagset, keep_state;
memcpy(label, r->label, sizeof(r->label));
@@ -6317,52 +6294,16 @@
r->os_fingerprint = PF_OSFP_ANY;
}
- 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");
- 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->rdr.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);
- }
- TAILQ_INIT(&r->route.list);
- for (h = route_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->route.list, pa, entries);
+ if (r->action == PF_RDR) {
+ error += apply_rdr_ports(r, &(r->rdr), rdr);
+ } else if (r->action == PF_NAT) {
+ error += apply_nat_ports(&(r->rdr), rdr);
}
+ error += apply_redirspec(&(r->nat), nat);
+ error += apply_redirspec(&(r->rdr), rdr);
+ error += apply_redirspec(&(r->route), route);
+
r->nat.proxy_port[0] = PF_NAT_PROXY_PORT_LOW;
r->nat.proxy_port[1] = PF_NAT_PROXY_PORT_HIGH;
@@ -6395,8 +6336,18 @@
FREE_LIST(struct node_uid, uids);
FREE_LIST(struct node_gid, gids);
FREE_LIST(struct node_icmp, icmp_types);
- FREE_LIST(struct node_host, rdr_hosts);
- FREE_LIST(struct node_host, nat_hosts);
+ if (nat) {
+ FREE_LIST(struct node_host, nat->host);
+ free(nat);
+ }
+ if (rdr) {
+ FREE_LIST(struct node_host, rdr->host);
+ free(rdr);
+ }
+ if (route) {
+ FREE_LIST(struct node_host, route->host);
+ free(route);
+ }
if (!added)
yyerror("rule expands to no valid combination");
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1737,6 +1737,16 @@
return (0);
}
+void
+pfctl_init_rule(struct pfctl_rule *r)
+{
+
+ memset(r, 0, sizeof(struct pfctl_rule));
+ TAILQ_INIT(&(r->rdr.list));
+ TAILQ_INIT(&(r->nat.list));
+ TAILQ_INIT(&(r->route.list));
+}
+
int
pfctl_append_rule(struct pfctl *pf, struct pfctl_rule *r,
const char *anchor_call)
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -277,6 +277,7 @@
int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
int pfctl_optimize_ruleset(struct pfctl *, struct pfctl_ruleset *);
+void pfctl_init_rule(struct pfctl_rule *r);
int pfctl_append_rule(struct pfctl *, struct pfctl_rule *, const char *);
int pfctl_append_eth_rule(struct pfctl *, struct pfctl_eth_rule *,
const char *);
diff --git a/sbin/pfctl/tests/files/Makefile b/sbin/pfctl/tests/files/Makefile
--- a/sbin/pfctl/tests/files/Makefile
+++ b/sbin/pfctl/tests/files/Makefile
@@ -4,6 +4,6 @@
BINDIR= ${TESTSDIR}
# We use ${.CURDIR} as workaround so that the glob patterns work.
-FILES!= echo ${.CURDIR}/pf????.in ${.CURDIR}/pf????.include ${.CURDIR}/pf????.ok
+FILES!= echo ${.CURDIR}/pf????.in ${.CURDIR}/pf????.include ${.CURDIR}/pf????.ok ${.CURDIR}/pf????.fail
.include <bsd.progs.mk>
diff --git a/sbin/pfctl/tests/files/pf1026.ok b/sbin/pfctl/tests/files/pf1026.ok
--- a/sbin/pfctl/tests/files/pf1026.ok
+++ b/sbin/pfctl/tests/files/pf1026.ok
@@ -1 +1 @@
-pass in on epair2b route-to (epair0a 192.0.2.2) inet6 from any to 64:ff9b::/96 flags S/SA keep state af-to inet from (epair0a)
+pass in on epair2b route-to (epair0a 192.0.2.2) inet6 from any to 64:ff9b::/96 flags S/SA keep state af-to inet from (epair0a) round-robin
diff --git a/sbin/pfctl/tests/files/pf1027.ok b/sbin/pfctl/tests/files/pf1027.ok
--- a/sbin/pfctl/tests/files/pf1027.ok
+++ b/sbin/pfctl/tests/files/pf1027.ok
@@ -1 +1 @@
-pass in on epair2b reply-to (epair0a 2001:db8::1) inet6 from any to 64:ff9b::/96 flags S/SA keep state af-to inet from (epair0a)
+pass in on epair2b reply-to (epair0a 2001:db8::1) inet6 from any to 64:ff9b::/96 flags S/SA keep state af-to inet from (epair0a) round-robin
diff --git a/sbin/pfctl/tests/files/pf1028.in b/sbin/pfctl/tests/files/pf1028.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1028.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1028.ok b/sbin/pfctl/tests/files/pf1028.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1028.ok
@@ -0,0 +1 @@
+rdr on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1029.in b/sbin/pfctl/tests/files/pf1029.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1029.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1002
diff --git a/sbin/pfctl/tests/files/pf1029.ok b/sbin/pfctl/tests/files/pf1029.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1029.ok
@@ -0,0 +1 @@
+rdr on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1002
diff --git a/sbin/pfctl/tests/files/pf1030.in b/sbin/pfctl/tests/files/pf1030.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1030.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 50001:65535
diff --git a/sbin/pfctl/tests/files/pf1030.ok b/sbin/pfctl/tests/files/pf1030.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1030.ok
@@ -0,0 +1 @@
+rdr on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 50001:65535
diff --git a/sbin/pfctl/tests/files/pf1031.in b/sbin/pfctl/tests/files/pf1031.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1031.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 port 1004:2004 -> 192.0.2.3 port 1004
diff --git a/sbin/pfctl/tests/files/pf1031.ok b/sbin/pfctl/tests/files/pf1031.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1031.ok
@@ -0,0 +1 @@
+rdr on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 port 1004:2004 -> 192.0.2.3 port 1004
diff --git a/sbin/pfctl/tests/files/pf1032.in b/sbin/pfctl/tests/files/pf1032.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1032.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 port 1005:2005 -> 192.0.2.3 port 3004:*
diff --git a/sbin/pfctl/tests/files/pf1032.ok b/sbin/pfctl/tests/files/pf1032.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1032.ok
@@ -0,0 +1 @@
+rdr on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 port 1005:2005 -> 192.0.2.3 port 3004:4004
diff --git a/sbin/pfctl/tests/files/pf1033.fail b/sbin/pfctl/tests/files/pf1033.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1033.fail
@@ -0,0 +1 @@
+the 'static-port' option is only valid with nat rules
diff --git a/sbin/pfctl/tests/files/pf1033.in b/sbin/pfctl/tests/files/pf1033.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1033.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 static-port
diff --git a/sbin/pfctl/tests/files/pf1034.fail b/sbin/pfctl/tests/files/pf1034.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1034.fail
@@ -0,0 +1 @@
+the 'map-e-portset' option is only valid with nat rules
diff --git a/sbin/pfctl/tests/files/pf1034.in b/sbin/pfctl/tests/files/pf1034.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1034.in
@@ -0,0 +1 @@
+rdr on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 map-e-portset 6/8/0x34
diff --git a/sbin/pfctl/tests/files/pf1035.in b/sbin/pfctl/tests/files/pf1035.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1035.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1035.ok b/sbin/pfctl/tests/files/pf1035.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1035.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1036.in b/sbin/pfctl/tests/files/pf1036.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1036.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 50001:65535
diff --git a/sbin/pfctl/tests/files/pf1036.ok b/sbin/pfctl/tests/files/pf1036.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1036.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1037.in b/sbin/pfctl/tests/files/pf1037.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1037.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1003
diff --git a/sbin/pfctl/tests/files/pf1037.ok b/sbin/pfctl/tests/files/pf1037.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1037.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1003
diff --git a/sbin/pfctl/tests/files/pf1038.in b/sbin/pfctl/tests/files/pf1038.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1038.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1004:2004
diff --git a/sbin/pfctl/tests/files/pf1038.ok b/sbin/pfctl/tests/files/pf1038.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1038.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1004:2004
diff --git a/sbin/pfctl/tests/files/pf1039.in b/sbin/pfctl/tests/files/pf1039.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1039.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 static-port
diff --git a/sbin/pfctl/tests/files/pf1039.ok b/sbin/pfctl/tests/files/pf1039.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1039.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 static-port
diff --git a/sbin/pfctl/tests/files/pf1040.fail b/sbin/pfctl/tests/files/pf1040.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1040.fail
@@ -0,0 +1 @@
+the 'static-port' option can't be used when specifying a port range
diff --git a/sbin/pfctl/tests/files/pf1040.in b/sbin/pfctl/tests/files/pf1040.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1040.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1006 static-port
diff --git a/sbin/pfctl/tests/files/pf1040.ok b/sbin/pfctl/tests/files/pf1040.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1040.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 map-e-portset 6/8/52
diff --git a/sbin/pfctl/tests/files/pf1041.in b/sbin/pfctl/tests/files/pf1041.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1041.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 map-e-portset 6/8/0x34
diff --git a/sbin/pfctl/tests/files/pf1041.ok b/sbin/pfctl/tests/files/pf1041.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1041.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 map-e-portset 6/8/52
diff --git a/sbin/pfctl/tests/files/pf1042.fail b/sbin/pfctl/tests/files/pf1042.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1042.fail
@@ -0,0 +1 @@
+the 'map-e-portset' option can't be used 'static-port'
diff --git a/sbin/pfctl/tests/files/pf1042.in b/sbin/pfctl/tests/files/pf1042.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1042.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 static-port map-e-portset 6/8/0x34
diff --git a/sbin/pfctl/tests/files/pf1043.fail b/sbin/pfctl/tests/files/pf1043.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1043.fail
@@ -0,0 +1 @@
+the 'map-e-portset' option can't be used when specifying a port range
diff --git a/sbin/pfctl/tests/files/pf1043.in b/sbin/pfctl/tests/files/pf1043.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1043.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3 port 1007 map-e-portset 6/8/0x34
diff --git a/sbin/pfctl/tests/files/pf1044.in b/sbin/pfctl/tests/files/pf1044.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1044.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> <targets> sticky-address
diff --git a/sbin/pfctl/tests/files/pf1044.ok b/sbin/pfctl/tests/files/pf1044.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1044.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> <targets> round-robin sticky-address
diff --git a/sbin/pfctl/tests/files/pf1045.in b/sbin/pfctl/tests/files/pf1045.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1045.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 bitmask
diff --git a/sbin/pfctl/tests/files/pf1045.ok b/sbin/pfctl/tests/files/pf1045.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1045.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 bitmask
diff --git a/sbin/pfctl/tests/files/pf1046.fail b/sbin/pfctl/tests/files/pf1046.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1046.fail
@@ -0,0 +1 @@
+tables are not supported by pool type
diff --git a/sbin/pfctl/tests/files/pf1046.in b/sbin/pfctl/tests/files/pf1046.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1046.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> <targets> bitmask
diff --git a/sbin/pfctl/tests/files/pf1047.fail b/sbin/pfctl/tests/files/pf1047.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1047.fail
@@ -0,0 +1 @@
+interface \(vtnet1\) is not supported by pool type
diff --git a/sbin/pfctl/tests/files/pf1047.in b/sbin/pfctl/tests/files/pf1047.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1047.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> (vtnet1) bitmask
diff --git a/sbin/pfctl/tests/files/pf1048.in b/sbin/pfctl/tests/files/pf1048.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1048.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 random
diff --git a/sbin/pfctl/tests/files/pf1048.ok b/sbin/pfctl/tests/files/pf1048.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1048.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 random
diff --git a/sbin/pfctl/tests/files/pf1049.in b/sbin/pfctl/tests/files/pf1049.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1049.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> { 192.0.2.3 }
diff --git a/sbin/pfctl/tests/files/pf1049.ok b/sbin/pfctl/tests/files/pf1049.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1049.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 192.0.2.3
diff --git a/sbin/pfctl/tests/files/pf1050.in b/sbin/pfctl/tests/files/pf1050.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1050.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> <targets>
diff --git a/sbin/pfctl/tests/files/pf1050.ok b/sbin/pfctl/tests/files/pf1050.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1050.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> <targets> round-robin
diff --git a/sbin/pfctl/tests/files/pf1051.in b/sbin/pfctl/tests/files/pf1051.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1051.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1 203.0.113.2 }
diff --git a/sbin/pfctl/tests/files/pf1051.ok b/sbin/pfctl/tests/files/pf1051.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1051.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1, 203.0.113.2 } round-robin
diff --git a/sbin/pfctl/tests/files/pf1052.in b/sbin/pfctl/tests/files/pf1052.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1052.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1 <targets> }
diff --git a/sbin/pfctl/tests/files/pf1052.ok b/sbin/pfctl/tests/files/pf1052.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1052.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1, <targets> } round-robin
diff --git a/sbin/pfctl/tests/files/pf1053.in b/sbin/pfctl/tests/files/pf1053.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1053.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24
diff --git a/sbin/pfctl/tests/files/pf1053.ok b/sbin/pfctl/tests/files/pf1053.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1053.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24
diff --git a/sbin/pfctl/tests/files/pf1054.in b/sbin/pfctl/tests/files/pf1054.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1054.in
@@ -0,0 +1,3 @@
+# XXX: it causes just the 0th address to be used without cycling
+# Probably a bug
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 round-robin
diff --git a/sbin/pfctl/tests/files/pf1054.ok b/sbin/pfctl/tests/files/pf1054.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1054.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 round-robin
diff --git a/sbin/pfctl/tests/files/pf1055.in b/sbin/pfctl/tests/files/pf1055.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1055.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 source-hash 0x42424242424242424242424242424242
diff --git a/sbin/pfctl/tests/files/pf1055.ok b/sbin/pfctl/tests/files/pf1055.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1055.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.0/24 source-hash 0x42424242424242424242424242424242
diff --git a/sbin/pfctl/tests/files/pf1056.in b/sbin/pfctl/tests/files/pf1056.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1056.in
@@ -0,0 +1 @@
+pass in on vtnet0 inet6 from any to 64:ff9b::/96 af-to inet from 203.0.113.1 to 203.0.113.2
diff --git a/sbin/pfctl/tests/files/pf1056.ok b/sbin/pfctl/tests/files/pf1056.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1056.ok
@@ -0,0 +1 @@
+pass in on vtnet0 inet6 from any to 64:ff9b::/96 flags S/SA keep state af-to inet from 203.0.113.1 to 203.0.113.2
diff --git a/sbin/pfctl/tests/files/pf1057.in b/sbin/pfctl/tests/files/pf1057.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1057.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> vlan1057
diff --git a/sbin/pfctl/tests/files/pf1057.ok b/sbin/pfctl/tests/files/pf1057.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1057.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> 203.0.113.5
diff --git a/sbin/pfctl/tests/files/pf1058.in b/sbin/pfctl/tests/files/pf1058.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1058.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1 vlan1058 }
diff --git a/sbin/pfctl/tests/files/pf1058.ok b/sbin/pfctl/tests/files/pf1058.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1058.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.1, 203.0.113.5 } round-robin
diff --git a/sbin/pfctl/tests/files/pf1059.in b/sbin/pfctl/tests/files/pf1059.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1059.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> (vlan1059)
diff --git a/sbin/pfctl/tests/files/pf1059.ok b/sbin/pfctl/tests/files/pf1059.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1059.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> (vlan1059) round-robin
diff --git a/sbin/pfctl/tests/files/pf1060.in b/sbin/pfctl/tests/files/pf1060.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1060.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.0 (vlan1060) }
diff --git a/sbin/pfctl/tests/files/pf1060.ok b/sbin/pfctl/tests/files/pf1060.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1060.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet proto tcp from 192.0.2.1 to 192.0.2.2 -> { 203.0.113.0, (vlan1060) } round-robin
diff --git a/sbin/pfctl/tests/files/pf1061.in b/sbin/pfctl/tests/files/pf1061.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1061.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 2001:db8::1 to 2001:db8::2 -> vlan1061:0
diff --git a/sbin/pfctl/tests/files/pf1061.ok b/sbin/pfctl/tests/files/pf1061.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1061.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet6 proto tcp from 2001:db8::1 to 2001:db8::2 -> 2001:db8::cb00:7105
diff --git a/sbin/pfctl/tests/files/pf1062.in b/sbin/pfctl/tests/files/pf1062.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1062.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 2001:db8::1 to 2001:db8::2 -> { 2001:db8::3 vlan1062:0 }
diff --git a/sbin/pfctl/tests/files/pf1062.ok b/sbin/pfctl/tests/files/pf1062.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1062.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet6 proto tcp from 2001:db8::1 to 2001:db8::2 -> { 2001:db8::3, 2001:db8::cb00:7105 } round-robin
diff --git a/sbin/pfctl/tests/files/pf1063.in b/sbin/pfctl/tests/files/pf1063.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1063.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 2001:db8::1 to 2001:db8::2 -> (vlan1063)
diff --git a/sbin/pfctl/tests/files/pf1063.ok b/sbin/pfctl/tests/files/pf1063.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1063.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet6 proto tcp from 2001:db8::1 to 2001:db8::2 -> (vlan1063) round-robin
diff --git a/sbin/pfctl/tests/files/pf1064.in b/sbin/pfctl/tests/files/pf1064.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1064.in
@@ -0,0 +1 @@
+nat on vtnet0 proto tcp from 2001:db8::1 to 2001:db8::2 -> { fe80::2 (vlan1064) }
diff --git a/sbin/pfctl/tests/files/pf1064.ok b/sbin/pfctl/tests/files/pf1064.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1064.ok
@@ -0,0 +1 @@
+nat on vtnet0 inet6 proto tcp from 2001:db8::1 to 2001:db8::2 -> { fe80::2, (vlan1064) } round-robin
diff --git a/sbin/pfctl/tests/pfctl_test.c b/sbin/pfctl/tests/pfctl_test.c
--- a/sbin/pfctl/tests/pfctl_test.c
+++ b/sbin/pfctl/tests/pfctl_test.c
@@ -119,27 +119,14 @@
}
static void
-run_pfctl_test(const char *input_path, const char *expected_path,
- const atf_tc_t *tc)
+run_command_pipe(const char *argv[], struct sbuf **output)
{
- int status;
+ posix_spawn_file_actions_t action;
pid_t pid;
int pipefds[2];
- char input_files_path[PATH_MAX];
- struct sbuf *expected_output;
- struct sbuf *real_output;
- posix_spawn_file_actions_t action;
-
- if (!check_pf_module_available())
- atf_tc_skip("pf(4) is not loaded");
-
- /* The test inputs need to be able to use relative includes. */
- snprintf(input_files_path, sizeof(input_files_path), "%s/files",
- atf_tc_get_config_var(tc, "srcdir"));
- ATF_REQUIRE_ERRNO(0, chdir(input_files_path) == 0);
+ int status;
ATF_REQUIRE_ERRNO(0, pipe(pipefds) == 0);
- expected_output = read_file(expected_path);
posix_spawn_file_actions_init(&action);
posix_spawn_file_actions_addclose(&action, STDIN_FILENO);
@@ -147,27 +134,118 @@
posix_spawn_file_actions_adddup2(&action, pipefds[0], STDOUT_FILENO);
posix_spawn_file_actions_adddup2(&action, pipefds[0], STDERR_FILENO);
- const char *argv[] = { "pfctl", "-o", "none", "-nvf", input_path,
- NULL };
- printf("Running %s %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3],
- argv[4]);
+ printf("Running ");
+ for (int i=0; argv[i] != NULL; i++)
+ printf("%s ", argv[i]);
+ printf("\n");
+
status = posix_spawnp(
- &pid, "pfctl", &action, NULL, __DECONST(char **, argv), environ);
+ &pid, argv[0], &action, NULL, __DECONST(char **, argv), environ);
ATF_REQUIRE_EQ_MSG(
status, 0, "posix_spawn failed: %s", strerror(errno));
posix_spawn_file_actions_destroy(&action);
close(pipefds[0]);
- real_output = read_fd(pipefds[1], 0);
- printf("---\n%s---\n", sbuf_data(real_output));
+ (*output) = read_fd(pipefds[1], 0);
+ printf("---\n%s---\n", sbuf_data(*output));
ATF_REQUIRE_EQ(waitpid(pid, &status, 0), pid);
ATF_REQUIRE_MSG(WIFEXITED(status),
- "pfctl returned non-zero! Output:\n %s", sbuf_data(real_output));
+ "%s returned non-zero! Output:\n %s", argv[0], sbuf_data(*output));
+ close(pipefds[1]);
+}
+
+static void
+run_command(const char *argv[])
+{
+ posix_spawn_file_actions_t action;
+ pid_t pid;
+ int status;
+
+ posix_spawn_file_actions_init(&action);
+ posix_spawn_file_actions_addopen(&action, STDOUT_FILENO, "/dev/null", O_WRONLY, 0);
+ posix_spawn_file_actions_addopen(&action, STDERR_FILENO, "/dev/null", O_WRONLY, 0);
+ posix_spawn_file_actions_addopen(&action, STDIN_FILENO, "/dev/zero", O_RDONLY, 0);
+
+ printf("Running ");
+ for (int i=0; argv[i] != NULL; i++)
+ printf("%s ", argv[i]);
+ printf("\n");
+
+ status = posix_spawnp(
+ &pid, argv[0], &action, NULL, __DECONST(char **, argv), environ);
+ posix_spawn_file_actions_destroy(&action);
+ waitpid(pid, &status, 0);
+}
+
+static void
+run_pfctl_test(const char *input_path, const char *output_path,
+ const atf_tc_t *tc, bool test_failure)
+{
+ char input_files_path[PATH_MAX];
+ struct sbuf *expected_output;
+ struct sbuf *real_output;
+
+ if (!check_pf_module_available())
+ atf_tc_skip("pf(4) is not loaded");
+
+ /* The test inputs need to be able to use relative includes. */
+ snprintf(input_files_path, sizeof(input_files_path), "%s/files",
+ atf_tc_get_config_var(tc, "srcdir"));
+ ATF_REQUIRE_ERRNO(0, chdir(input_files_path) == 0);
+ expected_output = read_file(output_path);
+
+ const char *argv[] = { "pfctl", "-o", "none", "-nvf", input_path,
+ NULL };
+ run_command_pipe(argv, &real_output);
+
+ if (test_failure) {
+ /*
+ * Error output contains additional strings like line number
+ * or "skipping rule due to errors", so use regexp to see
+ * if the expected error message is there somewhere.
+ */
+ ATF_CHECK_MATCH(sbuf_data(expected_output), sbuf_data(real_output));
+ sbuf_delete(expected_output);
+ } else {
+ ATF_CHECK_STREQ(sbuf_data(expected_output), sbuf_data(real_output));
+ sbuf_delete(expected_output);
+ }
- ATF_CHECK_STREQ(sbuf_data(expected_output), sbuf_data(real_output));
- sbuf_delete(expected_output);
sbuf_delete(real_output);
- close(pipefds[1]);
+}
+
+static void
+do_pf_test_iface_create(const char *number)
+{
+ struct sbuf *ifconfig_output;
+ char ifname[16] = {0};
+
+ snprintf(ifname, sizeof(ifname), "vlan%s", number);
+ const char *argv[] = { "ifconfig", ifname, "create", NULL};
+ run_command_pipe(argv, &ifconfig_output);
+ sbuf_delete(ifconfig_output);
+
+ const char *argv_inet[] = { "ifconfig", ifname, "inet", "203.0.113.5/30", NULL};
+ run_command_pipe(argv_inet, &ifconfig_output);
+ sbuf_delete(ifconfig_output);
+
+ const char *argv_inet6[] = { "ifconfig", ifname, "inet6", "2001:db8::203.0.113.5/126", NULL};
+ run_command_pipe(argv_inet6, &ifconfig_output);
+ sbuf_delete(ifconfig_output);
+
+ const char *argv_show[] = { "ifconfig", ifname, NULL};
+ run_command_pipe(argv_show, &ifconfig_output);
+ sbuf_delete(ifconfig_output);
+}
+
+static void
+do_pf_test_iface_remove(const char *number)
+{
+ char ifname[16] = {0};
+
+ snprintf(ifname, sizeof(ifname), "vlan%s", number);
+ const char *argv[] = { "ifconfig", ifname, "destroy", NULL};
+ run_command(argv);
}
static void
@@ -179,7 +257,21 @@
atf_tc_get_config_var(tc, "srcdir"), number);
asprintf(&expected_path, "%s/files/pf%s.ok",
atf_tc_get_config_var(tc, "srcdir"), number);
- run_pfctl_test(input_path, expected_path, tc);
+ run_pfctl_test(input_path, expected_path, tc, false);
+ free(input_path);
+ free(expected_path);
+}
+
+static void
+do_pf_test_fail(const char *number, const atf_tc_t *tc)
+{
+ char *input_path;
+ char *expected_path;
+ asprintf(&input_path, "%s/files/pf%s.in",
+ atf_tc_get_config_var(tc, "srcdir"), number);
+ asprintf(&expected_path, "%s/files/pf%s.fail",
+ atf_tc_get_config_var(tc, "srcdir"), number);
+ run_pfctl_test(input_path, expected_path, tc, true);
free(input_path);
free(expected_path);
}
@@ -190,10 +282,11 @@
char *expected_path;
asprintf(&expected_path, "%s/files/pf%s.ok",
atf_tc_get_config_var(tc, "srcdir"), number);
- run_pfctl_test(expected_path, expected_path, tc);
+ run_pfctl_test(expected_path, expected_path, tc, false);
free(expected_path);
}
+/* Standard tests perform the normal test and then the selfpf test */
#define PFCTL_TEST(number, descr) \
ATF_TC(pf##number); \
ATF_TC_HEAD(pf##number, tc) \
@@ -213,16 +306,53 @@
{ \
do_selfpf_test(#number, tc); \
}
+/* Tests for failure perform only the normal test */
+#define PFCTL_TEST_FAIL(number, descr) \
+ ATF_TC(pf##number); \
+ ATF_TC_HEAD(pf##number, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", descr); \
+ } \
+ ATF_TC_BODY(pf##number, tc) \
+ { \
+ do_pf_test_fail(#number, tc); \
+ }
+/* Tests with interface perform only the normal test */
+#define PFCTL_TEST_IFACE(number, descr) \
+ ATF_TC_WITH_CLEANUP(pf##number); \
+ ATF_TC_HEAD(pf##number, tc) \
+ { \
+ atf_tc_set_md_var(tc, "descr", descr); \
+ atf_tc_set_md_var(tc, "execenv", "jail"); \
+ atf_tc_set_md_var(tc, "execenv.jail.params", "vnet"); \
+ } \
+ ATF_TC_BODY(pf##number, tc) \
+ { \
+ do_pf_test_iface_create(#number); \
+ do_pf_test(#number, tc); \
+ } \
+ ATF_TC_CLEANUP(pf##number, tc) \
+ { \
+ do_pf_test_iface_remove(#number); \
+ }
#include "pfctl_test_list.inc"
#undef PFCTL_TEST
+#undef PFCTL_TEST_FAIL
+#undef PFCTL_TEST_IFACE
ATF_TP_ADD_TCS(tp)
{
#define PFCTL_TEST(number, descr) \
ATF_TP_ADD_TC(tp, pf##number); \
ATF_TP_ADD_TC(tp, selfpf##number);
+#define PFCTL_TEST_FAIL(number, descr) \
+ ATF_TP_ADD_TC(tp, pf##number);
+#define PFCTL_TEST_IFACE(number, descr) \
+ ATF_TP_ADD_TC(tp, pf##number);
#include "pfctl_test_list.inc"
#undef PFCTL_TEST
+#undef PFCTL_TEST_FAIL
+#undef PFCTL_TEST_IFACE
return atf_no_error();
}
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -136,3 +136,40 @@
PFCTL_TEST(1025, "nat64 with implicit address family")
PFCTL_TEST(1026, "nat64 with route-to")
PFCTL_TEST(1027, "nat64 with reply-to")
+PFCTL_TEST(1028, "RDR pool: For RDR rules no port specified means keep port")
+PFCTL_TEST(1029, "RDR pool: A single port is shown")
+PFCTL_TEST(1030, "RDR pool: The default values are shown for RDR rules")
+PFCTL_TEST(1031, "RDR pool: Multiple ports redirected to a single port")
+PFCTL_TEST(1032, "RDR pool: Multiple ports redirected to a port range")
+PFCTL_TEST_FAIL(1033, "RDR pool: static-port can't be used with RDR rules")
+PFCTL_TEST_FAIL(1034, "RDR pool: MAP-E port can't be used with RDR rules")
+PFCTL_TEST(1035, "NAT pool: For NAT rules no port specified means default values")
+PFCTL_TEST(1036, "NAT pool: Default port numbers are not shown, even if explicitly applied")
+PFCTL_TEST(1037, "NAT pool: Single port")
+PFCTL_TEST(1038, "NAT pool: Two ports")
+PFCTL_TEST(1039, "NAT pool: Static port")
+PFCTL_TEST_FAIL(1040, "NAT pool: Static port can't be used with port numbers")
+PFCTL_TEST(1041, "NAT pool: MAP-E is displayed using decimal system")
+PFCTL_TEST_FAIL(1042, "NAT pool: MAP-E port can't be used with static port")
+PFCTL_TEST_FAIL(1043, "NAT pool: MAP-E port can't be used with port numbers")
+PFCTL_TEST(1044, "pool: sticky-address is applied on top of round-robin")
+PFCTL_TEST(1045, "pool: bitmask is allowed for prefixes")
+PFCTL_TEST_FAIL(1046, "pool: bitmask is not allowed for tables")
+PFCTL_TEST_FAIL(1047, "pool: bitmask is not allowed for interfaces in brackets")
+PFCTL_TEST(1048, "pool: random is allowed for prefixes")
+PFCTL_TEST(1049, "pool: round-robin is not set for a single host, even if it looks like a table")
+PFCTL_TEST(1050, "pool: round-robin is set automatically for tables")
+PFCTL_TEST(1051, "pool: round-robin is set automatically for multiple targets")
+PFCTL_TEST(1052, "pool: hosts and table are allowed, round-robin is automatically set")
+PFCTL_TEST(1053, "pool: round-robin is not set automatically for prefixes")
+PFCTL_TEST(1054, "pool: round-robin is allowed for prefixes")
+PFCTL_TEST(1055, "pool: source hash")
+PFCTL_TEST(1056, "af-to: from and to")
+PFCTL_TEST_IFACE(1057, "Interface translation: IPv4 rule, interface without brackets is translated")
+PFCTL_TEST_IFACE(1058, "Interface translation: IPv4 rule, interface without brackets is translated, extra host, round-robin is applied")
+PFCTL_TEST_IFACE(1059, "Interface translation: IPv4 rule, interface with brackets is not translated, round-robin is applied")
+PFCTL_TEST_IFACE(1060, "Interface translation: IPv4 rule, interface with brackets is not translated, extra host, round-robin is applied")
+PFCTL_TEST_IFACE(1061, "Interface translation: IPv6 rule, interface without brackets is translated")
+PFCTL_TEST_IFACE(1062, "Interface translation: IPv6 rule, interface without brackets is translated, extra host, round-robin is applied")
+PFCTL_TEST_IFACE(1063, "Interface translation: IPv6 rule, interface with brackets is not translated, round-robin is applied")
+PFCTL_TEST_IFACE(1064, "Interface translation: IPv6 rule, interface with brackets is not translated, extra host, round robin is applied")
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Aug 12, 3:33 AM (1 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29398003
Default Alt Text
D49218.1786505635.diff (56 KB)
Attached To
Mode
D49218: pfctl: Split pool parsing into separate functions
Attached
Detach File
Event Timeline
Log In to Comment