From: Alexandr Nedvedicky Subject: Re: tell pfctl(8) route-to no longer expects network interface To: tech@openbsd.org Date: Sun, 3 May 2026 00:06:53 +0200 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 *,