Date: Fri, 06 Feb 2026 03:38:51 +0000 From: Zhenlei Huang <zlei@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: a622030b4bae - main - lagg: Make the none protocol a first-class citizen Message-ID: <6985624b.42e7d.c91bd19@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=a622030b4baec2136984cea7bd25c2985a2ae9b3 commit a622030b4baec2136984cea7bd25c2985a2ae9b3 Author: Zhenlei Huang <zlei@FreeBSD.org> AuthorDate: 2026-02-06 03:37:43 +0000 Commit: Zhenlei Huang <zlei@FreeBSD.org> CommitDate: 2026-02-06 03:37:43 +0000 lagg: Make the none protocol a first-class citizen All the other protocols have corresponding start and input routines, which are used in the fast path. Currently the none protocol is treated specially. In the fast path it is checked to indicate whether a working protocol is configured. There are two issues raised by this design: 1. In production, other protocols are commonly used, but not the none protocol. It smells like an overkill to always check it in the fast path. It is unfair to other commonly used protocols. 2. PR 289017 reveals that there's a small window between checking the protocol and calling lagg_proto_start(). lagg_proto_start() is possible to see the none protocol and do NULL deferencing. Fix them by making the none protocol a first-class citizen so that it has start and input routines just the same as other protocols. Then we can stop checking it in the fast path, since lagg_proto_start() and lagg_proto_input() will never fail to work. The error ENETDOWN is chosen for the start routine. Obviously no active ports are available, and the packets will go nowhere. It is also a better error than ENXIO, since indeed the interface is configured and has a TX algorithm (the none protocol). PR: 289017 Diagnosed by: Qiu-ji Chen <chenqiuji666@gmail.com> Tested by: Gui-Dong Han <hanguidong02@gmail.com> Reviewed by: glebius MFC after: 5 days Differential Revision: https://reviews.freebsd.org/D55123 --- sys/net/if_lagg.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 5b52bfa80e3b..21ea2b30459b 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -169,6 +169,11 @@ static void lagg_media_status(struct ifnet *, struct ifmediareq *); static struct lagg_port *lagg_link_active(struct lagg_softc *, struct lagg_port *); +/* No proto */ +static int lagg_none_start(struct lagg_softc *, struct mbuf *); +static struct mbuf *lagg_none_input(struct lagg_softc *, struct lagg_port *, + struct mbuf *); + /* Simple round robin */ static void lagg_rr_attach(struct lagg_softc *); static int lagg_rr_start(struct lagg_softc *, struct mbuf *); @@ -219,7 +224,9 @@ static const struct lagg_proto { void (*pr_portreq)(struct lagg_port *, void *); } lagg_protos[] = { { - .pr_num = LAGG_PROTO_NONE + .pr_num = LAGG_PROTO_NONE, + .pr_start = lagg_none_start, + .pr_input = lagg_none_input, }, { .pr_num = LAGG_PROTO_ROUNDROBIN, @@ -2129,8 +2136,8 @@ lagg_transmit_ethernet(struct ifnet *ifp, struct mbuf *m) if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) MPASS(m->m_pkthdr.snd_tag->ifp == ifp); #endif - /* We need a Tx algorithm and at least one port */ - if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0) { + /* We need at least one port */ + if (sc->sc_count == 0) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return (ENXIO); @@ -2151,8 +2158,8 @@ lagg_transmit_infiniband(struct ifnet *ifp, struct mbuf *m) if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) MPASS(m->m_pkthdr.snd_tag->ifp == ifp); #endif - /* We need a Tx algorithm and at least one port */ - if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0) { + /* We need at least one port */ + if (sc->sc_count == 0) { m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return (ENXIO); @@ -2180,8 +2187,7 @@ lagg_input_ethernet(struct ifnet *ifp, struct mbuf *m) NET_EPOCH_ASSERT(); if ((scifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - lp->lp_detaching != 0 || - sc->sc_proto == LAGG_PROTO_NONE) { + lp->lp_detaching != 0) { m_freem(m); return (NULL); } @@ -2215,8 +2221,7 @@ lagg_input_infiniband(struct ifnet *ifp, struct mbuf *m) NET_EPOCH_ASSERT(); if ((scifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - lp->lp_detaching != 0 || - sc->sc_proto == LAGG_PROTO_NONE) { + lp->lp_detaching != 0) { m_freem(m); return (NULL); } @@ -2390,6 +2395,25 @@ lagg_enqueue(struct ifnet *ifp, struct mbuf *m) return (ifp->if_transmit)(ifp, m); } +/* + * No proto + */ +static int +lagg_none_start(struct lagg_softc *sc, struct mbuf *m) +{ + m_freem(m); + if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); + /* No active ports available */ + return (ENETDOWN); +} + +static struct mbuf * +lagg_none_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) +{ + m_freem(m); + return (NULL); +} + /* * Simple round robin aggregation */home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6985624b.42e7d.c91bd19>
