summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_var.h
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-08-03 19:29:47 +0000
committerrwatson <rwatson@FreeBSD.org>2005-08-03 19:29:47 +0000
commit7504160c1e1a408af3d9f6b998e6e9ce49dcf158 (patch)
tree7da6aeba14225658b424b8a1f07d30e9523cbc3e /sys/netinet/in_var.h
parent405f9b654c12682dc78887f78db0d01ebe3acbdf (diff)
downloadFreeBSD-src-7504160c1e1a408af3d9f6b998e6e9ce49dcf158.zip
FreeBSD-src-7504160c1e1a408af3d9f6b998e6e9ce49dcf158.tar.gz
Introduce in_multi_mtx, which will protect IPv4-layer multicast address
lists, as well as accessor macros. For now, this is a recursive mutex due code sequences where IPv4 multicast calls into IGMP calls into ip_output(), which then tests for a multicast forwarding case. For support macros in in_var.h to check multicast address lists, assert that in_multi_mtx is held. Acquire in_multi_mtx around iteration over the IPv4 multicast address lists, such as in ip_input() and ip_output(). Acquire in_multi_mtx when manipulating the IPv4 layer multicast addresses, as well as over the manipulation of ifnet multicast address lists in order to keep the two layers in sync. Lock down accesses to IPv4 multicast addresses in IGMP, or assert the lock when performing IGMP join/leave events. Eliminate spl's associated with IPv4 multicast addresses, portions of IGMP that weren't previously expunged by IGMP locking. Add in_multi_mtx, igmp_mtx, and if_addr_mtx lock order to hard-coded lock order in WITNESS, in that order. Problem reported by: Ed Maste <emaste at phaedrus dot sandvine dot ca> MFC after: 10 days
Diffstat (limited to 'sys/netinet/in_var.h')
-rw-r--r--sys/netinet/in_var.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 95a4558..5792a0b 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -167,6 +167,17 @@ SYSCTL_DECL(_net_inet_raw);
extern LIST_HEAD(in_multihead, in_multi) in_multihead;
/*
+ * Lock macros for IPv4 layer multicast address lists. IPv4 lock goes
+ * before link layer multicast locks in the lock order. In most cases,
+ * consumers of IN_*_MULTI() macros should acquire the locks before
+ * calling them; users of the in_{add,del}multi() functions should not.
+ */
+extern struct mtx in_multi_mtx;
+#define IN_MULTI_LOCK() mtx_lock(&in_multi_mtx)
+#define IN_MULTI_UNLOCK() mtx_unlock(&in_multi_mtx)
+#define IN_MULTI_LOCK_ASSERT() mtx_assert(&in_multi_mtx, MA_OWNED)
+
+/*
* Structure used by macros below to remember position when stepping through
* all of the in_multi records.
*/
@@ -185,6 +196,7 @@ struct in_multistep {
do { \
struct ifmultiaddr *ifma; \
\
+ IN_MULTI_LOCK_ASSERT(); \
IF_ADDR_LOCK(ifp); \
TAILQ_FOREACH(ifma, &((ifp)->if_multiaddrs), ifma_link) { \
if (ifma->ifma_addr->sa_family == AF_INET \
@@ -207,6 +219,7 @@ do { \
/* struct in_multistep step; */ \
/* struct in_multi *inm; */ \
do { \
+ IN_MULTI_LOCK_ASSERT(); \
if (((inm) = (step).i_inm) != NULL) \
(step).i_inm = LIST_NEXT((step).i_inm, inm_link); \
} while(0)
@@ -215,6 +228,7 @@ do { \
/* struct in_multistep step; */ \
/* struct in_multi *inm; */ \
do { \
+ IN_MULTI_LOCK_ASSERT(); \
(step).i_inm = LIST_FIRST(&in_multihead); \
IN_NEXT_MULTI((step), (inm)); \
} while(0)
OpenPOWER on IntegriCloud