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:
parent
d386f3a3c3
commit
0c458752ce
@ -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)) {
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user