Turn off TSO if interface is added to layer 2 devices.
authorjan <jan@openbsd.org>
Mon, 27 Feb 2023 09:35:32 +0000 (09:35 +0000)
committerjan <jan@openbsd.org>
Mon, 27 Feb 2023 09:35:32 +0000 (09:35 +0000)
ok bluhm@, claudio@

sys/net/if.c
sys/net/if.h
sys/net/if_bridge.c
sys/net/if_tpmr.c
sys/net/if_veb.c

index e805f21..90a78d7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.683 2022/11/23 16:57:37 kn Exp $     */
+/*     $OpenBSD: if.c,v 1.684 2023/02/27 09:35:32 jan Exp $    */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -2056,43 +2056,20 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
                        ifr->ifr_flags &= ~IFXF_WOL;
                        error = ENOTSUP;
                }
+#endif
 
                if (ISSET(ifp->if_capabilities, IFCAP_TSO) &&
                    ISSET(ifr->ifr_flags, IFXF_TSO) !=
                    ISSET(ifp->if_xflags, IFXF_TSO)) {
-                       struct ifreq ifrq;
-
-                       s = splnet();
-
                        if (ISSET(ifr->ifr_flags, IFXF_TSO))
-                               ifp->if_xflags |= IFXF_TSO;
+                               ifsettso(ifp, 1);
                        else
-                               ifp->if_xflags &= ~IFXF_TSO;
-
-                       NET_ASSERT_LOCKED();    /* for ioctl */
-                       KERNEL_ASSERT_LOCKED(); /* for if_flags */
-
-                       if (ISSET(ifp->if_flags, IFF_UP)) {
-                               /* go down for a moment... */
-                               ifp->if_flags &= ~IFF_UP;
-                               ifrq.ifr_flags = ifp->if_flags;
-                               (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
-                                   (caddr_t)&ifrq);
-
-                               /* ... and up again */
-                               ifp->if_flags |= IFF_UP;
-                               ifrq.ifr_flags = ifp->if_flags;
-                               (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
-                                   (caddr_t)&ifrq);
-                       }
-
-                       splx(s);
+                               ifsettso(ifp, 0);
                } else if (!ISSET(ifp->if_capabilities, IFCAP_TSO) &&
                    ISSET(ifr->ifr_flags, IFXF_TSO)) {
                        ifr->ifr_flags &= ~IFXF_TSO;
                        error = ENOTSUP;
                }
-#endif
 
                if (error == 0)
                        ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
@@ -3135,6 +3112,38 @@ ifpromisc(struct ifnet *ifp, int pswitch)
        return (error);
 }
 
+/* Set/clear TSO flag and restart interface if needed. */
+void
+ifsettso(struct ifnet *ifp, int on)
+{
+       struct ifreq ifrq;
+       int s = splnet();
+
+       NET_ASSERT_LOCKED();    /* for ioctl */
+       KERNEL_ASSERT_LOCKED(); /* for if_flags */
+
+       if (on && !ISSET(ifp->if_xflags, IFXF_TSO))
+               SET(ifp->if_xflags, IFXF_TSO);
+       else if (!on && ISSET(ifp->if_xflags, IFXF_TSO))
+               CLR(ifp->if_xflags, IFXF_TSO);
+       else
+               goto out;
+
+       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);
+}
+
 void
 ifa_add(struct ifnet *ifp, struct ifaddr *ifa)
 {
index 278679b..6a04662 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.h,v 1.209 2022/06/27 15:11:23 jan Exp $    */
+/*     $OpenBSD: if.h,v 1.210 2023/02/27 09:35:32 jan Exp $    */
 /*     $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $  */
 
 /*
@@ -544,6 +544,7 @@ void        if_getdata(struct ifnet *, struct if_data *);
 void   ifinit(void);
 int    ifioctl(struct socket *, u_long, caddr_t, struct proc *);
 int    ifpromisc(struct ifnet *, int);
+void   ifsettso(struct ifnet *, int);
 struct ifg_group *if_creategroup(const char *);
 int    if_addgroup(struct ifnet *, const char *);
 int    if_delgroup(struct ifnet *, const char *);
index 708f3d5..a202556 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bridge.c,v 1.364 2022/08/07 00:57:43 bluhm Exp $   */
+/*     $OpenBSD: if_bridge.c,v 1.365 2023/02/27 09:35:32 jan Exp $     */
 
 /*
  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -337,6 +337,10 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                 * released.
                 */
 
+               NET_LOCK();
+               ifsettso(ifs, 0);
+               NET_UNLOCK();
+
                bif->bridge_sc = sc;
                bif->ifp = ifs;
                bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
@@ -395,6 +399,11 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                        error = ENOMEM;
                        break;
                }
+
+               NET_LOCK();
+               ifsettso(ifs, 0);
+               NET_UNLOCK();
+
                bif->bridge_sc = sc;
                bif->ifp = ifs;
                bif->bif_flags = IFBIF_SPAN;
index 5fc186c..9f2b2de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_tpmr.c,v 1.31 2021/07/07 20:19:01 sashan Exp $ */
+/*     $OpenBSD: if_tpmr.c,v 1.32 2023/02/27 09:35:32 jan Exp $ */
 
 /*
  * Copyright (c) 2019 The University of Queensland
@@ -521,6 +521,8 @@ tpmr_add_port(struct tpmr_softc *sc, const struct ifbreq *req)
                goto put;
        }
 
+       ifsettso(ifp0, 0);
+
        p->p_ifp0 = ifp0;
        p->p_tpmr = sc;
 
index b24eab6..c5f865b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_veb.c,v 1.29 2022/06/01 17:34:13 sashan Exp $ */
+/*     $OpenBSD: if_veb.c,v 1.30 2023/02/27 09:35:32 jan Exp $ */
 
 /*
  * Copyright (c) 2021 David Gwynne <dlg@openbsd.org>
@@ -1465,6 +1465,8 @@ veb_add_port(struct veb_softc *sc, const struct ifbreq *req, unsigned int span)
                goto put;
        }
 
+       ifsettso(ifp0, 0);
+
        p->p_ifp0 = ifp0;
        p->p_veb = sc;