On Wed, May 17, 2023 at 12:46:02PM +0300, Vitaliy Makkoveev wrote:
> 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().
rwlock or mutex? As sysctl mlocks userland memory, copyin/copyout
cannot sleep here. So it should be safe to use a mutex.
And why is this ip6_soiikey in the kernel anyway? I guess it is
from a time when address configuration was done in the kernel.
Could slaacd(8) just read /etc/soii.key?
> 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);
> }