Module Name: src
Committed By: ozaki-r
Date: Wed Dec 6 05:11:10 UTC 2017
Modified Files:
src/sys/net: if.c if.h if_bridge.c if_vlan.c
Log Message:
Ensure to hold if_ioctl_lock when calling if_flags_set
To generate a diff of this commit:
cvs rdiff -u -r1.400 -r1.401 src/sys/net/if.c
cvs rdiff -u -r1.244 -r1.245 src/sys/net/if.h
cvs rdiff -u -r1.141 -r1.142 src/sys/net/if_bridge.c
cvs rdiff -u -r1.113 -r1.114 src/sys/net/if_vlan.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.400 src/sys/net/if.c:1.401
--- src/sys/net/if.c:1.400 Wed Nov 22 10:19:14 2017
+++ src/sys/net/if.c Wed Dec 6 05:11:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.400 2017/11/22 10:19:14 ozaki-r Exp $ */
+/* $NetBSD: if.c,v 1.401 2017/12/06 05:11:10 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.400 2017/11/22 10:19:14 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.401 2017/12/06 05:11:10 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1322,9 +1322,6 @@ if_detach(struct ifnet *ifp)
psref_target_destroy(&ifp->if_psref, ifnet_psref_class);
PSLIST_ENTRY_DESTROY(ifp, if_pslist_entry);
- mutex_obj_free(ifp->if_ioctl_lock);
- ifp->if_ioctl_lock = NULL;
-
if (ifp->if_slowtimo != NULL && ifp->if_slowtimo_ch != NULL) {
ifp->if_slowtimo = NULL;
callout_halt(ifp->if_slowtimo_ch, NULL);
@@ -1353,6 +1350,10 @@ if_detach(struct ifnet *ifp)
carp_ifdetach(ifp);
#endif
+ /* carp_ifdetach still uses the lock */
+ mutex_obj_free(ifp->if_ioctl_lock);
+ ifp->if_ioctl_lock = NULL;
+
/*
* Rip all the addresses off the interface. This should make
* all of the routes go away.
@@ -2507,9 +2508,11 @@ if_slowtimo(void *arg)
int
ifpromisc(struct ifnet *ifp, int pswitch)
{
- int pcount, ret;
+ int pcount, ret = 0;
short nflags;
+ mutex_enter(ifp->if_ioctl_lock);
+
pcount = ifp->if_pcount;
if (pswitch) {
/*
@@ -2518,11 +2521,11 @@ ifpromisc(struct ifnet *ifp, int pswitch
* consult IFF_PROMISC when it is brought up.
*/
if (ifp->if_pcount++ != 0)
- return 0;
+ goto out;
nflags = ifp->if_flags | IFF_PROMISC;
} else {
if (--ifp->if_pcount > 0)
- return 0;
+ goto out;
nflags = ifp->if_flags & ~IFF_PROMISC;
}
ret = if_flags_set(ifp, nflags);
@@ -2530,6 +2533,8 @@ ifpromisc(struct ifnet *ifp, int pswitch
if (ret != 0) {
ifp->if_pcount = pcount;
}
+out:
+ mutex_exit(ifp->if_ioctl_lock);
return ret;
}
@@ -3402,6 +3407,8 @@ if_flags_set(ifnet_t *ifp, const short f
{
int rc;
+ KASSERT(mutex_owned(ifp->if_ioctl_lock));
+
if (ifp->if_setflags != NULL)
rc = (*ifp->if_setflags)(ifp, flags);
else {
@@ -3450,6 +3457,30 @@ if_mcast_op(ifnet_t *ifp, const unsigned
return rc;
}
+int
+if_enable_vlan_mtu(struct ifnet *ifp)
+{
+ int error;
+
+ mutex_enter(ifp->if_ioctl_lock);
+ error= ether_enable_vlan_mtu(ifp);
+ mutex_exit(ifp->if_ioctl_lock);
+
+ return error;
+}
+
+int
+if_disable_vlan_mtu(struct ifnet *ifp)
+{
+ int error;
+
+ mutex_enter(ifp->if_ioctl_lock);
+ error= ether_disable_vlan_mtu(ifp);
+ mutex_exit(ifp->if_ioctl_lock);
+
+ return error;
+}
+
static void
sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
struct ifaltq *ifq)
Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.244 src/sys/net/if.h:1.245
--- src/sys/net/if.h:1.244 Wed Nov 22 03:03:18 2017
+++ src/sys/net/if.h Wed Dec 6 05:11:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.244 2017/11/22 03:03:18 ozaki-r Exp $ */
+/* $NetBSD: if.h,v 1.245 2017/12/06 05:11:10 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -1020,6 +1020,8 @@ int if_do_dad(struct ifnet *);
int if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
int if_flags_set(struct ifnet *, const short);
int if_clone_list(int, char *, int *);
+int if_enable_vlan_mtu(struct ifnet *);
+int if_disable_vlan_mtu(struct ifnet *);
struct ifnet *ifunit(const char *);
struct ifnet *if_get(const char *, struct psref *);
Index: src/sys/net/if_bridge.c
diff -u src/sys/net/if_bridge.c:1.141 src/sys/net/if_bridge.c:1.142
--- src/sys/net/if_bridge.c:1.141 Fri Nov 17 07:52:07 2017
+++ src/sys/net/if_bridge.c Wed Dec 6 05:11:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.141 2017/11/17 07:52:07 ozaki-r Exp $ */
+/* $NetBSD: if_bridge.c,v 1.142 2017/12/06 05:11:10 ozaki-r Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.141 2017/11/17 07:52:07 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.142 2017/12/06 05:11:10 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -772,7 +772,8 @@ bridge_ioctl_add(struct bridge_softc *sc
}
/* FALLTHROUGH */
case IFT_L2TP:
- if ((error = ether_enable_vlan_mtu(ifs)) > 0)
+ error = if_enable_vlan_mtu(ifs);
+ if (error > 0)
goto out;
/*
* Place the interface into promiscuous mode.
@@ -853,7 +854,7 @@ bridge_ioctl_del(struct bridge_softc *sc
* Don't call it with holding a spin lock.
*/
(void) ifpromisc(ifs, 0);
- (void) ether_disable_vlan_mtu(ifs);
+ (void) if_disable_vlan_mtu(ifs);
break;
default:
#ifdef DIAGNOSTIC
Index: src/sys/net/if_vlan.c
diff -u src/sys/net/if_vlan.c:1.113 src/sys/net/if_vlan.c:1.114
--- src/sys/net/if_vlan.c:1.113 Mon Nov 27 01:34:06 2017
+++ src/sys/net/if_vlan.c Wed Dec 6 05:11:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vlan.c,v 1.113 2017/11/27 01:34:06 jmcneill Exp $ */
+/* $NetBSD: if_vlan.c,v 1.114 2017/12/06 05:11:10 ozaki-r Exp $ */
/*-
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.113 2017/11/27 01:34:06 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.114 2017/12/06 05:11:10 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -451,7 +451,8 @@ vlan_config(struct ifvlan *ifv, struct i
nmib->ifvm_mintu = ETHERMIN;
if (ec->ec_nvlans++ == 0) {
- if ((error = ether_enable_vlan_mtu(p)) >= 0) {
+ error = if_enable_vlan_mtu(p);
+ if (error >= 0) {
if (error) {
ec->ec_nvlans--;
goto done;
@@ -593,7 +594,7 @@ vlan_unconfig_locked(struct ifvlan *ifv,
{
struct ethercom *ec = (void *)p;
if (--ec->ec_nvlans == 0)
- (void)ether_disable_vlan_mtu(p);
+ (void)if_disable_vlan_mtu(p);
ether_ifdetach(ifp);
/* Restore vlan_ioctl overwritten by ether_ifdetach */