git: dacffdd4dc51 - stable/12 - pfsync: support deferring IPv6 packets
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 02 Mar 2023 16:25:46 UTC
The branch stable/12 has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=dacffdd4dc511ae73e8fd3eb19f9efe4ecb26ba1
commit dacffdd4dc511ae73e8fd3eb19f9efe4ecb26ba1
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-02-14 06:11:38 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-03-02 11:15:28 +0000
pfsync: support deferring IPv6 packets
When we send out a deferred packet we must make sure to call
ip6_output() for IPv6 packets. If not we might end up attempting to
ip_fragment() an IPv6 packet, which could lead to us reading outside of
the mbuf.
PR: 268246
Reviewed by: melifaro, zlei
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D38586
(cherry picked from commit 9a1cab6d79b7286e5f650f57ed95625e6ddb8e4b)
---
sys/netpfil/pf/if_pfsync.c | 71 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 56 insertions(+), 15 deletions(-)
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 98319f2b583f..e3e3fa3ad6a2 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -102,12 +102,16 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+
#define PFSYNC_MINPKT ( \
sizeof(struct ip) + \
sizeof(struct pfsync_header) + \
sizeof(struct pfsync_subheader) )
struct pfsync_bucket;
+struct pfsync_softc;
struct pfsync_pkt {
struct ip *ip;
@@ -170,6 +174,7 @@ static void pfsync_q_ins(struct pf_kstate *, int, bool);
static void pfsync_q_del(struct pf_kstate *, bool, struct pfsync_bucket *);
static void pfsync_update_state(struct pf_kstate *);
+static void pfsync_tx(struct pfsync_softc *, struct mbuf *);
struct pfsync_upd_req_item {
TAILQ_ENTRY(pfsync_upd_req_item) ur_entry;
@@ -186,8 +191,6 @@ struct pfsync_deferral {
struct mbuf *pd_m;
};
-struct pfsync_sofct;
-
struct pfsync_bucket
{
int b_id;
@@ -1839,7 +1842,7 @@ pfsync_defer_tmo(void *arg)
free(pd, M_PFSYNC);
PFSYNC_BUCKET_UNLOCK(b);
- ip_output(m, NULL, NULL, 0, NULL, NULL);
+ pfsync_tx(sc, m);
pf_release_state(st);
@@ -2321,6 +2324,55 @@ pfsync_push_all(struct pfsync_softc *sc)
}
}
+static void
+pfsync_tx(struct pfsync_softc *sc, struct mbuf *m)
+{
+ struct ip *ip;
+ int error, af;
+
+ ip = mtod(m, struct ip *);
+ MPASS(ip->ip_v == IPVERSION || ip->ip_v == (IPV6_VERSION >> 4));
+
+ af = ip->ip_v == IPVERSION ? AF_INET : AF_INET6;
+
+ /*
+ * We distinguish between a deferral packet and our
+ * own pfsync packet based on M_SKIP_FIREWALL
+ * flag. This is XXX.
+ */
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if (m->m_flags & M_SKIP_FIREWALL) {
+ error = ip_output(m, NULL, NULL, 0,
+ NULL, NULL);
+ } else {
+ error = ip_output(m, NULL, NULL,
+ IP_RAWOUTPUT, &sc->sc_imo, NULL);
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (m->m_flags & M_SKIP_FIREWALL) {
+ error = ip6_output(m, NULL, NULL, 0,
+ NULL, NULL, NULL);
+ } else {
+ MPASS(false);
+ /* We don't support pfsync over IPv6. */
+ /*error = ip6_output(m, NULL, NULL,
+ IP_RAWOUTPUT, &sc->sc_imo6, NULL);*/
+ }
+ break;
+#endif
+ }
+
+ if (error == 0)
+ V_pfsyncstats.pfsyncs_opackets++;
+ else
+ V_pfsyncstats.pfsyncs_oerrors++;
+}
+
static void
pfsyncintr(void *arg)
{
@@ -2347,18 +2399,7 @@ pfsyncintr(void *arg)
n = m->m_nextpkt;
m->m_nextpkt = NULL;
- /*
- * We distinguish between a deferral packet and our
- * own pfsync packet based on M_SKIP_FIREWALL
- * flag. This is XXX.
- */
- if (m->m_flags & M_SKIP_FIREWALL)
- ip_output(m, NULL, NULL, 0, NULL, NULL);
- else if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo,
- NULL) == 0)
- V_pfsyncstats.pfsyncs_opackets++;
- else
- V_pfsyncstats.pfsyncs_oerrors++;
+ pfsync_tx(sc, m);
}
}
CURVNET_RESTORE();