From patchwork Sun Mar 1 00:34:48 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hlusiak X-Patchwork-Id: 23899 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 5A589DDE0E for ; Sun, 1 Mar 2009 11:34:45 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755029AbZCAAem (ORCPT ); Sat, 28 Feb 2009 19:34:42 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754974AbZCAAel (ORCPT ); Sat, 28 Feb 2009 19:34:41 -0500 Received: from moutng.kundenserver.de ([212.227.126.188]:64961 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754942AbZCAAek (ORCPT ); Sat, 28 Feb 2009 19:34:40 -0500 Received: from sascha.localnet ([78.52.121.176]) by mrelayeu.kundenserver.de (node=mrelayeu7) with ESMTP (Nemesis) id 0ML2xA-1LdZdd1Hc7-0006Ht; Sun, 01 Mar 2009 01:34:37 +0100 From: Sascha Hlusiak To: netdev@vger.kernel.org Subject: [PATCH] Assign linklocal addresses to isatap from link dev Date: Sun, 1 Mar 2009 01:34:48 +0100 User-Agent: KMail/1.11.0 (Linux/2.6.28-gentoo-r2; KDE/4.2.0; i686; ; ) MIME-Version: 1.0 Message-Id: <200903010134.54405.mail@saschahlusiak.de> X-Provags-ID: V01U2FsdGVkX1/JJI0iUGCuohcspAgikg3Hxr3SNAzmQJI0u7k 3cQWjL+8Iko/jlMuR9sGagn4dridUftCR6NxOTmhX/tg9fSra/ S7jYNmyDUx5MUEj/nzu7E5UJeWUgx04 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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: 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 Thanks, Sascha Hlusiak --- 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 + * addresses from link dev */ #include @@ -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; }