From nobody Tue Nov 23 17:48:13 2021 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 57EE4188E320; Tue, 23 Nov 2021 17:48:14 +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 4HzBSY4tyyz4h2L; Tue, 23 Nov 2021 17:48:13 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 658601AE87; Tue, 23 Nov 2021 17:48:13 +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 1ANHmDrg095397; Tue, 23 Nov 2021 17:48:13 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1ANHmDpJ095396; Tue, 23 Nov 2021 17:48:13 GMT (envelope-from git) Date: Tue, 23 Nov 2021 17:48:13 GMT Message-Id: <202111231748.1ANHmDpJ095396@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: 90c55481b273 - main - pf: fix netpfil.common.dummynet:pf_nat test 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: 90c55481b2731224f9e3a013bb7957dfa3251ea8 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1637689693; 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=qx+jFNpupzgYOOGxqmHOQaMXilWJOlNfMFP1W/cqMkA=; b=XLJ/0irjZJwJSxqAi65UQGURkIN1bDgTwLkl6J76uxBosJxV15/Hjl6aLmHjQQxsboiyto Varf3HU17ukzAnz2H9NsWHriZOstXFO+LE9jj3E6bcXr+barfYYTLhICkv5AzTPthRkE81 Rs9yXVcxycURMZfqZf5zEZ7kl/vlh8I8oXdoK5hC7bhZE+eMQN8zE6Qat6TSluSIveFanx 7WuVBBl7NYTBtIOn9geNZuB1j7GNrpJU9gdTB8oA94ol/hUTrbEvOmFa6SfPQwCu78qda6 G2VuTjI+ilD3RwsK9xJYkZnxQVxBytBWX4jfclbEEEr3vpn+nsgHpEojG8+leQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1637689693; a=rsa-sha256; cv=none; b=v5EsobIDWW8Z+X/Kk8J1cY75AVAkI2nsY4GGkxyqcxFVOkImrWzRyaPlYThyjwFakt973/ gQQ7W4AUfdSOmMOZLR3DgCOj9paT55y/mKUM1+wfk8QNraouMvX/pGIXygZnjoO+c0sVhA /eOCyFAFHusqjOV2dLUogkvV8S3uGdbJWDpBHUFktnLvMKTeuNbRUGNpo2wQBy62vzg/1H Z4Uq1KCqN0Oo1DiVpcuskDKngbLUhjxGez36mT++nti5ROrD64wtfaaNoOX3EInchizT2z 05+QOCidaup0taBSWen856mbuu7SQBdZgzVKa25SvecGRDEx+F7unz/Yny4q1w== 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=90c55481b2731224f9e3a013bb7957dfa3251ea8 commit 90c55481b2731224f9e3a013bb7957dfa3251ea8 Author: Kristof Provost AuthorDate: 2021-11-22 20:47:18 +0000 Commit: Kristof Provost CommitDate: 2021-11-23 15:46:35 +0000 pf: fix netpfil.common.dummynet:pf_nat test This test failed if ipfw was loaded (as well as pf). pf used the same tag as dummynet to indicate a packet had already gone through dummynet. However, ipfw removes this tag, so pf didn't realise the packet had already gone through dummynet. Introduce a separate flag, in the existing pf mtag rather than re-using the ipfw tag. There were no free flag bits, but PF_TAG_FRAGCACHE is no longer used so its bit can be re-purposed. MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D33087 --- sys/netpfil/pf/pf.c | 115 ++++++++++++++++++++++++----------------------- sys/netpfil/pf/pf_mtag.h | 2 +- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 34fa7918d697..837417d6a43d 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6450,13 +6450,25 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb * pd.pf_mtag = pf_find_mtag(m); + if (ip_dn_io_ptr != NULL && pd.pf_mtag != NULL && + pd.pf_mtag->flags & PF_TAG_DUMMYNET) { + /* Dummynet re-injects packets after they've + * completed their delay. We've already + * processed them, so pass unconditionally. */ + + /* But only once. We may see the packet multiple times (e.g. + * PFIL_IN/PFIL_OUT). */ + pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET; + + return (PF_PASS); + } + PF_RULES_RLOCK(); - if ((__predict_false(ip_divert_ptr != NULL) || ip_dn_io_ptr != NULL) && + if (__predict_false(ip_divert_ptr != NULL) && ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) { struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1); - if ((rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) || - (rr->info & IPFW_IS_DUMMYNET)) { + if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) { if (pd.pf_mtag == NULL && ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { action = PF_DROP; @@ -6464,13 +6476,6 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb * } pd.pf_mtag->flags |= PF_PACKET_LOOPED; m_tag_delete(m, ipfwtag); - if (rr->info & IPFW_IS_DUMMYNET) { - /* Dummynet re-injects packets after they've - * completed their delay. We've already - * processed them, so pass unconditionally. */ - PF_RULES_RUNLOCK(); - return (PF_PASS); - } } if (pd.pf_mtag && pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) { m->m_flags |= M_FASTFWD_OURS; @@ -6870,19 +6875,29 @@ done: pd.act.flags = r->free_flags; } if (pd.act.dnpipe || pd.act.dnrpipe) { + struct ip_fw_args dnflow; if (ip_dn_io_ptr == NULL) { m_freem(*m0); *m0 = NULL; action = PF_DROP; REASON_SET(&reason, PFRES_MEMORY); - } else { - struct ip_fw_args dnflow; + break; + } - if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { - ip_dn_io_ptr(m0, &dnflow); - if (*m0 == NULL) - action = PF_DROP; - } + if (pd.pf_mtag == NULL && + ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { + m_freem(*m0); + *m0 = NULL; + action = PF_DROP; + REASON_SET(&reason, PFRES_MEMORY); + break; + } + + if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { + pd.pf_mtag->flags |= PF_TAG_DUMMYNET; + ip_dn_io_ptr(m0, &dnflow); + if (*m0 == NULL) + action = PF_DROP; } } break; @@ -6905,7 +6920,6 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb u_short action, reason = 0, log = 0; struct mbuf *m = *m0, *n = NULL; struct m_tag *mtag; - struct m_tag *ipfwtag; struct ip6_hdr *h = NULL; struct pf_krule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; struct pf_kstate *s = NULL; @@ -6938,29 +6952,19 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb if (m->m_flags & M_SKIP_FIREWALL) return (PF_PASS); + if (ip_dn_io_ptr != NULL && pd.pf_mtag != NULL && + pd.pf_mtag->flags & PF_TAG_DUMMYNET) { + pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET; + /* Dummynet re-injects packets after they've + * completed their delay. We've already + * processed them, so pass unconditionally. */ + return (PF_PASS); + } + PF_RULES_RLOCK(); /* We do IP header normalization and packet reassembly here */ - if (ip_dn_io_ptr != NULL && - ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) { - struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1); - if (rr->info & IPFW_IS_DUMMYNET) { - if (pd.pf_mtag == NULL && - ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { - action = PF_DROP; - goto done; - } - pd.pf_mtag->flags |= PF_PACKET_LOOPED; - m_tag_delete(m, ipfwtag); - if (rr->info & IPFW_IS_DUMMYNET) { - /* Dummynet re-injects packets after they've - * completed their delay. We've already - * processed them, so pass unconditionally. */ - PF_RULES_RUNLOCK(); - return (PF_PASS); - } - } - } else if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { + if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { action = PF_DROP; goto done; } @@ -7326,31 +7330,30 @@ done: pd.act.flags = r->free_flags; } if (pd.act.dnpipe || pd.act.dnrpipe) { + struct ip_fw_args dnflow; + if (ip_dn_io_ptr == NULL) { m_freem(*m0); *m0 = NULL; action = PF_DROP; REASON_SET(&reason, PFRES_MEMORY); - } else { - struct ip_fw_args dnflow; - - if (pd.pf_mtag == NULL && - ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { - m_freem(*m0); - *m0 = NULL; - action = PF_DROP; - REASON_SET(&reason, PFRES_MEMORY); - if (s) - PF_STATE_UNLOCK(s); - return (action); - } + break; + } - if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { - ip_dn_io_ptr(m0, &dnflow); + if (pd.pf_mtag == NULL && + ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { + m_freem(*m0); + *m0 = NULL; + action = PF_DROP; + REASON_SET(&reason, PFRES_MEMORY); + break; + } - if (*m0 == NULL) - action = PF_DROP; - } + if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { + pd.pf_mtag->flags |= PF_TAG_DUMMYNET; + ip_dn_io_ptr(m0, &dnflow); + if (*m0 == NULL) + action = PF_DROP; } } break; diff --git a/sys/netpfil/pf/pf_mtag.h b/sys/netpfil/pf/pf_mtag.h index e3f6f85f21d0..e3b9426bacc8 100644 --- a/sys/netpfil/pf/pf_mtag.h +++ b/sys/netpfil/pf/pf_mtag.h @@ -37,7 +37,7 @@ #ifdef _KERNEL #define PF_TAG_GENERATED 0x01 -#define PF_TAG_FRAGCACHE 0x02 +#define PF_TAG_DUMMYNET 0x02 #define PF_TAG_TRANSLATE_LOCALHOST 0x04 #define PF_PACKET_LOOPED 0x08 #define PF_FASTFWD_OURS_PRESENT 0x10