This is preparation for usage in bpf_setsockopt. v2: - change first parameter type to struct sock (Eric Dumazet) Signed-off-by: Dmitry Yakunin <zeil@xxxxxxxxxxxxxx> Acked-by: Martin KaFai Lau <kafai@xxxxxx> --- include/net/tcp.h | 18 ++++++++++++++++++ net/ipv4/tcp.c | 15 ++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index b681338..e0a815f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1465,6 +1465,24 @@ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) tcp_jiffies32 - tp->rcv_tstamp); } +/* val must be validated at the top level function */ +static inline void keepalive_time_set(struct sock *sk, int val) +{ + struct tcp_sock *tp = tcp_sk(sk); + + tp->keepalive_time = val * HZ; + if (sock_flag(sk, SOCK_KEEPOPEN) && + !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { + u32 elapsed = keepalive_time_elapsed(tp); + + if (tp->keepalive_time > elapsed) + elapsed = tp->keepalive_time - elapsed; + else + elapsed = 0; + inet_csk_reset_keepalive_timer(sk, elapsed); + } +} + static inline int tcp_fin_time(const struct sock *sk) { int fin_timeout = tcp_sk(sk)->linger2 ? : sock_net(sk)->ipv4.sysctl_tcp_fin_timeout; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9700649..a366ab7 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3003,19 +3003,8 @@ static int do_tcp_setsockopt(struct sock *sk, int level, case TCP_KEEPIDLE: if (val < 1 || val > MAX_TCP_KEEPIDLE) err = -EINVAL; - else { - tp->keepalive_time = val * HZ; - if (sock_flag(sk, SOCK_KEEPOPEN) && - !((1 << sk->sk_state) & - (TCPF_CLOSE | TCPF_LISTEN))) { - u32 elapsed = keepalive_time_elapsed(tp); - if (tp->keepalive_time > elapsed) - elapsed = tp->keepalive_time - elapsed; - else - elapsed = 0; - inet_csk_reset_keepalive_timer(sk, elapsed); - } - } + else + keepalive_time_set(sk, val); break; case TCP_KEEPINTVL: if (val < 1 || val > MAX_TCP_KEEPINTVL) -- 2.7.4