From nobody Wed Apr 26 09:19:47 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Q5tcN1zCZz47kBT; Wed, 26 Apr 2023 09:19:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Q5tcN1PlTz3KbB; Wed, 26 Apr 2023 09:19:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682500788; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+JOYy0HFhaRdu+HgLG/NuDh6D8XZLXBl3k45uSiWpNI=; b=R3ZM8lPdU6tkKqLSZI1cPzrll9tUF/uuVRHvbvv/9G7zhZpu3U6wtePUmrm28K17LJ+pRU C/W1p5aiaood/n3ZPmuwkHJbtMkPKtyMpaUOO1hQmB2vadjkOvvjf4+fcJ1n4WQyyhWBuv is+dyfB6UJbWa2ZASxxC1wQwGKepZqLgDWOeeMKcu2FdO04CUgRBGDibafKN+7KPMd96Ny hu3z+WLlYKMx+aVOnHs9OB5t1x9IeE+tLrfKjLVNAWdHqoPvDMmDoqV0kG2tlFd8sQXumo yGpidjDpPsBHrNQ0PL008EPtwI3zP7d61k0ogyDnSPklzPaDoO7dK8ok3HnCEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682500788; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+JOYy0HFhaRdu+HgLG/NuDh6D8XZLXBl3k45uSiWpNI=; b=cALjhU82NtZ/kWpd9qftchFCct0GjNKOQwF2rYmZpYLDqxmTXxHicQlfpZEu+HCPyy2lBW eqQwkiKViHh2XpCf46IQNKVNvjd1Ua5douwQmqNjGgvtwt0gAQeBMM8IMLLJJUnbeM4+pz YMFQX4UE7APM3Qlfhnragt/MRoXvtbqntA++R3XZr/YP2CWIsKH7KBvczSrEXcyncWSxc1 DvQhSe+k29CaNpW8yL8h708VqPTWXk2uGQPLPH9u8joPaiZ9H+X/5yruI/n1BN8Ajqp3Ri 3WBG/4NyYEmHnwikMRtBgAZM1MXNIQ1gm+DCHVbuN8eyfUm0L1aLKI7fMQZuNA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682500788; a=rsa-sha256; cv=none; b=iAmhJUcHfj3xJCiM2Igj2Fyuwa+PvraAr+pDMgk3rgE4E2XZ3JXk1rqrSJ/AYrLyo/qhjJ ev8pA2LfT2mRnoPKtVj6m1XJ4doDfwXD8UthToyxaDltMII2ww+4WxRtTv/ThI4xtZRIs3 h3NyTSj9dE0j04CEsQkW8fJK/V7NSZw7BHbHCrSWa+Au11C95jUsgJOMYqvLhq1Xmi1a67 rYqJ2uMlEFOWeiewoKit0sW3mUk3rgYyq0k8gzYPDbMBNn0GQnt6dA0eSxOJl5y1nyoR1b Z15nYbrKPWVCqmNC5zFtEVc1RhWSnVwo7PAV3IgVc0aqSux4540Yb0l1e4S1mA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Q5tcN0TZLzTNv; Wed, 26 Apr 2023 09:19:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33Q9JlHP092129; Wed, 26 Apr 2023 09:19:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33Q9JlgI092128; Wed, 26 Apr 2023 09:19:47 GMT (envelope-from git) Date: Wed, 26 Apr 2023 09:19:47 GMT Message-Id: <202304260919.33Q9JlgI092128@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: ef661d4a5bf9 - main - pf: introduce ridentifier and labels to ether rules List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ef661d4a5bf912e4d4850faaf50664532d82541c Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=ef661d4a5bf912e4d4850faaf50664532d82541c commit ef661d4a5bf912e4d4850faaf50664532d82541c Author: Christian McDonald AuthorDate: 2023-04-24 18:55:34 +0000 Commit: Kristof Provost CommitDate: 2023-04-26 09:14:41 +0000 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") --- lib/libpfctl/libpfctl.c | 20 +++++++++++++++++++- lib/libpfctl/libpfctl.h | 3 +++ sbin/pfctl/parse.y | 33 +++++++++++++++++++++++++++++++++ sbin/pfctl/pfctl_parser.c | 9 +++++++++ sbin/pfctl/tests/files/pf1013.in | 1 + sbin/pfctl/tests/files/pf1013.ok | 1 + sbin/pfctl/tests/files/pf1014.in | 1 + sbin/pfctl/tests/files/pf1014.ok | 1 + sbin/pfctl/tests/files/pf1015.in | 1 + sbin/pfctl/tests/files/pf1015.ok | 1 + sbin/pfctl/tests/files/pf1016.in | 1 + sbin/pfctl/tests/files/pf1016.ok | 1 + sbin/pfctl/tests/files/pf1017.in | 1 + sbin/pfctl/tests/files/pf1017.ok | 1 + sbin/pfctl/tests/pfctl_test_list.inc | 5 +++++ share/man/man5/pf.conf.5 | 5 +++-- sys/net/pfvar.h | 3 +++ sys/netpfil/pf/pf_nv.c | 27 +++++++++++++++++++++++++++ 18 files changed, 112 insertions(+), 3 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index c75f9ab12889..4f251e92d9aa 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -625,6 +625,9 @@ pfctl_eth_addr_to_nveth_addr(const struct pfctl_eth_addr *addr) static void pfctl_nveth_rule_to_eth_rule(const nvlist_t *nvl, struct pfctl_eth_rule *rule) { + const char *const *labels; + size_t labelcount, i; + rule->nr = nvlist_get_number(nvl, "nr"); rule->quick = nvlist_get_bool(nvl, "quick"); strlcpy(rule->ifname, nvlist_get_string(nvl, "ifname"), IFNAMSIZ); @@ -636,6 +639,12 @@ pfctl_nveth_rule_to_eth_rule(const nvlist_t *nvl, struct pfctl_eth_rule *rule) rule->match_tag = nvlist_get_number(nvl, "match_tag"); rule->match_tag_not = nvlist_get_bool(nvl, "match_tag_not"); + labels = nvlist_get_string_array(nvl, "labels", &labelcount); + assert(labelcount <= PF_RULE_MAX_LABEL_COUNT); + for (i = 0; i < labelcount; i++) + strlcpy(rule->label[i], labels[i], PF_RULE_LABEL_SIZE); + rule->ridentifier = nvlist_get_number(nvl, "ridentifier"); + pfctl_nveth_addr_to_eth_addr(nvlist_get_nvlist(nvl, "src"), &rule->src); pfctl_nveth_addr_to_eth_addr(nvlist_get_nvlist(nvl, "dst"), @@ -775,7 +784,7 @@ pfctl_add_eth_rule(int dev, const struct pfctl_eth_rule *r, const char *anchor, nvlist_t *nvl, *addr; void *packed; int error = 0; - size_t size; + size_t labelcount, size; nvl = nvlist_create(0); @@ -811,6 +820,15 @@ pfctl_add_eth_rule(int dev, const struct pfctl_eth_rule *r, const char *anchor, pfctl_nv_add_rule_addr(nvl, "ipsrc", &r->ipsrc); pfctl_nv_add_rule_addr(nvl, "ipdst", &r->ipdst); + labelcount = 0; + while (r->label[labelcount][0] != 0 && + labelcount < PF_RULE_MAX_LABEL_COUNT) { + nvlist_append_string_array(nvl, "labels", + r->label[labelcount]); + labelcount++; + } + nvlist_add_number(nvl, "ridentifier", r->ridentifier); + nvlist_add_string(nvl, "qname", r->qname); nvlist_add_string(nvl, "tagname", r->tagname); nvlist_add_number(nvl, "dnpipe", r->dnpipe); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 1a07b74dc10f..064adafcf3ed 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -87,6 +87,9 @@ struct pfctl_eth_addr { struct pfctl_eth_rule { uint32_t nr; + char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE]; + uint32_t ridentifier; + bool quick; /* Filter */ diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index e5629f9fcd5f..b0f631a5998c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -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) { diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 1f8627f5e246..c3aa840bca40 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -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]) diff --git a/sbin/pfctl/tests/files/pf1013.in b/sbin/pfctl/tests/files/pf1013.in new file mode 100644 index 000000000000..053804e1a35a --- /dev/null +++ b/sbin/pfctl/tests/files/pf1013.in @@ -0,0 +1 @@ +ether block out on igb0 ridentifier 12345678 diff --git a/sbin/pfctl/tests/files/pf1013.ok b/sbin/pfctl/tests/files/pf1013.ok new file mode 100644 index 000000000000..7395f3fd6311 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1013.ok @@ -0,0 +1 @@ +ether block out on igb0 l3 all ridentifier 12345678 diff --git a/sbin/pfctl/tests/files/pf1014.in b/sbin/pfctl/tests/files/pf1014.in new file mode 100644 index 000000000000..8739034f1bda --- /dev/null +++ b/sbin/pfctl/tests/files/pf1014.in @@ -0,0 +1 @@ +ether block out on igb0 label "test" diff --git a/sbin/pfctl/tests/files/pf1014.ok b/sbin/pfctl/tests/files/pf1014.ok new file mode 100644 index 000000000000..d0086cb25e54 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1014.ok @@ -0,0 +1 @@ +ether block out on igb0 l3 all label "test" diff --git a/sbin/pfctl/tests/files/pf1015.in b/sbin/pfctl/tests/files/pf1015.in new file mode 100644 index 000000000000..11c7a211ae8a --- /dev/null +++ b/sbin/pfctl/tests/files/pf1015.in @@ -0,0 +1 @@ +ether block out on igb0 label "test" label "another label" diff --git a/sbin/pfctl/tests/files/pf1015.ok b/sbin/pfctl/tests/files/pf1015.ok new file mode 100644 index 000000000000..d3ea76f1875b --- /dev/null +++ b/sbin/pfctl/tests/files/pf1015.ok @@ -0,0 +1 @@ +ether block out on igb0 l3 all label "test" label "another label" diff --git a/sbin/pfctl/tests/files/pf1016.in b/sbin/pfctl/tests/files/pf1016.in new file mode 100644 index 000000000000..a7b1f6bc0ca9 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1016.in @@ -0,0 +1 @@ +ether block out on igb0 label "test" ridentifier 12345678 diff --git a/sbin/pfctl/tests/files/pf1016.ok b/sbin/pfctl/tests/files/pf1016.ok new file mode 100644 index 000000000000..f1d59c988730 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1016.ok @@ -0,0 +1 @@ +ether block out on igb0 l3 all label "test" ridentifier 12345678 diff --git a/sbin/pfctl/tests/files/pf1017.in b/sbin/pfctl/tests/files/pf1017.in new file mode 100644 index 000000000000..ad523337bdc5 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1017.in @@ -0,0 +1 @@ +ether block out on igb0 label "test" label "another test" ridentifier 12345678 diff --git a/sbin/pfctl/tests/files/pf1017.ok b/sbin/pfctl/tests/files/pf1017.ok new file mode 100644 index 000000000000..0efdd55e27a0 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1017.ok @@ -0,0 +1 @@ +ether block out on igb0 l3 all label "test" label "another test" ridentifier 12345678 diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc index 0b7d89099efe..7caf66221e2d 100644 --- a/sbin/pfctl/tests/pfctl_test_list.inc +++ b/sbin/pfctl/tests/pfctl_test_list.inc @@ -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") diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index 88c509f36ff7..8292812f7817 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -28,7 +28,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd April 21, 2023 +.Dd April 26, 2023 .Dt PF.CONF 5 .Os .Sh NAME @@ -3108,7 +3108,8 @@ logopts = logopt [ "," logopts ] logopt = "all" | "user" | "to" interface-name etherfilteropt-list = etherfilteropt-list etherfilteropt | etherfilteropt -etherfilteropt = "tag" string | "tagged" string | "queue" ( string ) +etherfilteropt = "tag" string | "tagged" string | "queue" ( string ) | + "ridentifier" number | "label" string filteropt-list = filteropt-list filteropt | filteropt filteropt = user | group | flags | icmp-type | icmp6-type | "tos" tos | diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 2f017923afa1..a82735f71c8c 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -703,6 +703,9 @@ struct pf_keth_rule { uint8_t action; uint16_t dnpipe; uint32_t dnflags; + + char label[PF_RULE_MAX_LABEL_COUNT][PF_RULE_LABEL_SIZE]; + uint32_t ridentifier; }; union pf_krule_ptr { diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 544477407861..4391dc0ef8d5 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -1051,6 +1051,11 @@ pf_keth_rule_to_nveth_rule(const struct pf_keth_rule *krule) if (nvl == NULL) return (NULL); + for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++) { + nvlist_append_string_array(nvl, "labels", krule->label[i]); + } + nvlist_add_number(nvl, "ridentifier", krule->ridentifier); + nvlist_add_number(nvl, "nr", krule->nr); nvlist_add_bool(nvl, "quick", krule->quick); nvlist_add_string(nvl, "ifname", krule->ifname); @@ -1126,8 +1131,29 @@ pf_nveth_rule_to_keth_rule(const nvlist_t *nvl, { int error = 0; +#define ERROUT(x) ERROUT_FUNCTION(errout, x) + bzero(krule, sizeof(*krule)); + 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) + ERROUT(E2BIG); + + for (size_t i = 0; i < items; i++) { + ret = strlcpy(krule->label[i], strs[i], + sizeof(krule->label[0])); + if (ret >= sizeof(krule->label[0])) + ERROUT(E2BIG); + } + } + + PFNV_CHK(pf_nvuint32_opt(nvl, "ridentifier", &krule->ridentifier, 0)); + PFNV_CHK(pf_nvuint32(nvl, "nr", &krule->nr)); PFNV_CHK(pf_nvbool(nvl, "quick", &krule->quick)); PFNV_CHK(pf_nvstring(nvl, "ifname", krule->ifname, @@ -1192,6 +1218,7 @@ pf_nveth_rule_to_keth_rule(const nvlist_t *nvl, krule->action != PF_MATCH) return (EBADMSG); +#undef ERROUT errout: return (error); }