Index: sys/dev/pci/if_ix.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/dev/pci/if_ix.c,v diff -u -p -u -p -r1.218 if_ix.c --- sys/dev/pci/if_ix.c 4 Oct 2024 05:22:10 -0000 1.218 +++ sys/dev/pci/if_ix.c 21 Feb 2025 17:59:24 -0000 @@ -550,6 +550,19 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c } break; + case SIOCSIFXFLAGS: + if (ISSET(ifr->ifr_flags, IFXF_LRO) != + ISSET(ifp->if_xflags, IFXF_LRO)) { + if (ISSET(ifr->ifr_flags, IFXF_LRO)) + SET(ifp->if_xflags, IFXF_LRO); + else + CLR(ifp->if_xflags, IFXF_LRO); + + if (ifp->if_flags & IFF_UP) + ixgbe_init(sc); + } + break; + case SIOCSIFMEDIA: case SIOCGIFMEDIA: IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)"); Index: sys/dev/pci/if_vmx.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/dev/pci/if_vmx.c,v diff -u -p -u -p -r1.90 if_vmx.c --- sys/dev/pci/if_vmx.c 24 Jan 2025 10:29:43 -0000 1.90 +++ sys/dev/pci/if_vmx.c 21 Feb 2025 17:59:24 -0000 @@ -1370,6 +1370,19 @@ vmxnet3_reset(struct vmxnet3_softc *sc) WRITE_CMD(sc, VMXNET3_CMD_RESET); } +void +vmxnet4_set_features(struct vmxnet3_softc *sc) +{ + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + + /* TCP Large Receive Offload */ + if (ISSET(ifp->if_xflags, IFXF_LRO)) + SET(sc->sc_ds->upt_features, UPT1_F_LRO); + else + CLR(sc->sc_ds->upt_features, UPT1_F_LRO); + WRITE_CMD(sc, VMXNET3_CMD_SET_FEATURE); +} + int vmxnet3_init(struct vmxnet3_softc *sc) { @@ -1403,12 +1416,7 @@ vmxnet3_init(struct vmxnet3_softc *sc) return EIO; } - /* TCP Large Receive Offload */ - if (ISSET(ifp->if_xflags, IFXF_LRO)) - SET(sc->sc_ds->upt_features, UPT1_F_LRO); - else - CLR(sc->sc_ds->upt_features, UPT1_F_LRO); - WRITE_CMD(sc, VMXNET3_CMD_SET_FEATURE); + vmxnet4_set_features(sc); /* Program promiscuous mode and multicast filters. */ vmxnet3_iff(sc); @@ -1474,6 +1482,17 @@ vmxnet3_ioctl(struct ifnet *ifp, u_long } else { if (ifp->if_flags & IFF_RUNNING) vmxnet3_stop(ifp); + } + break; + case SIOCSIFXFLAGS: + if (ISSET(ifr->ifr_flags, IFXF_LRO) != + ISSET(ifp->if_xflags, IFXF_LRO)) { + if (ISSET(ifr->ifr_flags, IFXF_LRO)) + SET(ifp->if_xflags, IFXF_LRO); + else + CLR(ifp->if_xflags, IFXF_LRO); + + vmxnet4_set_features(sc); } break; case SIOCSIFMEDIA: Index: sys/dev/pv/if_vio.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/dev/pv/if_vio.c,v diff -u -p -u -p -r1.69 if_vio.c --- sys/dev/pv/if_vio.c 30 Jan 2025 07:48:50 -0000 1.69 +++ sys/dev/pv/if_vio.c 21 Feb 2025 17:59:24 -0000 @@ -352,6 +352,7 @@ int vio_set_rx_filter(struct vio_softc * void vio_iff(struct vio_softc *); int vio_media_change(struct ifnet *); void vio_media_status(struct ifnet *, struct ifmediareq *); +void vio_set_offloads(struct ifnet *); int vio_ctrleof(struct virtqueue *); int vio_ctrl_start(struct vio_softc *, uint8_t, uint8_t, int, int *); int vio_ctrl_submit(struct vio_softc *, int); @@ -953,6 +954,28 @@ vio_media_status(struct ifnet *ifp, stru imr->ifm_status |= IFM_ACTIVE|IFM_FDX; } +void +vio_set_offloads(struct ifnet *ifp) +{ + struct vio_softc *sc = ifp->if_softc; + struct virtio_softc *vsc = sc->sc_virtio; + uint64_t features = 0; + + if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) { + if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_CSUM)) + SET(features, VIRTIO_NET_F_GUEST_CSUM); + + if (ISSET(ifp->if_xflags, IFXF_LRO)) { + if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_TSO4)) + SET(features, VIRTIO_NET_F_GUEST_TSO4); + if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_TSO6)) + SET(features, VIRTIO_NET_F_GUEST_TSO6); + } + + vio_ctrl_guest_offloads(sc, features); + } +} + /* * Interface functions for ifnet */ @@ -960,7 +983,6 @@ int vio_init(struct ifnet *ifp) { struct vio_softc *sc = ifp->if_softc; - struct virtio_softc *vsc = sc->sc_virtio; int qidx; vio_stop(ifp, 0); @@ -977,22 +999,7 @@ vio_init(struct ifnet *ifp) } vio_iff(sc); vio_link_state(ifp); - - if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) { - uint64_t features = 0; - - if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_CSUM)) - SET(features, VIRTIO_NET_F_GUEST_CSUM); - - if (ISSET(ifp->if_xflags, IFXF_LRO)) { - if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_TSO4)) - SET(features, VIRTIO_NET_F_GUEST_TSO4); - if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_TSO6)) - SET(features, VIRTIO_NET_F_GUEST_TSO6); - } - - vio_ctrl_guest_offloads(sc, features); - } + vio_set_offloads(ifp); SET(ifp->if_flags, IFF_RUNNING); @@ -1312,6 +1319,17 @@ vio_ioctl(struct ifnet *ifp, u_long cmd, } else { if (ifp->if_flags & IFF_RUNNING) vio_stop(ifp, 1); + } + break; + case SIOCSIFXFLAGS: + if (ISSET(ifr->ifr_flags, IFXF_LRO) != + ISSET(ifp->if_xflags, IFXF_LRO)) { + if (ISSET(ifr->ifr_flags, IFXF_LRO)) + SET(ifp->if_xflags, IFXF_LRO); + else + CLR(ifp->if_xflags, IFXF_LRO); + + vio_set_offloads(ifp); } break; case SIOCGIFMEDIA: Index: sys/net/if.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if.c,v diff -u -p -u -p -r1.726 if.c --- sys/net/if.c 3 Feb 2025 08:58:52 -0000 1.726 +++ sys/net/if.c 21 Feb 2025 17:59:24 -0000 @@ -3353,29 +3353,26 @@ ifpromisc(struct ifnet *ifp, int pswitch int ifsetlro(struct ifnet *ifp, int on) { - struct ifreq ifrq; int error = 0; int s = splnet(); - struct if_parent parent; + struct ifreq ifr; - memset(&parent, 0, sizeof(parent)); - if ((*ifp->if_ioctl)(ifp, SIOCGIFPARENT, (caddr_t)&parent) != -1) { - struct ifnet *ifp0 = if_unit(parent.ifp_parent); - - if (ifp0 != NULL) { - ifsetlro(ifp0, on); - if_put(ifp0); - } - } + NET_ASSERT_LOCKED(); /* for ioctl */ + KERNEL_ASSERT_LOCKED(); /* for if_flags */ + + memset(&ifr, 0, sizeof ifr); + if (on) + SET(ifr.ifr_flags, IFXF_LRO); + + error = ((*ifp->if_ioctl)(ifp, SIOCSIFXFLAGS, (caddr_t)&ifr)); + if (error == 0) + goto out; if (!ISSET(ifp->if_capabilities, IFCAP_LRO)) { error = ENOTSUP; goto out; } - NET_ASSERT_LOCKED(); /* for ioctl */ - KERNEL_ASSERT_LOCKED(); /* for if_flags */ - if (on && !ISSET(ifp->if_xflags, IFXF_LRO)) { if (ifp->if_type == IFT_ETHER && ether_brport_isset(ifp)) { error = EBUSY; @@ -3384,21 +3381,7 @@ ifsetlro(struct ifnet *ifp, int on) SET(ifp->if_xflags, IFXF_LRO); } else if (!on && ISSET(ifp->if_xflags, IFXF_LRO)) CLR(ifp->if_xflags, IFXF_LRO); - else - goto out; - /* restart interface */ - if (ISSET(ifp->if_flags, IFF_UP)) { - /* go down for a moment... */ - CLR(ifp->if_flags, IFF_UP); - ifrq.ifr_flags = ifp->if_flags; - (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); - - /* ... and up again */ - SET(ifp->if_flags, IFF_UP); - ifrq.ifr_flags = ifp->if_flags; - (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); - } out: splx(s); Index: sys/net/if_aggr.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_aggr.c,v diff -u -p -u -p -r1.47 if_aggr.c --- sys/net/if_aggr.c 18 Dec 2024 01:56:05 -0000 1.47 +++ sys/net/if_aggr.c 21 Feb 2025 17:59:24 -0000 @@ -856,6 +856,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) @@ -875,6 +876,11 @@ aggr_ioctl(struct ifnet *ifp, u_long cmd if (ISSET(ifp->if_flags, IFF_RUNNING)) error = aggr_down(sc); } + break; + + case SIOCSIFXFLAGS: + TAILQ_FOREACH(p, &sc->sc_ports, p_entry) + ifsetlro(p->p_ifp0, ISSET(ifr->ifr_flags, IFXF_LRO)); break; case SIOCSIFLLADDR: Index: sys/net/if_bpe.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_bpe.c,v diff -u -p -u -p -r1.22 if_bpe.c --- sys/net/if_bpe.c 23 Dec 2023 10:52:54 -0000 1.22 +++ sys/net/if_bpe.c 21 Feb 2025 17:59:24 -0000 @@ -305,6 +305,7 @@ bpe_ioctl(struct ifnet *ifp, u_long cmd, struct bpe_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; struct ifbrparam *bparam = (struct ifbrparam *)data; + struct ifnet *ifp0; int error = 0; switch (cmd) { @@ -317,6 +318,13 @@ bpe_ioctl(struct ifnet *ifp, u_long cmd, } else { if (ISSET(ifp->if_flags, IFF_RUNNING)) error = bpe_down(sc); + } + break; + + case SIOCSIFXFLAGS: + if ((ifp0 = if_get(sc->sc_key.k_if)) != NULL) { + ifsetlro(ifp0, ISSET(ifr->ifr_flags, IFXF_LRO)); + if_put(ifp0); } break; Index: sys/net/if_trunk.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_trunk.c,v diff -u -p -u -p -r1.154 if_trunk.c --- sys/net/if_trunk.c 23 Dec 2023 10:52:54 -0000 1.154 +++ sys/net/if_trunk.c 21 Feb 2025 17:59:24 -0000 @@ -846,6 +846,12 @@ trunk_ioctl(struct ifnet *ifp, u_long cm case SIOCSIFFLAGS: error = ENETRESET; break; + + case SIOCSIFXFLAGS: + SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) + ifsetlro(tp->tp_if, ISSET(ifr->ifr_flags, IFXF_LRO)); + break; + case SIOCADDMULTI: error = trunk_ether_addmulti(tr, ifr); break; Index: sys/net/if_vlan.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_vlan.c,v diff -u -p -u -p -r1.219 if_vlan.c --- sys/net/if_vlan.c 9 Jun 2024 16:25:28 -0000 1.219 +++ sys/net/if_vlan.c 21 Feb 2025 17:59:24 -0000 @@ -701,6 +701,13 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd } break; + case SIOCSIFXFLAGS: + if ((ifp0 = if_get(sc->sc_ifidx0)) != NULL) { + ifsetlro(ifp0, ISSET(ifr->ifr_flags, IFXF_LRO)); + if_put(ifp0); + } + break; + case SIOCSVNETID: if (ifr->ifr_vnetid < EVL_VLID_MIN || ifr->ifr_vnetid > EVL_VLID_MAX) { Index: sys/net/if_vxlan.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/net/if_vxlan.c,v diff -u -p -u -p -r1.100 if_vxlan.c --- sys/net/if_vxlan.c 31 Oct 2024 11:41:31 -0000 1.100 +++ sys/net/if_vxlan.c 21 Feb 2025 17:59:24 -0000 @@ -729,6 +729,7 @@ vxlan_ioctl(struct ifnet *ifp, u_long cm struct vxlan_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; struct ifbrparam *bparam = (struct ifbrparam *)data; + struct ifnet *ifp0; int error = 0; switch (cmd) { @@ -743,6 +744,13 @@ vxlan_ioctl(struct ifnet *ifp, u_long cm } else { if (ISSET(ifp->if_flags, IFF_RUNNING)) error = vxlan_down(sc); + } + break; + + case SIOCSIFXFLAGS: + if ((ifp0 = if_get(sc->sc_if_index0)) != NULL) { + ifsetlro(ifp0, ISSET(ifr->ifr_flags, IFXF_LRO)); + if_put(ifp0); } break; Index: sys/netinet/ip_carp.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/ip_carp.c,v diff -u -p -u -p -r1.365 ip_carp.c --- sys/netinet/ip_carp.c 19 Dec 2024 22:10:35 -0000 1.365 +++ sys/netinet/ip_carp.c 21 Feb 2025 17:59:24 -0000 @@ -2045,6 +2045,13 @@ carp_ioctl(struct ifnet *ifp, u_long cmd } break; + case SIOCSIFXFLAGS: + if ((ifp0 = if_get(sc->sc_carpdevidx)) != NULL) { + ifsetlro(ifp0, ISSET(ifr->ifr_flags, IFXF_LRO)); + if_put(ifp0); + } + break; + case SIOCSVH: KERNEL_ASSERT_LOCKED(); /* touching carp_vhosts */ vhe = SRPL_FIRST_LOCKED(&sc->carp_vhosts);