pf: introduce ridentifier and labels to ether rules

Make Ethernet rules more similar to the usual layer 3 rules by also
allowing ridentifier and labels to be set on them.

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Christian McDonald
2023-04-24 14:55:34 -04:00
committed by Kristof Provost
parent 0912408a28
commit ef661d4a5b
18 changed files with 112 additions and 3 deletions
+33
View File
@@ -379,6 +379,7 @@ int expand_skip_interface(struct node_if *);
int check_rulestate(int);
int getservice(char *);
int rule_label(struct pfctl_rule *, char *s[PF_RULE_MAX_LABEL_COUNT]);
int eth_rule_label(struct pfctl_eth_rule *, char *s[PF_RULE_MAX_LABEL_COUNT]);
int rt_tableid_max(void);
void mv_rules(struct pfctl_ruleset *, struct pfctl_ruleset *);
@@ -1243,6 +1244,11 @@ etherrule : ETHER action dir quick interface bridge etherproto etherfromto l3fro
memcpy(&r.qname, $10.queues.qname, sizeof(r.qname));
r.dnpipe = $10.dnpipe;
r.dnflags = $10.free_flags;
if (eth_rule_label(&r, $10.label))
YYERROR;
for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
free($10.label[i]);
r.ridentifier = $10.ridentifier;
expand_eth_rule(&r, $5, $7, $8.src, $8.dst,
$9.src.host, $9.dst.host, $6, "");
@@ -1366,6 +1372,16 @@ etherfilter_opt : etherqname {
}
filter_opts.queues = $1;
}
| RIDENTIFIER number {
filter_opts.ridentifier = $2;
}
| label {
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[filter_opts.labelcount++] = $1;
}
| TAG string {
filter_opts.tag = $2;
}
@@ -6945,6 +6961,23 @@ rule_label(struct pfctl_rule *r, char *s[PF_RULE_MAX_LABEL_COUNT])
return (0);
}
int
eth_rule_label(struct pfctl_eth_rule *r, char *s[PF_RULE_MAX_LABEL_COUNT])
{
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[0])-1);
return (-1);
}
}
return (0);
}
u_int16_t
parseicmpspec(char *w, sa_family_t af)
{
+9
View File
@@ -755,6 +755,8 @@ print_eth_rule(struct pfctl_eth_rule *r, const char *anchor_call,
static const char *actiontypes[] = { "pass", "block", "", "", "", "",
"", "", "", "", "", "", "match" };
int i;
if (rule_numbers)
printf("@%u ", r->nr);
@@ -797,6 +799,13 @@ print_eth_rule(struct pfctl_eth_rule *r, const char *anchor_call,
print_fromto(&r->ipsrc, PF_OSFP_ANY, &r->ipdst,
r->proto == ETHERTYPE_IP ? AF_INET : AF_INET6, 0,
0, 0);
i = 0;
while (r->label[i][0])
printf(" label \"%s\"", r->label[i++]);
if (r->ridentifier)
printf(" ridentifier %u", r->ridentifier);
if (r->qname[0])
printf(" queue %s", r->qname);
if (r->tagname[0])
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 ridentifier 12345678
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 l3 all ridentifier 12345678
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 label "test"
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 l3 all label "test"
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 label "test" label "another label"
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 l3 all label "test" label "another label"
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 label "test" ridentifier 12345678
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 l3 all label "test" ridentifier 12345678
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 label "test" label "another test" ridentifier 12345678
+1
View File
@@ -0,0 +1 @@
ether block out on igb0 l3 all label "test" label "another test" ridentifier 12345678
+5
View File
@@ -123,3 +123,8 @@ PFCTL_TEST(1009, "Ethernet rule with mask")
PFCTL_TEST(1010, "POM_STICKYADDRESS test")
PFCTL_TEST(1011, "Test disabling scrub fragment reassemble")
PFCTL_TEST(1012, "Test scrub fragment reassemble is default")
PFCTL_TEST(1013, "Ethernet rule with ridentifier")
PFCTL_TEST(1014, "Ethernet rule with one label")
PFCTL_TEST(1015, "Ethernet rule with several labels")
PFCTL_TEST(1016, "Ethernet rule with ridentifier and one label")
PFCTL_TEST(1017, "Ethernet rule with ridentifier and several labels")