
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

I think this has been there for long time (maybe since 2.4...).

With the following patch, I can connect local link-local address.
- Change incoming interface according to the scoping architecture
- Choose source address on appropriate interface, according to the
  scoping architecture.

Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/net/ipv6/addrconf.c  |    2 +-
 25-akpm/net/ipv6/ip6_input.c |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff -puN net/ipv6/addrconf.c~ipv6-fix-address-interface-handling-according-to-the-scoping-architecture net/ipv6/addrconf.c
--- 25/net/ipv6/addrconf.c~ipv6-fix-address-interface-handling-according-to-the-scoping-architecture	Thu Mar 24 15:25:47 2005
+++ 25-akpm/net/ipv6/addrconf.c	Thu Mar 24 15:25:47 2005
@@ -942,7 +942,7 @@ out:
 int ipv6_get_saddr(struct dst_entry *dst,
 		   struct in6_addr *daddr, struct in6_addr *saddr)
 {
-	return ipv6_dev_get_saddr(dst ? dst->dev : NULL, daddr, saddr);
+	return ipv6_dev_get_saddr(dst ? ((struct rt6_info *)dst)->rt6i_idev->dev : NULL, daddr, saddr);
 }
 
 
diff -puN net/ipv6/ip6_input.c~ipv6-fix-address-interface-handling-according-to-the-scoping-architecture net/ipv6/ip6_input.c
--- 25/net/ipv6/ip6_input.c~ipv6-fix-address-interface-handling-according-to-the-scoping-architecture	Thu Mar 24 15:25:47 2005
+++ 25-akpm/net/ipv6/ip6_input.c	Thu Mar 24 15:25:47 2005
@@ -71,10 +71,18 @@ int ipv6_rcv(struct sk_buff *skb, struct
 		goto out;
 	}
 
-	/* Store incoming device index. When the packet will
-	   be queued, we cannot refer to skb->dev anymore.
+	/*
+	 * Store incoming device index. When the packet will
+	 * be queued, we cannot refer to skb->dev anymore.
+	 *
+	 * BTW, when we send a packet for our own local address on a
+	 * non-loopback interface (e.g. ethX), it is being delivered
+	 * via the loopback interface (lo) here; skb->dev = &loopback_dev.
+	 * It, however, should be considered as if it is being
+	 * arrived via the sending interface (ethX), because of the
+	 * nature of scoping architecture. --yoshfuji
 	 */
-	IP6CB(skb)->iif = dev->ifindex;
+	IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex;
 
 	if (skb->len < sizeof(struct ipv6hdr))
 		goto err;
_
