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