The branch main has been updated by kp:

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

commit 0c458752ceee14818034df7bfcdfb04129dceeda
Author:     Yannis Planus <[email protected]>
AuthorDate: 2021-01-28 13:59:07 +0000
Commit:     Kristof Provost <[email protected]>
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 */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "[email protected]"

Reply via email to