Download raw body.
sysctl(2): push locking down to udp_sysctl()
Mostly to deliver protocol statistics lockless. Atomically accessed
`udpctl_vars' variables are already moved from net lock, sysctl(2)
related locks are useless for them. Complicated UDPCTL_BADDYNAMIC and
UDPCTL_ROOTONLY cases were left as is.
Index: sys/netinet/in_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_proto.c,v
diff -u -p -r1.113 in_proto.c
--- sys/netinet/in_proto.c 22 Aug 2024 10:58:31 -0000 1.113
+++ sys/netinet/in_proto.c 4 Dec 2024 20:19:32 -0000
@@ -185,7 +185,8 @@ const struct protosw inetsw[] = {
.pr_type = SOCK_DGRAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_UDP,
- .pr_flags = PR_ATOMIC|PR_ADDR|PR_SPLICE|PR_MPINPUT|PR_MPSOCKET,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_SPLICE|PR_MPINPUT|PR_MPSOCKET|
+ PR_MPSYSCTL,
.pr_input = udp_input,
.pr_ctlinput = udp_ctlinput,
.pr_ctloutput = ip_ctloutput,
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
diff -u -p -r1.327 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 5 Nov 2024 22:44:20 -0000 1.327
+++ sys/netinet/udp_usrreq.c 4 Dec 2024 20:19:32 -0000
@@ -172,6 +172,7 @@ void udp_sbappend(struct inpcb *, struct
u_int32_t);
int udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *);
void udp_notify(struct inpcb *, int);
+int udp_sysctl_locked(int *, u_int, void *, size_t *, void *, size_t);
int udp_sysctl_udpstat(void *, size_t *, void *);
#ifndef UDB_INITIAL_HASH_SIZE
@@ -1259,19 +1260,50 @@ int
udp_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);
switch (name[0]) {
case UDPCTL_BADDYNAMIC:
+ case UDPCTL_ROOTONLY: {
+ size_t savelen = *oldlenp;
+ int error;
+
+ if ((error = sysctl_vslock(oldp, savelen)))
+ return (error);
+ error = udp_sysctl_locked(name, namelen, oldp, oldlenp,
+ newp, newlen);
+ sysctl_vsunlock(oldp, savelen);
+
+ return (error);
+ }
+ case UDPCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+
+ return (udp_sysctl_udpstat(oldp, oldlenp, newp));
+
+ default:
+ return (sysctl_bounded_arr(udpctl_vars, nitems(udpctl_vars),
+ name, namelen, oldp, oldlenp, newp, newlen));
+ }
+ /* NOTREACHED */
+}
+
+int
+udp_sysctl_locked(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ void *newp, size_t newlen)
+{
+ int error = ENOPROTOOPT;
+
+ switch (name[0]) {
+ case UDPCTL_BADDYNAMIC:
NET_LOCK();
error = sysctl_struct(oldp, oldlenp, newp, newlen,
baddynamicports.udp, sizeof(baddynamicports.udp));
NET_UNLOCK();
- return (error);
+ break;
case UDPCTL_ROOTONLY:
if (newp && securelevel > 0)
@@ -1280,20 +1312,10 @@ udp_sysctl(int *name, u_int namelen, voi
error = sysctl_struct(oldp, oldlenp, newp, newlen,
rootonlyports.udp, sizeof(rootonlyports.udp));
NET_UNLOCK();
- return (error);
-
- case UDPCTL_STATS:
- if (newp != NULL)
- return (EPERM);
-
- return (udp_sysctl_udpstat(oldp, oldlenp, newp));
-
- default:
- error = sysctl_bounded_arr(udpctl_vars, nitems(udpctl_vars),
- name, namelen, oldp, oldlenp, newp, newlen);
- return (error);
+ break;
}
- /* NOTREACHED */
+
+ return (error);
}
int
Index: sys/netinet6/in6_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_proto.c,v
diff -u -p -r1.119 in6_proto.c
--- sys/netinet6/in6_proto.c 20 Aug 2024 07:46:27 -0000 1.119
+++ sys/netinet6/in6_proto.c 4 Dec 2024 20:19:32 -0000
@@ -136,7 +136,8 @@ const struct protosw inet6sw[] = {
.pr_type = SOCK_DGRAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_UDP,
- .pr_flags = PR_ATOMIC|PR_ADDR|PR_SPLICE|PR_MPINPUT|PR_MPSOCKET,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_SPLICE|PR_MPINPUT|PR_MPSOCKET|
+ PR_MPSYSCTL,
.pr_input = udp_input,
.pr_ctlinput = udp6_ctlinput,
.pr_ctloutput = ip6_ctloutput,
sysctl(2): push locking down to udp_sysctl()