Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Dec 2012 17:12:23 +0000 (UTC)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r243866 - in head: sbin/ifconfig sbin/route sys/net
Message-ID:  <201212041712.qB4HCN9O041426@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hrs
Date: Tue Dec  4 17:12:23 2012
New Revision: 243866
URL: http://svnweb.freebsd.org/changeset/base/243866

Log:
  - 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]

Modified:
  head/sbin/ifconfig/af_inet6.c
  head/sbin/route/route.c
  head/sys/net/rtsock.c

Modified: head/sbin/ifconfig/af_inet6.c
==============================================================================
--- head/sbin/ifconfig/af_inet6.c	Tue Dec  4 16:54:43 2012	(r243865)
+++ head/sbin/ifconfig/af_inet6.c	Tue Dec  4 17:12:23 2012	(r243866)
@@ -251,8 +251,9 @@ in6_status(int s __unused, const struct 
 	if ((flags6 & IN6_IFF_TEMPORARY) != 0)
 		printf("temporary ");
 
-        if (sin->sin6_scope_id)
-		printf("scopeid 0x%x ", sin->sin6_scope_id);
+	if (((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id)
+		printf("scopeid 0x%x ",
+		    ((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id);
 
 	if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) {
 		printf("pltime ");

Modified: head/sbin/route/route.c
==============================================================================
--- head/sbin/route/route.c	Tue Dec  4 16:54:43 2012	(r243865)
+++ head/sbin/route/route.c	Tue Dec  4 17:12:23 2012	(r243866)
@@ -1208,6 +1208,16 @@ getaddr(int which, char *str, struct hos
 			exit(1);
 		}
 		memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
+#ifdef __KAME__
+		if ((IN6_IS_ADDR_LINKLOCAL(&su->sin6.sin6_addr) ||
+		    IN6_IS_ADDR_MC_LINKLOCAL(&su->sin6.sin6_addr) ||
+		    IN6_IS_ADDR_MC_NODELOCAL(&su->sin6.sin6_addr)) &&
+		    su->sin6.sin6_scope_id) {
+			*(u_int16_t *)&su->sin6.sin6_addr.s6_addr[2] =
+			    htons(su->sin6.sin6_scope_id);
+			su->sin6.sin6_scope_id = 0;
+		}
+#endif
 		freeaddrinfo(res);
 		if (q != NULL)
 			*q++ = '/';

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Tue Dec  4 16:54:43 2012	(r243865)
+++ head/sys/net/rtsock.c	Tue Dec  4 17:12:23 2012	(r243866)
@@ -804,28 +804,31 @@ route_output(struct mbuf *m, struct sock
 			}
 			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 *rt
 		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, 
 			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 *
 	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 *
 		IF_ADDR_RUNLOCK(ifp);
 	}
 done:
-	IFNET_RUNLOCK();
+	IFNET_RUNLOCK_NOSLEEP();
 	return (error);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212041712.qB4HCN9O041426>