Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 May 2022 19:58:12 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 37c452292132 - main - pf: also apply dummynet to route-to/dup-to packets
Message-ID:  <202205121958.24CJwCFt075554@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=37c452292132c062a4deb2b136facb9b6a675cf9

commit 37c452292132c062a4deb2b136facb9b6a675cf9
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-05-09 09:11:42 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-05-12 19:50:09 +0000

    pf: also apply dummynet to route-to/dup-to packets
    
    If packets are processed by a route-to/dup-to/reply-to rule (i.e. they
    pass through pf_route(6)) dummynet was not applied to them.
    This is because pf_route(6) passes packets directly to ifp->if_output(),
    so the dummynet functions were never called.
    
    Factor out the dummynet code and call dummynet prior to
    ifp->if_output(). This has a secondary benefit of reducing some code
    duplication between the IPv4 and IPv6 paths.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D35158
---
 sys/netpfil/pf/pf.c | 144 ++++++++++++++++++++++++----------------------------
 1 file changed, 67 insertions(+), 77 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index e9185c4d8587..343668030d0d 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -281,6 +281,8 @@ static int		 pf_state_key_ctor(void *, int, void *, int);
 static u_int32_t	 pf_tcp_iss(struct pf_pdesc *);
 void			 pf_rule_to_actions(struct pf_krule *,
 			    struct pf_rule_actions *);
+static int		 pf_dummynet(struct pf_pdesc *, int, struct pf_kstate *,
+			    struct pf_krule *, struct mbuf **);
 static int		 pf_test_eth_rule(int, struct pfi_kkif *,
 			    struct mbuf **);
 static int		 pf_test_rule(struct pf_krule **, struct pf_kstate **,
@@ -6247,7 +6249,7 @@ static void
 pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
     struct pf_kstate *s, struct pf_pdesc *pd, struct inpcb *inp)
 {
-	struct mbuf		*m0, *m1;
+	struct mbuf		*m0, *m1, *md;
 	struct sockaddr_in	dst;
 	struct ip		*ip;
 	struct ifnet		*ifp = NULL;
@@ -6295,6 +6297,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 		}
 	} else {
 		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
+			pf_dummynet(pd, dir, s, r, m);
 			if (s)
 				PF_STATE_UNLOCK(s);
 			return;
@@ -6377,7 +6380,11 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 			m0->m_pkthdr.csum_flags &= ~CSUM_IP;
 		}
 		m_clrprotoflags(m0);	/* Avoid confusing lower layers. */
-		error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
+
+		md = m0;
+		error = pf_dummynet(pd, dir, s, r, &md);
+		if (md != NULL)
+			error = (*ifp->if_output)(ifp, md, sintosa(&dst), NULL);
 		goto done;
 	}
 
@@ -6407,7 +6414,11 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 		m0->m_nextpkt = NULL;
 		if (error == 0) {
 			m_clrprotoflags(m0);
-			error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
+			md = m0;
+			error = pf_dummynet(pd, dir, s, r, &md);
+			if (md != NULL)
+				error = (*ifp->if_output)(ifp, md,
+				    sintosa(&dst), NULL);
 		} else
 			m_freem(m0);
 	}
@@ -6434,7 +6445,7 @@ static void
 pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
     struct pf_kstate *s, struct pf_pdesc *pd, struct inpcb *inp)
 {
-	struct mbuf		*m0;
+	struct mbuf		*m0, *md;
 	struct sockaddr_in6	dst;
 	struct ip6_hdr		*ip6;
 	struct ifnet		*ifp = NULL;
@@ -6480,6 +6491,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 		}
 	} else {
 		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
+			pf_dummynet(pd, dir, s, r, m);
 			if (s)
 				PF_STATE_UNLOCK(s);
 			return;
@@ -6551,8 +6563,12 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 	 */
 	if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr))
 		dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
-	if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu)
-		nd6_output_ifp(ifp, ifp, m0, &dst, NULL);
+	if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
+		md = m0;
+		pf_dummynet(pd, dir, s, r, &md);
+		if (md != NULL)
+			nd6_output_ifp(ifp, ifp, md, &dst, NULL);
+	}
 	else {
 		in6_ifstat_inc(ifp, ifs6_in_toobig);
 		if (r->rt != PF_DUPTO) {
@@ -6807,6 +6823,45 @@ pf_test_eth(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
 	return (pf_test_eth_rule(dir, kif, m0));
 }
 
+static int
+pf_dummynet(struct pf_pdesc *pd, int dir, struct pf_kstate *s,
+    struct pf_krule *r, struct mbuf **m0)
+{
+	if (s && (s->dnpipe || s->dnrpipe)) {
+		pd->act.dnpipe = s->dnpipe;
+		pd->act.dnrpipe = s->dnrpipe;
+		pd->act.flags = s->state_flags;
+	} else if (r->dnpipe || r->dnrpipe) {
+		pd->act.dnpipe = r->dnpipe;
+		pd->act.dnrpipe = r->dnrpipe;
+		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;
+			return (ENOMEM);
+		}
+
+		if (pd->pf_mtag == NULL &&
+		    ((pd->pf_mtag = pf_get_mtag(*m0)) == NULL)) {
+			m_freem(*m0);
+			*m0 = NULL;
+			return (ENOMEM);
+		}
+
+		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)
+				pd->pf_mtag->flags &= ~PF_TAG_DUMMYNET;
+		}
+	}
+
+	return (0);
+}
+
 #ifdef INET
 int
 pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
@@ -7266,41 +7321,9 @@ done:
 			pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
 			return (action);
 		}
-		/* Dummynet processing. */
-		if (s && (s->dnpipe || s->dnrpipe)) {
-			pd.act.dnpipe = s->dnpipe;
-			pd.act.dnrpipe = s->dnrpipe;
-			pd.act.flags = s->state_flags;
-		} else if (r->dnpipe || r->dnrpipe) {
-			pd.act.dnpipe = r->dnpipe;
-			pd.act.dnrpipe = r->dnrpipe;
-			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);
-				break;
-			}
-
-			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)
-					pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET;
-			}
+		if (pf_dummynet(&pd, dir, s, r, m0) != 0) {
+			action = PF_DROP;
+			REASON_SET(&reason, PFRES_MEMORY);
 		}
 		break;
 	}
@@ -7723,42 +7746,9 @@ done:
 			pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
 			return (action);
 		}
-		/* Dummynet processing. */
-		if (s && (s->dnpipe || s->dnrpipe)) {
-			pd.act.dnpipe = s->dnpipe;
-			pd.act.dnrpipe = s->dnrpipe;
-			pd.act.flags = s->state_flags;
-		} else {
-			pd.act.dnpipe = r->dnpipe;
-			pd.act.dnrpipe = r->dnrpipe;
-			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);
-				break;
-			}
-
-			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)
-					pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET;
-			}
+		if (pf_dummynet(&pd, dir, s, r, m0) != 0) {
+			action = PF_DROP;
+			REASON_SET(&reason, PFRES_MEMORY);
 		}
 		break;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202205121958.24CJwCFt075554>