diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 11:33:00 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 15:28:21 +0100 |
commit | af5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch) | |
tree | c5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/sys/netinet6/scope6.c | |
parent | BUS_SPACE(9): Use simple memory model for ARM (diff) | |
download | rtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2 |
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/sys/netinet6/scope6.c')
-rw-r--r-- | freebsd/sys/netinet6/scope6.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/freebsd/sys/netinet6/scope6.c b/freebsd/sys/netinet6/scope6.c index 655022d6..a5c7d7b1 100644 --- a/freebsd/sys/netinet6/scope6.c +++ b/freebsd/sys/netinet6/scope6.c @@ -123,11 +123,11 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) int error = 0; struct scope6_id *sid = NULL; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_WLOCK(ifp); sid = SID(ifp); if (!sid) { /* paranoid? */ - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_WUNLOCK(ifp); return (EINVAL); } @@ -141,7 +141,6 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) * interface addresses, routing table entries, PCB entries... */ - SCOPE6_LOCK(); for (i = 0; i < 16; i++) { if (idlist->s6id_list[i] && idlist->s6id_list[i] != sid->s6id_list[i]) { @@ -151,8 +150,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) */ if (i == IPV6_ADDR_SCOPE_INTFACELOCAL && idlist->s6id_list[i] != ifp->if_index) { - IF_AFDATA_UNLOCK(ifp); - SCOPE6_UNLOCK(); + IF_AFDATA_WUNLOCK(ifp); return (EINVAL); } @@ -164,8 +162,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) * IDs, but we check the consistency for * safety in later use. */ - IF_AFDATA_UNLOCK(ifp); - SCOPE6_UNLOCK(); + IF_AFDATA_WUNLOCK(ifp); return (EINVAL); } @@ -177,8 +174,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) sid->s6id_list[i] = idlist->s6id_list[i]; } } - SCOPE6_UNLOCK(); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_WUNLOCK(ifp); return (error); } @@ -186,20 +182,19 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) int scope6_get(struct ifnet *ifp, struct scope6_id *idlist) { - /* We only need to lock the interface's afdata for SID() to work. */ - IF_AFDATA_LOCK(ifp); - struct scope6_id *sid = SID(ifp); + struct scope6_id *sid; + /* We only need to lock the interface's afdata for SID() to work. */ + IF_AFDATA_RLOCK(ifp); + sid = SID(ifp); if (sid == NULL) { /* paranoid? */ - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); return (EINVAL); } - SCOPE6_LOCK(); *idlist = *sid; - SCOPE6_UNLOCK(); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); return (0); } @@ -390,7 +385,7 @@ sa6_recoverscope(struct sockaddr_in6 *sin6) zoneid = ntohs(sin6->sin6_addr.s6_addr16[1]); if (zoneid) { /* sanity check */ - if (zoneid < 0 || V_if_index < zoneid) + if (V_if_index < zoneid) return (ENXIO); if (!ifnet_byindex(zoneid)) return (ENXIO); @@ -416,7 +411,7 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id) u_int32_t zoneid = 0; struct scope6_id *sid; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); sid = SID(ifp); @@ -433,19 +428,17 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id) */ if (IN6_IS_ADDR_LOOPBACK(in6)) { if (!(ifp->if_flags & IFF_LOOPBACK)) { - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); return (EINVAL); } else { if (ret_id != NULL) *ret_id = 0; /* there's no ambiguity */ - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); return (0); } } scope = in6_addrscope(in6); - - SCOPE6_LOCK(); switch (scope) { case IPV6_ADDR_SCOPE_INTFACELOCAL: /* should be interface index */ zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_INTFACELOCAL]; @@ -467,8 +460,7 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id) zoneid = 0; /* XXX: treat as global. */ break; } - SCOPE6_UNLOCK(); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if (ret_id != NULL) *ret_id = zoneid; @@ -496,3 +488,16 @@ in6_clearscope(struct in6_addr *in6) return (modified); } + +/* + * Return the scope identifier or zero. + */ +uint16_t +in6_getscope(struct in6_addr *in6) +{ + + if (IN6_IS_SCOPE_LINKLOCAL(in6) || IN6_IS_ADDR_MC_INTFACELOCAL(in6)) + return (in6->s6_addr16[1]); + + return (0); +} |