Merge tag 'for-linus-4.4-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[deliverable/linux.git] / net / ipv4 / inet_diag.c
index 0ac1d68dc8a6b3fd5c465cf38e8ad5bdc9f145dd..ab9f8a66615d0872b586a0c2745196c58f6026be 100644 (file)
@@ -730,91 +730,21 @@ static void twsk_build_assert(void)
 #endif
 }
 
-static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
-                              struct netlink_callback *cb,
-                              const struct inet_diag_req_v2 *r,
-                              const struct nlattr *bc)
-{
-       struct inet_connection_sock *icsk = inet_csk(sk);
-       struct inet_sock *inet = inet_sk(sk);
-       struct inet_diag_entry entry;
-       int j, s_j, reqnum, s_reqnum;
-       struct listen_sock *lopt;
-       int err = 0;
-
-       s_j = cb->args[3];
-       s_reqnum = cb->args[4];
-
-       if (s_j > 0)
-               s_j--;
-
-       entry.family = sk->sk_family;
-
-       spin_lock(&icsk->icsk_accept_queue.syn_wait_lock);
-
-       lopt = icsk->icsk_accept_queue.listen_opt;
-       if (!lopt || !reqsk_queue_len(&icsk->icsk_accept_queue))
-               goto out;
-
-       if (bc) {
-               entry.sport = inet->inet_num;
-               entry.userlocks = sk->sk_userlocks;
-       }
-
-       for (j = s_j; j < lopt->nr_table_entries; j++) {
-               struct request_sock *req, *head = lopt->syn_table[j];
-
-               reqnum = 0;
-               for (req = head; req; reqnum++, req = req->dl_next) {
-                       struct inet_request_sock *ireq = inet_rsk(req);
-
-                       if (reqnum < s_reqnum)
-                               continue;
-                       if (r->id.idiag_dport != ireq->ir_rmt_port &&
-                           r->id.idiag_dport)
-                               continue;
-
-                       if (bc) {
-                               /* Note: entry.sport and entry.userlocks are already set */
-                               entry_fill_addrs(&entry, req_to_sk(req));
-                               entry.dport = ntohs(ireq->ir_rmt_port);
-
-                               if (!inet_diag_bc_run(bc, &entry))
-                                       continue;
-                       }
-
-                       err = inet_req_diag_fill(req_to_sk(req), skb,
-                                                NETLINK_CB(cb->skb).portid,
-                                                cb->nlh->nlmsg_seq,
-                                                NLM_F_MULTI, cb->nlh);
-                       if (err < 0) {
-                               cb->args[3] = j + 1;
-                               cb->args[4] = reqnum;
-                               goto out;
-                       }
-               }
-
-               s_reqnum = 0;
-       }
-
-out:
-       spin_unlock(&icsk->icsk_accept_queue.syn_wait_lock);
-
-       return err;
-}
-
 void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
                         struct netlink_callback *cb,
                         const struct inet_diag_req_v2 *r, struct nlattr *bc)
 {
        struct net *net = sock_net(skb->sk);
        int i, num, s_i, s_num;
+       u32 idiag_states = r->idiag_states;
 
+       if (idiag_states & TCPF_SYN_RECV)
+               idiag_states |= TCPF_NEW_SYN_RECV;
        s_i = cb->args[1];
        s_num = num = cb->args[2];
 
        if (cb->args[0] == 0) {
-               if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV)))
+               if (!(idiag_states & TCPF_LISTEN))
                        goto skip_listen_ht;
 
                for (i = s_i; i < INET_LHTABLE_SIZE; i++) {
@@ -844,21 +774,11 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
                                    r->id.idiag_sport)
                                        goto next_listen;
 
-                               if (!(r->idiag_states & TCPF_LISTEN) ||
-                                   r->id.idiag_dport ||
+                               if (r->id.idiag_dport ||
                                    cb->args[3] > 0)
-                                       goto syn_recv;
-
-                               if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
-                                       spin_unlock_bh(&ilb->lock);
-                                       goto done;
-                               }
-
-syn_recv:
-                               if (!(r->idiag_states & TCPF_SYN_RECV))
                                        goto next_listen;
 
-                               if (inet_diag_dump_reqs(skb, sk, cb, r, bc) < 0) {
+                               if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
                                        spin_unlock_bh(&ilb->lock);
                                        goto done;
                                }
@@ -879,7 +799,7 @@ skip_listen_ht:
                s_i = num = s_num = 0;
        }
 
-       if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
+       if (!(idiag_states & ~TCPF_LISTEN))
                goto out;
 
        for (i = s_i; i <= hashinfo->ehash_mask; i++) {
@@ -906,7 +826,7 @@ skip_listen_ht:
                                goto next_normal;
                        state = (sk->sk_state == TCP_TIME_WAIT) ?
                                inet_twsk(sk)->tw_substate : sk->sk_state;
-                       if (!(r->idiag_states & (1 << state)))
+                       if (!(idiag_states & (1 << state)))
                                goto next_normal;
                        if (r->sdiag_family != AF_UNSPEC &&
                            sk->sk_family != r->sdiag_family)
This page took 0.040097 seconds and 5 git commands to generate.