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 */

Reply via email to