summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2022-08-22 10:37:28 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2022-08-22 10:37:28 +0000
commit7b63f372dc76ea2dad97ef9197710e5e653f6215 (patch)
tree8aaa6056ca17d7cee070c8d2a567344a6b12e463 /sys/netinet6
parent43e1b15fa12ce7c8b1b58bdb5c3f9daacc185fbe (diff)
Use rwlock per inpcb table to protect notify list. The notify
function may sleep, so holding a mutex is not possible. The same list entry and rwlock is used for UDP multicast and raw IP delivery. By adding a write lock, exclusive netlock is no longer necessary for PCB notify and UDP and raw IP input. OK mvs@
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_pcb.c6
-rw-r--r--sys/netinet6/raw_ip6.c10
2 files changed, 11 insertions, 5 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 43a6e739e28..471a9614fea 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_pcb.c,v 1.119 2022/08/08 12:06:31 bluhm Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.120 2022/08/22 10:37:27 bluhm Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -387,8 +387,6 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
u_int32_t flowinfo;
u_int rdomain;
- NET_ASSERT_LOCKED_EXCLUSIVE();
-
if ((unsigned)cmd >= PRC_NCMDS)
return;
@@ -430,6 +428,7 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
SIMPLEQ_INIT(&inpcblist);
rdomain = rtable_l2(rtable);
+ rw_enter_write(&table->inpt_notify);
mtx_enter(&table->inpt_mtx);
TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) {
if ((inp->inp_flags & INP_IPV6) == 0)
@@ -513,6 +512,7 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
(*notify)(inp, errno);
in_pcbunref(inp);
}
+ rw_exit_write(&table->inpt_notify);
}
struct inpcb *
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 3809f776044..29af83ad5e4 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.154 2022/08/22 08:08:46 mvs Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.155 2022/08/22 10:37:27 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -172,8 +172,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
}
}
#endif
- NET_ASSERT_LOCKED_EXCLUSIVE();
SIMPLEQ_INIT(&inpcblist);
+ rw_enter_write(&rawin6pcbtable.inpt_notify);
mtx_enter(&rawin6pcbtable.inpt_mtx);
TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) {
if (in6p->inp_socket->so_state & SS_CANTRCVMORE)
@@ -224,6 +224,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
struct counters_ref ref;
uint64_t *counters;
+ rw_exit_write(&rawin6pcbtable.inpt_notify);
+
if (proto != IPPROTO_ICMPV6) {
rip6stat_inc(rip6s_nosock);
if (m->m_flags & M_MCAST)
@@ -240,6 +242,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
counters = counters_enter(&ref, ip6counters);
counters[ip6s_delivered]--;
counters_leave(&ref, ip6counters);
+
+ return IPPROTO_DONE;
}
while ((in6p = SIMPLEQ_FIRST(&inpcblist)) != NULL) {
@@ -267,6 +271,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
}
in_pcbunref(in6p);
}
+ rw_exit_write(&rawin6pcbtable.inpt_notify);
+
return IPPROTO_DONE;
}