net: add net.ipv4.tcp_wan_timestamps sysctl to switch timestamps function

if need to disable timestamps for wan connections, but enable it for lan connecitons.
so do like this:
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_wan_timestamps = 0

if tcp_timestamps is 0, disable all timestamps include lan and wan.

Signed-off-by: Zhiping Du <zhipingdu@tencent.com>
This commit is contained in:
Zhiping du 2020-05-06 17:13:41 +08:00 committed by Honglin Li
parent 2159f357c8
commit 8fafa5a142
4 changed files with 29 additions and 1 deletions

View File

@ -241,5 +241,6 @@ struct netns_ipv4 {
atomic_t rt_genid;
siphash_key_t ip_id_key;
int sysctl_tcp_wan_timestamps;
};
#endif

View File

@ -1188,6 +1188,24 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost,
bool is_sack_reneg, struct rate_sample *rs);
void tcp_rate_check_app_limited(struct sock *sk);
static inline int is_private_ip(__be32 daddr) {
__u8 i, j;
#if defined(__LITTLE_ENDIAN)
i = daddr & 0xFF;
j = (daddr >> 8) & 0xFF;
#elif defined(__BIG_ENDIAN)
i = (daddr >> 24) & 0xFF;
j = (daddr >> 16) & 0xFF;
#else
#error Unknown Endian
#endif
return i == 11 || i == 30 || i == 9 || i == 127 || i == 10 ||
i == 21 || i == 22 || i == 26 || i == 28 || i == 29 ||
(i == 172 && j >= 16 && j < 32) ||
(i == 192 && j == 168) ||
(i == 100 && j >= 64 && j <= 127 );
}
static inline bool tcp_skb_sent_after(u64 t1, u64 t2, u32 seq1, u32 seq2)
{
return t1 > t2 || (t1 == t2 && after(seq1, seq2));

View File

@ -580,6 +580,13 @@ static struct ctl_table ipv4_table[] = {
.extra1 = &sysctl_fib_sync_mem_min,
.extra2 = &sysctl_fib_sync_mem_max,
},
{
.procname = "tcp_wan_timestamps",
.data = &init_net.ipv4.sysctl_tcp_wan_timestamps,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_tw_ignore_syn_tsval_zero",
.data = &sysctl_tcp_tw_ignore_syn_tsval_zero,

View File

@ -4070,6 +4070,7 @@ void tcp_parse_options(const struct net *net,
{
const unsigned char *ptr;
const struct tcphdr *th = tcp_hdr(skb);
struct iphdr *iph = ip_hdr(skb);
int length = (th->doff * 4) - sizeof(struct tcphdr);
ptr = (const unsigned char *)(th + 1);
@ -4124,7 +4125,8 @@ void tcp_parse_options(const struct net *net,
case TCPOPT_TIMESTAMP:
if ((opsize == TCPOLEN_TIMESTAMP) &&
((estab && opt_rx->tstamp_ok) ||
(!estab && READ_ONCE(net->ipv4.sysctl_tcp_timestamps)))) {
(!estab && READ_ONCE(net->ipv4.sysctl_tcp_timestamps) &&
(net->ipv4.sysctl_tcp_wan_timestamps || is_private_ip(iph->saddr))))) {
opt_rx->saw_tstamp = 1;
opt_rx->rcv_tsval = get_unaligned_be32(ptr);
opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4);