In article <[email protected]> (at Fri, 11 Mar 2005 17:33:08 -0800), Andrew Morton <[email protected]> says:
> Felix von Leitner <[email protected]> wrote:
> >
> > Now about IPv6: npush and npoll are two applications I wrote. npush
> > sends multicast announcements and opens a TCP socket. npoll receives
> > the multicast announcement and connects to the source IP/port/scope_id
> > of the announcement. If both are run on the same machine, npoll sees
> > the link local address of eth0 as source IP, and the interface number of
> > eth0 as scope_id. So far so good. Trying to connect() however hangs.
> > Since this has been broken in different ways for as long as I can
> > remember in Linux, and I keep complaining about it every half a year or
> > so. Can't someone fix this once and for all? IPv4 checks whether we
> > are connecting to our own address and reroutes through loopback, why
> > can't IPv6?
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 <[email protected]>
===== net/ipv6/ip6_input.c 1.23 vs edited =====
--- 1.23/net/ipv6/ip6_input.c 2005-03-10 14:12:11 +09:00
+++ edited/net/ipv6/ip6_input.c 2005-03-24 17:49:15 +09:00
@@ -71,10 +71,18 @@
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;
===== net/ipv6/addrconf.c 1.134 vs edited =====
--- 1.134/net/ipv6/addrconf.c 2005-03-15 14:21:11 +09:00
+++ edited/net/ipv6/addrconf.c 2005-03-24 11:52:17 +09:00
@@ -942,7 +942,7 @@
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);
}
--
Hideaki YOSHIFUJI @ USAGI Project <[email protected]>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]