Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107488840
D29936.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D29936.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -53,7 +53,7 @@
struct pf_rule_addr src;
struct pf_rule_addr dst;
union pf_rule_ptr skip[PF_SKIP_COUNT];
- char label[PF_RULE_LABEL_SIZE];
+ char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -301,7 +301,8 @@
pf_nvrule_to_rule(const nvlist_t *nvl, struct pfctl_rule *rule)
{
const uint64_t *skip;
- size_t skipcount;
+ const char *const *labels;
+ size_t skipcount, labelcount;
rule->nr = nvlist_get_number(nvl, "nr");
@@ -314,7 +315,10 @@
for (int i = 0; i < PF_SKIP_COUNT; i++)
rule->skip[i].nr = skip[i];
- strlcpy(rule->label, nvlist_get_string(nvl, "label"), PF_RULE_LABEL_SIZE);
+ labels = nvlist_get_string_array(nvl, "labels", &labelcount);
+ assert(labelcount <= PF_RULE_MAX_LABEL_COUNT);
+ for (size_t i = 0; i < labelcount; i++)
+ strlcpy(rule->label[i], labels[i], PF_RULE_LABEL_SIZE);
strlcpy(rule->ifname, nvlist_get_string(nvl, "ifname"), IFNAMSIZ);
strlcpy(rule->qname, nvlist_get_string(nvl, "qname"), PF_QNAME_SIZE);
strlcpy(rule->pqname, nvlist_get_string(nvl, "pqname"), PF_QNAME_SIZE);
@@ -404,6 +408,7 @@
u_int64_t timeouts[PFTM_MAX];
u_int64_t set_prio[2];
nvlist_t *nvl, *nvlr;
+ size_t labelcount;
int ret;
nvl = nvlist_create(0);
@@ -418,7 +423,14 @@
pfctl_nv_add_rule_addr(nvlr, "src", &r->src);
pfctl_nv_add_rule_addr(nvlr, "dst", &r->dst);
- nvlist_add_string(nvlr, "label", r->label);
+ labelcount = 0;
+ while (r->label[labelcount][0] != 0 &&
+ labelcount < PF_RULE_MAX_LABEL_COUNT) {
+ nvlist_append_string_array(nvlr, "labels",
+ r->label[labelcount]);
+ labelcount++;
+ }
+
nvlist_add_string(nvlr, "ifname", r->ifname);
nvlist_add_string(nvlr, "qname", r->qname);
nvlist_add_string(nvlr, "pqname", r->pqname);
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -55,6 +55,7 @@
#include <net/altq/altq_hfsc.h>
#include <net/altq/altq_fairq.h>
+#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -241,7 +242,8 @@
} keep;
int fragment;
int allowopts;
- char *label;
+ char *label[PF_RULE_MAX_LABEL_COUNT];
+ int labelcount;
struct node_qassign queues;
char *tag;
char *match_tag;
@@ -256,7 +258,8 @@
} filter_opts;
static struct antispoof_opts {
- char *label;
+ char *label[PF_RULE_MAX_LABEL_COUNT];
+ int labelcount;
u_int rtableid;
} antispoof_opts;
@@ -349,7 +352,7 @@
int check_rulestate(int);
int getservice(char *);
-int rule_label(struct pfctl_rule *, char *);
+int rule_label(struct pfctl_rule *, char *s[PF_RULE_MAX_LABEL_COUNT]);
int rt_tableid_max(void);
void mv_rules(struct pfctl_ruleset *, struct pfctl_ruleset *);
@@ -887,7 +890,8 @@
r.match_tag_not = $9.match_tag_not;
if (rule_label(&r, $9.label))
YYERROR;
- free($9.label);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
+ free($9.label[i]);
r.flags = $9.flags.b1;
r.flagset = $9.flags.b2;
if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
@@ -1333,7 +1337,8 @@
} else
free(hh);
}
- free($5.label);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
+ free($5.label[i]);
}
;
@@ -1374,11 +1379,11 @@
;
antispoof_opt : label {
- if (antispoof_opts.label) {
- yyerror("label cannot be redefined");
+ if (antispoof_opts.labelcount >= PF_RULE_MAX_LABEL_COUNT) {
+ yyerror("label can only be used %d times", PF_RULE_MAX_LABEL_COUNT);
YYERROR;
}
- antispoof_opts.label = $1;
+ antispoof_opts.label[antispoof_opts.labelcount++] = $1;
}
| RTABLE NUMBER {
if ($2 < 0 || $2 > rt_tableid_max()) {
@@ -2093,7 +2098,8 @@
r.match_tag_not = $9.match_tag_not;
if (rule_label(&r, $9.label))
YYERROR;
- free($9.label);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
+ free($9.label[i]);
r.flags = $9.flags.b1;
r.flagset = $9.flags.b2;
if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
@@ -2531,11 +2537,11 @@
filter_opts.allowopts = 1;
}
| label {
- if (filter_opts.label) {
- yyerror("label cannot be redefined");
+ if (filter_opts.labelcount >= PF_RULE_MAX_LABEL_COUNT) {
+ yyerror("label can only be used %d times", PF_RULE_MAX_LABEL_COUNT);
YYERROR;
}
- filter_opts.label = $1;
+ filter_opts.label[filter_opts.labelcount++] = $1;
}
| qname {
if (filter_opts.queues.qname) {
@@ -5316,15 +5322,15 @@
sa_family_t af = r->af;
int added = 0, error = 0;
char ifname[IF_NAMESIZE];
- char label[PF_RULE_LABEL_SIZE];
+ char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
struct pf_pooladdr *pa;
struct node_host *h;
u_int8_t flags, flagset, keep_state;
- if (strlcpy(label, r->label, sizeof(label)) >= sizeof(label))
- errx(1, "expand_rule: strlcpy");
+ memcpy(label, r->label, sizeof(r->label));
+ assert(sizeof(r->label) == sizeof(label));
if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
errx(1, "expand_rule: strlcpy");
if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
@@ -5373,17 +5379,17 @@
else
memset(r->ifname, '\0', sizeof(r->ifname));
- if (strlcpy(r->label, label, sizeof(r->label)) >=
- sizeof(r->label))
- errx(1, "expand_rule: strlcpy");
+ memcpy(r->label, label, sizeof(r->label));
if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
sizeof(r->tagname))
errx(1, "expand_rule: strlcpy");
if (strlcpy(r->match_tagname, match_tagname,
sizeof(r->match_tagname)) >= sizeof(r->match_tagname))
errx(1, "expand_rule: strlcpy");
- expand_label(r->label, PF_RULE_LABEL_SIZE, r->ifname, r->af,
- src_host, src_port, dst_host, dst_port, proto->proto);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
+ expand_label(r->label[i], PF_RULE_LABEL_SIZE,
+ r->ifname, r->af, src_host, src_port, dst_host,
+ dst_port, proto->proto);
expand_label(r->tagname, PF_TAG_NAME_SIZE, r->ifname, r->af,
src_host, src_port, dst_host, dst_port, proto->proto);
expand_label(r->match_tagname, PF_TAG_NAME_SIZE, r->ifname,
@@ -6273,13 +6279,16 @@
}
int
-rule_label(struct pfctl_rule *r, char *s)
+rule_label(struct pfctl_rule *r, char *s[PF_RULE_MAX_LABEL_COUNT])
{
- if (s) {
- if (strlcpy(r->label, s, sizeof(r->label)) >=
- sizeof(r->label)) {
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) {
+ if (s[i] == NULL)
+ return (0);
+
+ if (strlcpy(r->label[i], s[i], sizeof(r->label[0])) >=
+ sizeof(r->label[0])) {
yyerror("rule label too long (max %d chars)",
- sizeof(r->label)-1);
+ sizeof(r->label[0])-1);
return (-1);
}
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -996,11 +996,18 @@
goto error;
switch (format) {
- case PFCTL_SHOW_LABELS:
- if (rule.label[0]) {
- printf("%s %llu %llu %llu %llu"
+ case PFCTL_SHOW_LABELS: {
+ bool show = false;
+ int i = 0;
+
+ while (rule.label[i][0]) {
+ printf("%s ", rule.label[i++]);
+ show = true;
+ }
+
+ if (show) {
+ printf("%llu %llu %llu %llu"
" %llu %llu %llu %ju\n",
- rule.label,
(unsigned long long)rule.evaluations,
(unsigned long long)(rule.packets[0] +
rule.packets[1]),
@@ -1013,6 +1020,7 @@
(uintmax_t)rule.states_tot);
}
break;
+ }
case PFCTL_SHOW_RULES:
brace = 0;
if (rule.label[0] && (opts & PF_OPT_SHOWALL))
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1019,8 +1019,9 @@
printf(" fragment reassemble");
}
- if (r->label[0])
- printf(" label \"%s\"", r->label);
+ i = 0;
+ while (r->label[i][0])
+ printf(" label \"%s\"", r->label[i++]);
if (r->qname[0] && r->pqname[0])
printf(" queue(%s, %s)", r->qname, r->pqname);
else if (r->qname[0])
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -324,7 +324,7 @@
struct pf_rule_addr src;
struct pf_rule_addr dst;
union pf_krule_ptr skip[PF_SKIP_COUNT];
- char label[PF_RULE_LABEL_SIZE];
+ char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -450,6 +450,7 @@
#define PF_SKIP_COUNT 8
union pf_rule_ptr skip[PF_SKIP_COUNT];
#define PF_RULE_LABEL_SIZE 64
+#define PF_RULE_MAX_LABEL_COUNT 5
char label[PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -992,7 +992,8 @@
pf_hash_rule_addr(ctx, &rule->src);
pf_hash_rule_addr(ctx, &rule->dst);
- PF_MD5_UPD_STR(rule, label);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
+ PF_MD5_UPD_STR(rule, label[i]);
PF_MD5_UPD_STR(rule, ifname);
PF_MD5_UPD_STR(rule, match_tagname);
PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
@@ -1556,7 +1557,7 @@
rule->skip[i].nr = krule->skip[i].ptr->nr;
}
- strlcpy(rule->label, krule->label, sizeof(rule->label));
+ strlcpy(rule->label, krule->label[0], sizeof(rule->label));
strlcpy(rule->ifname, krule->ifname, sizeof(rule->ifname));
strlcpy(rule->qname, krule->qname, sizeof(rule->qname));
strlcpy(rule->pqname, krule->pqname, sizeof(rule->pqname));
@@ -1977,7 +1978,30 @@
PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"),
&rule->dst));
- PFNV_CHK(pf_nvstring(nvl, "label", rule->label, sizeof(rule->label)));
+ if (nvlist_exists_string(nvl, "label")) {
+ PFNV_CHK(pf_nvstring(nvl, "label", rule->label[0],
+ sizeof(rule->label[0])));
+ } else if (nvlist_exists_string_array(nvl, "labels")) {
+ const char *const *strs;
+ size_t items;
+ int ret;
+
+ strs = nvlist_get_string_array(nvl, "labels", &items);
+ if (items > PF_RULE_MAX_LABEL_COUNT) {
+ error = E2BIG;
+ goto errout;
+ }
+
+ for (size_t i = 0; i < items; i++) {
+ ret = strlcpy(rule->label[i], strs[i],
+ sizeof(rule->label[0]));
+ if (ret >= sizeof(rule->label[0])) {
+ error = E2BIG;
+ goto errout;
+ }
+ }
+ }
+
PFNV_CHK(pf_nvstring(nvl, "ifname", rule->ifname,
sizeof(rule->ifname)));
PFNV_CHK(pf_nvstring(nvl, "qname", rule->qname, sizeof(rule->qname)));
@@ -2151,7 +2175,10 @@
rule->skip[i].ptr ? rule->skip[i].ptr->nr : -1);
}
- nvlist_add_string(nvl, "label", rule->label);
+ for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) {
+ nvlist_append_string_array(nvl, "labels", rule->label[i]);
+ }
+ nvlist_add_string(nvl, "label", rule->label[0]);
nvlist_add_string(nvl, "ifname", rule->ifname);
nvlist_add_string(nvl, "qname", rule->qname);
nvlist_add_string(nvl, "pqname", rule->pqname);
@@ -2284,7 +2311,7 @@
bcopy(&rule->src, &krule->src, sizeof(rule->src));
bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
- strlcpy(krule->label, rule->label, sizeof(rule->label));
+ strlcpy(krule->label[0], rule->label, sizeof(rule->label));
strlcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
strlcpy(krule->qname, rule->qname, sizeof(rule->qname));
strlcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
@@ -2522,6 +2549,20 @@
return (error);
}
+static bool
+pf_label_match(const struct pf_krule *rule, const char *label)
+{
+ int i = 0;
+
+ while (*rule->label[i]) {
+ if (strcmp(rule->label[i], label) == 0)
+ return (true);
+ i++;
+ }
+
+ return (false);
+}
+
static int
pf_killstates_row(struct pfioc_state_kill *psk, struct pf_idhash *ih)
{
@@ -2571,8 +2612,8 @@
psk->psk_dst.port[0], psk->psk_dst.port[1], dstport))
continue;
- if (psk->psk_label[0] && (! s->rule.ptr->label[0] ||
- strcmp(psk->psk_label, s->rule.ptr->label)))
+ if (psk->psk_label[0] &&
+ ! pf_label_match(s->rule.ptr, psk->psk_label))
continue;
if (psk->psk_ifname[0] && strcmp(psk->psk_ifname,
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -1545,7 +1545,7 @@
strlcpy(e->name, path, sizeof(e->name));
if (path[0])
strlcat(e->name, "/", sizeof(e->name));
- strlcat(e->name, rule.label, sizeof(e->name));
+ strlcat(e->name, rule.label[0], sizeof(e->name));
e->evals = rule.evaluations;
e->bytes[IN] = rule.bytes[IN];
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jan 15, 10:37 PM (17 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15816301
Default Alt Text
D29936.diff (12 KB)
Attached To
Mode
D29936: pf: Allow multiple labels to be set on a rule
Attached
Detach File
Event Timeline
Log In to Comment