aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-10-21 06:59:31 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-22 07:33:48 -0400
commita3d1289126e7b14307074b76bf1677015ea5036f (patch)
tree27b60edc21b35d9850daf9875f285c1f814e1939 /net/core
parenta61f80261306ad11d9c8a453307a56417cfeae03 (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.c38
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);
928errout_dev:
929 dev_put(dev);
930errout: 928errout:
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);
1189errout:
1190 dev_put(dev);
1191 1191
1192 return err; 1192 return err;
1193} 1193}