diff options
author | hsu <hsu@FreeBSD.org> | 2002-12-24 03:03:39 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2002-12-24 03:03:39 +0000 |
commit | 32436a25c0510e4371c6f02353b447c09ba9db0d (patch) | |
tree | 5e53dfd4f16f3a5c2080f2ce73aed007b1be63a1 /sys/net/rtsock.c | |
parent | 018c02046059a2588bdd154c9136e4467aafa156 (diff) | |
download | FreeBSD-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.c | 32 |
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: |