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
This commit is contained in:
Yannis Planus 2021-01-28 14:59:07 +01:00 committed by Kristof Provost
parent d386f3a3c3
commit 0c458752ce
2 changed files with 45 additions and 6 deletions

View File

@ -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)) {

View File

@ -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 */