summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-09 08:35:39 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-09 08:35:39 +0000
commit1a50b2beba0c4dbdca6896cfada79d51fe09f032 (patch)
treeb711148996636dd12aa605080d14f8c65ddac843 /sys/netinet6
parent6cd55fecbaf42a75cd6f0827f8989adb17a0bc96 (diff)
Reduces the scope of the NET_LOCK() in sysctl(2) path.
Exposes per-CPU counters to real parrallelism. ok visa@, bluhm@, jca@
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c14
-rw-r--r--sys/netinet6/ip6_divert.c26
-rw-r--r--sys/netinet6/ip6_input.c33
3 files changed, 52 insertions, 21 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 9602b127d07..3becc223313 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.c,v 1.216 2017/09/01 15:05:31 mpi Exp $ */
+/* $OpenBSD: icmp6.c,v 1.217 2017/10/09 08:35:38 mpi Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@@ -1887,6 +1887,8 @@ int
icmp6_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;
@@ -1896,9 +1898,13 @@ icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
case ICMPV6CTL_STATS:
return icmp6_sysctl_icmp6stat(oldp, oldlenp, newp);
default:
- if (name[0] < ICMPV6CTL_MAXID)
- return (sysctl_int_arr(icmpv6ctl_vars, name, namelen,
- oldp, oldlenp, newp, newlen));
+ if (name[0] < ICMPV6CTL_MAXID) {
+ NET_LOCK();
+ error = sysctl_int_arr(icmpv6ctl_vars, name, namelen,
+ oldp, oldlenp, newp, newlen);
+ NET_UNLOCK();
+ return (error);
+ }
return ENOPROTOOPT;
}
/* NOTREACHED */
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 011514a521e..1f20dc64d83 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.53 2017/10/06 22:08:30 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.54 2017/10/09 08:35:38 mpi Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -363,23 +363,35 @@ int
divert6_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 DIVERT6CTL_SENDSPACE:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &divert6_sendspace));
+ NET_LOCK();
+ error = sysctl_int(oldp, oldlenp, newp, newlen,
+ &divert6_sendspace);
+ NET_UNLOCK();
+ return (error);
case DIVERT6CTL_RECVSPACE:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &divert6_recvspace));
+ NET_LOCK();
+ error = sysctl_int(oldp, oldlenp, newp, newlen,
+ &divert6_recvspace);
+ NET_UNLOCK();
+ return (error);
case DIVERT6CTL_STATS:
return (divert6_sysctl_div6stat(oldp, oldlenp, newp));
default:
- if (name[0] < DIVERT6CTL_MAXID)
- return sysctl_int_arr(divert6ctl_vars, name, namelen,
+ if (name[0] < DIVERT6CTL_MAXID) {
+ NET_LOCK();
+ error = sysctl_int_arr(divert6ctl_vars, name, namelen,
oldp, oldlenp, newp, newlen);
+ NET_UNLOCK();
+ return (error);
+ }
return (ENOPROTOOPT);
}
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index ade41a8a03b..4e588d83394 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.202 2017/08/22 15:02:34 mpi Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.203 2017/10/09 08:35:38 mpi Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -1383,8 +1383,6 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
#endif
int error;
- NET_ASSERT_LOCKED();
-
/* Almost all sysctl names at this level are terminal. */
if (namelen != 1 && name[0] != IPV6CTL_IFQUEUE)
return (ENOTDIR);
@@ -1398,18 +1396,27 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
case IPV6CTL_MRTSTATS:
if (newp != NULL)
return (EPERM);
- return (sysctl_struct(oldp, oldlenp, newp, newlen,
- &mrt6stat, sizeof(mrt6stat)));
+ NET_LOCK();
+ error = sysctl_struct(oldp, oldlenp, newp, newlen,
+ &mrt6stat, sizeof(mrt6stat));
+ NET_UNLOCK();
+ return (error);
case IPV6CTL_MRTPROTO:
return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto);
case IPV6CTL_MRTMIF:
if (newp)
return (EPERM);
- return mrt6_sysctl_mif(oldp, oldlenp);
+ NET_LOCK();
+ error = mrt6_sysctl_mif(oldp, oldlenp);
+ NET_UNLOCK();
+ return (error);
case IPV6CTL_MRTMFC:
if (newp)
return (EPERM);
- return mrt6_sysctl_mfc(oldp, oldlenp);
+ NET_LOCK();
+ error = mrt6_sysctl_mfc(oldp, oldlenp);
+ NET_UNLOCK();
+ return (error);
#else
case IPV6CTL_MRTSTATS:
case IPV6CTL_MRTPROTO:
@@ -1418,19 +1425,25 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
return (EOPNOTSUPP);
#endif
case IPV6CTL_MTUDISCTIMEOUT:
+ NET_LOCK();
error = sysctl_int(oldp, oldlenp, newp, newlen,
&ip6_mtudisc_timeout);
if (icmp6_mtudisc_timeout_q != NULL)
rt_timer_queue_change(icmp6_mtudisc_timeout_q,
ip6_mtudisc_timeout);
+ NET_UNLOCK();
return (error);
case IPV6CTL_IFQUEUE:
return (sysctl_niq(name + 1, namelen - 1,
oldp, oldlenp, newp, newlen, &ip6intrq));
default:
- if (name[0] < IPV6CTL_MAXID)
- return (sysctl_int_arr(ipv6ctl_vars, name, namelen,
- oldp, oldlenp, newp, newlen));
+ if (name[0] < IPV6CTL_MAXID) {
+ NET_LOCK();
+ error = sysctl_int_arr(ipv6ctl_vars, name, namelen,
+ oldp, oldlenp, newp, newlen);
+ NET_UNLOCK();
+ return (error);
+ }
return (EOPNOTSUPP);
}
/* NOTREACHED */