Download raw body.
pppoe transmit optimisation
this let's packets being sent out pppoe interfaces bypass queues and go
straight onto the underlying interface.
it's complementary to src/sys/net/if_pppoe.c r1.85 "let pppoe data
packets go through if_vinput instead of the pppoeinq", but where that
skipped a queue on the rx side, this diff does it on the tx side.
i don't use pppoe anymore, so i need someone to test this diff before i
can commiti it.
Index: if_pppoe.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppoe.c,v
diff -u -p -r1.84 if_pppoe.c
--- if_pppoe.c 26 Jun 2024 01:40:49 -0000 1.84
+++ if_pppoe.c 12 May 2025 04:04:16 -0000
@@ -42,6 +42,7 @@
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/ioctl.h>
+#include <sys/percpu.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_types.h>
@@ -156,6 +157,7 @@ static void pppoe_abort_connect(struct p
static int pppoe_ioctl(struct ifnet *, unsigned long, caddr_t);
static void pppoe_tls(struct sppp *);
static void pppoe_tlf(struct sppp *);
+static int pppoe_enqueue(struct ifnet *, struct mbuf *);
static void pppoe_start(struct ifnet *);
/* internal timeout handling */
@@ -231,6 +233,7 @@ pppoe_clone_create(struct if_clone *ifc,
sc->sc_sppp.pp_flags |= PP_KEEPALIVE; /* use LCP keepalive */
sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN; /* framing added to ppp packets */
sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
+ sc->sc_sppp.pp_if.if_enqueue = pppoe_enqueue;
sc->sc_sppp.pp_if.if_start = pppoe_start;
sc->sc_sppp.pp_if.if_rtrequest = p2p_rtrequest;
sc->sc_sppp.pp_if.if_xflags = IFXF_CLONED;
@@ -246,6 +249,7 @@ pppoe_clone_create(struct if_clone *ifc,
if_attach(&sc->sc_sppp.pp_if);
if_alloc_sadl(&sc->sc_sppp.pp_if);
sppp_attach(&sc->sc_sppp.pp_if);
+ if_counters_alloc(&sc->sc_sppp.pp_if);
#if NBPFILTER > 0
bpfattach(&sc->sc_sppp.pp_if.if_bpf, &sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
#endif
@@ -1389,13 +1393,55 @@ pppoe_tlf(struct sppp *sp)
timeout_add_msec(&sc->sc_timeout, 20);
}
+int
+pppoe_transmit(struct pppoe_softc *sc, struct mbuf *m)
+{
+ size_t len;
+ uint8_t *p;
+
+ len = m->m_pkthdr.len;
+ M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
+ if (m == NULL)
+ return (ENOBUFS);
+
+ p = mtod(m, u_int8_t *);
+ PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
+
+#if NBPFILTER > 0
+ if (sc->sc_sppp.pp_if.if_bpf)
+ bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+
+ return (pppoe_output(sc, m));
+}
+
+int
+pppoe_enqueue(struct ifnet *ifp, struct mbuf *m)
+{
+ struct pppoe_softc *sc;
+ int error;
+
+ if (!ifq_is_priq(&ifp->if_snd))
+ return (if_enqueue_ifq(ifp, m));
+
+ sc = ifp->if_softc;
+ if (sc->sc_state < PPPOE_STATE_SESSION) {
+ m_freem(m);
+ return (ENETDOWN);
+ }
+
+ error = pppoe_transmit(sc, m);
+ if (error != 0)
+ counters_inc(ifp->if_counters, ifc_oerrors);
+
+ return (error);
+}
+
static void
pppoe_start(struct ifnet *ifp)
{
struct pppoe_softc *sc = (void *)ifp;
struct mbuf *m;
- size_t len;
- u_int8_t *p;
if (sppp_isempty(ifp))
return;
@@ -1407,21 +1453,6 @@ pppoe_start(struct ifnet *ifp)
}
while ((m = sppp_dequeue(ifp)) != NULL) {
- len = m->m_pkthdr.len;
- M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
- if (m == NULL) {
- ifp->if_oerrors++;
- continue;
- }
- p = mtod(m, u_int8_t *);
- PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
-
-#if NBPFILTER > 0
- if(sc->sc_sppp.pp_if.if_bpf)
- bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m,
- BPF_DIRECTION_OUT);
-#endif
-
- pppoe_output(sc, m);
+ pppoe_transmit(sc, m);
}
}
pppoe transmit optimisation