Avoid enabling TSO on interfaces which are already attached to a bridge.
authorjan <jan@openbsd.org>
Tue, 7 Mar 2023 20:09:47 +0000 (20:09 +0000)
committerjan <jan@openbsd.org>
Tue, 7 Mar 2023 20:09:47 +0000 (20:09 +0000)
with tweaks from claudio and deraadt

ok claudio, bluhm

sbin/ifconfig/ifconfig.8
sys/net/if.c
sys/net/if.h

index 6bd446b..beeb8e8 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ifconfig.8,v 1.390 2023/02/27 14:53:38 jmc Exp $
+.\"    $OpenBSD: ifconfig.8,v 1.391 2023/03/07 20:09:47 jan Exp $
 .\"    $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $
 .\"     $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $
 .\"
@@ -31,7 +31,7 @@
 .\"
 .\"     @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
 .\"
-.Dd $Mdocdate: February 27 2023 $
+.Dd $Mdocdate: March 7 2023 $
 .Dt IFCONFIG 8
 .Os
 .Sh NAME
@@ -501,6 +501,11 @@ such as
 .Xr aggr 4 ,
 and
 .Xr carp 4 .
+It is not possible to use TSO with interfaces attached to a
+.Xr bridge 4 ,
+.Xr veb 4 ,
+or
+.Xr tpmr 4 .
 Changing this option will re-initialize the network interface.
 .It Cm -tso
 Disable TSO.
index 90a78d7..8ae5964 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.684 2023/02/27 09:35:32 jan Exp $    */
+/*     $OpenBSD: if.c,v 1.685 2023/03/07 20:09:48 jan Exp $    */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -2058,18 +2058,9 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
                }
 #endif
 
-               if (ISSET(ifp->if_capabilities, IFCAP_TSO) &&
-                   ISSET(ifr->ifr_flags, IFXF_TSO) !=
-                   ISSET(ifp->if_xflags, IFXF_TSO)) {
-                       if (ISSET(ifr->ifr_flags, IFXF_TSO))
-                               ifsettso(ifp, 1);
-                       else
-                               ifsettso(ifp, 0);
-               } else if (!ISSET(ifp->if_capabilities, IFCAP_TSO) &&
-                   ISSET(ifr->ifr_flags, IFXF_TSO)) {
-                       ifr->ifr_flags &= ~IFXF_TSO;
-                       error = ENOTSUP;
-               }
+               if (ISSET(ifr->ifr_flags, IFXF_TSO) !=
+                   ISSET(ifp->if_xflags, IFXF_TSO))
+                       error = ifsettso(ifp, ISSET(ifr->ifr_flags, IFXF_TSO));
 
                if (error == 0)
                        ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
@@ -3113,18 +3104,27 @@ ifpromisc(struct ifnet *ifp, int pswitch)
 }
 
 /* Set/clear TSO flag and restart interface if needed. */
-void
+int
 ifsettso(struct ifnet *ifp, int on)
 {
        struct ifreq ifrq;
+       int error = 0;
        int s = splnet();
 
        NET_ASSERT_LOCKED();    /* for ioctl */
        KERNEL_ASSERT_LOCKED(); /* for if_flags */
 
-       if (on && !ISSET(ifp->if_xflags, IFXF_TSO))
+       if (on && !ISSET(ifp->if_xflags, IFXF_TSO)) {
+               if (!ISSET(ifp->if_capabilities, IFCAP_TSO)) {
+                       error = ENOTSUP;
+                       goto out;
+               }
+               if (ether_brport_isset(ifp)) {
+                       error = EBUSY;
+                       goto out;
+               }
                SET(ifp->if_xflags, IFXF_TSO);
-       else if (!on && ISSET(ifp->if_xflags, IFXF_TSO))
+       else if (!on && ISSET(ifp->if_xflags, IFXF_TSO))
                CLR(ifp->if_xflags, IFXF_TSO);
        else
                goto out;
@@ -3142,6 +3142,8 @@ ifsettso(struct ifnet *ifp, int on)
        }
  out:
        splx(s);
+
+       return error;
 }
 
 void
index 6a04662..757ff96 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.h,v 1.210 2023/02/27 09:35:32 jan Exp $    */
+/*     $OpenBSD: if.h,v 1.211 2023/03/07 20:09:48 jan Exp $    */
 /*     $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $  */
 
 /*
@@ -544,7 +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);
+int    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 *);