git: 0c458752ceee - main - pf: duplicate frames only once when using dup-to pf rule

Kristof Provost kp at FreeBSD.org
Thu Jan 28 16:48:51 UTC 2021


The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=0c458752ceee14818034df7bfcdfb04129dceeda

commit 0c458752ceee14818034df7bfcdfb04129dceeda
Author:     Yannis Planus <yannis.planus at alstomgroup.com>
AuthorDate: 2021-01-28 13:59:07 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
CommitDate: 2021-01-28 15:46:44 +0000

    pf: duplicate frames only once when using dup-to pf rule
    
    When using DUP-TO rule, frames are duplicated 3 times on both output
    interfaces and duplication interface. Add a flag to not duplicate a
    duplicated frame.
    
    Inspired by a patch from Miłosz Kaniewski milosz.kaniewski at gmail.com
    https://lists.freebsd.org/pipermail/freebsd-pf/2015-November/007886.html
    
    Reviewed by:            kp@
    Differential Revision:  https://reviews.freebsd.org/D27018
---
 sys/netpfil/pf/pf.c      | 50 ++++++++++++++++++++++++++++++++++++++++++------
 sys/netpfil/pf/pf_mtag.h |  1 +
 2 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 4cccb0101650..86354e69d11f 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -5488,10 +5488,29 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 	}
 
 	if (r->rt == PF_DUPTO) {
-		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
-			if (s)
+		if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
+			if (s == NULL) {
+				ifp = r->rpool.cur->kif ?
+				    r->rpool.cur->kif->pfik_ifp : NULL;
+			} else {
+				ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
 				PF_STATE_UNLOCK(s);
-			return;
+			}
+			if (ifp == oifp) {
+				/* When the 2nd interface is not skipped */
+				return;
+			} else {
+				m0 = *m;
+				*m = NULL;
+				goto bad;
+			}
+		} else {
+			pd->pf_mtag->flags |= PF_DUPLICATED;
+			if (((m0 = m_dup(*m, M_NOWAIT)) == NULL)) {
+				if (s)
+					PF_STATE_UNLOCK(s);
+				return;
+			}
 		}
 	} else {
 		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
@@ -5649,10 +5668,29 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
 	}
 
 	if (r->rt == PF_DUPTO) {
-		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
-			if (s)
+		if ((pd->pf_mtag->flags & PF_DUPLICATED)) {
+			if (s == NULL) {
+				ifp = r->rpool.cur->kif ?
+				    r->rpool.cur->kif->pfik_ifp : NULL;
+			} else {
+				ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
 				PF_STATE_UNLOCK(s);
-			return;
+			}
+			if (ifp == oifp) {
+				/* When the 2nd interface is not skipped */
+				return;
+			} else {
+				m0 = *m;
+				*m = NULL;
+				goto bad;
+			}
+		} else {
+			pd->pf_mtag->flags |= PF_DUPLICATED;
+			if (((m0 = m_dup(*m, M_NOWAIT)) == NULL)) {
+				if (s)
+					PF_STATE_UNLOCK(s);
+				return;
+			}
 		}
 	} else {
 		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
diff --git a/sys/netpfil/pf/pf_mtag.h b/sys/netpfil/pf/pf_mtag.h
index 67c79350e8eb..ad28ab7a7c30 100644
--- a/sys/netpfil/pf/pf_mtag.h
+++ b/sys/netpfil/pf/pf_mtag.h
@@ -42,6 +42,7 @@
 #define	PF_PACKET_LOOPED		0x08
 #define	PF_FASTFWD_OURS_PRESENT		0x10
 #define	PF_REASSEMBLED			0x20
+#define	PF_DUPLICATED			0x40
 
 struct pf_mtag {
 	void		*hdr;		/* saved hdr pos in mbuf, for ECN */


More information about the dev-commits-src-all mailing list