Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Ensure to hold if_ioctl_lock on if_up and if_down
details: https://anonhg.NetBSD.org/src/rev/ba60e89919c1
branches: trunk
changeset: 357964:ba60e89919c1
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Wed Dec 06 08:12:54 2017 +0000
description:
Ensure to hold if_ioctl_lock on if_up and if_down
One exception for if_down is if_detach; in the case the lock isn't needed
because it's guaranteed that no other one can access ifp at that point.
diffstat:
sys/net/if.c | 73 +++++++++++++++++++++++++++++++++++++++++++-----------
sys/net/if.h | 3 +-
sys/net/if_vlan.c | 6 ++--
3 files changed, 63 insertions(+), 19 deletions(-)
diffs (195 lines):
diff -r d3e9884787c1 -r ba60e89919c1 sys/net/if.c
--- a/sys/net/if.c Wed Dec 06 07:40:16 2017 +0000
+++ b/sys/net/if.c Wed Dec 06 08:12:54 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.402 2017/12/06 05:59:59 ozaki-r Exp $ */
+/* $NetBSD: if.c,v 1.403 2017/12/06 08:12:54 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.402 2017/12/06 05:59:59 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.403 2017/12/06 08:12:54 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -209,6 +209,9 @@
static int if_clone_create(const char *);
static int if_clone_destroy(const char *);
static void if_link_state_change_si(void *);
+static void if_up_locked(struct ifnet *);
+static void _if_down(struct ifnet *);
+static void if_down_deactivated(struct ifnet *);
struct if_percpuq {
struct ifnet *ipq_ifp;
@@ -1333,7 +1336,7 @@
/*
* Do an if_down() to give protocols a chance to do something.
*/
- if_down(ifp);
+ if_down_deactivated(ifp);
#ifdef ALTQ
if (ALTQ_IS_ENABLED(&ifp->if_snd))
@@ -2400,13 +2403,8 @@
pserialize_read_exit(s);
}
-/*
- * Mark an interface down and notify protocols of
- * the transition.
- * NOTE: must be called at splsoftnet or equivalent.
- */
-void
-if_down(struct ifnet *ifp)
+static void
+_if_down(struct ifnet *ifp)
{
struct ifaddr *ifa;
struct domain *dp;
@@ -2442,19 +2440,50 @@
}
}
+static void
+if_down_deactivated(struct ifnet *ifp)
+{
+
+ KASSERT(if_is_deactivated(ifp));
+ _if_down(ifp);
+}
+
+void
+if_down_locked(struct ifnet *ifp)
+{
+
+ KASSERT(mutex_owned(ifp->if_ioctl_lock));
+ _if_down(ifp);
+}
+
/*
- * Mark an interface up and notify protocols of
+ * Mark an interface down and notify protocols of
* the transition.
* NOTE: must be called at splsoftnet or equivalent.
*/
void
-if_up(struct ifnet *ifp)
+if_down(struct ifnet *ifp)
+{
+
+ mutex_enter(ifp->if_ioctl_lock);
+ if_down_locked(ifp);
+ mutex_exit(ifp->if_ioctl_lock);
+}
+
+/*
+ * Must be called with holding if_ioctl_lock.
+ */
+static void
+if_up_locked(struct ifnet *ifp)
{
#ifdef notyet
struct ifaddr *ifa;
#endif
struct domain *dp;
+ KASSERT(mutex_owned(ifp->if_ioctl_lock));
+
+ KASSERT(!if_is_deactivated(ifp));
ifp->if_flags |= IFF_UP;
nanotime(&ifp->if_lastchange);
#ifdef notyet
@@ -2500,6 +2529,20 @@
}
/*
+ * Mark an interface up and notify protocols of
+ * the transition.
+ * NOTE: must be called at splsoftnet or equivalent.
+ */
+void
+if_up(struct ifnet *ifp)
+{
+
+ mutex_enter(ifp->if_ioctl_lock);
+ if_up_locked(ifp);
+ mutex_exit(ifp->if_ioctl_lock);
+}
+
+/*
* Set/clear promiscuous mode on interface ifp based on the truth value
* of pswitch. The calls are reference counted so that only the first
* "on" request actually has an effect, as does the final "off" request.
@@ -2789,12 +2832,12 @@
KERNEL_LOCK_IF_IFP_MPSAFE(ifp);
if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
s = splsoftnet();
- if_down(ifp);
+ if_down_locked(ifp);
splx(s);
}
if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
s = splsoftnet();
- if_up(ifp);
+ if_up_locked(ifp);
splx(s);
}
KERNEL_UNLOCK_IF_IFP_MPSAFE(ifp);
@@ -3103,7 +3146,7 @@
if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
if ((ifp->if_flags & IFF_UP) != 0) {
int s = splsoftnet();
- if_up(ifp);
+ if_up_locked(ifp);
splx(s);
}
}
diff -r d3e9884787c1 -r ba60e89919c1 sys/net/if.h
--- a/sys/net/if.h Wed Dec 06 07:40:16 2017 +0000
+++ b/sys/net/if.h Wed Dec 06 08:12:54 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.246 2017/12/06 05:59:59 ozaki-r Exp $ */
+/* $NetBSD: if.h,v 1.247 2017/12/06 08:12:54 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -1006,6 +1006,7 @@
void if_purgeaddrs(struct ifnet *, int, void (*)(struct ifaddr *));
void if_detach(struct ifnet *);
void if_down(struct ifnet *);
+void if_down_locked(struct ifnet *);
void if_link_state_change(struct ifnet *, int);
void if_link_state_change_softint(struct ifnet *, int);
void if_up(struct ifnet *);
diff -r d3e9884787c1 -r ba60e89919c1 sys/net/if_vlan.c
--- a/sys/net/if_vlan.c Wed Dec 06 07:40:16 2017 +0000
+++ b/sys/net/if_vlan.c Wed Dec 06 08:12:54 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vlan.c,v 1.116 2017/12/06 07:40:16 ozaki-r Exp $ */
+/* $NetBSD: if_vlan.c,v 1.117 2017/12/06 08:12:54 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.116 2017/12/06 07:40:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.117 2017/12/06 08:12:54 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -653,7 +653,7 @@
if ((ifp->if_flags & IFF_PROMISC) != 0)
vlan_safe_ifpromisc_locked(ifp, 0);
- if_down(ifp);
+ if_down_locked(ifp);
ifp->if_capabilities = 0;
mutex_enter(&ifv->ifv_lock);
done:
Home |
Main Index |
Thread Index |
Old Index