From patchwork Thu Jan 30 13:05:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Gundersen X-Patchwork-Id: 315330 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 9DC552C00D5 for ; Fri, 31 Jan 2014 00:05:52 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753231AbaA3NFN (ORCPT ); Thu, 30 Jan 2014 08:05:13 -0500 Received: from mail-ee0-f48.google.com ([74.125.83.48]:36105 "EHLO mail-ee0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752768AbaA3NFL (ORCPT ); Thu, 30 Jan 2014 08:05:11 -0500 Received: by mail-ee0-f48.google.com with SMTP id t10so1565266eei.7 for ; Thu, 30 Jan 2014 05:05:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=bNFuSUe0FFs6P71J3z7B96I4TD9+rBHOave/MTDNjhU=; b=j5zDYQcX4EqKUWFUe2bjISx5c7LURU+CUMUFk76U5e5A/62wicbBLMUHeXMyCbWL4t NZccoAU9n64ToC5vpGaZPATcmYEjmxoWXWPUbqZV+HZjEu4G6oLROPL2xfsjQUbuoLZg 9l7RcsuML3igGOckCb2GTvADIIHKYhYSIPYB+BbKbz9I1Lv6LxSDQd4d96pLgURTw3M6 uogmG3Qr5zh3UlUmmVCmXmlJtsFaJgrT/59ar+RJLkQq2AVFcGfWpXh9cgxFKtuZAHpr PpfO+xskX5qthPp87s2WPEWOPpBvgtUJK02woYPeE0MQODid0SrAwzrtrAJnYxIrTje3 tYBg== X-Gm-Message-State: ALoCoQlip0rZ80AVifhr150uyA6N9jM3k4qmA3bnhMy1XHWxJCQ1rpaqJw15Kh/gNhVrdqMPlV3K X-Received: by 10.14.203.197 with SMTP id f45mr1409787eeo.90.1391087110509; Thu, 30 Jan 2014 05:05:10 -0800 (PST) Received: from tomegun-air.space.hackerspace.be (ip-62-235-135-131.dsl.scarlet.be. [62.235.135.131]) by mx.google.com with ESMTPSA id 4sm22223178eed.14.2014.01.30.05.05.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 30 Jan 2014 05:05:09 -0800 (PST) From: Tom Gundersen To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, John Fastabend , Thomas Graf , Nicolas Dichtel , Vlad Yasevich , Tom Gundersen , Marcel Holtmann , "David S. Miller" Subject: [PATCH] rtnetlink: return the newly created link in response to newlink Date: Thu, 30 Jan 2014 14:05:44 +0100 Message-Id: <1391087144-24490-1-git-send-email-teg@jklm.no> X-Mailer: git-send-email 1.8.5.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Userspace needs to reliably know the ifindex of the netdevs it creates, as we cannot rely on the ifname staying unchanged. Earlier, a simlpe NLMSG_ERROR would be returned, but this returns the corresponding RTM_NEWLINK on success instead. Signed-off-by: Tom Gundersen Cc: Marcel Holtmann Cc: David S. Miller --- net/core/rtnetlink.c | 100 ++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cf67144..31c1322 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1725,6 +1725,54 @@ static int rtnl_group_changelink(struct net *net, int group, return 0; } +static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh) +{ + struct net *net = sock_net(skb->sk); + struct ifinfomsg *ifm; + char ifname[IFNAMSIZ]; + struct nlattr *tb[IFLA_MAX+1]; + struct net_device *dev = NULL; + struct sk_buff *nskb; + int err; + u32 ext_filter_mask = 0; + + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); + if (err < 0) + return err; + + if (tb[IFLA_IFNAME]) + nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); + + if (tb[IFLA_EXT_MASK]) + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); + + ifm = nlmsg_data(nlh); + if (ifm->ifi_index > 0) + dev = __dev_get_by_index(net, ifm->ifi_index); + else if (tb[IFLA_IFNAME]) + dev = __dev_get_by_name(net, ifname); + else + return -EINVAL; + + if (dev == NULL) + return -ENODEV; + + nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL); + if (nskb == NULL) + return -ENOBUFS; + + err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).portid, + nlh->nlmsg_seq, 0, 0, ext_filter_mask); + if (err < 0) { + /* -EMSGSIZE implies BUG in if_nlmsg_size */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(nskb); + } else + err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); + + return err; +} + static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); @@ -1871,63 +1919,19 @@ replay: goto out; } + ifm->ifi_index = dev->ifindex; + err = rtnl_configure_link(dev, ifm); if (err < 0) unregister_netdevice(dev); + else + rtnl_getlink(skb, nlh); out: put_net(dest_net); return err; } } -static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh) -{ - struct net *net = sock_net(skb->sk); - struct ifinfomsg *ifm; - char ifname[IFNAMSIZ]; - struct nlattr *tb[IFLA_MAX+1]; - struct net_device *dev = NULL; - struct sk_buff *nskb; - int err; - u32 ext_filter_mask = 0; - - err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); - if (err < 0) - return err; - - if (tb[IFLA_IFNAME]) - nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); - - if (tb[IFLA_EXT_MASK]) - ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); - - ifm = nlmsg_data(nlh); - if (ifm->ifi_index > 0) - dev = __dev_get_by_index(net, ifm->ifi_index); - else if (tb[IFLA_IFNAME]) - dev = __dev_get_by_name(net, ifname); - else - return -EINVAL; - - if (dev == NULL) - return -ENODEV; - - nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL); - if (nskb == NULL) - return -ENOBUFS; - - err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).portid, - nlh->nlmsg_seq, 0, 0, ext_filter_mask); - if (err < 0) { - /* -EMSGSIZE implies BUG in if_nlmsg_size */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(nskb); - } else - err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid); - - return err; -} - static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk);