Download raw body.
sysctl(2): push locking down to udp_sysctl()
On Wed, Dec 04, 2024 at 11:36:24PM +0300, Vitaliy Makkoveev wrote:
> 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.
OK bluhm@
> 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()