summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_domain.c14
-rw-r--r--sys/netinet/in_proto.c4
-rw-r--r--sys/netinet/ip_divert.c25
-rw-r--r--sys/netinet6/in6_proto.c4
-rw-r--r--sys/netinet6/ip6_divert.c23
-rw-r--r--sys/sys/protosw.h3
6 files changed, 40 insertions, 33 deletions
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 1c314806bb6..4e7a54d23d8 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_domain.c,v 1.67 2024/08/14 17:52:47 mvs Exp $ */
+/* $OpenBSD: uipc_domain.c,v 1.68 2024/08/16 09:20:34 mvs Exp $ */
/* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */
/*
@@ -237,14 +237,18 @@ net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
protocol = name[1];
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_protocol == protocol && pr->pr_sysctl) {
- size_t savelen = *oldlenp;
+ size_t savelen;
int error;
- if ((error = sysctl_vslock(oldp, savelen)))
- return (error);
+ if ((pr->pr_flags & PR_MPSYSCTL) == 0) {
+ savelen = *oldlenp;
+ if ((error = sysctl_vslock(oldp, savelen)))
+ return (error);
+ }
error = (*pr->pr_sysctl)(name + 2, namelen - 2,
oldp, oldlenp, newp, newlen);
- sysctl_vsunlock(oldp, savelen);
+ if ((pr->pr_flags & PR_MPSYSCTL) == 0)
+ sysctl_vsunlock(oldp, savelen);
return (error);
}
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 579522f6017..a279775fde9 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_proto.c,v 1.107 2024/07/26 14:38:20 bluhm Exp $ */
+/* $OpenBSD: in_proto.c,v 1.108 2024/08/16 09:20:35 mvs Exp $ */
/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
/*
@@ -354,7 +354,7 @@ const struct protosw inetsw[] = {
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_DIVERT,
- .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL,
.pr_ctloutput = rip_ctloutput,
.pr_usrreqs = &divert_usrreqs,
.pr_init = divert_init,
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 260d23c8f9f..21157d22f5f 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.96 2024/07/12 19:50:35 bluhm Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.97 2024/08/16 09:20:35 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -41,17 +41,22 @@
#include <net/pfvar.h>
+/*
+ * Locks used to protect data:
+ * a atomic
+ */
+
struct inpcbtable divbtable;
struct cpumem *divcounters;
#ifndef DIVERT_SENDSPACE
#define DIVERT_SENDSPACE (65536 + 100)
#endif
-u_int divert_sendspace = DIVERT_SENDSPACE;
+u_int divert_sendspace = DIVERT_SENDSPACE; /* [a] */
#ifndef DIVERT_RECVSPACE
#define DIVERT_RECVSPACE (65536 + 100)
#endif
-u_int divert_recvspace = DIVERT_RECVSPACE;
+u_int divert_recvspace = DIVERT_RECVSPACE; /* [a] */
#ifndef DIVERTHASHSIZE
#define DIVERTHASHSIZE 128
@@ -271,7 +276,8 @@ divert_attach(struct socket *so, int proto, int wait)
if (error)
return error;
- error = soreserve(so, divert_sendspace, divert_recvspace);
+ error = soreserve(so, atomic_load_int(&divert_sendspace),
+ atomic_load_int(&divert_recvspace));
if (error)
return error;
@@ -346,8 +352,6 @@ int
divert_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
size_t newlen)
{
- int error;
-
/* All sysctl names at this level are terminal. */
if (namelen != 1)
return (ENOTDIR);
@@ -356,12 +360,9 @@ divert_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
case DIVERTCTL_STATS:
return (divert_sysctl_divstat(oldp, oldlenp, newp));
default:
- NET_LOCK();
- error = sysctl_bounded_arr(divertctl_vars,
- nitems(divertctl_vars), name, namelen, oldp, oldlenp, newp,
- newlen);
- NET_UNLOCK();
- return (error);
+ return (sysctl_bounded_arr(divertctl_vars,
+ nitems(divertctl_vars), name, namelen, oldp, oldlenp,
+ newp, newlen));
}
/* NOTREACHED */
}
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 2d7343a52a3..d35cff479b6 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_proto.c,v 1.117 2024/07/26 14:38:20 bluhm Exp $ */
+/* $OpenBSD: in6_proto.c,v 1.118 2024/08/16 09:20:35 mvs Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@@ -289,7 +289,7 @@ const struct protosw inet6sw[] = {
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_DIVERT,
- .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreqs = &divert6_usrreqs,
.pr_init = divert6_init,
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 06111f6d3c8..dc815d5f8d8 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.96 2024/07/12 19:50:35 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.97 2024/08/16 09:20:35 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -44,17 +44,22 @@
#include <net/pfvar.h>
+/*
+ * Locks used to protect data:
+ * a atomic
+ */
+
struct inpcbtable divb6table;
struct cpumem *div6counters;
#ifndef DIVERT_SENDSPACE
#define DIVERT_SENDSPACE (65536 + 100)
#endif
-u_int divert6_sendspace = DIVERT_SENDSPACE;
+u_int divert6_sendspace = DIVERT_SENDSPACE; /* [a] */
#ifndef DIVERT_RECVSPACE
#define DIVERT_RECVSPACE (65536 + 100)
#endif
-u_int divert6_recvspace = DIVERT_RECVSPACE;
+u_int divert6_recvspace = DIVERT_RECVSPACE; /* [a] */
#ifndef DIVERTHASHSIZE
#define DIVERTHASHSIZE 128
@@ -279,7 +284,8 @@ divert6_attach(struct socket *so, int proto, int wait)
if (error)
return (error);
- error = soreserve(so, divert6_sendspace, divert6_recvspace);
+ error = soreserve(so, atomic_load_int(&divert6_sendspace),
+ atomic_load_int(&divert6_recvspace));
if (error)
return (error);
@@ -322,8 +328,6 @@ int
divert6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen)
{
- int error;
-
/* All sysctl names at this level are terminal. */
if (namelen != 1)
return (ENOTDIR);
@@ -332,12 +336,9 @@ divert6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
case DIVERT6CTL_STATS:
return (divert6_sysctl_div6stat(oldp, oldlenp, newp));
default:
- NET_LOCK();
- error = sysctl_bounded_arr(divert6ctl_vars,
+ return (sysctl_bounded_arr(divert6ctl_vars,
nitems(divert6ctl_vars), name, namelen, oldp, oldlenp,
- newp, newlen);
- NET_UNLOCK();
- return (error);
+ newp, newlen));
}
/* NOTREACHED */
}
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 575fdbd9c73..6aa88bafb46 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: protosw.h,v 1.67 2024/07/12 19:50:35 bluhm Exp $ */
+/* $OpenBSD: protosw.h,v 1.68 2024/08/16 09:20:35 mvs Exp $ */
/* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */
/*-
@@ -131,6 +131,7 @@ struct protosw {
#define PR_SPLICE 0x0040 /* socket splicing is possible */
#define PR_MPINPUT 0x0080 /* input runs with shared netlock */
#define PR_MPSOCKET 0x0100 /* socket uses shared netlock */
+#define PR_MPSYSCTL 0x0200 /* mp-safe sysctl(2) handler */
/*
* The arguments to usrreq are: