diff options
author | markj <markj@FreeBSD.org> | 2016-05-23 20:15:08 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2016-05-23 20:15:08 +0000 |
commit | 86c15ee95be472ad4c660cb88e5d2b7e7821db5d (patch) | |
tree | b67802e40793bf785532d6b68ca4fd4903e84e8e | |
parent | fa8c81268ac25d9e16157670de4dd18f3cd4808c (diff) | |
download | FreeBSD-src-86c15ee95be472ad4c660cb88e5d2b7e7821db5d.zip FreeBSD-src-86c15ee95be472ad4c660cb88e5d2b7e7821db5d.tar.gz |
Acquire the nd6 lock in the prefix list sysctl handler.
The nd6 lock will be used to synchronize access to the NDP prefix list.
MFC after: 2 weeks
Tested by: Jason Wolfe (as part of a larger change)
-rw-r--r-- | sys/netinet6/nd6.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index f71cd6a..e255e91 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2610,15 +2610,17 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS) if (req->newptr) return (EPERM); + error = sysctl_wire_old_buffer(req, 0); + if (error != 0) + return (error); + bzero(&p, sizeof(p)); p.origin = PR_ORIG_RA; bzero(&s6, sizeof(s6)); s6.sin6_family = AF_INET6; s6.sin6_len = sizeof(s6); - /* - * XXX locking - */ + ND6_RLOCK(); LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) { p.prefix = pr->ndpr_prefix; if (sa6_recoverscope(&p.prefix)) { @@ -2651,7 +2653,7 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS) p.advrtrs++; error = SYSCTL_OUT(req, &p, sizeof(p)); if (error != 0) - return (error); + break; LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) { s6.sin6_addr = pfr->router->rtaddr; if (sa6_recoverscope(&s6)) @@ -2660,8 +2662,9 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS) ip6_sprintf(ip6buf, &pfr->router->rtaddr)); error = SYSCTL_OUT(req, &s6, sizeof(s6)); if (error != 0) - return (error); + break; } } - return (0); + ND6_RUNLOCK(); + return (error); } |