aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-11-22 20:28:10 +0000
committerKristof Provost <kp@FreeBSD.org>2021-11-23 15:46:15 +0000
commit18d04cd2d42c16209c8f615bb9735dded328915b (patch)
tree960ca1a38a356208083e8778cc4d0e6a924e572a
parentc36f90417b734e56ef938cc2d19601001c709f40 (diff)
downloadsrc-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
-rw-r--r--sys/netpfil/pf/pf.c87
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;
}