From: YOSHIFUJI Hideaki 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 Signed-off-by: Andrew Morton --- 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; _