Patchwork Assign linklocal addresses to isatap from link dev

login
register
mail settings
Submitter Sascha Hlusiak
Date March 1, 2009, 12:34 a.m.
Message ID <200903010134.54405.mail@saschahlusiak.de>
Download mbox | patch
Permalink /patch/23899/
State Deferred
Delegated to: David Miller
Headers show

Comments

Sascha Hlusiak - March 1, 2009, 12:34 a.m.
Hello,

To use isatap on a client, I use the following command:
# ip tunnel add isatap0 mode isatap remote $REMOTE_V4 dev eth0

(without the attached iproute2-patch that command would fail because of the 
remote option; patch is sent to maintainer).

Old implemention would then add a linklocal address based on the unset 'local' 
option, which is obviously wrong: fe80::5efe:0:0/64

With my patch applied and the tunnel created like above, if a link is attached 
to the tunnel, all it's ipv4 addresses are added as isatap compatible 
linklocal addresses to the tunnel device. The wrong isatap ll-address above 
will not be added anymore, if the 'local' option is unset.


# ip addr
2: eth0: UNKNOWN qlen 1000
   [...]
    inet 192.168.6.5/24 brd 192.168.6.255 scope global eth0
    inet 192.168.6.9/32 scope global eth0
   [...]
7: is0@eth0: <POINTOPOINT,NOARP,UP,LOWER_UP>
    link/sit 0.0.0.0 peer x.x.x.x
    inet6 fe80::5efe:c0a8:609/64 scope link
       valid_lft forever preferred_lft forever
    inet6 fe80::5efe:c0a8:605/64 scope link
       valid_lft forever preferred_lft forever

That way stateless autoconf works with isatap tunnels and without knowledge of 
the local v4 address.


    Signed-off-by: Sascha Hlusiak <mail@saschahlusiak.de>


Thanks,
Sascha Hlusiak
David Miller - March 4, 2009, 11:28 a.m.
From: Sascha Hlusiak <mail@saschahlusiak.de>
Date: Sun, 1 Mar 2009 01:34:48 +0100

> That way stateless autoconf works with isatap tunnels and without
> knowledge of the local v4 address.

This is not my understanding of how ISATAP works on hosts.

Real autoconf is not performed, but rather you must configure your
system with a PRL (potential routers list) and these routers are
probed periodically in order to keep track of which of them are still
functioning and also to perform a sort-of unicast-only autoconf.

I am pretty sure that the person who added the ISATAP code created the
current behavior intentionally.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sascha Hlusiak - March 4, 2009, 5:49 p.m.
> > That way stateless autoconf works with isatap tunnels and without
> > knowledge of the local v4 address.
>
> Real autoconf is not performed, but rather you must configure your
> system with a PRL (potential routers list) and these routers are
> probed periodically in order to keep track of which of them are still
> functioning and also to perform a sort-of unicast-only autoconf.
Well, since ISATAP is just a SIT, it still needs a link local address for 
autoconf and it needs to have it's v4 Address embedded in the lowest 32 bit of 
the linklocal address. It will then do normal autoconf with the potential 
router by sending a proper router solicitation messages, either directed or 
multicast.

I see that the current implementation disables sending of RS when on ISATAP, 
which is not correct because RS are needed to do the autoconf.

At least that's the way the implementation in MS Windows works.

> I am pretty sure that the person who added the ISATAP code created the
> current behavior intentionally.
Well, the current implementation does not cover clients at all, because 
the ip command refuses to create tunnels without the remote parameter, which 
is neccessary because it's the potential router.

It then does not derive the linklocal address correctly, making it impossible 
to do autoconf with the server. Using SIT does work as such as you still need 
to add the correct ISATAP linklocal address to the interface. 

I think ISATAP Client support in Linux could be more automated.


- Sascha
David Miller - March 13, 2009, 9:43 p.m.
From: Sascha Hlusiak <mail@saschahlusiak.de>
Date: Wed, 4 Mar 2009 18:49:41 +0100

> > > That way stateless autoconf works with isatap tunnels and without
> > > knowledge of the local v4 address.
> >
> > Real autoconf is not performed, but rather you must configure your
> > system with a PRL (potential routers list) and these routers are
> > probed periodically in order to keep track of which of them are still
> > functioning and also to perform a sort-of unicast-only autoconf.
> Well, since ISATAP is just a SIT, it still needs a link local address for 
> autoconf and it needs to have it's v4 Address embedded in the lowest 32 bit of 
> the linklocal address. It will then do normal autoconf with the potential 
> router by sending a proper router solicitation messages, either directed or 
> multicast.
> 
> I see that the current implementation disables sending of RS when on ISATAP, 
> which is not correct because RS are needed to do the autoconf.
> 
> At least that's the way the implementation in MS Windows works.
> 
> > I am pretty sure that the person who added the ISATAP code created the
> > current behavior intentionally.
> Well, the current implementation does not cover clients at all, because 
> the ip command refuses to create tunnels without the remote parameter, which 
> is neccessary because it's the potential router.
> 
> It then does not derive the linklocal address correctly, making it impossible 
> to do autoconf with the server. Using SIT does work as such as you still need 
> to add the correct ISATAP linklocal address to the interface. 
> 
> I think ISATAP Client support in Linux could be more automated.

Let's ask the ISATAP author the intent of the situation.
CC:'d

Fred?
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

--- net/ipv6/addrconf.c.orig	2009-03-01 00:51:40.000000000 +0100
+++ net/ipv6/addrconf.c	2009-03-01 01:07:31.000000000 +0100
@@ -36,6 +36,8 @@ 
  *	YOSHIFUJI Hideaki @USAGI	:	improved source address
  *						selection; consider scope,
  *						status etc.
+ *	Sascha Hlusiak				isatap: assign linklocal
+ *	<mail@saschahlusiak.de>			addresses from link dev
  */
 
 #include <linux/errno.h>
@@ -1556,13 +1558,6 @@ 
 }
 EXPORT_SYMBOL(__ipv6_isatap_ifid);
 
-static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
-{
-	if (dev->priv_flags & IFF_ISATAP)
-		return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
-	return -1;
-}
-
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1574,8 +1569,6 @@ 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
-	case ARPHRD_SIT:
-		return addrconf_ifid_sit(eui, dev);
 	}
 	return -1;
 }
@@ -2363,6 +2356,25 @@ 
 }
 
 #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+static void
+isatap_add_v4_addrs(struct inet6_dev *idev, struct net_device *link_dev)
+{
+	struct in_device *in_dev = __in_dev_get_rtnl(link_dev);
+	struct in6_addr addr;
+	struct in_ifaddr *ifa;
+
+	if (!link_dev->flags & IFF_UP)
+		return;
+	if (!in_dev)
+		return;
+
+	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+		ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
+		if (!__ipv6_isatap_ifid(addr.s6_addr + 8, ifa->ifa_local))
+			addrconf_add_linklocal(idev, &addr);
+	}
+}
+
 static void addrconf_sit_config(struct net_device *dev)
 {
 	struct inet6_dev *idev;
@@ -2382,11 +2394,23 @@ 
 
 	if (dev->priv_flags & IFF_ISATAP) {
 		struct in6_addr addr;
+		struct net_device *link_dev;
+		struct net *net = dev_net(dev);
 
 		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
 		addrconf_prefix_route(&addr, 64, dev, 0, 0);
-		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
-			addrconf_add_linklocal(idev, &addr);
+
+		if (*(__be32 *)dev->dev_addr) {
+			if (!__ipv6_isatap_ifid(addr.s6_addr + 8,
+						*(__be32 *)dev->dev_addr))
+				addrconf_add_linklocal(idev, &addr);
+		}
+		/* Add all v4 addrs from the tunnel dev */
+		if (idev->dev->iflink &&
+		    (link_dev = __dev_get_by_index(net, idev->dev->iflink))) {
+			isatap_add_v4_addrs(idev, link_dev);
+		}
+
 		return;
 	}