Introduce `ip6_soiikey_lock' rwlock(9) to protect `ip6_soiikey'. It accessed only by ip6_sysctl_soiikey() and ip6_sysctl() is the only ip6_sysctl_soiikey() caller so context switch is allowed here. Also remove unused `oldkey' from ip6_sysctl_soiikey().
For IPV6CTL_MRTSTATS, IPV6CTL_MRTMIF and IPV6CTL_MRTMFC cases netlock could be relaxed to share netlock, but with separate diffs. ok? Index: sys/netinet6/in6_proto.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_proto.c,v retrieving revision 1.112 diff -u -p -r1.112 in6_proto.c --- sys/netinet6/in6_proto.c 23 Nov 2022 14:48:28 -0000 1.112 +++ sys/netinet6/in6_proto.c 17 May 2023 09:37:05 -0000 @@ -128,6 +128,7 @@ const struct protosw inet6sw[] = { { .pr_domain = &inet6domain, .pr_protocol = IPPROTO_IPV6, + .pr_flags = PR_MPSYSCTL, .pr_init = ip6_init, .pr_slowtimo = frag6_slowtimo, .pr_sysctl = ip6_sysctl Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.254 diff -u -p -r1.254 ip6_input.c --- sys/netinet6/ip6_input.c 21 Aug 2022 14:15:55 -0000 1.254 +++ sys/netinet6/ip6_input.c 17 May 2023 09:37:05 -0000 @@ -118,6 +118,7 @@ struct niqueue ip6intrq = NIQUEUE_INITIA struct cpumem *ip6counters; uint8_t ip6_soiikey[IP6_SOIIKEY_LEN]; +struct rwlock ip6_soiikey_lock = RWLOCK_INITIALIZER("soiikeylk"); int ip6_ours(struct mbuf **, int *, int, int); int ip6_check_rh0hdr(struct mbuf *, int *); @@ -1477,17 +1478,16 @@ ip6_sysctl_ip6stat(void *oldp, size_t *o int ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - uint8_t oldkey[IP6_SOIIKEY_LEN]; int error; error = suser(curproc); if (error != 0) return (error); - memcpy(oldkey, ip6_soiikey, sizeof(oldkey)); - + rw_enter_write(&ip6_soiikey_lock); error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey, sizeof(ip6_soiikey)); + rw_exit_write(&ip6_soiikey_lock); return (error); }