cfg80211: make wdev_list accessible to drivers
[cascardo/linux.git] / net / ipv4 / udp_diag.c
index df1966f..3d5ccf4 100644 (file)
@@ -36,10 +36,11 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
                        const struct inet_diag_req_v2 *req)
 {
        int err = -EINVAL;
-       struct sock *sk;
+       struct sock *sk = NULL;
        struct sk_buff *rep;
        struct net *net = sock_net(in_skb->sk);
 
+       rcu_read_lock();
        if (req->sdiag_family == AF_INET)
                sk = __udp4_lib_lookup(net,
                                req->id.idiag_src[0], req->id.idiag_sport,
@@ -54,9 +55,9 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
                                req->id.idiag_dport,
                                req->id.idiag_if, tbl, NULL);
 #endif
-       else
-               goto out_nosk;
-
+       if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+               sk = NULL;
+       rcu_read_unlock();
        err = -ENOENT;
        if (!sk)
                goto out_nosk;
@@ -96,24 +97,23 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb,
                     struct netlink_callback *cb,
                     const struct inet_diag_req_v2 *r, struct nlattr *bc)
 {
-       int num, s_num, slot, s_slot;
        struct net *net = sock_net(skb->sk);
+       int num, s_num, slot, s_slot;
 
        s_slot = cb->args[0];
        num = s_num = cb->args[1];
 
        for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) {
-               struct sock *sk;
-               struct hlist_nulls_node *node;
                struct udp_hslot *hslot = &table->hash[slot];
+               struct sock *sk;
 
                num = 0;
 
-               if (hlist_nulls_empty(&hslot->head))
+               if (hlist_empty(&hslot->head))
                        continue;
 
                spin_lock_bh(&hslot->lock);
-               sk_nulls_for_each(sk, node, &hslot->head) {
+               sk_for_each(sk, &hslot->head) {
                        struct inet_sock *inet = inet_sk(sk);
 
                        if (!net_eq(sock_net(sk), net))