Download raw body.
tell pfctl(8) route-to no longer expects network interface
Hello,
diff below is better, but still breaks regress test pfail57.in:
pass in inet af-to inet6 from 2001:db8::1
pass in inet af-to inet6 from 2001:db8::1 route-to lo0
pass in inet af-to inet6 from 2001:db8::1 reply-to lo0
pass in inet af-to inet6 from 2001:db8::1 dup-to lo0
pass in inet6 af-to inet from 192.0.2.1
pass in inet6 af-to inet from 192.0.2.1 route-to lo0
pass in inet6 af-to inet from 192.0.2.1 reply-to lo0
pass in inet6 af-to inet from 192.0.2.1 dup-to lo0
The diff is minimalistic change which refuses interface name
as route-to/reply-to/dup-to parameter. If we agree
it is not desired to pass interface name, then test needs
to be adjusted too.
The diff below refuses rules like;
pass in inet6 af-to inet from 192.0.2.1 dup-to lo0
or
pass in inet6 af-to inet from 192.0.2.1 dup-to (lo0)
The diff itself is hack. We just remember the parser
input and re-check it when we know the context where
the parsed value is being used.
Also the change does not address the case as follows:
pass in inet6 af-to inet from 192.0.2.1 route-to lo0 - re0
rule above is still accepted. And route-to parameter
is interpreted as address range defined by addresses
bound to lo0 and re0.
thanks and
regards
sashan
--------8<---------------8<-----------------8<--------
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 92764edcf3b..be3c6348f2c 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -3147,8 +3147,7 @@ host : STRING {
yyerror("could not parse host specification");
YYERROR;
}
- free($1);
-
+ $$->parser_input = $1;
}
| STRING '-' STRING {
struct node_host *b, *e;
@@ -3326,7 +3325,7 @@ dynaddr : '(' STRING ')' {
yyerror("interface name too long");
YYERROR;
}
- free(op);
+ $$->parser_input = op;
$$->next = NULL;
$$->tail = $$;
}
@@ -4212,6 +4211,16 @@ routespec : redirspec pool_opts {
if (redir == NULL)
err(1, "routespec calloc");
redir->host = $1;
+ if (redir->host->parser_input != NULL) {
+ struct node_host *chk_if;
+
+ chk_if = host_if(redir->host->parser_input, 0);
+ if (chk_if != NULL) {
+ yyerror("route-to/reply-to/dup-to: "
+ "network interface not expected");
+ YYERROR;
+ }
+ }
filter_opts.rroute.rdr = redir;
memcpy(&filter_opts.rroute.pool_opts, &$2,
sizeof(filter_opts.rroute.pool_opts));
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index c65a805ad90..b85a10c0391 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -150,6 +150,7 @@ struct node_host {
u_int32_t ifindex; /* link-local IPv6 addrs */
u_int16_t weight; /* load balancing weight */
char *ifname;
+ char *parser_input;
u_int ifa_flags;
struct node_host *next;
struct node_host *tail;
@@ -332,6 +333,7 @@ char *ifa_indextoname(unsigned int, char *);
struct node_host *ifa_exists(const char *);
struct node_host *ifa_lookup(const char *, int);
struct node_host *host(const char *, int);
+struct node_host *host_if(const char *, int);
int append_addr(struct pfr_buffer *, char *, int, int);
int append_addr_host(struct pfr_buffer *,
tell pfctl(8) route-to no longer expects network interface