linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] rtnetlink: return the newly created link in response to newlink
@ 2014-01-30 13:05 Tom Gundersen
  2014-01-30 14:27 ` Thomas Graf
  0 siblings, 1 reply; 3+ messages in thread
From: Tom Gundersen @ 2014-01-30 13:05 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, John Fastabend, Thomas Graf, Nicolas Dichtel,
	Vlad Yasevich, Tom Gundersen, Marcel Holtmann, David S. Miller

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 <teg@jklm.no>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: David S. Miller <davem@davemloft.net>
---
 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);
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] rtnetlink: return the newly created link in response to newlink
  2014-01-30 13:05 [PATCH] rtnetlink: return the newly created link in response to newlink Tom Gundersen
@ 2014-01-30 14:27 ` Thomas Graf
  2014-01-31  0:57   ` Tom Gundersen
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Graf @ 2014-01-30 14:27 UTC (permalink / raw)
  To: Tom Gundersen
  Cc: netdev, linux-kernel, John Fastabend, Nicolas Dichtel,
	Vlad Yasevich, Marcel Holtmann, David S. Miller

On 01/30/14 at 02:05pm, Tom Gundersen wrote:
> 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.

This breaks existing Netlink applications in user space. User space
apps are not prepared to receive both a RTM_NEWLINK reply _and_
the ACK unless they have set NLM_F_ECHO in the original request.

You can already reliably retrieve the ifindex by listening to
RTNLGRP_LINK messages and be notified about the link created
including all follow-up renames.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] rtnetlink: return the newly created link in response to newlink
  2014-01-30 14:27 ` Thomas Graf
@ 2014-01-31  0:57   ` Tom Gundersen
  0 siblings, 0 replies; 3+ messages in thread
From: Tom Gundersen @ 2014-01-31  0:57 UTC (permalink / raw)
  To: Thomas Graf
  Cc: netdev, LKML, John Fastabend, Nicolas Dichtel, Vlad Yasevich,
	Marcel Holtmann, David S. Miller

Hi Thomas,

Thanks for your reply.

On Thu, Jan 30, 2014 at 3:27 PM, Thomas Graf <tgraf@suug.ch> wrote:
> On 01/30/14 at 02:05pm, Tom Gundersen wrote:
>> 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.
>
> This breaks existing Netlink applications in user space. User space
> apps are not prepared to receive both a RTM_NEWLINK reply _and_
> the ACK unless they have set NLM_F_ECHO in the original request.
>
> You can already reliably retrieve the ifindex by listening to
> RTNLGRP_LINK messages and be notified about the link created
> including all follow-up renames.

Ok, we'll keep doing this instead.

Cheers,

Tom

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-01-31  0:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-30 13:05 [PATCH] rtnetlink: return the newly created link in response to newlink Tom Gundersen
2014-01-30 14:27 ` Thomas Graf
2014-01-31  0:57   ` Tom Gundersen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).