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);
 }

Reply via email to