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: 03/23/2006 16:39:24
>>>>> On Thu, 23 Mar 2006 16:33:47 +0900, 
>>>>> JINMEI Tatuya <jinmei@isl.rdc.toshiba.co.jp> 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).

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

--- in6_src.c.orig	Thu Mar 23 16:20:31 2006
+++ in6_src.c	Thu Mar 23 16:36:25 2006
@@ -201,6 +201,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
@@ -260,18 +261,31 @@
 	}
 
 	/*
-	 * Otherwise, if the socket has already bound the source, just use it.
+	 * Choose the best one based on the outgoing interface and the
+	 * destination address.  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).
+	 */
+	/* get the outgoing interface */
+	error = in6_selectif(dstsock, opts, mopts, ro, &ifp);
+
+	/*
+	 * If the socket has already bound the source, just use it.  We don't
+	 * care at the moment whether in6_selectif() succeeded, 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 defined(MIP6) && NMIP > 0
 	/*