[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2abfa2ceefa2b472382a57b9d5d4c420a68de952.1738940816.git.pabeni@redhat.com>
Date: Fri, 7 Feb 2025 17:23:44 +0100
From: Paolo Abeni <pabeni@...hat.com>
To: netdev@...r.kernel.org
Cc: Willem de Bruijn <willemdebruijn.kernel@...il.com>,
Eric Dumazet <edumazet@...gle.com>,
Kuniyuki Iwashima <kuniyu@...zon.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Simon Horman <horms@...nel.org>,
Neal Cardwell <ncardwell@...gle.com>,
David Ahern <dsahern@...nel.org>
Subject: [RFC PATCH 1/2] sock: introduce set_tsflags operation
The generic socket code for SO_TIMESTAMPING_* carries some TCP
specific bits. Add a new protocol operation hooked on such socket
option and move the TCP implementation into the relevant callback.
Place the new hook after all the core checks, to allow the protocol
to take "conclusive" actions.
The next patch will add a tsflags implementation for the UDP protocol.
Signed-off-by: Paolo Abeni <pabeni@...hat.com>
---
include/net/sock.h | 1 +
include/net/tcp.h | 1 +
net/core/sock.c | 24 +++++++++---------------
net/ipv4/tcp.c | 16 ++++++++++++++++
net/ipv4/tcp_ipv4.c | 1 +
net/ipv6/tcp_ipv6.c | 1 +
6 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 8036b3b79cd8..282dd23b90dc 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1246,6 +1246,7 @@ struct proto {
int optname, char __user *optval,
int __user *option);
void (*keepalive)(struct sock *sk, int valbool);
+ int (*tsflags)(struct sock *sk, int val);
#ifdef CONFIG_COMPAT
int (*compat_ioctl)(struct sock *sk,
unsigned int cmd, unsigned long arg);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 5b2b04835688..962500d0c4a9 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -416,6 +416,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
unsigned int optlen);
void tcp_set_keepalive(struct sock *sk, int val);
+int tcp_set_tsflags(struct sock *sk, int val);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int flags, int *addr_len);
diff --git a/net/core/sock.c b/net/core/sock.c
index eae2ae70a2e0..aafba8e30080 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -911,21 +911,6 @@ int sock_set_timestamping(struct sock *sk, int optname,
!(val & SOF_TIMESTAMPING_OPT_ID))
return -EINVAL;
- if (val & SOF_TIMESTAMPING_OPT_ID &&
- !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
- if (sk_is_tcp(sk)) {
- if ((1 << sk->sk_state) &
- (TCPF_CLOSE | TCPF_LISTEN))
- return -EINVAL;
- if (val & SOF_TIMESTAMPING_OPT_ID_TCP)
- atomic_set(&sk->sk_tskey, tcp_sk(sk)->write_seq);
- else
- atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una);
- } else {
- atomic_set(&sk->sk_tskey, 0);
- }
- }
-
if (val & SOF_TIMESTAMPING_OPT_STATS &&
!(val & SOF_TIMESTAMPING_OPT_TSONLY))
return -EINVAL;
@@ -936,6 +921,15 @@ int sock_set_timestamping(struct sock *sk, int optname,
return ret;
}
+ if (sk->sk_prot->tsflags) {
+ if (sk->sk_prot->tsflags(sk, val))
+ return -EINVAL;
+ } else {
+ if (val & SOF_TIMESTAMPING_OPT_ID &&
+ !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID))
+ atomic_set(&sk->sk_tskey, 0);
+ }
+
WRITE_ONCE(sk->sk_tsflags, val);
sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7f43d31c9400..4bd795d311d2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1741,6 +1741,22 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
}
EXPORT_SYMBOL(tcp_set_rcvlowat);
+int tcp_set_tsflags(struct sock *sk, int val)
+{
+ if (val & SOF_TIMESTAMPING_OPT_ID &&
+ !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+ if ((1 << sk->sk_state) &
+ (TCPF_CLOSE | TCPF_LISTEN))
+ return -EINVAL;
+ if (val & SOF_TIMESTAMPING_OPT_ID_TCP)
+ atomic_set(&sk->sk_tskey, tcp_sk(sk)->write_seq);
+ else
+ atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(tcp_set_tsflags);
+
void tcp_update_recv_tstamps(struct sk_buff *skb,
struct scm_timestamping_internal *tss)
{
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index cc2b5194a18d..d37ff97508d2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -3361,6 +3361,7 @@ struct proto tcp_prot = {
.getsockopt = tcp_getsockopt,
.bpf_bypass_getsockopt = tcp_bpf_bypass_getsockopt,
.keepalive = tcp_set_keepalive,
+ .tsflags = tcp_set_tsflags,
.recvmsg = tcp_recvmsg,
.sendmsg = tcp_sendmsg,
.splice_eof = tcp_splice_eof,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 2debdf085a3b..99092c9c1856 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2334,6 +2334,7 @@ struct proto tcpv6_prot = {
.getsockopt = tcp_getsockopt,
.bpf_bypass_getsockopt = tcp_bpf_bypass_getsockopt,
.keepalive = tcp_set_keepalive,
+ .tsflags = tcp_set_tsflags,
.recvmsg = tcp_recvmsg,
.sendmsg = tcp_sendmsg,
.splice_eof = tcp_splice_eof,
--
2.48.1
Powered by blists - more mailing lists