aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2022-05-31 12:00:52 +0000
committerKristof Provost <kp@FreeBSD.org>2022-06-20 08:16:20 +0000
commit1f61367f8d61fd6963a47296a86f553c403b5f91 (patch)
tree06bcd6dcc0742f4961685289e0765cc0a783a165 /sbin
parente417249016efcca73c9edad21b94b1315bc44601 (diff)
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/parse.y33
-rw-r--r--sbin/pfctl/pfctl_parser.c5
2 files changed, 38 insertions, 0 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 21729fc7ba4e..506716bca689 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1197,6 +1197,14 @@ etherrule : ETHER action dir quick interface etherproto etherfromto l3fromto eth
r.quick = $4.quick;
if ($9.tag != NULL)
memcpy(&r.tagname, $9.tag, sizeof(r.tagname));
+ if ($9.match_tag)
+ if (strlcpy(r.match_tagname, $9.match_tag,
+ PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
+ yyerror("tag too long, max %u chars",
+ PF_TAG_NAME_SIZE - 1);
+ YYERROR;
+ }
+ r.match_tag_not = $9.match_tag_not;
if ($9.queues.qname != NULL)
memcpy(&r.qname, $9.queues.qname, sizeof(r.qname));
r.dnpipe = $9.dnpipe;
@@ -1320,6 +1328,10 @@ etherfilter_opt : etherqname {
| TAG string {
filter_opts.tag = $2;
}
+ | not TAGGED string {
+ filter_opts.match_tag = $3;
+ filter_opts.match_tag_not = $1;
+ }
| DNPIPE number {
filter_opts.dnpipe = $2;
filter_opts.free_flags |= PFRULE_DN_IS_PIPE;
@@ -5772,6 +5784,18 @@ expand_eth_rule(struct pfctl_eth_rule *r,
struct node_mac *srcs, struct node_mac *dsts,
struct node_host *ipsrcs, struct node_host *ipdsts, const char *anchor_call)
{
+ char tagname[PF_TAG_NAME_SIZE];
+ char match_tagname[PF_TAG_NAME_SIZE];
+ char qname[PF_QNAME_SIZE];
+
+ if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
+ errx(1, "expand_eth_rule: tagname");
+ if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
+ sizeof(match_tagname))
+ errx(1, "expand_eth_rule: match_tagname");
+ if (strlcpy(qname, r->qname, sizeof(qname)) >= sizeof(qname))
+ errx(1, "expand_eth_rule: qname");
+
LOOP_THROUGH(struct node_if, interface, interfaces,
LOOP_THROUGH(struct node_etherproto, proto, protos,
LOOP_THROUGH(struct node_mac, src, srcs,
@@ -5800,6 +5824,15 @@ expand_eth_rule(struct pfctl_eth_rule *r,
r->dst.isset = dst->isset;
r->nr = pf->eastack[pf->asd]->match++;
+ if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
+ sizeof(r->tagname))
+ errx(1, "expand_eth_rule: r->tagname");
+ if (strlcpy(r->match_tagname, match_tagname,
+ sizeof(r->match_tagname)) >= sizeof(r->match_tagname))
+ errx(1, "expand_eth_rule: r->match_tagname");
+ if (strlcpy(r->qname, qname, sizeof(r->qname)) >= sizeof(r->qname))
+ errx(1, "expand_eth_rule: r->qname");
+
pfctl_append_eth_rule(pf, r, anchor_call);
))))));
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 1f6a194591c0..a05683f0cbce 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -791,6 +791,11 @@ print_eth_rule(struct pfctl_eth_rule *r, const char *anchor_call,
printf(" queue %s", r->qname);
if (r->tagname[0])
printf(" tag %s", r->tagname);
+ if (r->match_tagname[0]) {
+ if (r->match_tag_not)
+ printf(" !");
+ printf(" tagged %s", r->match_tagname);
+ }
if (r->dnpipe)
printf(" %s %d",
r->dnflags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue",