diff options
author | hrs <hrs@FreeBSD.org> | 2012-12-04 17:12:23 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2012-12-04 17:12:23 +0000 |
commit | db5359d69a9ec06842730b8af2a30072a38b5aa1 (patch) | |
tree | 0bacd21c19dc243343418c7f98224210dfb97a47 /sys | |
parent | 74acd0aa7d7396577a2cb30cb186ea86e8b8e03d (diff) | |
download | FreeBSD-src-db5359d69a9ec06842730b8af2a30072a38b5aa1.zip FreeBSD-src-db5359d69a9ec06842730b8af2a30072a38b5aa1.tar.gz |
- Fix LOR in sa6_recoverscope() in rt_msg2()[1].
- Check V_deembed_scopeid before checking if sa_family == AF_INET6.
- Fix scope id handing in route(8)[2] and ifconfig(8).
Reported by: rpaulo[1], Mateusz Guzik[1], peter[2]
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/rtsock.c | 71 |
1 files changed, 32 insertions, 39 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 1ff6bca..d1bf200 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -804,28 +804,31 @@ route_output(struct mbuf *m, struct socket *so) } info.rti_info[RTAX_DST] = rt_key(rt); #ifdef INET6 - switch (rt_key(rt)->sa_family) { - case AF_INET6: - if (V_deembed_scopeid == 0) + if (V_deembed_scopeid) { + switch (rt_key(rt)->sa_family) { + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&ss_dst; + bcopy(rt_key(rt), sin6, sizeof(*sin6)); + if (sa6_recoverscope(sin6) == 0) + info.rti_info[RTAX_DST] = + (struct sockaddr *)sin6; break; - sin6 = (struct sockaddr_in6 *)&ss_dst; - bcopy(rt_key(rt), sin6, sizeof(*sin6)); - if (sa6_recoverscope(sin6) == 0) - info.rti_info[RTAX_DST] = - (struct sockaddr *)sin6; - break; + } } #endif info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; #ifdef INET6 - switch (rt->rt_gateway->sa_family) { - case AF_INET6: - sin6 = (struct sockaddr_in6 *)&ss_gw; - bcopy(rt->rt_gateway, sin6, sizeof(*sin6)); - if (sa6_recoverscope(sin6) == 0) - info.rti_info[RTAX_GATEWAY] = - (struct sockaddr *)sin6; - break; + if (V_deembed_scopeid) { + switch (rt->rt_gateway->sa_family) { + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&ss_gw; + bcopy(rt->rt_gateway, sin6, + sizeof(*sin6)); + if (sa6_recoverscope(sin6) == 0) + info.rti_info[RTAX_GATEWAY] = + (struct sockaddr *)sin6; + break; + } } #endif info.rti_info[RTAX_NETMASK] = rt_mask(rt); @@ -1130,15 +1133,11 @@ rt_msg1(int type, struct rt_addrinfo *rtinfo) rtinfo->rti_addrs |= (1 << i); dlen = SA_SIZE(sa); #ifdef INET6 - switch (sa->sa_family) { - case AF_INET6: - if (V_deembed_scopeid == 0) - break; + if (V_deembed_scopeid && sa->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *)&ss; bcopy(sa, sin6, sizeof(*sin6)); if (sa6_recoverscope(sin6) == 0) sa = (struct sockaddr *)sin6; - break; } #endif m_copyback(m, len, dlen, (caddr_t)sa); @@ -1219,15 +1218,11 @@ again: rtinfo->rti_addrs |= (1 << i); dlen = SA_SIZE(sa); #ifdef INET6 - switch (sa->sa_family) { - case AF_INET6: - if (V_deembed_scopeid == 0) - break; + if (V_deembed_scopeid && sa->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *)&ss; bcopy(sa, sin6, sizeof(*sin6)); if (sa6_recoverscope(sin6) == 0) sa = (struct sockaddr *)sin6; - break; } #endif if (cp) { @@ -1594,18 +1589,16 @@ sysctl_dumpentry(struct radix_node *rn, void *vw) info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; } #ifdef INET6 - for (i = 0; i < RTAX_MAX; i++) { - if (info.rti_info[i] == NULL) - continue; - switch (info.rti_info[i]->sa_family) { - case AF_INET6: - if (V_deembed_scopeid == 0) - break; + if (V_deembed_scopeid) { + for (i = 0; i < RTAX_MAX; i++) { + if (info.rti_info[i] == NULL) + continue; + if (info.rti_info[i]->sa_family != AF_INET6) + continue; sin6 = (struct sockaddr_in6 *)&ss[i]; bcopy(info.rti_info[i], sin6, sizeof(*sin6)); if (sa6_recoverscope(sin6) == 0) info.rti_info[i] = (struct sockaddr *)sin6; - break; } } #endif @@ -1811,7 +1804,7 @@ sysctl_iflist(int af, struct walkarg *w) int len, error = 0; bzero((caddr_t)&info, sizeof(info)); - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (w->w_arg && w->w_arg != ifp->if_index) continue; @@ -1856,7 +1849,7 @@ sysctl_iflist(int af, struct walkarg *w) done: if (ifp != NULL) IF_ADDR_RUNLOCK(ifp); - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (error); } @@ -1870,7 +1863,7 @@ sysctl_ifmalist(int af, struct walkarg *w) struct ifaddr *ifa; bzero((caddr_t)&info, sizeof(info)); - IFNET_RLOCK(); + IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (w->w_arg && w->w_arg != ifp->if_index) continue; @@ -1905,7 +1898,7 @@ sysctl_ifmalist(int af, struct walkarg *w) IF_ADDR_RUNLOCK(ifp); } done: - IFNET_RUNLOCK(); + IFNET_RUNLOCK_NOSLEEP(); return (error); } |