Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[pandora-kernel.git] / net / core / rtnetlink.c
index d7c4bb4..d2ba259 100644 (file)
@@ -1007,10 +1007,11 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
        s_h = cb->args[0];
        s_idx = cb->args[1];
 
+       rcu_read_lock();
        for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
                idx = 0;
                head = &net->dev_index_head[h];
-               hlist_for_each_entry(dev, node, head, index_hlist) {
+               hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
                        if (idx < s_idx)
                                goto cont;
                        if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
@@ -1023,6 +1024,7 @@ cont:
                }
        }
 out:
+       rcu_read_unlock();
        cb->args[1] = idx;
        cb->args[0] = h;
 
@@ -1499,6 +1501,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        char ifname[IFNAMSIZ];
        struct nlattr *tb[IFLA_MAX+1];
        int err;
+       LIST_HEAD(list_kill);
 
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
        if (err < 0)
@@ -1522,7 +1525,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        if (!ops)
                return -EOPNOTSUPP;
 
-       ops->dellink(dev, NULL);
+       ops->dellink(dev, &list_kill);
+       unregister_netdevice_many(&list_kill);
+       list_del(&list_kill);
        return 0;
 }
 
@@ -1570,12 +1575,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
        dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
        dev->real_num_tx_queues = real_num_queues;
 
-       if (strchr(dev->name, '%')) {
-               err = dev_alloc_name(dev, dev->name);
-               if (err < 0)
-                       goto err_free;
-       }
-
        if (tb[IFLA_MTU])
                dev->mtu = nla_get_u32(tb[IFLA_MTU]);
        if (tb[IFLA_ADDRESS])
@@ -1595,8 +1594,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
 
        return dev;
 
-err_free:
-       free_netdev(dev);
 err:
        return ERR_PTR(err);
 }
@@ -1879,7 +1876,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        int min_len;
        int family;
        int type;
-       int err;
 
        type = nlh->nlmsg_type;
        if (type > RTM_MAX)
@@ -1906,11 +1902,8 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                if (dumpit == NULL)
                        return -EOPNOTSUPP;
 
-               __rtnl_unlock();
                rtnl = net->rtnl;
-               err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
-               rtnl_lock();
-               return err;
+               return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
        }
 
        memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
@@ -1980,7 +1973,7 @@ static int __net_init rtnetlink_net_init(struct net *net)
 {
        struct sock *sk;
        sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
-                                  rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
+                                  rtnetlink_rcv, NULL, THIS_MODULE);
        if (!sk)
                return -ENOMEM;
        net->rtnl = sk;