]> www.infradead.org Git - users/hch/misc.git/commitdiff
bpf: Add networking timestamping support to bpf_get/setsockopt()
authorJason Xing <kerneljasonxing@gmail.com>
Thu, 20 Feb 2025 07:29:29 +0000 (15:29 +0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Thu, 20 Feb 2025 22:28:37 +0000 (14:28 -0800)
The new SK_BPF_CB_FLAGS and new SK_BPF_CB_TX_TIMESTAMPING are
added to bpf_get/setsockopt. The later patches will implement the
BPF networking timestamping. The BPF program will use
bpf_setsockopt(SK_BPF_CB_FLAGS, SK_BPF_CB_TX_TIMESTAMPING) to
enable the BPF networking timestamping on a socket.

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-2-kerneljasonxing@gmail.com
include/net/sock.h
include/uapi/linux/bpf.h
net/core/filter.c
tools/include/uapi/linux/bpf.h

index 60ebf3c7b229e257b164e0de1f56543ea69f38f3..a95eedacae76caaddc02cd3bf96859cc4a197a4f 100644 (file)
@@ -303,6 +303,7 @@ struct sk_filter;
   *    @sk_stamp: time stamp of last packet received
   *    @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only
   *    @sk_tsflags: SO_TIMESTAMPING flags
+  *    @sk_bpf_cb_flags: used in bpf_setsockopt()
   *    @sk_use_task_frag: allow sk_page_frag() to use current->task_frag.
   *                       Sockets that can be used under memory reclaim should
   *                       set this to false.
@@ -525,6 +526,8 @@ struct sock {
        u8                      sk_txtime_deadline_mode : 1,
                                sk_txtime_report_errors : 1,
                                sk_txtime_unused : 6;
+#define SK_BPF_CB_FLAG_TEST(SK, FLAG) ((SK)->sk_bpf_cb_flags & (FLAG))
+       u8                      sk_bpf_cb_flags;
 
        void                    *sk_user_data;
 #ifdef CONFIG_SECURITY
index 2acf9b33637174bd16b1d12ccc6410c5f55a7ea9..4e0632848440b910088ab54e2679f35bee42d1e3 100644 (file)
@@ -6913,6 +6913,12 @@ enum {
        BPF_SOCK_OPS_ALL_CB_FLAGS       = 0x7F,
 };
 
+enum {
+       SK_BPF_CB_TX_TIMESTAMPING       = 1<<0,
+       SK_BPF_CB_MASK                  = (SK_BPF_CB_TX_TIMESTAMPING - 1) |
+                                          SK_BPF_CB_TX_TIMESTAMPING
+};
+
 /* List of known BPF sock_ops operators.
  * New entries can only be added at the end
  */
@@ -7091,6 +7097,7 @@ enum {
        TCP_BPF_SYN_IP          = 1006, /* Copy the IP[46] and TCP header */
        TCP_BPF_SYN_MAC         = 1007, /* Copy the MAC, IP[46], and TCP header */
        TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
+       SK_BPF_CB_FLAGS         = 1009, /* Get or set sock ops flags in socket */
 };
 
 enum {
index ffec7b4357f9f80e373f49a1333e459d853392cb..5b7e44dfc037c6f3c38e928db6c20215ac1226ee 100644 (file)
@@ -5222,6 +5222,25 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = {
        .arg1_type      = ARG_PTR_TO_CTX,
 };
 
+static int sk_bpf_set_get_cb_flags(struct sock *sk, char *optval, bool getopt)
+{
+       u32 sk_bpf_cb_flags;
+
+       if (getopt) {
+               *(u32 *)optval = sk->sk_bpf_cb_flags;
+               return 0;
+       }
+
+       sk_bpf_cb_flags = *(u32 *)optval;
+
+       if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK)
+               return -EINVAL;
+
+       sk->sk_bpf_cb_flags = sk_bpf_cb_flags;
+
+       return 0;
+}
+
 static int sol_socket_sockopt(struct sock *sk, int optname,
                              char *optval, int *optlen,
                              bool getopt)
@@ -5238,6 +5257,7 @@ static int sol_socket_sockopt(struct sock *sk, int optname,
        case SO_MAX_PACING_RATE:
        case SO_BINDTOIFINDEX:
        case SO_TXREHASH:
+       case SK_BPF_CB_FLAGS:
                if (*optlen != sizeof(int))
                        return -EINVAL;
                break;
@@ -5247,6 +5267,9 @@ static int sol_socket_sockopt(struct sock *sk, int optname,
                return -EINVAL;
        }
 
+       if (optname == SK_BPF_CB_FLAGS)
+               return sk_bpf_set_get_cb_flags(sk, optval, getopt);
+
        if (getopt) {
                if (optname == SO_BINDTODEVICE)
                        return -EINVAL;
index 2acf9b33637174bd16b1d12ccc6410c5f55a7ea9..4e0632848440b910088ab54e2679f35bee42d1e3 100644 (file)
@@ -6913,6 +6913,12 @@ enum {
        BPF_SOCK_OPS_ALL_CB_FLAGS       = 0x7F,
 };
 
+enum {
+       SK_BPF_CB_TX_TIMESTAMPING       = 1<<0,
+       SK_BPF_CB_MASK                  = (SK_BPF_CB_TX_TIMESTAMPING - 1) |
+                                          SK_BPF_CB_TX_TIMESTAMPING
+};
+
 /* List of known BPF sock_ops operators.
  * New entries can only be added at the end
  */
@@ -7091,6 +7097,7 @@ enum {
        TCP_BPF_SYN_IP          = 1006, /* Copy the IP[46] and TCP header */
        TCP_BPF_SYN_MAC         = 1007, /* Copy the MAC, IP[46], and TCP header */
        TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
+       SK_BPF_CB_FLAGS         = 1009, /* Get or set sock ops flags in socket */
 };
 
 enum {