diff options
author | Kristof Provost <kp@FreeBSD.org> | 2021-11-22 20:28:10 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2021-11-23 15:46:15 +0000 |
commit | 18d04cd2d42c16209c8f615bb9735dded328915b (patch) | |
tree | 960ca1a38a356208083e8778cc4d0e6a924e572a /sys/netpfil | |
parent | c36f90417b734e56ef938cc2d19601001c709f40 (diff) | |
download | src-18d04cd2d42c16209c8f615bb9735dded328915b.tar.gz src-18d04cd2d42c16209c8f615bb9735dded328915b.zip |
pf: align IPv6 dummynet handling with IPv4
In e5c4987e3f we fixed issues with nat and dummynet, but only changed
the IPv4 code. Make the same change for IPv6 as well.
Reviewed by: glebius
MFC after: 3 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D33086
Diffstat (limited to 'sys/netpfil')
-rw-r--r-- | sys/netpfil/pf/pf.c | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 1ddb61836e2e..34fa7918d697 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6873,6 +6873,7 @@ done: if (ip_dn_io_ptr == NULL) { m_freem(*m0); *m0 = NULL; + action = PF_DROP; REASON_SET(&reason, PFRES_MEMORY); } else { struct ip_fw_args dnflow; @@ -6951,6 +6952,13 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb } pd.pf_mtag->flags |= PF_PACKET_LOOPED; m_tag_delete(m, ipfwtag); + if (rr->info & IPFW_IS_DUMMYNET) { + /* Dummynet re-injects packets after they've + * completed their delay. We've already + * processed them, so pass unconditionally. */ + PF_RULES_RUNLOCK(); + return (PF_PASS); + } } } else if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { action = PF_DROP; @@ -7211,47 +7219,6 @@ done: } #endif /* ALTQ */ - 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) && !PACKET_LOOPED(&pd)) { - if (ip_dn_io_ptr == NULL) { - action = PF_DROP; - REASON_SET(&reason, PFRES_MEMORY); - } else { - struct ip_fw_args dnflow; - - if (pd.pf_mtag == NULL && - ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) { - action = PF_DROP; - REASON_SET(&reason, PFRES_MEMORY); - if (s) - PF_STATE_UNLOCK(s); - return (action); - } - - if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { - ip_dn_io_ptr(m0, &dnflow); - - if (*m0 == NULL) { - if (s) - PF_STATE_UNLOCK(s); - return (action); - } else { - /* This is dummynet fast io processing */ - m_tag_delete(*m0, m_tag_first(*m0)); - pd.pf_mtag->flags &= ~PF_PACKET_LOOPED; - } - } - } - } - if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && (s->nat_rule.ptr->action == PF_RDR || @@ -7348,6 +7315,44 @@ 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) { + if (ip_dn_io_ptr == NULL) { + m_freem(*m0); + *m0 = NULL; + action = PF_DROP; + REASON_SET(&reason, PFRES_MEMORY); + } else { + struct ip_fw_args dnflow; + + 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); + if (s) + PF_STATE_UNLOCK(s); + return (action); + } + + if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) { + ip_dn_io_ptr(m0, &dnflow); + + if (*m0 == NULL) + action = PF_DROP; + } + } + } break; } |