Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_tstamp: add SCM_TS_OPT_ID for RAW sockets

The last type of sockets which supports SOF_TIMESTAMPING_OPT_ID is RAW
sockets. To add new option this patch converts all callers (direct and
indirect) of _sock_tx_timestamp to provide sockcm_cookie instead of
tsflags. And while here fix __sock_tx_timestamp to receive tsflags as
__u32 instead of __u16.

Reviewed-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
Link: https://patch.msgid.link/20241001125716.2832769-3-vadfed@meta.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Vadim Fedorenko and committed by
Jakub Kicinski
822b5bc6 4aecca4c

+31 -21
+18 -9
include/net/sock.h
··· 2660 2660 sock_write_timestamp(sk, 0); 2661 2661 } 2662 2662 2663 - void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags); 2663 + void __sock_tx_timestamp(__u32 tsflags, __u8 *tx_flags); 2664 2664 2665 2665 /** 2666 2666 * _sock_tx_timestamp - checks whether the outgoing packet is to be time stamped 2667 2667 * @sk: socket sending this packet 2668 - * @tsflags: timestamping flags to use 2668 + * @sockc: pointer to socket cmsg cookie to get timestamping info 2669 2669 * @tx_flags: completed with instructions for time stamping 2670 2670 * @tskey: filled in with next sk_tskey (not for TCP, which uses seqno) 2671 2671 * 2672 2672 * Note: callers should take care of initial ``*tx_flags`` value (usually 0) 2673 2673 */ 2674 - static inline void _sock_tx_timestamp(struct sock *sk, __u16 tsflags, 2674 + static inline void _sock_tx_timestamp(struct sock *sk, 2675 + const struct sockcm_cookie *sockc, 2675 2676 __u8 *tx_flags, __u32 *tskey) 2676 2677 { 2678 + __u32 tsflags = sockc->tsflags; 2679 + 2677 2680 if (unlikely(tsflags)) { 2678 2681 __sock_tx_timestamp(tsflags, tx_flags); 2679 2682 if (tsflags & SOF_TIMESTAMPING_OPT_ID && tskey && 2680 - tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) 2681 - *tskey = atomic_inc_return(&sk->sk_tskey) - 1; 2683 + tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) { 2684 + if (tsflags & SOCKCM_FLAG_TS_OPT_ID) 2685 + *tskey = sockc->ts_opt_id; 2686 + else 2687 + *tskey = atomic_inc_return(&sk->sk_tskey) - 1; 2688 + } 2682 2689 } 2683 2690 if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS))) 2684 2691 *tx_flags |= SKBTX_WIFI_STATUS; 2685 2692 } 2686 2693 2687 - static inline void sock_tx_timestamp(struct sock *sk, __u16 tsflags, 2694 + static inline void sock_tx_timestamp(struct sock *sk, 2695 + const struct sockcm_cookie *sockc, 2688 2696 __u8 *tx_flags) 2689 2697 { 2690 - _sock_tx_timestamp(sk, tsflags, tx_flags, NULL); 2698 + _sock_tx_timestamp(sk, sockc, tx_flags, NULL); 2691 2699 } 2692 2700 2693 - static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags) 2701 + static inline void skb_setup_tx_timestamp(struct sk_buff *skb, 2702 + const struct sockcm_cookie *sockc) 2694 2703 { 2695 - _sock_tx_timestamp(skb->sk, tsflags, &skb_shinfo(skb)->tx_flags, 2704 + _sock_tx_timestamp(skb->sk, sockc, &skb_shinfo(skb)->tx_flags, 2696 2705 &skb_shinfo(skb)->tskey); 2697 2706 } 2698 2707
+1 -1
net/can/raw.c
··· 966 966 skb->mark = READ_ONCE(sk->sk_mark); 967 967 skb->tstamp = sockc.transmit_time; 968 968 969 - skb_setup_tx_timestamp(skb, sockc.tsflags); 969 + skb_setup_tx_timestamp(skb, &sockc); 970 970 971 971 err = can_send(skb, ro->loopback); 972 972
+1 -1
net/ipv4/ip_output.c
··· 1331 1331 cork->priority = ipc->priority; 1332 1332 cork->transmit_time = ipc->sockc.transmit_time; 1333 1333 cork->tx_flags = 0; 1334 - sock_tx_timestamp(sk, ipc->sockc.tsflags, &cork->tx_flags); 1334 + sock_tx_timestamp(sk, &ipc->sockc, &cork->tx_flags); 1335 1335 if (ipc->sockc.tsflags & SOCKCM_FLAG_TS_OPT_ID) { 1336 1336 cork->flags |= IPCORK_TS_OPT_ID; 1337 1337 cork->ts_opt_id = ipc->sockc.ts_opt_id;
+1 -1
net/ipv4/raw.c
··· 370 370 371 371 skb->ip_summed = CHECKSUM_NONE; 372 372 373 - skb_setup_tx_timestamp(skb, sockc->tsflags); 373 + skb_setup_tx_timestamp(skb, sockc); 374 374 375 375 if (flags & MSG_CONFIRM) 376 376 skb_set_dst_pending_confirm(skb, 1);
+4 -3
net/ipv4/tcp.c
··· 477 477 } 478 478 EXPORT_SYMBOL(tcp_init_sock); 479 479 480 - static void tcp_tx_timestamp(struct sock *sk, u16 tsflags) 480 + static void tcp_tx_timestamp(struct sock *sk, struct sockcm_cookie *sockc) 481 481 { 482 482 struct sk_buff *skb = tcp_write_queue_tail(sk); 483 + u32 tsflags = sockc->tsflags; 483 484 484 485 if (tsflags && skb) { 485 486 struct skb_shared_info *shinfo = skb_shinfo(skb); 486 487 struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); 487 488 488 - sock_tx_timestamp(sk, tsflags, &shinfo->tx_flags); 489 + sock_tx_timestamp(sk, sockc, &shinfo->tx_flags); 489 490 if (tsflags & SOF_TIMESTAMPING_TX_ACK) 490 491 tcb->txstamp_ack = 1; 491 492 if (tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) ··· 1322 1321 1323 1322 out: 1324 1323 if (copied) { 1325 - tcp_tx_timestamp(sk, sockc.tsflags); 1324 + tcp_tx_timestamp(sk, &sockc); 1326 1325 tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); 1327 1326 } 1328 1327 out_nopush:
+1 -1
net/ipv6/ip6_output.c
··· 1401 1401 cork->base.gso_size = ipc6->gso_size; 1402 1402 cork->base.tx_flags = 0; 1403 1403 cork->base.mark = ipc6->sockc.mark; 1404 - sock_tx_timestamp(sk, ipc6->sockc.tsflags, &cork->base.tx_flags); 1404 + sock_tx_timestamp(sk, &ipc6->sockc, &cork->base.tx_flags); 1405 1405 if (ipc6->sockc.tsflags & SOCKCM_FLAG_TS_OPT_ID) { 1406 1406 cork->base.flags |= IPCORK_TS_OPT_ID; 1407 1407 cork->base.ts_opt_id = ipc6->sockc.ts_opt_id;
+1 -1
net/ipv6/raw.c
··· 629 629 630 630 skb->ip_summed = CHECKSUM_NONE; 631 631 632 - skb_setup_tx_timestamp(skb, sockc->tsflags); 632 + skb_setup_tx_timestamp(skb, sockc); 633 633 634 634 if (flags & MSG_CONFIRM) 635 635 skb_set_dst_pending_confirm(skb, 1);
+3 -3
net/packet/af_packet.c
··· 2118 2118 skb->priority = READ_ONCE(sk->sk_priority); 2119 2119 skb->mark = READ_ONCE(sk->sk_mark); 2120 2120 skb_set_delivery_type_by_clockid(skb, sockc.transmit_time, sk->sk_clockid); 2121 - skb_setup_tx_timestamp(skb, sockc.tsflags); 2121 + skb_setup_tx_timestamp(skb, &sockc); 2122 2122 2123 2123 if (unlikely(extra_len == 4)) 2124 2124 skb->no_fcs = 1; ··· 2650 2650 skb->priority = READ_ONCE(po->sk.sk_priority); 2651 2651 skb->mark = READ_ONCE(po->sk.sk_mark); 2652 2652 skb_set_delivery_type_by_clockid(skb, sockc->transmit_time, po->sk.sk_clockid); 2653 - skb_setup_tx_timestamp(skb, sockc->tsflags); 2653 + skb_setup_tx_timestamp(skb, sockc); 2654 2654 skb_zcopy_set_nouarg(skb, ph.raw); 2655 2655 2656 2656 skb_reserve(skb, hlen); ··· 3115 3115 goto out_free; 3116 3116 } 3117 3117 3118 - skb_setup_tx_timestamp(skb, sockc.tsflags); 3118 + skb_setup_tx_timestamp(skb, &sockc); 3119 3119 3120 3120 if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) && 3121 3121 !packet_extra_vlan_len_allowed(dev, skb)) {
+1 -1
net/socket.c
··· 687 687 } 688 688 EXPORT_SYMBOL(sock_release); 689 689 690 - void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) 690 + void __sock_tx_timestamp(__u32 tsflags, __u8 *tx_flags) 691 691 { 692 692 u8 flags = *tx_flags; 693 693