Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
sysctl: push netlock down to mrt{,6}_sysctl_mfc()
To:
Alexander Bluhm <bluhm@openbsd.org>, tech@openbsd.org
Date:
Tue, 24 Jun 2025 23:22:56 +0300

Download raw body.

Thread
Move copyout() and sleeping M_WAITOK malloc(9) out of netlock. I like to
keep exclusive netlock instead of shared because the walker callback
does `rt_gateway' dereference. May be I'm too wary, but the locking
relax could be done with separate diff.

Also, the netlock could be pushed deep down to the `rtableid' loop, like
below, to allow stack to run between iterations.

        for (rtableid = 0; rtableid <= RT_TABLEID_MAX; rtableid++) {
                NET_LOCK();
                rtable_walk(rtableid, AF_INET6, NULL, mrt6_rtwalk_mf6csysctl,
                    &msa);
                NET_UNLOCK();
        }

Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.414
diff -u -p -r1.414 ip_input.c
--- sys/netinet/ip_input.c	24 Jun 2025 18:05:51 -0000	1.414
+++ sys/netinet/ip_input.c	24 Jun 2025 20:07:35 -0000
@@ -1804,10 +1804,7 @@ ip_sysctl(int *name, u_int namelen, void
 	case IPCTL_MRTMFC:
 		if (newp)
 			return (EPERM);
-		NET_LOCK();
-		error = mrt_sysctl_mfc(oldp, oldlenp);
-		NET_UNLOCK();
-		return (error);
+		return (mrt_sysctl_mfc(oldp, oldlenp));
 	case IPCTL_MRTVIF:
 		if (newp)
 			return (EPERM);
Index: sys/netinet/ip_mroute.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.147
diff -u -p -r1.147 ip_mroute.c
--- sys/netinet/ip_mroute.c	23 Jun 2025 20:56:38 -0000	1.147
+++ sys/netinet/ip_mroute.c	24 Jun 2025 20:07:59 -0000
@@ -524,10 +524,12 @@ mrt_sysctl_mfc(void *oldp, size_t *oldle
 		msa.msa_len = *oldlenp;
 	}
 
+	NET_LOCK();
 	for (rtableid = 0; rtableid <= RT_TABLEID_MAX; rtableid++) {
 		rtable_walk(rtableid, AF_INET, NULL, mrt_rtwalk_mfcsysctl,
 		    &msa);
 	}
+	NET_UNLOCK();
 
 	if (msa.msa_minfos != NULL && msa.msa_needed > 0 &&
 	    (error = copyout(msa.msa_minfos, oldp, msa.msa_needed)) != 0) {
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.277
diff -u -p -r1.277 ip6_input.c
--- sys/netinet6/ip6_input.c	24 Jun 2025 18:03:47 -0000	1.277
+++ sys/netinet6/ip6_input.c	24 Jun 2025 20:08:19 -0000
@@ -1531,10 +1531,7 @@ ip6_sysctl(int *name, u_int namelen, voi
 	case IPV6CTL_MRTMFC:
 		if (newp)
 			return (EPERM);
-		NET_LOCK();
-		error = mrt6_sysctl_mfc(oldp, oldlenp);
-		NET_UNLOCK();
-		return (error);
+		return (mrt6_sysctl_mfc(oldp, oldlenp));
 #else
 	case IPV6CTL_MRTSTATS:
 	case IPV6CTL_MRTPROTO:
Index: sys/netinet6/ip6_mroute.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v
retrieving revision 1.148
diff -u -p -r1.148 ip6_mroute.c
--- sys/netinet6/ip6_mroute.c	24 Jun 2025 18:03:47 -0000	1.148
+++ sys/netinet6/ip6_mroute.c	24 Jun 2025 20:08:19 -0000
@@ -472,10 +472,12 @@ mrt6_sysctl_mfc(void *oldp, size_t *oldl
 		msa.ms6a_len = *oldlenp;
 	}
 
+	NET_LOCK();
 	for (rtableid = 0; rtableid <= RT_TABLEID_MAX; rtableid++) {
 		rtable_walk(rtableid, AF_INET6, NULL, mrt6_rtwalk_mf6csysctl,
 		    &msa);
 	}
+	NET_UNLOCK();
 
 	if (msa.ms6a_minfos != NULL && msa.ms6a_needed > 0 &&
 	    (error = copyout(msa.ms6a_minfos, oldp, msa.ms6a_needed)) != 0) {