diff options
Diffstat (limited to 'sbin/pfctl')
-rw-r--r-- | sbin/pfctl/parse.y | 50 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.8 | 24 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 6 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_radix.c | 3 | ||||
-rw-r--r-- | sbin/pfctl/tests/files/pf1073.in | 1 | ||||
-rw-r--r-- | sbin/pfctl/tests/files/pf1073.ok | 1 | ||||
-rw-r--r-- | sbin/pfctl/tests/files/pf1074.fail | 1 | ||||
-rw-r--r-- | sbin/pfctl/tests/files/pf1074.in | 1 | ||||
-rw-r--r-- | sbin/pfctl/tests/pfctl_test_list.inc | 2 |
9 files changed, 57 insertions, 32 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 00c36b218055..59c27d1f5d7c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -238,6 +238,7 @@ static struct pool_opts { #define POM_TYPE 0x01 #define POM_STICKYADDRESS 0x02 #define POM_ENDPI 0x04 +#define POM_IPV6NH 0x08 u_int8_t opts; int type; int staticport; @@ -543,7 +544,7 @@ int parseport(char *, struct range *r, int); %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW ALLOW_RELATED %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS %token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE AFTO NATTO RDRTO -%token BINATTO MAXPKTRATE MAXPKTSIZE +%token BINATTO MAXPKTRATE MAXPKTSIZE IPV6NH %token <v.string> STRING %token <v.number> NUMBER %token <v.i> PORTBINARY @@ -2648,13 +2649,16 @@ pfrule : action dir logquick interface route af proto fromto YYERROR; } r.rt = $5.rt; - decide_address_family($5.redirspec->host, &r.af); - if (!(r.rule_flag & PFRULE_AFTO)) - remove_invalid_hosts(&($5.redirspec->host), &r.af); - if ($5.redirspec->host == NULL) { - yyerror("no routing address with " - "matching address family found."); - YYERROR; + + if (!($5.redirspec->pool_opts.opts & PF_POOL_IPV6NH)) { + decide_address_family($5.redirspec->host, &r.af); + if (!(r.rule_flag & PFRULE_AFTO)) + remove_invalid_hosts(&($5.redirspec->host), &r.af); + if ($5.redirspec->host == NULL) { + yyerror("no routing address with " + "matching address family found."); + YYERROR; + } } } #ifdef __FreeBSD__ @@ -2978,7 +2982,8 @@ filter_opt : USER uids { filter_opts.nat = $4; filter_opts.nat->af = $2; - if ($4->af && $4->af != $2) { + remove_invalid_hosts(&($4->host), &(filter_opts.nat->af)); + if ($4->host == NULL) { yyerror("af-to addresses must be in the " "target address family"); YYERROR; @@ -2998,8 +3003,9 @@ filter_opt : USER uids { 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)) { + remove_invalid_hosts(&($4->host), &(filter_opts.nat->af)); + remove_invalid_hosts(&($6->host), &(filter_opts.rdr->af)); + if ($4->host == NULL || $6->host == NULL) { yyerror("af-to addresses must be in the " "target address family"); YYERROR; @@ -4674,6 +4680,14 @@ pool_opt : BITMASK { pool_opts.marker |= POM_ENDPI; pool_opts.opts |= PF_POOL_ENDPI; } + | IPV6NH { + if (pool_opts.marker & POM_IPV6NH) { + yyerror("prefer-ipv6-nexthop cannot be redefined"); + YYERROR; + } + pool_opts.marker |= POM_IPV6NH; + pool_opts.opts |= PF_POOL_IPV6NH; + } | MAPEPORTSET number '/' number '/' number { if (pool_opts.mape.offset) { yyerror("map-e-portset cannot be redefined"); @@ -4813,6 +4827,12 @@ natrule : nataction interface af proto fromto tag tagged rtable "address'"); YYERROR; } + if ($9->pool_opts.opts & PF_POOL_IPV6NH) { + yyerror("The prefer-ipv6-nexthop option " + "can't be used for nat/rdr/binat pools" + ); + YYERROR; + } if (!r.af && ! $9->host->ifindex) r.af = $9->host->af; @@ -5074,13 +5094,6 @@ route_host : STRING { route_host_list : route_host optnl { $$ = $1; } | route_host_list comma route_host optnl { - if ($1->af == 0) - $1->af = $3->af; - if ($1->af != $3->af) { - yyerror("all pool addresses must be in the " - "same address family"); - YYERROR; - } $1->tail->next = $3; $1->tail = $3->tail; $$ = $1; @@ -6678,6 +6691,7 @@ lookup(char *s) { "pass", PASS}, { "pflow", PFLOW}, { "port", PORT}, + { "prefer-ipv6-nexthop", IPV6NH}, { "prio", PRIO}, { "priority", PRIORITY}, { "priq", PRIQ}, diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index f582c6301124..5a74a8fd3444 100644 --- a/sbin/pfctl/pfctl.8 +++ b/sbin/pfctl/pfctl.8 @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd July 7, 2025 +.Dd August 5, 2025 .Dt PFCTL 8 .Os .Sh NAME @@ -410,6 +410,7 @@ This is the default behaviour. .It Fl o Cm profile Enable basic ruleset optimizations with profiling. .El +.Pp For further information on the ruleset optimizer, see .Xr pf.conf 5 . .It Fl P @@ -431,7 +432,7 @@ Perform reverse DNS lookups on states and tables when displaying them. and .Fl r are mutually exclusive. -.It Fl s Ar modifier +.It Fl s Ar modifier Op Fl R Ar id Show the filter parameters specified by .Ar modifier (may be abbreviated): @@ -563,19 +564,16 @@ no free ports in translation port range .It Fl S Do not perform domain name resolution. If a name cannot be resolved without DNS, an error will be reported. -.It Fl T Ar command Op Ar address ... +.It Fl t Ar table Fl T Ar command Op Ar address ... Specify the .Ar command -(may be abbreviated) to apply to the table. +(may be abbreviated) to apply to +.Ar table . Commands include: .Pp -.Bl -tag -width xxxxxxxxxxxx -compact -.It Fl T Cm kill -Kill a table. -.It Fl T Cm flush -Flush all addresses of a table. +.Bl -tag -width "-T expire number" -compact .It Fl T Cm add -Add one or more addresses in a table. +Add one or more addresses to a table. Automatically create a persistent table if it does not exist. .It Fl T Cm delete Delete one or more addresses from a table. @@ -586,6 +584,10 @@ seconds ago. For entries which have never had their statistics cleared, .Ar number refers to the time they were added to the table. +.It Fl T Cm flush +Flush all addresses in a table. +.It Fl T Cm kill +Kill a table. .It Fl T Cm replace Replace the addresses of the table. Automatically create a persistent table if it does not exist. @@ -765,8 +767,6 @@ tables of the same name from anchors attached below it. .It C This flag is set when per-address counters are enabled on the table. .El -.It Fl t Ar table -Specify the name of the table. .It Fl v Produce more verbose output. A second use of diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 18b78a150c28..3c4f9f6b4334 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -508,6 +508,8 @@ print_pool(struct pfctl_pool *pool, u_int16_t p1, u_int16_t p2, int id) if (pool->mape.offset > 0) printf(" map-e-portset %u/%u/%u", pool->mape.offset, pool->mape.psidlen, pool->mape.psid); + if (pool->opts & PF_POOL_IPV6NH) + printf(" prefer-ipv6-nexthop"); } void @@ -1438,7 +1440,7 @@ ifa_add_groups_to_map(char *ifa_name) ENTRY item; ENTRY *ret_item; int *answer; - + item.key = ifg->ifgrq_group; if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) { struct ifgroupreq ifgr2; @@ -1580,7 +1582,7 @@ is_a_group(char *name) { ENTRY item; ENTRY *ret_item; - + item.key = name; if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) return (0); diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c index 0fe9ca8813bb..398c5e998330 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -122,6 +122,9 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, { int ret; + if (*nadd) + *nadd = 0; + ret = pfctl_table_add_addrs_h(pfh, tbl, addr, size, nadd, flags); if (ret) { errno = ret; diff --git a/sbin/pfctl/tests/files/pf1073.in b/sbin/pfctl/tests/files/pf1073.in new file mode 100644 index 000000000000..477995893ac3 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1073.in @@ -0,0 +1 @@ +pass in on vtnet0 route-to ( vtnet1 2001:db8::1 ) prefer-ipv6-nexthop inet diff --git a/sbin/pfctl/tests/files/pf1073.ok b/sbin/pfctl/tests/files/pf1073.ok new file mode 100644 index 000000000000..f34867508c75 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1073.ok @@ -0,0 +1 @@ +pass in on vtnet0 route-to (vtnet1 2001:db8::1) prefer-ipv6-nexthop inet all flags S/SA keep state diff --git a/sbin/pfctl/tests/files/pf1074.fail b/sbin/pfctl/tests/files/pf1074.fail new file mode 100644 index 000000000000..afe8ee3c458f --- /dev/null +++ b/sbin/pfctl/tests/files/pf1074.fail @@ -0,0 +1 @@ +no routing address with matching address family found. diff --git a/sbin/pfctl/tests/files/pf1074.in b/sbin/pfctl/tests/files/pf1074.in new file mode 100644 index 000000000000..5d285bc5d6e8 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1074.in @@ -0,0 +1 @@ +pass in on vtnet0 route-to ( vtnet1 2001:db8::1 ) inet diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc index 3a68cc06ec74..8bfccddf50e5 100644 --- a/sbin/pfctl/tests/pfctl_test_list.inc +++ b/sbin/pfctl/tests/pfctl_test_list.inc @@ -181,3 +181,5 @@ PFCTL_TEST(1069, "max-pkt-size") PFCTL_TEST_FAIL(1070, "include line number") PFCTL_TEST(1071, "mask length on (lo0)") PFCTL_TEST_FAIL(1072, "Invalid port range") +PFCTL_TEST(1073, "Filter AF different than route-to AF, with prefer-ipv6-nexthop") +PFCTL_TEST_FAIL(1074, "Filter AF different than route-to AF, without prefer-ipv6-nexthop") |