diff options
author | David S. Miller <davem@davemloft.net> | 2013-02-13 13:22:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-13 13:22:24 -0500 |
commit | b8fa4100350432504df438014e2e5e9c1bbb6325 (patch) | |
tree | 0fc416746eeca68bbba228958636dd919fc3785f /net/ipv4/tcp.c | |
parent | d0023f820e003857248d14f2213ac3930283f16c (diff) | |
parent | ee684b6f2830047d19877e5547989740f18b1a5d (diff) | |
download | op-kernel-dev-b8fa4100350432504df438014e2e5e9c1bbb6325.zip op-kernel-dev-b8fa4100350432504df438014e2e5e9c1bbb6325.tar.gz |
Merge branch 'tcp_tsoffset'
Andrey Vagin says:
====================
If a TCP socket will get live-migrated from one box to another the
timestamps (which are typically ON) will get screwed up -- the new
kernel will generate TS values that has nothing to do with what they
were on dump. The solution is to yet again fix the kernel and put a
"timestamp offset" on a socket.
A socket offset is added in places where externally visible tcp
timestamp option is parsed/initialized.
Connections in the SYN_RECV state are not supported, global
tcp_time_stamp is used for them, because repair mode doesn't support
this state. In a future it can be implemented by the similar way as for
TIME_WAIT sockets.
For time-wait sockets offset is inhereted by a proper tcp_sock.
A per-socket offset can be set only for sockets in repair mode.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2c7e596..801b07b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -400,6 +400,8 @@ void tcp_init_sock(struct sock *sk) tcp_enable_early_retrans(tp); icsk->icsk_ca_ops = &tcp_init_congestion_ops; + tp->tsoffset = 0; + sk->sk_state = TCP_CLOSE; sk->sk_write_space = sk_stream_write_space; @@ -2712,6 +2714,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level, else err = -EINVAL; break; + case TCP_TIMESTAMP: + if (!tp->repair) + err = -EPERM; + else + tp->tsoffset = val - tcp_time_stamp; + break; default: err = -ENOPROTOOPT; break; @@ -2960,6 +2968,9 @@ static int do_tcp_getsockopt(struct sock *sk, int level, case TCP_USER_TIMEOUT: val = jiffies_to_msecs(icsk->icsk_user_timeout); break; + case TCP_TIMESTAMP: + val = tcp_time_stamp + tp->tsoffset; + break; default: return -ENOPROTOOPT; } |