summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJan Klemkow <jan@cvs.openbsd.org>2023-02-27 09:35:33 +0000
committerJan Klemkow <jan@cvs.openbsd.org>2023-02-27 09:35:33 +0000
commitdb7128f9a26a8c9e208060a0538e628b6681f2bc (patch)
treedcdc6b52824fa9a50f42332672e1825049790788 /sys
parentec8075955e4fc782498731bc81aad797cd89663d (diff)
Turn off TSO if interface is added to layer 2 devices.
ok bluhm@, claudio@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c63
-rw-r--r--sys/net/if.h3
-rw-r--r--sys/net/if_bridge.c11
-rw-r--r--sys/net/if_tpmr.c4
-rw-r--r--sys/net/if_veb.c4
5 files changed, 54 insertions, 31 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index e805f21c42f..90a78d7f109 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -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)
{
diff --git a/sys/net/if.h b/sys/net/if.h
index 278679be2ef..6a046623747 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -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 *);
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 708f3d56abb..a202556e41f 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -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;
diff --git a/sys/net/if_tpmr.c b/sys/net/if_tpmr.c
index 5fc186c4a3e..9f2b2dec125 100644
--- a/sys/net/if_tpmr.c
+++ b/sys/net/if_tpmr.c
@@ -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;
diff --git a/sys/net/if_veb.c b/sys/net/if_veb.c
index b24eab61115..c5f865b7154 100644
--- a/sys/net/if_veb.c
+++ b/sys/net/if_veb.c
@@ -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;