Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Oct 2013 09:17:46 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r256605 - user/ae/inet6/sys/netinet6
Message-ID:  <201310160917.r9G9HktA099869@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Oct 16 09:17:46 2013
New Revision: 256605
URL: http://svnweb.freebsd.org/changeset/base/256605

Log:
  When choosing hop limit, handle link-local destinations specially.
  Also some style fixes.

Modified:
  user/ae/inet6/sys/netinet6/in6_src.c

Modified: user/ae/inet6/sys/netinet6/in6_src.c
==============================================================================
--- user/ae/inet6/sys/netinet6/in6_src.c	Wed Oct 16 09:15:07 2013	(r256604)
+++ user/ae/inet6/sys/netinet6/in6_src.c	Wed Oct 16 09:17:46 2013	(r256605)
@@ -1242,35 +1242,41 @@ in6_selectroute_fib(struct sockaddr_in6 
  * 1. Hoplimit value specified via ioctl.
  * 2. (If the outgoing interface is detected) the current
  *     hop limit of the interface specified by router advertisement.
- * 3. The system default hoplimit.
+ * 3. If destination address is from link-local scope, use its zoneid
+ *    to determine outgoing interface and use its hop limit.
+ * 4. The system default hoplimit.
  */
 int
 in6_selecthlim(struct inpcb *in6p, struct ifnet *ifp)
 {
+	struct route_in6 ro6;
 
 	if (in6p && in6p->in6p_hops >= 0)
 		return (in6p->in6p_hops);
-	else if (ifp)
+
+	if (ifp != NULL)
 		return (ND_IFINFO(ifp)->chlim);
-	else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
-		struct route_in6 ro6;
-		struct ifnet *lifp;
 
+	/* XXX: should we check for multicast here?*/
+	if (in6p && IN6_IS_ADDR_LINKLOCAL(&in6p->in6p_faddr)) {
+		if (in6p->in6p_zoneid != 0 &&
+		    (ifp = in6_getlinkifnet(in6p->in6p_zoneid)))
+			return (ND_IFINFO(ifp)->chlim);
+	} else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
 		bzero(&ro6, sizeof(ro6));
 		ro6.ro_dst.sin6_family = AF_INET6;
 		ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
 		ro6.ro_dst.sin6_addr = in6p->in6p_faddr;
 		in6_rtalloc(&ro6, in6p->inp_inc.inc_fibnum);
 		if (ro6.ro_rt) {
-			lifp = ro6.ro_rt->rt_ifp;
+			ifp = ro6.ro_rt->rt_ifp;
 			RTFREE(ro6.ro_rt);
-			if (lifp)
-				return (ND_IFINFO(lifp)->chlim);
+			if (ifp)
+				return (ND_IFINFO(ifp)->chlim);
 		}
 	}
 	return (V_ip6_defhlim);
 }
-
 /*
  * XXX: this is borrowed from in6_pcbbind(). If possible, we should
  * share this function by all *bsd*...



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