summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorhsu <hsu@FreeBSD.org>2002-12-24 03:03:39 +0000
committerhsu <hsu@FreeBSD.org>2002-12-24 03:03:39 +0000
commit32436a25c0510e4371c6f02353b447c09ba9db0d (patch)
tree5e53dfd4f16f3a5c2080f2ce73aed007b1be63a1 /sys/net/rtsock.c
parent018c02046059a2588bdd154c9136e4467aafa156 (diff)
downloadFreeBSD-src-32436a25c0510e4371c6f02353b447c09ba9db0d.zip
FreeBSD-src-32436a25c0510e4371c6f02353b447c09ba9db0d.tar.gz
SMP locking for radix nodes.
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 40f2ee1..0c441ef 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -367,11 +367,15 @@ route_output(m, so)
case RTM_LOCK:
if ((rnh = rt_tables[dst->sa_family]) == 0) {
senderr(EAFNOSUPPORT);
- } else if ((rt = (struct rtentry *)
- rnh->rnh_lookup(dst, netmask, rnh)) != NULL)
+ }
+ RADIX_NODE_HEAD_LOCK(rnh);
+ rt = (struct rtentry *) rnh->rnh_lookup(dst, netmask, rnh);
+ RADIX_NODE_HEAD_UNLOCK(rnh);
+ if (rt != NULL)
rt->rt_refcnt++;
else
senderr(ESRCH);
+
switch(rtm->rtm_type) {
case RTM_GET:
@@ -1024,11 +1028,25 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
case NET_RT_DUMP:
case NET_RT_FLAGS:
- for (i = 1; i <= AF_MAX; i++)
- if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
- (error = rnh->rnh_walktree(rnh,
- sysctl_dumpentry, &w)))
- break;
+ if (af != 0) {
+ if ((rnh = rt_tables[af]) != NULL) {
+ RADIX_NODE_HEAD_LOCK(rnh);
+ error = rnh->rnh_walktree(rnh,
+ sysctl_dumpentry, &w);
+ RADIX_NODE_HEAD_UNLOCK(rnh);
+ } else
+ error = EAFNOSUPPORT;
+ } else {
+ for (i = 1; i <= AF_MAX; i++)
+ if ((rnh = rt_tables[i]) != NULL) {
+ RADIX_NODE_HEAD_LOCK(rnh);
+ error = rnh->rnh_walktree(rnh,
+ sysctl_dumpentry, &w);
+ RADIX_NODE_HEAD_UNLOCK(rnh);
+ if (error)
+ break;
+ }
+ }
break;
case NET_RT_IFLIST:
OpenPOWER on IntegriCloud