Download raw body.
trunk/aggr(4): turn off lro if bridged
Hi,
When aggr(4) or trunk(4) attaches to bridged, they have to forward the
turn off LRO call to there trunkports. I don't find a way to do this
like the existing code for vlan(4) and friends. Thus, I have to
introduce a new ioctl for this kind of action.
With this diff a user no longer needs to disable tcplro manually when
working with bridged trunk(4) or aggr(4) interfaces.
ok?
bye,
Jan
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
diff -u -p -r1.718 if.c
--- net/if.c 6 Feb 2024 00:18:53 -0000 1.718
+++ net/if.c 3 May 2024 18:31:40 -0000
@@ -140,6 +140,10 @@
#include <sys/device.h>
+#include <crypto/siphash.h>
+#include <net/if_media.h>
+#include <net/if_trunk.h>
+
void if_attachsetup(struct ifnet *);
void if_attach_common(struct ifnet *);
void if_remove(struct ifnet *);
@@ -3247,6 +3251,10 @@ ifsetlro(struct ifnet *ifp, int on)
int s = splnet();
struct if_parent parent;
+ /*
+ * Forward ifsetlro() call to parents of bpe(4), gre(4), pfsync(4),
+ * vlan(4) and vxlan(4).
+ */
memset(&parent, 0, sizeof(parent));
if ((*ifp->if_ioctl)(ifp, SIOCGIFPARENT, (caddr_t)&parent) != -1) {
struct ifnet *ifp0 = if_unit(parent.ifp_parent);
@@ -3256,6 +3264,11 @@ ifsetlro(struct ifnet *ifp, int on)
if_put(ifp0);
}
}
+
+ /*
+ * Forward ifsetlro() call to all trunkports of trunk(4) and aggr(4).
+ */
+ (*ifp->if_ioctl)(ifp, SIOCSTRUNKPORTLRO, (caddr_t)&on);
if (!ISSET(ifp->if_capabilities, IFCAP_LRO)) {
error = ENOTSUP;
Index: net/if_aggr.c
===================================================================
RCS file: /cvs/src/sys/net/if_aggr.c,v
diff -u -p -r1.45 if_aggr.c
--- net/if_aggr.c 18 Mar 2024 06:14:50 -0000 1.45
+++ net/if_aggr.c 3 May 2024 19:18:27 -0000
@@ -833,6 +833,7 @@ aggr_ioctl(struct ifnet *ifp, u_long cmd
{
struct aggr_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
+ struct aggr_port *p;
int error = 0;
if (sc->sc_dead)
@@ -897,6 +898,10 @@ aggr_ioctl(struct ifnet *ifp, u_long cmd
error = aggr_add_port(sc, (struct trunk_reqport *)data);
break;
+ case SIOCSTRUNKPORTLRO:
+ TAILQ_FOREACH(p, &sc->sc_ports, p_entry)
+ ifsetlro(p->p_ifp0, *(int *)data);
+ break;
case SIOCSTRUNKDELPORT:
error = suser(curproc);
if (error != 0)
@@ -1184,6 +1189,10 @@ aggr_add_port(struct aggr_softc *sc, con
if (error != 0)
goto unmtu;
}
+
+ /* Turn off LRO if we are bridged. */
+ if (ether_brport_isset(ifp))
+ ifsetlro(ifp0, 0);
TAILQ_FOREACH(ma, &sc->sc_multiaddrs, m_entry) {
if (aggr_multi(sc, p, ma, SIOCADDMULTI) != 0) {
Index: net/if_trunk.c
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.c,v
diff -u -p -r1.154 if_trunk.c
--- net/if_trunk.c 23 Dec 2023 10:52:54 -0000 1.154
+++ net/if_trunk.c 3 May 2024 19:12:59 -0000
@@ -334,6 +334,10 @@ trunk_port_create(struct trunk_softc *tr
}
}
+ /* Turn off LRO if we are bridged. */
+ if (ether_brport_isset(&tr->tr_ac.ac_if))
+ ifsetlro(ifp, 0);
+
/* Change the interface type */
tp->tp_iftype = ifp->if_type;
ifp->if_type = IFT_IEEE8023ADLAG;
@@ -783,6 +787,10 @@ trunk_ioctl(struct ifnet *ifp, u_long cm
tro->to_lacpopts.lacp_ifqprio;
break;
}
+ break;
+ case SIOCSTRUNKPORTLRO:
+ SLIST_FOREACH(tp, &tr->tr_ports, tp_entries)
+ ifsetlro(tp->tp_if, *(int *)data);
break;
case SIOCGTRUNKPORT:
if (rp->rp_portname[0] == '\0' ||
Index: net/if_trunk.h
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.h,v
diff -u -p -r1.30 if_trunk.h
--- net/if_trunk.h 22 Jul 2020 02:16:02 -0000 1.30
+++ net/if_trunk.h 3 May 2024 18:14:28 -0000
@@ -150,6 +150,7 @@ struct trunk_opts {
#define SIOCGTRUNKOPTS _IOWR('i', 145, struct trunk_opts)
#define SIOCSTRUNKOPTS _IOW('i', 146, struct trunk_opts)
+#define SIOCSTRUNKPORTLRO _IOW('i', 147, int)
#ifdef _KERNEL
/*
trunk/aggr(4): turn off lro if bridged