Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

inet_diag: report delayed ack timer information

inet_sk_diag_fill() populates r->idiag_timer with the following
precedence order:

1 - Retransmit timer.
4 - Probe0 timer.
2 - Keepalive timer.

This patch adds a new value, last in the list, if other timers
are not active.

5 - Delayed ACK timer.

A corresponding iproute2 patch will follow to replace "unknown"
with "delack":

ESTAB 10 0 [2002:a05:6830:1f86::]:12875 [2002:a05:6830:1f85::]:50438

timer:(unknown,003ms,0) ino:152178 sk:3004 cgroup:unreachable:189 <->

skmem:(r1344,rb12780520,t0,tb262144,f2752,w0,o250,bl0,d0) ts usec_ts
...

Also add the following enum in uapi/linux/inet_diag.h
as suggested by David Ahern.

enum {
IDIAG_TIMER_OFF,
IDIAG_TIMER_ON,
IDIAG_TIMER_KEEPALIVE,
IDIAG_TIMER_TIMEWAIT,
IDIAG_TIMER_PROBE0,
IDIAG_TIMER_DELACK,
};

Neal Cardwell suggested to test for ICSK_ACK_TIMER:
inet_csk_clear_xmit_timer() does not call sk_stop_timer()
because INET_CSK_CLEAR_TIMERS is unset.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Neal Cardwell <ncardwell@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260305114829.2163276-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
c698f5cc db299707

+20 -6
+9
include/uapi/linux/inet_diag.h
··· 129 129 __u32 idiag_inode; 130 130 }; 131 131 132 + enum { 133 + IDIAG_TIMER_OFF, 134 + IDIAG_TIMER_ON, 135 + IDIAG_TIMER_KEEPALIVE, 136 + IDIAG_TIMER_TIMEWAIT, 137 + IDIAG_TIMER_PROBE0, 138 + IDIAG_TIMER_DELACK, 139 + }; 140 + 132 141 /* Extensions */ 133 142 134 143 enum {
+9 -4
net/ipv4/inet_diag.c
··· 241 241 242 242 inet_diag_msg_common_fill(r, sk); 243 243 r->idiag_state = sk->sk_state; 244 - r->idiag_timer = 0; 244 + r->idiag_timer = IDIAG_TIMER_OFF; 245 245 r->idiag_retrans = 0; 246 246 r->idiag_expires = 0; 247 247 ··· 284 284 if (icsk_pending == ICSK_TIME_RETRANS || 285 285 icsk_pending == ICSK_TIME_REO_TIMEOUT || 286 286 icsk_pending == ICSK_TIME_LOSS_PROBE) { 287 - r->idiag_timer = 1; 287 + r->idiag_timer = IDIAG_TIMER_ON; 288 288 r->idiag_retrans = READ_ONCE(icsk->icsk_retransmits); 289 289 r->idiag_expires = 290 290 jiffies_delta_to_msecs(tcp_timeout_expires(sk) - jiffies); 291 291 } else if (icsk_pending == ICSK_TIME_PROBE0) { 292 - r->idiag_timer = 4; 292 + r->idiag_timer = IDIAG_TIMER_PROBE0; 293 293 r->idiag_retrans = READ_ONCE(icsk->icsk_probes_out); 294 294 r->idiag_expires = 295 295 jiffies_delta_to_msecs(tcp_timeout_expires(sk) - jiffies); 296 296 } else if (timer_pending(&icsk->icsk_keepalive_timer)) { 297 - r->idiag_timer = 2; 297 + r->idiag_timer = IDIAG_TIMER_KEEPALIVE; 298 298 r->idiag_retrans = READ_ONCE(icsk->icsk_probes_out); 299 299 r->idiag_expires = 300 300 jiffies_delta_to_msecs(icsk->icsk_keepalive_timer.expires - jiffies); 301 + } else if ((READ_ONCE(icsk->icsk_ack.pending) & ICSK_ACK_TIMER) && 302 + timer_pending(&icsk->icsk_delack_timer)) { 303 + r->idiag_timer = IDIAG_TIMER_DELACK; 304 + r->idiag_expires = 305 + jiffies_delta_to_msecs(icsk_delack_timeout(icsk) - jiffies); 301 306 } 302 307 303 308 if ((ext & (1 << (INET_DIAG_INFO - 1))) && handler->idiag_info_size) {
+2 -2
net/ipv4/tcp_diag.c
··· 212 212 r->idiag_retrans = 0; 213 213 214 214 r->idiag_state = READ_ONCE(tw->tw_substate); 215 - r->idiag_timer = 3; 215 + r->idiag_timer = IDIAG_TIMER_TIMEWAIT; 216 216 tmo = tw->tw_timer.expires - jiffies; 217 217 r->idiag_expires = jiffies_delta_to_msecs(tmo); 218 218 r->idiag_rqueue = 0; ··· 247 247 r = nlmsg_data(nlh); 248 248 inet_diag_msg_common_fill(r, sk); 249 249 r->idiag_state = TCP_SYN_RECV; 250 - r->idiag_timer = 1; 250 + r->idiag_timer = IDIAG_TIMER_ON; 251 251 r->idiag_retrans = READ_ONCE(reqsk->num_retrans); 252 252 253 253 BUILD_BUG_ON(offsetof(struct inet_request_sock, ir_cookie) !=