Subject: Re: regression: bind interface and transmit to ff02::2
To: David Young <dyoung@pobox.com>
From: JINMEI Tatuya / =?ISO-2022-JP?B?GyRCP0BMQEMjOkgbKEI=?= <jinmei@isl.rdc.toshiba.co.jp>
List: tech-net
Date: 04/05/2006 12:12:45
--Multipart_Wed_Apr__5_12:12:45_2006-1
Content-Type: text/plain; charset=US-ASCII

>>>>> On Tue, 4 Apr 2006 11:15:00 -0500, 
>>>>> David Young <dyoung@pobox.com> said:

>> >> Correct.
>> 
>> > Okay, then it's not the intended behavior, sorry for the mess.  Please
>> > try the attached patch.
>> 
>> Oops, sorry, that patch was incorrect.  Please use this one (below).

> The patch didn't fix the bug; sendto(2) still fails with "No route
> to host."

Sorry, it was still incomplete.  Please try this one.  This time, I've
confirmed the behavior at least on my machine (it's not the very
latest version of current, but I believe tha patch will work
without any non-trivial hack).

					JINMEI, Tatuya
					Communication Platform Lab.
					Corporate R&D Center, Toshiba Corp.
					jinmei@isl.rdc.toshiba.co.jp


--Multipart_Wed_Apr__5_12:12:45_2006-1
Content-Type: text/plane; charset=ISO-2022-JP
Content-Disposition: attachment; filename="s.diff"
Content-Transfer-Encoding: 7bit

Index: in6_src.c
===================================================================
RCS file: /cvsroot/kame-netbsd-current/src/sys/netinet6/in6_src.c,v
retrieving revision 1.1.1.1.12.3
diff -u -r1.1.1.1.12.3 in6_src.c
--- in6_src.c	22 Dec 2005 09:19:39 -0000	1.1.1.1.12.3
+++ in6_src.c	5 Apr 2006 03:11:26 -0000
@@ -198,6 +198,7 @@
 	int dst_scope = -1, best_scope = -1, best_matchlen = -1;
 	struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL;
 	u_int32_t odstzone;
+	int error;
 #ifdef notyet /* until introducing ND extensions and address selection */
 	int prefer_tempaddr;
 #endif
@@ -211,6 +212,17 @@
 		*ifpp = NULL;
 
 	/*
+	 * Try to determine the outgoing interface for the given destination.
+	 * We do this regardless of whether the socket is bound, since the
+	 * caller may need this information as a side effect of the call
+	 * to this function (e.g., for identifying the appropriate scope zone
+	 * ID).
+	 */
+	error = in6_selectif(dstsock, opts, mopts, ro, &ifp);
+	if (ifpp)
+		*ifpp = ifp;
+
+	/*
 	 * If the source address is explicitly specified by the caller,
 	 * check if the requested source address is indeed a unicast address
 	 * assigned to the node, and can be used as the packet's source
@@ -221,12 +233,6 @@
 		struct sockaddr_in6 srcsock;
 		struct in6_ifaddr *ia6;
 
-		/* get the outgoing interface */
-		if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, &ifp))
-		    != 0) {
-			return (NULL);
-		}
-
 		/*
 		 * Determine the appropriate zone id of the source based on
 		 * the zone of the destination and the outgoing interface.
@@ -257,18 +263,26 @@
 	}
 
 	/*
-	 * Otherwise, if the socket has already bound the source, just use it.
+	 * If the socket has already bound the source, just use it.  We don't
+	 * care at the moment whether in6_selectif() succeeded above, even
+	 * though it would eventually cause an error.
 	 */
 	if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
 		return (laddr);
 
 	/*
-	 * If the address is not specified, choose the best one based on
-	 * the outgoing interface and the destination address.
+	 * The outgoing interface is crucial in the general selection procedure
+	 * below.  If it is not known at this point, we fail.
 	 */
-	/* get the outgoing interface */
-	if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, &ifp)) != 0)
+	if (ifp == NULL) {
+		*errorp = error;
 		return (NULL);
+	}
+
+	/*
+	 * If the address is not yet determined, choose the best one based on
+	 * the outgoing interface and the destination address.
+	 */
 
 #if defined(MIP6) && NMIP > 0
 	/*
@@ -556,8 +570,6 @@
 		return (NULL);
 	}
 
-	if (ifpp)
-		*ifpp = ifp;
 	return (&ia->ia_addr.sin6_addr);
 }
 #undef REPLACE

--Multipart_Wed_Apr__5_12:12:45_2006-1--