The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=8821216727043dde9cb23a66b884f7918c80063c
commit 8821216727043dde9cb23a66b884f7918c80063c Author: Kristof Provost <k...@freebsd.org> AuthorDate: 2025-08-27 13:41:07 +0000 Commit: Kristof Provost <k...@freebsd.org> CommitDate: 2025-09-25 12:41:08 +0000 pfctl: One shot rules can be used in pf.conf by specifying a "once" filter option. ok henning, mcbride Obtained from: OpenBSD, mikeb <mi...@openbsd.org>, 44b1b5a8a9 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sbin/pfctl/parse.y | 17 +++++++++++++++-- sbin/pfctl/pfctl_parser.c | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 0628b387b4b3..c35460f5443d 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -267,7 +267,7 @@ static struct filter_opts { #define FOM_SETTOS 0x0100 #define FOM_SCRUB_TCP 0x0200 #define FOM_SETPRIO 0x0400 -#define FOM_ONCE 0x1000 /* not yet implemmented */ +#define FOM_ONCE 0x1000 #define FOM_PRIO 0x2000 #define FOM_SETDELAY 0x4000 #define FOM_FRAGCACHE 0x8000 /* does not exist in OpenBSD */ @@ -541,7 +541,7 @@ int parseport(char *, struct range *r, int); %token ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME %token UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL %token DNPIPE DNQUEUE RIDENTIFIER -%token LOAD RULESET_OPTIMIZATION PRIO +%token LOAD RULESET_OPTIMIZATION PRIO ONCE %token STICKYADDRESS ENDPI MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW ALLOW_RELATED %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS @@ -1061,6 +1061,12 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto } } + if ($9.marker & FOM_ONCE) { + yyerror("cannot specify 'once' " + "on anchors"); + YYERROR; + } + if (filteropts_to_rule(&r, &$9)) YYERROR; @@ -2390,6 +2396,9 @@ pfrule : action dir logquick interface route af proto fromto r.quick = $3.quick; r.af = $6; + if ($9.marker & FOM_ONCE) + r.rule_flag |= PFRULE_ONCE; + if (filteropts_to_rule(&r, &$9)) YYERROR; @@ -3036,6 +3045,9 @@ filter_opt : USER uids { } filter_opts.max_pkt_size = $2; } + | ONCE { + filter_opts.marker |= FOM_ONCE; + } | filter_sets ; @@ -6725,6 +6737,7 @@ lookup(char *s) { "no-route", NOROUTE}, { "no-sync", NOSYNC}, { "on", ON}, + { "once", ONCE}, { "optimization", OPTIMIZATION}, { "os", OS}, { "out", OUT}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 9609e880584f..ce493570a25e 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1234,6 +1234,8 @@ print_rule(struct pfctl_rule *r, const char *anchor_call, int verbose, int numer printf(" %s %d", r->free_flags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue", r->dnpipe); + if (r->rule_flag & PFRULE_ONCE) + printf(" once"); if (r->qname[0] && r->pqname[0]) printf(" queue(%s, %s)", r->qname, r->pqname); else if (r->qname[0])