aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netpfil/pf/pf.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 881b3cf91140..d9c0beb0169f 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -9130,6 +9130,28 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
}
+ if (pd->dir == PF_IN) {
+ uint16_t tmp;
+ /*
+ * Make sure dummynet gets the correct direction, in case it needs to
+ * re-inject later.
+ */
+ pd->dir = PF_OUT;
+
+ /*
+ * The following processing is actually the rest of the inbound processing, even
+ * though we've marked it as outbound (so we don't look through dummynet) and it
+ * happens after the outbound processing (pf_test(PF_OUT) above).
+ * Swap the dummynet pipe numbers, because it's going to come to the wrong
+ * conclusion about what direction it's processing, and we can't fix it or it
+ * will re-inject incorrectly. Swapping the pipe numbers means that its incorrect
+ * decision will pick the right pipe, and everything will mostly work as expected.
+ */
+ tmp = pd->act.dnrpipe;
+ pd->act.dnrpipe = pd->act.dnpipe;
+ pd->act.dnpipe = tmp;
+ }
+
/*
* If the packet is too large for the outgoing interface,
* send back an icmp6 error.