diff options
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 31 | 
1 files changed, 30 insertions, 1 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8c5cd9efebbc..f1377f2a0472 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c  | |||
| @@ -252,6 +252,7 @@ | |||
| 252 | #include <linux/types.h> | 252 | #include <linux/types.h> | 
| 253 | #include <linux/fcntl.h> | 253 | #include <linux/fcntl.h> | 
| 254 | #include <linux/poll.h> | 254 | #include <linux/poll.h> | 
| 255 | #include <linux/inet_diag.h> | ||
| 255 | #include <linux/init.h> | 256 | #include <linux/init.h> | 
| 256 | #include <linux/fs.h> | 257 | #include <linux/fs.h> | 
| 257 | #include <linux/skbuff.h> | 258 | #include <linux/skbuff.h> | 
| @@ -401,6 +402,7 @@ void tcp_init_sock(struct sock *sk) | |||
| 401 | tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; | 402 | tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; | 
| 402 | tp->snd_cwnd_clamp = ~0; | 403 | tp->snd_cwnd_clamp = ~0; | 
| 403 | tp->mss_cache = TCP_MSS_DEFAULT; | 404 | tp->mss_cache = TCP_MSS_DEFAULT; | 
| 405 | u64_stats_init(&tp->syncp); | ||
| 404 | 406 | ||
| 405 | tp->reordering = sysctl_tcp_reordering; | 407 | tp->reordering = sysctl_tcp_reordering; | 
| 406 | tcp_enable_early_retrans(tp); | 408 | tcp_enable_early_retrans(tp); | 
| @@ -2592,11 +2594,12 @@ EXPORT_SYMBOL(compat_tcp_setsockopt); | |||
| 2592 | #endif | 2594 | #endif | 
| 2593 | 2595 | ||
| 2594 | /* Return information about state of tcp endpoint in API format. */ | 2596 | /* Return information about state of tcp endpoint in API format. */ | 
| 2595 | void tcp_get_info(const struct sock *sk, struct tcp_info *info) | 2597 | void tcp_get_info(struct sock *sk, struct tcp_info *info) | 
| 2596 | { | 2598 | { | 
| 2597 | const struct tcp_sock *tp = tcp_sk(sk); | 2599 | const struct tcp_sock *tp = tcp_sk(sk); | 
| 2598 | const struct inet_connection_sock *icsk = inet_csk(sk); | 2600 | const struct inet_connection_sock *icsk = inet_csk(sk); | 
| 2599 | u32 now = tcp_time_stamp; | 2601 | u32 now = tcp_time_stamp; | 
| 2602 | unsigned int start; | ||
| 2600 | u32 rate; | 2603 | u32 rate; | 
| 2601 | 2604 | ||
| 2602 | memset(info, 0, sizeof(*info)); | 2605 | memset(info, 0, sizeof(*info)); | 
| @@ -2663,6 +2666,12 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) | |||
| 2663 | 2666 | ||
| 2664 | rate = READ_ONCE(sk->sk_max_pacing_rate); | 2667 | rate = READ_ONCE(sk->sk_max_pacing_rate); | 
| 2665 | info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL; | 2668 | info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL; | 
| 2669 | |||
| 2670 | do { | ||
| 2671 | start = u64_stats_fetch_begin_irq(&tp->syncp); | ||
| 2672 | info->tcpi_bytes_acked = tp->bytes_acked; | ||
| 2673 | info->tcpi_bytes_received = tp->bytes_received; | ||
| 2674 | } while (u64_stats_fetch_retry_irq(&tp->syncp, start)); | ||
| 2666 | } | 2675 | } | 
| 2667 | EXPORT_SYMBOL_GPL(tcp_get_info); | 2676 | EXPORT_SYMBOL_GPL(tcp_get_info); | 
| 2668 | 2677 | ||
| @@ -2734,6 +2743,26 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
| 2734 | return -EFAULT; | 2743 | return -EFAULT; | 
| 2735 | return 0; | 2744 | return 0; | 
| 2736 | } | 2745 | } | 
| 2746 | case TCP_CC_INFO: { | ||
| 2747 | const struct tcp_congestion_ops *ca_ops; | ||
| 2748 | union tcp_cc_info info; | ||
| 2749 | size_t sz = 0; | ||
| 2750 | int attr; | ||
| 2751 | |||
| 2752 | if (get_user(len, optlen)) | ||
| 2753 | return -EFAULT; | ||
| 2754 | |||
| 2755 | ca_ops = icsk->icsk_ca_ops; | ||
| 2756 | if (ca_ops && ca_ops->get_info) | ||
| 2757 | sz = ca_ops->get_info(sk, ~0U, &attr, &info); | ||
| 2758 | |||
| 2759 | len = min_t(unsigned int, len, sz); | ||
| 2760 | if (put_user(len, optlen)) | ||
| 2761 | return -EFAULT; | ||
| 2762 | if (copy_to_user(optval, &info, len)) | ||
| 2763 | return -EFAULT; | ||
| 2764 | return 0; | ||
| 2765 | } | ||
| 2737 | case TCP_QUICKACK: | 2766 | case TCP_QUICKACK: | 
| 2738 | val = !icsk->icsk_ack.pingpong; | 2767 | val = !icsk->icsk_ack.pingpong; | 
| 2739 | break; | 2768 | break; | 
