Support the ACK case for bpf timestamping.
Add a new sock_ops callback, BPF_SOCK_OPS_TSTAMP_ACK_CB. This
callback will occur at the same timestamping point as the user
space's SCM_TSTAMP_ACK. The BPF program can use it to get the
same SCM_TSTAMP_ACK timestamp without modifying the user-space
application.
This patch extends txstamp_ack to two bits: 1 stands for
SO_TIMESTAMPING mode, 2 bpf extension.
Signed-off-by: Jason Xing <kerneljasonxing@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250220072940.99994-10-kerneljasonxing@gmail.com
 
 
        __u8            sacked;         /* State flags for SACK.        */
        __u8            ip_dsfield;     /* IPv4 tos or IPv6 dsfield     */
-       __u8            txstamp_ack:1,  /* Record TX timestamp for ack? */
+#define TSTAMP_ACK_SK  0x1
+#define TSTAMP_ACK_BPF 0x2
+       __u8            txstamp_ack:2,  /* Record TX timestamp for ack? */
                        eor:1,          /* Is skb MSG_EOR marked? */
                        has_rxtstamp:1, /* SKB has a RX timestamp       */
-                       unused:5;
+                       unused:4;
        __u32           ack_seq;        /* Sequence number ACK'd        */
        union {
                struct {
 
                                         * SK_BPF_CB_TX_TIMESTAMPING feature
                                         * is on.
                                         */
+       BPF_SOCK_OPS_TSTAMP_ACK_CB,     /* Called when all the skbs in the
+                                        * same sendmsg call are acked
+                                        * when SK_BPF_CB_TX_TIMESTAMPING
+                                        * feature is on.
+                                        */
 };
 
 /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
 
                return skb_shinfo(skb)->tx_flags & (hwtstamps ? SKBTX_HW_TSTAMP_NOBPF :
                                                    SKBTX_SW_TSTAMP);
        case SCM_TSTAMP_ACK:
-               return TCP_SKB_CB(skb)->txstamp_ack;
+               return TCP_SKB_CB(skb)->txstamp_ack & TSTAMP_ACK_SK;
        }
 
        return false;
                        op = BPF_SOCK_OPS_TSTAMP_SND_SW_CB;
                }
                break;
+       case SCM_TSTAMP_ACK:
+               op = BPF_SOCK_OPS_TSTAMP_ACK_CB;
+               break;
        default:
                return;
        }
 
 
                sock_tx_timestamp(sk, sockc, &shinfo->tx_flags);
                if (tsflags & SOF_TIMESTAMPING_TX_ACK)
-                       tcb->txstamp_ack = 1;
+                       tcb->txstamp_ack |= TSTAMP_ACK_SK;
                if (tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK)
                        shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1;
        }
 
                                         * SK_BPF_CB_TX_TIMESTAMPING feature
                                         * is on.
                                         */
+       BPF_SOCK_OPS_TSTAMP_ACK_CB,     /* Called when all the skbs in the
+                                        * same sendmsg call are acked
+                                        * when SK_BPF_CB_TX_TIMESTAMPING
+                                        * feature is on.
+                                        */
 };
 
 /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect