aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccid.h18
-rw-r--r--net/dccp/ccids/ccid3.c27
-rw-r--r--net/dccp/diag.c26
3 files changed, 70 insertions, 1 deletions
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index c6767b282244..962f1e9e2f7e 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -50,6 +50,10 @@ struct ccid {
50 struct sk_buff *skb, int len); 50 struct sk_buff *skb, int len);
51 void (*ccid_hc_tx_packet_sent)(struct sock *sk, int more, 51 void (*ccid_hc_tx_packet_sent)(struct sock *sk, int more,
52 int len); 52 int len);
53 void (*ccid_hc_rx_get_info)(struct sock *sk,
54 struct tcp_info *info);
55 void (*ccid_hc_tx_get_info)(struct sock *sk,
56 struct tcp_info *info);
53}; 57};
54 58
55extern int ccid_register(struct ccid *ccid); 59extern int ccid_register(struct ccid *ccid);
@@ -159,4 +163,18 @@ static inline void ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
159 if (ccid->ccid_hc_rx_insert_options != NULL) 163 if (ccid->ccid_hc_rx_insert_options != NULL)
160 ccid->ccid_hc_rx_insert_options(sk, skb); 164 ccid->ccid_hc_rx_insert_options(sk, skb);
161} 165}
166
167static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
168 struct tcp_info *info)
169{
170 if (ccid->ccid_hc_rx_get_info != NULL)
171 ccid->ccid_hc_rx_get_info(sk, info);
172}
173
174static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk,
175 struct tcp_info *info)
176{
177 if (ccid->ccid_hc_tx_get_info != NULL)
178 ccid->ccid_hc_tx_get_info(sk, info);
179}
162#endif /* _CCID_H */ 180#endif /* _CCID_H */
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 48c36afa4934..fe4cc85f5bcc 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -2020,6 +2020,31 @@ static void ccid3_hc_rx_exit(struct sock *sk)
2020 dp->dccps_hc_rx_ccid_private = NULL; 2020 dp->dccps_hc_rx_ccid_private = NULL;
2021} 2021}
2022 2022
2023static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
2024{
2025 const struct dccp_sock *dp = dccp_sk(sk);
2026 const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
2027
2028 if (hcrx == NULL)
2029 return;
2030
2031 info->tcpi_ca_state = hcrx->ccid3hcrx_state;
2032 info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
2033 info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt;
2034}
2035
2036static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
2037{
2038 const struct dccp_sock *dp = dccp_sk(sk);
2039 const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
2040
2041 if (hctx == NULL)
2042 return;
2043
2044 info->tcpi_rto = hctx->ccid3hctx_t_rto;
2045 info->tcpi_rtt = hctx->ccid3hctx_rtt;
2046}
2047
2023static struct ccid ccid3 = { 2048static struct ccid ccid3 = {
2024 .ccid_id = 3, 2049 .ccid_id = 3,
2025 .ccid_name = "ccid3", 2050 .ccid_name = "ccid3",
@@ -2037,6 +2062,8 @@ static struct ccid ccid3 = {
2037 .ccid_hc_rx_exit = ccid3_hc_rx_exit, 2062 .ccid_hc_rx_exit = ccid3_hc_rx_exit,
2038 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, 2063 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
2039 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv, 2064 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv,
2065 .ccid_hc_rx_get_info = ccid3_hc_rx_get_info,
2066 .ccid_hc_tx_get_info = ccid3_hc_tx_get_info,
2040}; 2067};
2041 2068
2042module_param(ccid3_debug, int, 0444); 2069module_param(ccid3_debug, int, 0444);
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index 0b10c176c35a..f675d8e642d3 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -14,19 +14,43 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/inet_diag.h> 15#include <linux/inet_diag.h>
16 16
17#include "ccid.h"
17#include "dccp.h" 18#include "dccp.h"
18 19
20static void dccp_get_info(struct sock *sk, struct tcp_info *info)
21{
22 struct dccp_sock *dp = dccp_sk(sk);
23 const struct inet_connection_sock *icsk = inet_csk(sk);
24
25 memset(info, 0, sizeof(*info));
26
27 info->tcpi_state = sk->sk_state;
28 info->tcpi_retransmits = icsk->icsk_retransmits;
29 info->tcpi_probes = icsk->icsk_probes_out;
30 info->tcpi_backoff = icsk->icsk_backoff;
31 info->tcpi_pmtu = dp->dccps_pmtu_cookie;
32
33 if (dp->dccps_options.dccpo_send_ack_vector)
34 info->tcpi_options |= TCPI_OPT_SACK;
35
36 ccid_hc_rx_get_info(dp->dccps_hc_rx_ccid, sk, info);
37 ccid_hc_tx_get_info(dp->dccps_hc_tx_ccid, sk, info);
38}
39
19static void dccp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, 40static void dccp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
20 void *_info) 41 void *_info)
21{ 42{
22 r->idiag_rqueue = r->idiag_wqueue = 0; 43 r->idiag_rqueue = r->idiag_wqueue = 0;
44
45 if (_info != NULL)
46 dccp_get_info(sk, _info);
23} 47}
24 48
25static struct inet_diag_handler dccp_diag_handler = { 49static struct inet_diag_handler dccp_diag_handler = {
26 .idiag_hashinfo = &dccp_hashinfo, 50 .idiag_hashinfo = &dccp_hashinfo,
27 .idiag_get_info = dccp_diag_get_info, 51 .idiag_get_info = dccp_diag_get_info,
28 .idiag_type = DCCPDIAG_GETSOCK, 52 .idiag_type = DCCPDIAG_GETSOCK,
29 .idiag_info_size = 0, 53 .idiag_info_size = sizeof(struct tcp_info),
30}; 54};
31 55
32static int __init dccp_diag_init(void) 56static int __init dccp_diag_init(void)