From patchwork Sat Dec 5 19:02:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B8rn_Mork?= X-Patchwork-Id: 553018 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.180.67]) by ozlabs.org (Postfix) with ESMTP id D6551140322 for ; Sun, 6 Dec 2015 06:02:25 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=mork.no header.i=@mork.no header.b=YASA2bAE; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752793AbbLETCV (ORCPT ); Sat, 5 Dec 2015 14:02:21 -0500 Received: from canardo.mork.no ([148.122.252.1]:52059 "EHLO canardo.mork.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752631AbbLETCT (ORCPT ); Sat, 5 Dec 2015 14:02:19 -0500 Received: from nemi.mork.no (nemi.mork.no [IPv6:2001:4641:0:2:e8b:fdff:fe08:971]) (authenticated bits=0) by canardo.mork.no (8.14.4/8.14.4) with ESMTP id tB5J29JW028208 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Sat, 5 Dec 2015 20:02:10 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mork.no; s=a; t=1449342133; bh=Egia4JJcOiJWAN8mXO6SdLhJd2I6LwhZ5c6Hn243PpM=; h=From:To:Cc:References:Date:Message-ID:From; b=YASA2bAETVIkAscbZ2TKMBzWSJIPqfxo3Rwc+5N5vchm2Ff6SPtY+OYCwr2Gt1HQt Qocze5lJyx94/XlOS8+jNNXVZ2a5qerFbP1ZItB7pVjpvPseUU2aoGwPgxCc5y8OO/ ZdZGI03AhvuJ7/QvJ4RN+mlzVra0F81jloXHp35wJANQuLkCddrx5d96OBdOedh0QP sD8kX5ekjSBrmAo1i/0aCWpOb/6IXg+MZ0rWFXoxUmqPxBqb+WfatK3XFdsR2HcsWn bJGsXMdjzYKKzhMIAt5LN7aeVLcDHt+cOAUEV+mjnXIct1pDRb6QSiZarqErIFGs4y GpVncg26N0Ykw== Received: from bjorn by nemi.mork.no with local (Exim 4.84) (envelope-from ) id 1a5I5x-0002DO-Ns; Sat, 05 Dec 2015 20:02:09 +0100 From: =?utf-8?Q?Bj=C3=B8rn_Mork?= To: Hannes Frederic Sowa Cc: , =?utf-8?B?5ZCJ6Jek6Iux5piO?= Subject: Re: [RFC] ipv6: use a random ifid for headerless devices Organization: m References: <1448884508-5235-1-git-send-email-bjorn@mork.no> <1448968942.3320842.454553905.2C5FBADD@webmail.messagingengine.com> <87vb8fjpou.fsf@nemi.mork.no> <1449225712.287884.457895729.21AD000E@webmail.messagingengine.com> Date: Sat, 05 Dec 2015 20:02:09 +0100 In-Reply-To: <1449225712.287884.457895729.21AD000E@webmail.messagingengine.com> (Hannes Frederic Sowa's message of "Fri, 04 Dec 2015 11:41:52 +0100") Message-ID: <87d1ukk9ce.fsf@nemi.mork.no> User-Agent: Gnus/5.130013 (Ma Gnus v0.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.98.7 at canardo X-Virus-Status: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hannes Frederic Sowa writes: > On Thu, Dec 3, 2015, at 20:29, Bjørn Mork wrote: > >> After looking more at addrconf, I started wondering if we couldn't abuse >> ipv6_generate_stable_address() for this purpose? We could add a new >> addr_gen_mode which would trigger automatic generation of a secret if >> stable_secret is uninitialized. This would be good enough to ensure >> stability until the interface is destroyed. And it would still allow >> the adminstrator to select IN6_ADDR_GEN_MODE_STABLE_PRIVACY by entering >> a new secret. > > I am fine with your proposal but I would really like to see it only > happen on the per-interface stable_secret instance. Do you think something like the patch below will be OK? Or would it be better to drop the additional mode and just generate a random secret if the mode is IN6_ADDR_GEN_MODE_STABLE_PRIVACY and the secrets are missing? Or would that be changing the userspace ABI? This is not clear to me... Bjørn From 099c0a856cc4d06d2da6eb7f1f684adff9820f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 4 Dec 2015 13:30:13 +0100 Subject: [PATCH] ipv6: addrconf: use stable address generator for ARPHRD_NONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new address generator mode, using the stable address generator with an automatically generated secret. Set it up as the default address generator for ARPHRD_NONE interfaces, which cannot use the EUI generator. A random secret is generated on first link up event, allowing a link local address to be added: 5: tun0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 500 link/none promiscuity 0 tun addrgenmode auto cat: /proc/sys/net/ipv6/conf/tun0/stable_secret: Input/output error b269:f3cc:e285:3de3:d9e5:ac1c:bf76:a7ca 5: tun0: mtu 1500 qdisc noqueue state UNKNOWN group default qlen 500 link/none promiscuity 0 tun inet6 fe80::19d4:c711:c8d3:451d/64 scope link flags 800 valid_lft forever preferred_lft forever Manually configuring a secret changes the mode to stable-privacy: A:~# echo :: > /proc/sys/net/ipv6/conf/tun0/stable_secret A:~# ip -d link show dev tun0 5: tun0: mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 500 link/none promiscuity 0 tun addrgenmode stable-privacy Changing the mode to auto will not change an existing secret. Signed-off-by: Bjørn Mork --- include/uapi/linux/if_link.h | 1 + net/ipv6/addrconf.c | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 5ad5737..999d765 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -218,6 +218,7 @@ enum in6_addr_gen_mode { IN6_ADDR_GEN_MODE_EUI64, IN6_ADDR_GEN_MODE_NONE, IN6_ADDR_GEN_MODE_STABLE_PRIVACY, + IN6_ADDR_GEN_MODE_AUTO, }; /* Bridge section */ diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d84742f..1b12ff3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -393,6 +393,9 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) ndev->cnf.rtr_solicits = 0; } #endif + /* this device type does not support the default EUI mode */ + if (dev->type == ARPHRD_NONE) + ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_AUTO; INIT_LIST_HEAD(&ndev->tempaddr_list); setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); @@ -2314,6 +2317,12 @@ static void manage_tempaddrs(struct inet6_dev *idev, } } +static bool is_addr_mode_generate_stable(struct inet6_dev *idev) +{ + return idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY || + idev->addr_gen_mode == IN6_ADDR_GEN_MODE_AUTO; +} + void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) { struct prefix_info *pinfo; @@ -2427,8 +2436,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) in6_dev->token.s6_addr + 8, 8); read_unlock_bh(&in6_dev->lock); tokenized = true; - } else if (in6_dev->addr_gen_mode == - IN6_ADDR_GEN_MODE_STABLE_PRIVACY && + } else if (is_addr_mode_generate_stable(in6_dev) && !ipv6_generate_stable_address(&addr, 0, in6_dev)) { addr_flags |= IFA_F_STABLE_PRIVACY; @@ -3028,6 +3036,17 @@ retry: return 0; } +static void ipv6_gen_mode_auto_init(struct inet6_dev *idev) +{ + struct ipv6_stable_secret *s = &idev->cnf.stable_secret; + + if (s->initialized) + return; + s = &idev->cnf.stable_secret; + get_random_bytes(&s->secret, sizeof(s->secret)); + s->initialized = true; +} + static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route) { struct in6_addr addr; @@ -3038,13 +3057,18 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route) ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); - if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY) { + switch (idev->addr_gen_mode) { + case IN6_ADDR_GEN_MODE_AUTO: + ipv6_gen_mode_auto_init(idev); + /* fallthrough */ + case IN6_ADDR_GEN_MODE_STABLE_PRIVACY: if (!ipv6_generate_stable_address(&addr, 0, idev)) addrconf_add_linklocal(idev, &addr, IFA_F_STABLE_PRIVACY); else if (prefix_route) addrconf_prefix_route(&addr, 64, idev->dev, 0, 0); - } else if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64) { + break; + case IN6_ADDR_GEN_MODE_EUI64: /* addrconf_add_linklocal also adds a prefix_route and we * only need to care about prefix routes if ipv6_generate_eui64 * couldn't generate one. @@ -3053,6 +3077,11 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route) addrconf_add_linklocal(idev, &addr, 0); else if (prefix_route) addrconf_prefix_route(&addr, 64, idev->dev, 0, 0); + break; + case IN6_ADDR_GEN_MODE_NONE: + default: + /* will not add any link local address */ + break; } } @@ -3069,7 +3098,8 @@ static void addrconf_dev_config(struct net_device *dev) (dev->type != ARPHRD_IEEE802154) && (dev->type != ARPHRD_IEEE1394) && (dev->type != ARPHRD_TUNNEL6) && - (dev->type != ARPHRD_6LOWPAN)) { + (dev->type != ARPHRD_6LOWPAN) && + (dev->type != ARPHRD_NONE)) { /* Alas, we support only Ethernet autoconfiguration. */ return; } @@ -4921,7 +4951,8 @@ static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla) if (mode != IN6_ADDR_GEN_MODE_EUI64 && mode != IN6_ADDR_GEN_MODE_NONE && - mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY) + mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY && + mode != IN6_ADDR_GEN_MODE_AUTO) return -EINVAL; if (mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY && -- 2.1.4