diff options
-rw-r--r-- | Documentation/networking/timestamping.txt | 10 | ||||
-rw-r--r-- | arch/alpha/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/frv/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/ia64/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/m32r/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/mips/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/mn10300/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/s390/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/xtensa/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | include/linux/tcp.h | 2 | ||||
-rw-r--r-- | include/uapi/asm-generic/socket.h | 2 | ||||
-rw-r--r-- | include/uapi/linux/net_tstamp.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/tcp.h | 8 | ||||
-rw-r--r-- | net/core/skbuff.c | 14 | ||||
-rw-r--r-- | net/core/sock.c | 7 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 20 | ||||
-rw-r--r-- | net/socket.c | 7 |
20 files changed, 90 insertions, 5 deletions
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index 671cccf0dcd2..96f50694a748 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt | |||
@@ -182,6 +182,16 @@ SOF_TIMESTAMPING_OPT_TSONLY: | |||
182 | the timestamp even if sysctl net.core.tstamp_allow_data is 0. | 182 | the timestamp even if sysctl net.core.tstamp_allow_data is 0. |
183 | This option disables SOF_TIMESTAMPING_OPT_CMSG. | 183 | This option disables SOF_TIMESTAMPING_OPT_CMSG. |
184 | 184 | ||
185 | SOF_TIMESTAMPING_OPT_STATS: | ||
186 | |||
187 | Optional stats that are obtained along with the transmit timestamps. | ||
188 | It must be used together with SOF_TIMESTAMPING_OPT_TSONLY. When the | ||
189 | transmit timestamp is available, the stats are available in a | ||
190 | separate control message of type SCM_TIMESTAMPING_OPT_STATS, as a | ||
191 | list of TLVs (struct nlattr) of types. These stats allow the | ||
192 | application to associate various transport layer stats with | ||
193 | the transmit timestamps, such as how long a certain block of | ||
194 | data was limited by peer's receiver window. | ||
185 | 195 | ||
186 | New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to | 196 | New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to |
187 | disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate | 197 | disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate |
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 9e46d6e656d9..afc901b7a6f6 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h | |||
@@ -97,4 +97,6 @@ | |||
97 | 97 | ||
98 | #define SO_CNX_ADVICE 53 | 98 | #define SO_CNX_ADVICE 53 |
99 | 99 | ||
100 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
101 | |||
100 | #endif /* _UAPI_ASM_SOCKET_H */ | 102 | #endif /* _UAPI_ASM_SOCKET_H */ |
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index afbc98f02d27..81e03530ed39 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h | |||
@@ -90,5 +90,7 @@ | |||
90 | 90 | ||
91 | #define SO_CNX_ADVICE 53 | 91 | #define SO_CNX_ADVICE 53 |
92 | 92 | ||
93 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
94 | |||
93 | #endif /* _ASM_SOCKET_H */ | 95 | #endif /* _ASM_SOCKET_H */ |
94 | 96 | ||
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 0018fad9039f..57feb0c1f7d7 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h | |||
@@ -99,4 +99,6 @@ | |||
99 | 99 | ||
100 | #define SO_CNX_ADVICE 53 | 100 | #define SO_CNX_ADVICE 53 |
101 | 101 | ||
102 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
103 | |||
102 | #endif /* _ASM_IA64_SOCKET_H */ | 104 | #endif /* _ASM_IA64_SOCKET_H */ |
diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index 5fe42fc7b6c5..5853f8e92c20 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h | |||
@@ -90,4 +90,6 @@ | |||
90 | 90 | ||
91 | #define SO_CNX_ADVICE 53 | 91 | #define SO_CNX_ADVICE 53 |
92 | 92 | ||
93 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
94 | |||
93 | #endif /* _ASM_M32R_SOCKET_H */ | 95 | #endif /* _ASM_M32R_SOCKET_H */ |
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 2027240aafbb..566ecdcb5b4b 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h | |||
@@ -108,4 +108,6 @@ | |||
108 | 108 | ||
109 | #define SO_CNX_ADVICE 53 | 109 | #define SO_CNX_ADVICE 53 |
110 | 110 | ||
111 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
112 | |||
111 | #endif /* _UAPI_ASM_SOCKET_H */ | 113 | #endif /* _UAPI_ASM_SOCKET_H */ |
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index 5129f23a9ee1..0e12527c4b0e 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h | |||
@@ -90,4 +90,6 @@ | |||
90 | 90 | ||
91 | #define SO_CNX_ADVICE 53 | 91 | #define SO_CNX_ADVICE 53 |
92 | 92 | ||
93 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
94 | |||
93 | #endif /* _ASM_SOCKET_H */ | 95 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 9c935d717df9..7a109b73ddf7 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h | |||
@@ -89,4 +89,6 @@ | |||
89 | 89 | ||
90 | #define SO_CNX_ADVICE 0x402E | 90 | #define SO_CNX_ADVICE 0x402E |
91 | 91 | ||
92 | #define SCM_TIMESTAMPING_OPT_STATS 0x402F | ||
93 | |||
92 | #endif /* _UAPI_ASM_SOCKET_H */ | 94 | #endif /* _UAPI_ASM_SOCKET_H */ |
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index 1672e3398270..44583a52f882 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h | |||
@@ -97,4 +97,6 @@ | |||
97 | 97 | ||
98 | #define SO_CNX_ADVICE 53 | 98 | #define SO_CNX_ADVICE 53 |
99 | 99 | ||
100 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
101 | |||
100 | #endif /* _ASM_POWERPC_SOCKET_H */ | 102 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 41b51c2f4f1b..b24a64cbfeb1 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h | |||
@@ -96,4 +96,6 @@ | |||
96 | 96 | ||
97 | #define SO_CNX_ADVICE 53 | 97 | #define SO_CNX_ADVICE 53 |
98 | 98 | ||
99 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
100 | |||
99 | #endif /* _ASM_SOCKET_H */ | 101 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 31aede3af088..a25dc32f5d6a 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h | |||
@@ -86,6 +86,8 @@ | |||
86 | 86 | ||
87 | #define SO_CNX_ADVICE 0x0037 | 87 | #define SO_CNX_ADVICE 0x0037 |
88 | 88 | ||
89 | #define SCM_TIMESTAMPING_OPT_STATS 0x0038 | ||
90 | |||
89 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | 91 | /* Security levels - as per NRL IPv6 - don't actually do anything */ |
90 | #define SO_SECURITY_AUTHENTICATION 0x5001 | 92 | #define SO_SECURITY_AUTHENTICATION 0x5001 |
91 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 | 93 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 |
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index 81435d995e11..9fdbe1fe0473 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h | |||
@@ -101,4 +101,6 @@ | |||
101 | 101 | ||
102 | #define SO_CNX_ADVICE 53 | 102 | #define SO_CNX_ADVICE 53 |
103 | 103 | ||
104 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
105 | |||
104 | #endif /* _XTENSA_SOCKET_H */ | 106 | #endif /* _XTENSA_SOCKET_H */ |
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index d5d3bd814338..00e0ee8f001f 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -428,4 +428,6 @@ static inline void tcp_saved_syn_free(struct tcp_sock *tp) | |||
428 | tp->saved_syn = NULL; | 428 | tp->saved_syn = NULL; |
429 | } | 429 | } |
430 | 430 | ||
431 | struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk); | ||
432 | |||
431 | #endif /* _LINUX_TCP_H */ | 433 | #endif /* _LINUX_TCP_H */ |
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 67d632f1743d..2c748ddad5f8 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h | |||
@@ -92,4 +92,6 @@ | |||
92 | 92 | ||
93 | #define SO_CNX_ADVICE 53 | 93 | #define SO_CNX_ADVICE 53 |
94 | 94 | ||
95 | #define SCM_TIMESTAMPING_OPT_STATS 54 | ||
96 | |||
95 | #endif /* __ASM_GENERIC_SOCKET_H */ | 97 | #endif /* __ASM_GENERIC_SOCKET_H */ |
diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h index 264e515de16f..464dcca5ed68 100644 --- a/include/uapi/linux/net_tstamp.h +++ b/include/uapi/linux/net_tstamp.h | |||
@@ -25,8 +25,9 @@ enum { | |||
25 | SOF_TIMESTAMPING_TX_ACK = (1<<9), | 25 | SOF_TIMESTAMPING_TX_ACK = (1<<9), |
26 | SOF_TIMESTAMPING_OPT_CMSG = (1<<10), | 26 | SOF_TIMESTAMPING_OPT_CMSG = (1<<10), |
27 | SOF_TIMESTAMPING_OPT_TSONLY = (1<<11), | 27 | SOF_TIMESTAMPING_OPT_TSONLY = (1<<11), |
28 | SOF_TIMESTAMPING_OPT_STATS = (1<<12), | ||
28 | 29 | ||
29 | SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TSONLY, | 30 | SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_STATS, |
30 | SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | | 31 | SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | |
31 | SOF_TIMESTAMPING_LAST | 32 | SOF_TIMESTAMPING_LAST |
32 | }; | 33 | }; |
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index 2863b661d6e1..c53de2691cec 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h | |||
@@ -220,6 +220,14 @@ struct tcp_info { | |||
220 | __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ | 220 | __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ |
221 | }; | 221 | }; |
222 | 222 | ||
223 | /* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */ | ||
224 | enum { | ||
225 | TCP_NLA_PAD, | ||
226 | TCP_NLA_BUSY, /* Time (usec) busy sending data */ | ||
227 | TCP_NLA_RWND_LIMITED, /* Time (usec) limited by receive window */ | ||
228 | TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer */ | ||
229 | }; | ||
230 | |||
223 | /* for TCP_MD5SIG socket option */ | 231 | /* for TCP_MD5SIG socket option */ |
224 | #define TCP_MD5SIG_MAXKEYLEN 80 | 232 | #define TCP_MD5SIG_MAXKEYLEN 80 |
225 | 233 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d1d1a5a5ad24..ea6fa954c7a0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3839,10 +3839,18 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3839 | if (!skb_may_tx_timestamp(sk, tsonly)) | 3839 | if (!skb_may_tx_timestamp(sk, tsonly)) |
3840 | return; | 3840 | return; |
3841 | 3841 | ||
3842 | if (tsonly) | 3842 | if (tsonly) { |
3843 | skb = alloc_skb(0, GFP_ATOMIC); | 3843 | #ifdef CONFIG_INET |
3844 | else | 3844 | if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) && |
3845 | sk->sk_protocol == IPPROTO_TCP && | ||
3846 | sk->sk_type == SOCK_STREAM) | ||
3847 | skb = tcp_get_timestamping_opt_stats(sk); | ||
3848 | else | ||
3849 | #endif | ||
3850 | skb = alloc_skb(0, GFP_ATOMIC); | ||
3851 | } else { | ||
3845 | skb = skb_clone(orig_skb, GFP_ATOMIC); | 3852 | skb = skb_clone(orig_skb, GFP_ATOMIC); |
3853 | } | ||
3846 | if (!skb) | 3854 | if (!skb) |
3847 | return; | 3855 | return; |
3848 | 3856 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 14e6145be33b..d8c7f8c877ca 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -854,6 +854,13 @@ set_rcvbuf: | |||
854 | sk->sk_tskey = 0; | 854 | sk->sk_tskey = 0; |
855 | } | 855 | } |
856 | } | 856 | } |
857 | |||
858 | if (val & SOF_TIMESTAMPING_OPT_STATS && | ||
859 | !(val & SOF_TIMESTAMPING_OPT_TSONLY)) { | ||
860 | ret = -EINVAL; | ||
861 | break; | ||
862 | } | ||
863 | |||
857 | sk->sk_tsflags = val; | 864 | sk->sk_tsflags = val; |
858 | if (val & SOF_TIMESTAMPING_RX_SOFTWARE) | 865 | if (val & SOF_TIMESTAMPING_RX_SOFTWARE) |
859 | sock_enable_timestamp(sk, | 866 | sock_enable_timestamp(sk, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index cdde20f49999..1149b48700a1 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2841,6 +2841,26 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
2841 | } | 2841 | } |
2842 | EXPORT_SYMBOL_GPL(tcp_get_info); | 2842 | EXPORT_SYMBOL_GPL(tcp_get_info); |
2843 | 2843 | ||
2844 | struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk) | ||
2845 | { | ||
2846 | const struct tcp_sock *tp = tcp_sk(sk); | ||
2847 | struct sk_buff *stats; | ||
2848 | struct tcp_info info; | ||
2849 | |||
2850 | stats = alloc_skb(3 * nla_total_size_64bit(sizeof(u64)), GFP_ATOMIC); | ||
2851 | if (!stats) | ||
2852 | return NULL; | ||
2853 | |||
2854 | tcp_get_info_chrono_stats(tp, &info); | ||
2855 | nla_put_u64_64bit(stats, TCP_NLA_BUSY, | ||
2856 | info.tcpi_busy_time, TCP_NLA_PAD); | ||
2857 | nla_put_u64_64bit(stats, TCP_NLA_RWND_LIMITED, | ||
2858 | info.tcpi_rwnd_limited, TCP_NLA_PAD); | ||
2859 | nla_put_u64_64bit(stats, TCP_NLA_SNDBUF_LIMITED, | ||
2860 | info.tcpi_sndbuf_limited, TCP_NLA_PAD); | ||
2861 | return stats; | ||
2862 | } | ||
2863 | |||
2844 | static int do_tcp_getsockopt(struct sock *sk, int level, | 2864 | static int do_tcp_getsockopt(struct sock *sk, int level, |
2845 | int optname, char __user *optval, int __user *optlen) | 2865 | int optname, char __user *optval, int __user *optlen) |
2846 | { | 2866 | { |
diff --git a/net/socket.c b/net/socket.c index e2584c51aa1f..e6318943ad07 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -693,9 +693,14 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
693 | (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && | 693 | (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && |
694 | ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) | 694 | ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) |
695 | empty = 0; | 695 | empty = 0; |
696 | if (!empty) | 696 | if (!empty) { |
697 | put_cmsg(msg, SOL_SOCKET, | 697 | put_cmsg(msg, SOL_SOCKET, |
698 | SCM_TIMESTAMPING, sizeof(tss), &tss); | 698 | SCM_TIMESTAMPING, sizeof(tss), &tss); |
699 | |||
700 | if (skb->len && (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS)) | ||
701 | put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS, | ||
702 | skb->len, skb->data); | ||
703 | } | ||
699 | } | 704 | } |
700 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); | 705 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); |
701 | 706 | ||