summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2022-09-05 14:56:10 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2022-09-05 14:56:10 +0000
commitc259ade4b4a1594c8470894d5b6fe2be84379d1f (patch)
treeb893d8f2cd7c29e4d342246959bcf933613e1459 /sys/netinet/ip_divert.c
parent2c2bdd66c73a7966917c34768e4942bd9a311a36 (diff)
Use shared netlock in soreceive(). The UDP and IP divert layer
provide locking of the PCB. If that is possible, use shared instead of exclusive netlock in soreceive(). The PCB mutex provides a per socket lock against multiple soreceive() running in parallel. Release and regrab both locks in sosleep_nsec(). OK mvs@
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 361d00c4ea4..1cdad66c298 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.86 2022/09/03 22:43:38 mvs Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.87 2022/09/05 14:56:09 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -65,6 +65,8 @@ const struct sysctl_bounded_args divertctl_vars[] = {
const struct pr_usrreqs divert_usrreqs = {
.pru_attach = divert_attach,
.pru_detach = divert_detach,
+ .pru_lock = divert_lock,
+ .pru_unlock = divert_unlock,
.pru_bind = divert_bind,
.pru_shutdown = divert_shutdown,
.pru_send = divert_send,
@@ -288,6 +290,24 @@ divert_detach(struct socket *so)
return (0);
}
+void
+divert_lock(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ NET_ASSERT_LOCKED();
+ mtx_enter(&inp->inp_mtx);
+}
+
+void
+divert_unlock(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ NET_ASSERT_LOCKED();
+ mtx_leave(&inp->inp_mtx);
+}
+
int
divert_bind(struct socket *so, struct mbuf *addr, struct proc *p)
{