aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNeal Cardwell <ncardwell@google.com>2014-01-10 15:34:45 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-14 01:35:46 -0500
commit70315d22d3c7383f9a508d0aab21e2eb35b2303a (patch)
tree434e5ce293a26e477458c771be03d194551b88da /net
parent9ef9730ba84d4021a27d3a1679fd50f9bac0e0e7 (diff)
inet_diag: fix inet_diag_dump_icsk() to use correct state for timewait sockets
Fix inet_diag_dump_icsk() to reflect the fact that both TCP_TIME_WAIT and TCP_FIN_WAIT2 connections are represented by inet_timewait_sock (not just TIME_WAIT), and for such sockets the tw_substate field holds the real state, which can be either TCP_TIME_WAIT or TCP_FIN_WAIT2. This brings the inet_diag state-matching code in line with the field it uses to populate idiag_state. This is also analogous to the info exported in /proc/net/tcp, where get_tcp4_sock() exports sk->sk_state and get_timewait4_sock() exports tw->tw_substate. Before fixing this, (a) neither "ss -nemoi" nor "ss -nemoi state fin-wait-2" would return a socket in TCP_FIN_WAIT2; and (b) "ss -nemoi state time-wait" would also return sockets in state TCP_FIN_WAIT2. This is an old bug that predates 05dbc7b ("tcp/dccp: remove twchain"). Signed-off-by: Neal Cardwell <ncardwell@google.com> Cc: Eric Dumazet <edumazet@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/inet_diag.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index a0f52dac8940..e34dccbc4d70 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -930,12 +930,15 @@ skip_listen_ht:
930 spin_lock_bh(lock); 930 spin_lock_bh(lock);
931 sk_nulls_for_each(sk, node, &head->chain) { 931 sk_nulls_for_each(sk, node, &head->chain) {
932 int res; 932 int res;
933 int state;
933 934
934 if (!net_eq(sock_net(sk), net)) 935 if (!net_eq(sock_net(sk), net))
935 continue; 936 continue;
936 if (num < s_num) 937 if (num < s_num)
937 goto next_normal; 938 goto next_normal;
938 if (!(r->idiag_states & (1 << sk->sk_state))) 939 state = (sk->sk_state == TCP_TIME_WAIT) ?
940 inet_twsk(sk)->tw_substate : sk->sk_state;
941 if (!(r->idiag_states & (1 << state)))
939 goto next_normal; 942 goto next_normal;
940 if (r->sdiag_family != AF_UNSPEC && 943 if (r->sdiag_family != AF_UNSPEC &&
941 sk->sk_family != r->sdiag_family) 944 sk->sk_family != r->sdiag_family)