diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-06-17 15:24:29 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-06-17 15:24:30 -0700 |
| commit | b9ebe0cd5d53852e2edd7c7ffb0879712a9f8cdf (patch) | |
| tree | 585235f37d8bd09a28c1efee494424a90a81e65d /net | |
| parent | Merge branch 'vsock-test-improve-transport_uaf-test' (diff) | |
| parent | net: timestamp: add helper returning skb's tx tstamp (diff) | |
| download | linux-b9ebe0cd5d53852e2edd7c7ffb0879712a9f8cdf.tar.gz linux-b9ebe0cd5d53852e2edd7c7ffb0879712a9f8cdf.zip | |
Merge branch 'io_uring-cmd-for-tx-timestamps'
Pavel Begunkov says:
====================
io_uring cmd for tx timestamps (part)
Apply the networking helpers for the io_uring timestamp API.
====================
Link: https://patch.msgid.link/cover.1750065793.git.asml.silence@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/socket.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/net/socket.c b/net/socket.c index 9a0e720f0859..2cab805943c0 100644 --- a/net/socket.c +++ b/net/socket.c @@ -843,6 +843,52 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, sizeof(ts_pktinfo), &ts_pktinfo); } +bool skb_has_tx_timestamp(struct sk_buff *skb, const struct sock *sk) +{ + const struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); + u32 tsflags = READ_ONCE(sk->sk_tsflags); + + if (serr->ee.ee_errno != ENOMSG || + serr->ee.ee_origin != SO_EE_ORIGIN_TIMESTAMPING) + return false; + + /* software time stamp available and wanted */ + if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && skb->tstamp) + return true; + /* hardware time stamps available and wanted */ + return (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && + skb_hwtstamps(skb)->hwtstamp; +} + +int skb_get_tx_timestamp(struct sk_buff *skb, struct sock *sk, + struct timespec64 *ts) +{ + u32 tsflags = READ_ONCE(sk->sk_tsflags); + ktime_t hwtstamp; + int if_index = 0; + + if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && + ktime_to_timespec64_cond(skb->tstamp, ts)) + return SOF_TIMESTAMPING_TX_SOFTWARE; + + if (!(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) || + skb_is_swtx_tstamp(skb, false)) + return -ENOENT; + + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) + hwtstamp = get_timestamp(sk, skb, &if_index); + else + hwtstamp = skb_hwtstamps(skb)->hwtstamp; + + if (tsflags & SOF_TIMESTAMPING_BIND_PHC) + hwtstamp = ptp_convert_timestamp(&hwtstamp, + READ_ONCE(sk->sk_bind_phc)); + if (!ktime_to_timespec64_cond(hwtstamp, ts)) + return -ENOENT; + + return SOF_TIMESTAMPING_TX_HARDWARE; +} + /* * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) */ |
