diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-10-21 06:59:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-22 07:33:48 -0400 |
commit | a3d1289126e7b14307074b76bf1677015ea5036f (patch) | |
tree | 27b60edc21b35d9850daf9875f285c1f814e1939 /net/core | |
parent | a61f80261306ad11d9c8a453307a56417cfeae03 (diff) |
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: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/rtnetlink.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index eb42873f2a3a..ba13b0974a7b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -910,9 +910,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
910 | err = -EINVAL; | 910 | err = -EINVAL; |
911 | ifm = nlmsg_data(nlh); | 911 | ifm = nlmsg_data(nlh); |
912 | if (ifm->ifi_index > 0) | 912 | if (ifm->ifi_index > 0) |
913 | dev = dev_get_by_index(net, ifm->ifi_index); | 913 | dev = __dev_get_by_index(net, ifm->ifi_index); |
914 | else if (tb[IFLA_IFNAME]) | 914 | else if (tb[IFLA_IFNAME]) |
915 | dev = dev_get_by_name(net, ifname); | 915 | dev = __dev_get_by_name(net, ifname); |
916 | else | 916 | else |
917 | goto errout; | 917 | goto errout; |
918 | 918 | ||
@@ -922,11 +922,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
922 | } | 922 | } |
923 | 923 | ||
924 | if ((err = validate_linkmsg(dev, tb)) < 0) | 924 | if ((err = validate_linkmsg(dev, tb)) < 0) |
925 | goto errout_dev; | 925 | goto errout; |
926 | 926 | ||
927 | err = do_setlink(dev, ifm, tb, ifname, 0); | 927 | err = do_setlink(dev, ifm, tb, ifname, 0); |
928 | errout_dev: | ||
929 | dev_put(dev); | ||
930 | errout: | 928 | errout: |
931 | return err; | 929 | return err; |
932 | } | 930 | } |
@@ -1154,6 +1152,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1154 | { | 1152 | { |
1155 | struct net *net = sock_net(skb->sk); | 1153 | struct net *net = sock_net(skb->sk); |
1156 | struct ifinfomsg *ifm; | 1154 | struct ifinfomsg *ifm; |
1155 | char ifname[IFNAMSIZ]; | ||
1157 | struct nlattr *tb[IFLA_MAX+1]; | 1156 | struct nlattr *tb[IFLA_MAX+1]; |
1158 | struct net_device *dev = NULL; | 1157 | struct net_device *dev = NULL; |
1159 | struct sk_buff *nskb; | 1158 | struct sk_buff *nskb; |
@@ -1163,19 +1162,23 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1163 | if (err < 0) | 1162 | if (err < 0) |
1164 | return err; | 1163 | return err; |
1165 | 1164 | ||
1165 | if (tb[IFLA_IFNAME]) | ||
1166 | nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); | ||
1167 | |||
1166 | ifm = nlmsg_data(nlh); | 1168 | ifm = nlmsg_data(nlh); |
1167 | if (ifm->ifi_index > 0) { | 1169 | if (ifm->ifi_index > 0) |
1168 | dev = dev_get_by_index(net, ifm->ifi_index); | 1170 | dev = __dev_get_by_index(net, ifm->ifi_index); |
1169 | if (dev == NULL) | 1171 | else if (tb[IFLA_IFNAME]) |
1170 | return -ENODEV; | 1172 | dev = __dev_get_by_name(net, ifname); |
1171 | } else | 1173 | else |
1172 | return -EINVAL; | 1174 | return -EINVAL; |
1173 | 1175 | ||
1176 | if (dev == NULL) | ||
1177 | return -ENODEV; | ||
1178 | |||
1174 | nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); | 1179 | nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); |
1175 | if (nskb == NULL) { | 1180 | if (nskb == NULL) |
1176 | err = -ENOBUFS; | 1181 | return -ENOBUFS; |
1177 | goto errout; | ||
1178 | } | ||
1179 | 1182 | ||
1180 | err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, | 1183 | err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, |
1181 | nlh->nlmsg_seq, 0, 0); | 1184 | nlh->nlmsg_seq, 0, 0); |
@@ -1183,11 +1186,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1183 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ | 1186 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ |
1184 | WARN_ON(err == -EMSGSIZE); | 1187 | WARN_ON(err == -EMSGSIZE); |
1185 | kfree_skb(nskb); | 1188 | kfree_skb(nskb); |
1186 | goto errout; | 1189 | } else |
1187 | } | 1190 | err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid); |
1188 | err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid); | ||
1189 | errout: | ||
1190 | dev_put(dev); | ||
1191 | 1191 | ||
1192 | return err; | 1192 | return err; |
1193 | } | 1193 | } |