Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Ensure to call if_mcast_op with holding IFNET_LOCK
details: https://anonhg.NetBSD.org/src/rev/fa2f1b06c2ec
branches: trunk
changeset: 828460:fa2f1b06c2ec
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Fri Dec 15 04:03:46 2017 +0000
description:
Ensure to call if_mcast_op with holding IFNET_LOCK
Note that CARP doesn't deal with IFNET_LOCK yet.
diffstat:
sys/net/if.c | 25 ++++++++++++++--
sys/net/if.h | 3 +-
sys/net/if_vlan.c | 10 +++++-
sys/netinet/in.c | 7 +++-
sys/netinet/in_pcb.c | 7 +++-
sys/netinet/ip_output.c | 22 +++++++++++---
sys/netinet6/in6.c | 11 +++++--
sys/netinet6/in6_pcb.c | 11 ++++++-
sys/netinet6/ip6_output.c | 21 ++++++++++++--
sys/netinet6/nd6.c | 69 ++++++++++++++++++++++++++++++++++++++++------
sys/netinet6/nd6_rtr.c | 6 ++-
11 files changed, 158 insertions(+), 34 deletions(-)
diffs (truncated from 553 to 300 lines):
diff -r deae1207f6dc -r fa2f1b06c2ec sys/net/if.c
--- a/sys/net/if.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/net/if.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.414 2017/12/14 05:46:54 ozaki-r Exp $ */
+/* $NetBSD: if.c,v 1.415 2017/12/15 04:03:46 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.414 2017/12/14 05:46:54 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.415 2017/12/15 04:03:46 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -2721,12 +2721,27 @@
psref_release(psref, &ifp->if_psref, ifnet_psref_class);
}
+/*
+ * Return ifp having idx. Return NULL if not found. Normally if_byindex
+ * should be used.
+ */
+ifnet_t *
+_if_byindex(u_int idx)
+{
+
+ return (__predict_true(idx < if_indexlim)) ? ifindex2ifnet[idx] : NULL;
+}
+
+/*
+ * Return ifp having idx. Return NULL if not found or the found ifp is
+ * already deactivated.
+ */
ifnet_t *
if_byindex(u_int idx)
{
ifnet_t *ifp;
- ifp = (__predict_true(idx < if_indexlim)) ? ifindex2ifnet[idx] : NULL;
+ ifp = _if_byindex(idx);
if (ifp != NULL && if_is_deactivated(ifp))
ifp = NULL;
return ifp;
@@ -3570,6 +3585,10 @@
int rc;
struct ifreq ifr;
+ /* CARP still doesn't deal with the lock yet */
+#if !defined(NCARP) || (NCARP == 0)
+ KASSERT(IFNET_LOCKED(ifp));
+#endif
if (ifp->if_mcastop != NULL)
rc = (*ifp->if_mcastop)(ifp, cmd, sa);
else {
diff -r deae1207f6dc -r fa2f1b06c2ec sys/net/if.h
--- a/sys/net/if.h Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/net/if.h Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.253 2017/12/11 03:29:20 ozaki-r Exp $ */
+/* $NetBSD: if.h,v 1.254 2017/12/15 04:03:46 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -1026,6 +1026,7 @@
struct ifnet *ifunit(const char *);
struct ifnet *if_get(const char *, struct psref *);
ifnet_t *if_byindex(u_int);
+ifnet_t *_if_byindex(u_int);
ifnet_t *if_get_byindex(u_int, struct psref *);
ifnet_t *if_get_bylla(const void *, unsigned char, struct psref *);
void if_put(const struct ifnet *, struct psref *);
diff -r deae1207f6dc -r fa2f1b06c2ec sys/net/if_vlan.c
--- a/sys/net/if_vlan.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/net/if_vlan.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vlan.c,v 1.119 2017/12/11 03:29:20 ozaki-r Exp $ */
+/* $NetBSD: if_vlan.c,v 1.120 2017/12/15 04:03:46 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.119 2017/12/11 03:29:20 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.120 2017/12/15 04:03:46 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1160,7 +1160,9 @@
mib = ifv->ifv_mib;
KERNEL_LOCK_UNLESS_IFP_MPSAFE(mib->ifvm_p);
+ IFNET_LOCK(mib->ifvm_p);
error = if_mcast_op(mib->ifvm_p, SIOCADDMULTI, sa);
+ IFNET_UNLOCK(mib->ifvm_p);
KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(mib->ifvm_p);
if (error != 0)
@@ -1201,7 +1203,9 @@
/* We no longer use this multicast address. Tell parent so. */
mib = ifv->ifv_mib;
+ IFNET_LOCK(mib->ifvm_p);
error = if_mcast_op(mib->ifvm_p, SIOCDELMULTI, sa);
+ IFNET_UNLOCK(mib->ifvm_p);
if (error == 0) {
/* And forget about this address. */
@@ -1236,8 +1240,10 @@
}
while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) {
+ IFNET_LOCK(mib->ifvm_p);
(void)if_mcast_op(mib->ifvm_p, SIOCDELMULTI,
(const struct sockaddr *)&mc->mc_addr);
+ IFNET_UNLOCK(mib->ifvm_p);
LIST_REMOVE(mc, mc_entries);
free(mc, M_DEVBUF);
}
diff -r deae1207f6dc -r fa2f1b06c2ec sys/netinet/in.c
--- a/sys/netinet/in.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/netinet/in.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in.c,v 1.210 2017/11/17 07:37:12 ozaki-r Exp $ */
+/* $NetBSD: in.c,v 1.211 2017/12/15 04:03:46 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.210 2017/11/17 07:37:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.211 2017/12/15 04:03:46 ozaki-r Exp $");
#include "arp.h"
@@ -912,11 +912,14 @@
void
in_purgeif(struct ifnet *ifp) /* MUST be called at splsoftnet() */
{
+
+ IFNET_LOCK(ifp);
if_purgeaddrs(ifp, AF_INET, in_purgeaddr);
igmp_purgeif(ifp); /* manipulates pools */
#ifdef MROUTING
ip_mrouter_detach(ifp);
#endif
+ IFNET_UNLOCK(ifp);
}
/*
diff -r deae1207f6dc -r fa2f1b06c2ec sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/netinet/in_pcb.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in_pcb.c,v 1.179 2017/08/10 04:31:58 ryo Exp $ */
+/* $NetBSD: in_pcb.c,v 1.180 2017/12/15 04:03:46 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.179 2017/08/10 04:31:58 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.180 2017/12/15 04:03:46 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -777,7 +777,10 @@
need_unlock = true;
}
+ /* IFNET_LOCK must be taken after solock */
+ IFNET_LOCK(ifp);
in_purgeifmcast(inp->inp_moptions, ifp);
+ IFNET_UNLOCK(ifp);
if (need_unlock)
inp_unlock(inp);
diff -r deae1207f6dc -r fa2f1b06c2ec sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/netinet/ip_output.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_output.c,v 1.286 2017/12/11 05:47:18 ryo Exp $ */
+/* $NetBSD: ip_output.c,v 1.287 2017/12/15 04:03:46 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.286 2017/12/11 05:47:18 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.287 2017/12/15 04:03:46 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1771,7 +1771,10 @@
* Everything looks good; add a new record to the multicast
* address list for the given interface.
*/
- if ((imo->imo_membership[i] = in_addmulti(&ia, ifp)) == NULL) {
+ IFNET_LOCK(ifp);
+ imo->imo_membership[i] = in_addmulti(&ia, ifp);
+ IFNET_UNLOCK(ifp);
+ if (imo->imo_membership[i] == NULL) {
error = ENOBUFS;
goto out;
}
@@ -1830,7 +1833,9 @@
* Give up the multicast address record to which the
* membership points.
*/
+ IFNET_LOCK(ifp);
in_delmulti(imo->imo_membership[i]);
+ IFNET_UNLOCK(ifp);
/*
* Remove the gap in the membership array.
@@ -2023,8 +2028,15 @@
/* The owner of imo (inp) should be protected by solock */
if (imo != NULL) {
- for (i = 0; i < imo->imo_num_memberships; ++i)
- in_delmulti(imo->imo_membership[i]);
+ for (i = 0; i < imo->imo_num_memberships; ++i) {
+ struct in_multi *inm = imo->imo_membership[i];
+ struct ifnet *ifp = inm->inm_ifp;
+ IFNET_LOCK(ifp);
+ in_delmulti(inm);
+ /* ifp should not leave thanks to solock */
+ IFNET_UNLOCK(ifp);
+ }
+
kmem_intr_free(imo, sizeof(*imo));
}
}
diff -r deae1207f6dc -r fa2f1b06c2ec sys/netinet6/in6.c
--- a/sys/netinet6/in6.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/netinet6/in6.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.254 2017/11/23 07:09:20 ozaki-r Exp $ */
+/* $NetBSD: in6.c,v 1.255 2017/12/15 04:03:46 ozaki-r Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.254 2017/11/23 07:09:20 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.255 2017/12/15 04:03:46 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1385,6 +1385,7 @@
struct in6_multi_mship *imm;
KASSERT(!ifa_held(ifa));
+ KASSERT(IFNET_LOCKED(ifp));
ifa->ifa_flags |= IFA_DESTROYING;
@@ -1400,12 +1401,14 @@
/*
* leave from multicast groups we have joined for the interface
*/
+ again:
mutex_enter(&in6_ifaddr_lock);
while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
LIST_REMOVE(imm, i6mm_chain);
mutex_exit(&in6_ifaddr_lock);
+ KASSERT(imm->i6mm_maddr->in6m_ifp == ifp);
in6_leavegroup(imm);
- mutex_enter(&in6_ifaddr_lock);
+ goto again;
}
mutex_exit(&in6_ifaddr_lock);
@@ -1456,7 +1459,9 @@
in6_purgeif(struct ifnet *ifp)
{
+ IFNET_LOCK(ifp);
in6_ifdetach(ifp);
+ IFNET_UNLOCK(ifp);
}
void
diff -r deae1207f6dc -r fa2f1b06c2ec sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c Fri Dec 15 02:24:22 2017 +0000
+++ b/sys/netinet6/in6_pcb.c Fri Dec 15 04:03:46 2017 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index