diff options
Diffstat (limited to 'net/sctp/sctp_diag.c')
-rw-r--r-- | net/sctp/sctp_diag.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c index f69edcf219e5..f3508aa75815 100644 --- a/net/sctp/sctp_diag.c +++ b/net/sctp/sctp_diag.c | |||
@@ -13,6 +13,7 @@ static void inet_diag_msg_sctpasoc_fill(struct inet_diag_msg *r, | |||
13 | { | 13 | { |
14 | union sctp_addr laddr, paddr; | 14 | union sctp_addr laddr, paddr; |
15 | struct dst_entry *dst; | 15 | struct dst_entry *dst; |
16 | struct timer_list *t3_rtx = &asoc->peer.primary_path->T3_rtx_timer; | ||
16 | 17 | ||
17 | laddr = list_entry(asoc->base.bind_addr.address_list.next, | 18 | laddr = list_entry(asoc->base.bind_addr.address_list.next, |
18 | struct sctp_sockaddr_entry, list)->a; | 19 | struct sctp_sockaddr_entry, list)->a; |
@@ -40,10 +41,15 @@ static void inet_diag_msg_sctpasoc_fill(struct inet_diag_msg *r, | |||
40 | } | 41 | } |
41 | 42 | ||
42 | r->idiag_state = asoc->state; | 43 | r->idiag_state = asoc->state; |
43 | r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX; | 44 | if (timer_pending(t3_rtx)) { |
44 | r->idiag_retrans = asoc->rtx_data_chunks; | 45 | r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX; |
45 | r->idiag_expires = jiffies_to_msecs( | 46 | r->idiag_retrans = asoc->rtx_data_chunks; |
46 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] - jiffies); | 47 | r->idiag_expires = jiffies_to_msecs(t3_rtx->expires - jiffies); |
48 | } else { | ||
49 | r->idiag_timer = 0; | ||
50 | r->idiag_retrans = 0; | ||
51 | r->idiag_expires = 0; | ||
52 | } | ||
47 | } | 53 | } |
48 | 54 | ||
49 | static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb, | 55 | static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb, |
@@ -350,7 +356,7 @@ static int sctp_ep_dump(struct sctp_endpoint *ep, void *p) | |||
350 | if (cb->args[4] < cb->args[1]) | 356 | if (cb->args[4] < cb->args[1]) |
351 | goto next; | 357 | goto next; |
352 | 358 | ||
353 | if ((r->idiag_states & ~TCPF_LISTEN) && !list_empty(&ep->asocs)) | 359 | if (!(r->idiag_states & TCPF_LISTEN) && !list_empty(&ep->asocs)) |
354 | goto next; | 360 | goto next; |
355 | 361 | ||
356 | if (r->sdiag_family != AF_UNSPEC && | 362 | if (r->sdiag_family != AF_UNSPEC && |
@@ -418,11 +424,13 @@ static int sctp_diag_dump_one(struct sk_buff *in_skb, | |||
418 | paddr.v4.sin_family = AF_INET; | 424 | paddr.v4.sin_family = AF_INET; |
419 | } else { | 425 | } else { |
420 | laddr.v6.sin6_port = req->id.idiag_sport; | 426 | laddr.v6.sin6_port = req->id.idiag_sport; |
421 | memcpy(&laddr.v6.sin6_addr, req->id.idiag_src, 64); | 427 | memcpy(&laddr.v6.sin6_addr, req->id.idiag_src, |
428 | sizeof(laddr.v6.sin6_addr)); | ||
422 | laddr.v6.sin6_family = AF_INET6; | 429 | laddr.v6.sin6_family = AF_INET6; |
423 | 430 | ||
424 | paddr.v6.sin6_port = req->id.idiag_dport; | 431 | paddr.v6.sin6_port = req->id.idiag_dport; |
425 | memcpy(&paddr.v6.sin6_addr, req->id.idiag_dst, 64); | 432 | memcpy(&paddr.v6.sin6_addr, req->id.idiag_dst, |
433 | sizeof(paddr.v6.sin6_addr)); | ||
426 | paddr.v6.sin6_family = AF_INET6; | 434 | paddr.v6.sin6_family = AF_INET6; |
427 | } | 435 | } |
428 | 436 | ||
@@ -465,7 +473,7 @@ skip: | |||
465 | * 3 : to mark if we have dumped the ep info of the current asoc | 473 | * 3 : to mark if we have dumped the ep info of the current asoc |
466 | * 4 : to work as a temporary variable to traversal list | 474 | * 4 : to work as a temporary variable to traversal list |
467 | */ | 475 | */ |
468 | if (!(idiag_states & ~TCPF_LISTEN)) | 476 | if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE))) |
469 | goto done; | 477 | goto done; |
470 | sctp_for_each_transport(sctp_tsp_dump, net, cb->args[2], &commp); | 478 | sctp_for_each_transport(sctp_tsp_dump, net, cb->args[2], &commp); |
471 | done: | 479 | done: |