From nobody Wed Mar 2 16:00:57 2022 X-Original-To: dev-commits-src-main@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 4C98C19E12B9; Wed, 2 Mar 2022 16:01:00 +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 4K7zP56p8Qz3NL4; Wed, 2 Mar 2022 16:00:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646236859; 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=EvE6FiE0dXSRp1H0zk94Web5pyRxixZCTm3Vr+3hbPA=; b=jv80Yl350NrLR/CFS8Vr1AI77yIk416X6ONgkTZz+5JYlqvWuxOe2oSAn20iyRoRJZ3eY6 JZjDhYAiTGuNPPzoaYlTaX7nAETmjlvG1HWa2o6MxmU8jkmqIf69nqYBBxvKY951wxEsVj H5iQaE2WpugVFwUWxaBo1UDA5vvxWV0OtdX2Qql1VUXHpKCJqXnaE4TWXc1OrEnhp7FkAX g5gEQLRY6Vc6oqGSiH4HHrAig6KwC573F5JvsmfOaj5VBa8wXJ6DfKW1gxB4BgEMiOIGuX ZGRgmQc72HRDH8ObBvyy8t8I7bPS/SOfX+JLXCpmHhW1xOHnkO9yFqb3R5hdCA== 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 4F522264E9; Wed, 2 Mar 2022 16:00:57 +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 222G0vS2091307; Wed, 2 Mar 2022 16:00:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 222G0vGY091306; Wed, 2 Mar 2022 16:00:57 GMT (envelope-from git) Date: Wed, 2 Mar 2022 16:00:57 GMT Message-Id: <202203021600.222G0vGY091306@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: fb330f3931a2 - main - pf: support dummynet on L2 rules List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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: fb330f3931a2df0cebd2c8726f9d5362cceb0f2a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646236859; 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=EvE6FiE0dXSRp1H0zk94Web5pyRxixZCTm3Vr+3hbPA=; b=awGmDIsd8UHNAq5lqB5bXlmfs5SE6hWf/JWrSnfHejovJAU4wNFHhpnFjKBllKbfFJ2sZ8 ubjjTMMLTlR2xzCp4wnE7Zc9Y2NA14sJYOeqcRe8+CvL4fZa1b+SRI0nwUQFkRETHaolSE Z95AyGq+mqYDEL6TC0pa9zx0hOLua49ifCo8e/pCgitdUiD8Jk7gY/TqtfP3vZhSRvcnHC P0ysRU9zVAHGi99jewToElz9Rnog6o9aiMCO2014mULg1u5WE334xlxFzR4YpYjHM82gNt 6JbKpRkU1qpQo2u3Uk3GF/nTANnVX4eKxcSSXQOoCtBwZWmUFndOOF9JotCjTw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646236859; a=rsa-sha256; cv=none; b=uHAugM/YVNa2DzK3j1HUmzSYOTEaRKcOlBpaS1uOyhG9rh0iwSFZiG7AmNehKf/YacpNOJ b9VaB2tH0e6T/LV5+kdDsM3TrzE9hM1qSn3u7kyJNUmv7465seRT/G50WN76If3LvkItsQ JuppF2SlWA7qtcgst2HOjt/VKA0XMWwFLPHQ15fXiUpn0tFr1S46836vdvcfakqYWlt7pg Yk2zqjdCLvydFcmLMaTnbmmoiymdKSfGpkNQQVZFieufqxY55uSWXmKNv3z9kFyygKEKHn yWmTL5QTFy4VppFKuYdqK2BgS9ySMkZHr3yo59HW4//o5mXBBUamFiG5jO4AMw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=fb330f3931a2df0cebd2c8726f9d5362cceb0f2a commit fb330f3931a2df0cebd2c8726f9d5362cceb0f2a Author: Kristof Provost AuthorDate: 2021-09-27 12:50:30 +0000 Commit: Kristof Provost CommitDate: 2022-03-02 16:00:06 +0000 pf: support dummynet on L2 rules Allow packets to be tagged with dummynet information. Note that we do not apply dummynet shaping on the L2 traffic, but instead mark it for dummynet processing in the L3 code. This is the same approach as we take for ALTQ. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D32222 --- lib/libpfctl/libpfctl.c | 6 ++++++ lib/libpfctl/libpfctl.h | 2 ++ sbin/pfctl/parse.y | 10 ++++++++++ sbin/pfctl/pfctl_parser.c | 4 ++++ sys/net/pfvar.h | 2 ++ sys/netpfil/pf/pf.c | 35 +++++++++++++++++++++++++++++++++-- sys/netpfil/pf/pf_mtag.h | 2 ++ sys/netpfil/pf/pf_nv.c | 8 +++++++- 8 files changed, 66 insertions(+), 3 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 7255d18410a8..fd7dd7a474a0 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -603,6 +603,9 @@ pfctl_nveth_rule_to_eth_rule(const nvlist_t *nvl, struct pfctl_eth_rule *rule) strlcpy(rule->tagname, nvlist_get_string(nvl, "tagname"), PF_TAG_NAME_SIZE); + rule->dnpipe = nvlist_get_number(nvl, "dnpipe"); + rule->dnflags = nvlist_get_number(nvl, "dnflags"); + rule->action = nvlist_get_number(nvl, "action"); } @@ -709,6 +712,9 @@ pfctl_add_eth_rule(int dev, const struct pfctl_eth_rule *r, uint32_t ticket) nvlist_add_string(nvl, "qname", r->qname); nvlist_add_string(nvl, "tagname", r->tagname); + nvlist_add_number(nvl, "dnpipe", r->dnpipe); + nvlist_add_number(nvl, "dnflags", r->dnflags); + nvlist_add_number(nvl, "action", r->action); packed = nvlist_pack(nvl, &size); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index b44200e00ad9..6c3dbfc5d0df 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -96,6 +96,8 @@ struct pfctl_eth_rule { /* Action */ char qname[PF_QNAME_SIZE]; char tagname[PF_TAG_NAME_SIZE]; + uint16_t dnpipe; + uint32_t dnflags; uint8_t action; TAILQ_ENTRY(pfctl_eth_rule) entries; diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 1bf9372cd7a6..a2d8cfef8232 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1200,6 +1200,8 @@ etherrule : ETHER action dir quick interface etherproto etherfromto etherfilter_ memcpy(&r.tagname, $8.tag, sizeof(r.tagname)); if ($8.queues.qname != NULL) memcpy(&r.qname, $8.queues.qname, sizeof(r.qname)); + r.dnpipe = $8.dnpipe; + r.dnflags = $8.free_flags; expand_eth_rule(&r, $5, $6); } @@ -1229,6 +1231,14 @@ etherfilter_opt : etherqname { | TAG string { filter_opts.tag = $2; } + | DNPIPE number { + filter_opts.dnpipe = $2; + filter_opts.free_flags |= PFRULE_DN_IS_PIPE; + } + | DNQUEUE number { + filter_opts.dnpipe = $2; + filter_opts.free_flags |= PFRULE_DN_IS_QUEUE; + } ; scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index c7e980103fad..bde6d4b10696 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -747,6 +747,10 @@ print_eth_rule(struct pfctl_eth_rule *r, int rule_numbers) printf(" queue %s", r->qname); if (r->tagname[0]) printf(" tag %s", r->tagname); + if (r->dnpipe) + printf(" %s %d", + r->dnflags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue", + r->dnpipe); } void diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index a0b23759857a..11fb57b49fca 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -617,6 +617,8 @@ struct pf_keth_rule { char tagname[PF_TAG_NAME_SIZE]; uint16_t tag; uint8_t action; + uint16_t dnpipe; + uint32_t dnflags; }; TAILQ_HEAD(pf_keth_rules, pf_keth_rule); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 8bf309caf7d4..09d727508750 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -3813,6 +3813,22 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf *m) mtag->qid = r->qid; } + /* Dummynet */ + if (r->dnpipe) { + /** While dummynet supports handling Ethernet packets directly + * it still wants some L3/L4 information, and we're not set up + * to provide that here. Instead we'll do what we do for ALTQ + * and merely mark the packet with the dummynet queue/pipe number. + **/ + mtag = pf_get_mtag(m); + if (mtag == NULL) { + counter_u64_add(V_pf_status.counters[PFRES_MEMORY], 1); + return (PF_DROP); + } + mtag->dnpipe = r->dnpipe; + mtag->dnflags = r->dnflags; + } + action = r->action; return (action); @@ -6515,8 +6531,13 @@ pf_pdesc_to_dnflow(int dir, const struct pf_pdesc *pd, { int dndir = r->direction; - if (s && dndir == PF_INOUT) + if (s && dndir == PF_INOUT) { dndir = s->direction; + } else if (dndir == PF_INOUT) { + /* Assume primary direction. Happens when we've set dnpipe in + * the ethernet level code. */ + dndir = dir; + } memset(dnflow, 0, sizeof(*dnflow)); @@ -6541,7 +6562,7 @@ pf_pdesc_to_dnflow(int dir, const struct pf_pdesc *pd, } dnflow->rule.info |= IPFW_IS_DUMMYNET; - if (r->free_flags & PFRULE_DN_IS_PIPE) + if (r->free_flags & PFRULE_DN_IS_PIPE || pd->act.flags & PFRULE_DN_IS_PIPE) dnflow->rule.info |= IPFW_IS_PIPE; dnflow->f_id.proto = pd->proto; @@ -6635,6 +6656,11 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb * memset(&pd, 0, sizeof(pd)); pd.pf_mtag = pf_find_mtag(m); + if (pd.pf_mtag && pd.pf_mtag->dnpipe) { + pd.act.dnpipe = pd.pf_mtag->dnpipe; + pd.act.flags = pd.pf_mtag->dnflags; + } + if (ip_dn_io_ptr != NULL && pd.pf_mtag != NULL && pd.pf_mtag->flags & PF_TAG_DUMMYNET) { /* Dummynet re-injects packets after they've @@ -7134,6 +7160,11 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb memset(&pd, 0, sizeof(pd)); pd.pf_mtag = pf_find_mtag(m); + if (pd.pf_mtag && pd.pf_mtag->dnpipe) { + pd.act.dnpipe = pd.pf_mtag->dnpipe; + pd.act.flags = pd.pf_mtag->dnflags; + } + if (ip_dn_io_ptr != NULL && pd.pf_mtag != NULL && pd.pf_mtag->flags & PF_TAG_DUMMYNET) { pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET; diff --git a/sys/netpfil/pf/pf_mtag.h b/sys/netpfil/pf/pf_mtag.h index 82b8d32fbdfc..50928d4b204b 100644 --- a/sys/netpfil/pf/pf_mtag.h +++ b/sys/netpfil/pf/pf_mtag.h @@ -52,6 +52,8 @@ struct pf_mtag { u_int16_t tag; /* tag id */ u_int8_t flags; u_int8_t routed; + u_int16_t dnpipe; + u_int32_t dnflags; }; static __inline struct pf_mtag * diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 24128a21c363..b662bb4e7d95 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -1081,6 +1081,9 @@ pf_keth_rule_to_nveth_rule(const struct pf_keth_rule *krule) nvlist_add_string(nvl, "qname", krule->qname); nvlist_add_string(nvl, "tagname", krule->tagname); + nvlist_add_number(nvl, "dnpipe", krule->dnpipe); + nvlist_add_number(nvl, "dnflags", krule->dnflags); + nvlist_add_number(nvl, "action", krule->action); return (nvl); @@ -1090,7 +1093,7 @@ int pf_nveth_rule_to_keth_rule(const nvlist_t *nvl, struct pf_keth_rule *krule) { - int error; + int error = 0; bzero(krule, sizeof(*krule)); @@ -1119,6 +1122,9 @@ pf_nveth_rule_to_keth_rule(const nvlist_t *nvl, PFNV_CHK(pf_nvstring(nvl, "tagname", krule->tagname, sizeof(krule->tagname))); + PFNV_CHK(pf_nvuint16_opt(nvl, "dnpipe", &krule->dnpipe, 0)); + PFNV_CHK(pf_nvuint32_opt(nvl, "dnflags", &krule->dnflags, 0)); + PFNV_CHK(pf_nvuint8(nvl, "action", &krule->action)); if (krule->action != PF_PASS && krule->action != PF_DROP)