Commit a3d12891 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

rtnetlink: rtnl_setlink() and rtnl_getlink() changes

rtnl_getlink() & rtnl_setlink() run with RTNL held, we can use
__dev_get_by_index() and __dev_get_by_name() variants and avoid
dev_hold()/dev_put()

Adds to rtnl_getlink() the capability to find a device by its name,
not only by its index.
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a61f8026
...@@ -910,9 +910,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ...@@ -910,9 +910,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
err = -EINVAL; err = -EINVAL;
ifm = nlmsg_data(nlh); ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0) if (ifm->ifi_index > 0)
dev = dev_get_by_index(net, ifm->ifi_index); dev = __dev_get_by_index(net, ifm->ifi_index);
else if (tb[IFLA_IFNAME]) else if (tb[IFLA_IFNAME])
dev = dev_get_by_name(net, ifname); dev = __dev_get_by_name(net, ifname);
else else
goto errout; goto errout;
...@@ -922,11 +922,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ...@@ -922,11 +922,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
} }
if ((err = validate_linkmsg(dev, tb)) < 0) if ((err = validate_linkmsg(dev, tb)) < 0)
goto errout_dev; goto errout;
err = do_setlink(dev, ifm, tb, ifname, 0); err = do_setlink(dev, ifm, tb, ifname, 0);
errout_dev:
dev_put(dev);
errout: errout:
return err; return err;
} }
...@@ -1154,6 +1152,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ...@@ -1154,6 +1152,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{ {
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct ifinfomsg *ifm; struct ifinfomsg *ifm;
char ifname[IFNAMSIZ];
struct nlattr *tb[IFLA_MAX+1]; struct nlattr *tb[IFLA_MAX+1];
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct sk_buff *nskb; struct sk_buff *nskb;
...@@ -1163,19 +1162,23 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ...@@ -1163,19 +1162,23 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (err < 0) if (err < 0)
return err; return err;
if (tb[IFLA_IFNAME])
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
ifm = nlmsg_data(nlh); ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0) { if (ifm->ifi_index > 0)
dev = dev_get_by_index(net, ifm->ifi_index); dev = __dev_get_by_index(net, ifm->ifi_index);
if (dev == NULL) else if (tb[IFLA_IFNAME])
return -ENODEV; dev = __dev_get_by_name(net, ifname);
} else else
return -EINVAL; return -EINVAL;
if (dev == NULL)
return -ENODEV;
nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
if (nskb == NULL) { if (nskb == NULL)
err = -ENOBUFS; return -ENOBUFS;
goto errout;
}
err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
nlh->nlmsg_seq, 0, 0); nlh->nlmsg_seq, 0, 0);
...@@ -1183,11 +1186,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ...@@ -1183,11 +1186,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
/* -EMSGSIZE implies BUG in if_nlmsg_size */ /* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE); WARN_ON(err == -EMSGSIZE);
kfree_skb(nskb); kfree_skb(nskb);
goto errout; } else
} err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
errout:
dev_put(dev);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment