@@ -383,6 +383,7 @@ struct bt_sock {
struct list_head accept_q;
struct sock *parent;
unsigned long flags;
+ atomic_t bpf_tskey;
void (*skb_msg_name)(struct sk_buff *, void *, int *);
void (*skb_put_cmsg)(struct sk_buff *, struct msghdr *, struct sock *);
};
@@ -28,6 +28,7 @@
#include <linux/export.h>
#include <linux/debugfs.h>
#include <linux/errqueue.h>
+#include <linux/bpf-cgroup.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -3072,6 +3073,7 @@ void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset,
const struct sockcm_cookie *sockc)
{
struct sock *sk = skb ? skb->sk : NULL;
+ bool have_tskey = false;
/* This shall be called on a single skb of those generated by user
* sendmsg(), and only when the sendmsg() does not return error to
@@ -3096,6 +3098,20 @@ void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset,
skb_shinfo(skb)->tskey = key - 1;
}
+ have_tskey = true;
+ }
+
+ if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) &&
+ SK_BPF_CB_FLAG_TEST(sk, SK_BPF_CB_TX_TIMESTAMPING)) {
+ struct bt_sock *bt_sk = container_of(sk, struct bt_sock, sk);
+ int key = atomic_inc_return(&bt_sk->bpf_tskey);
+
+ if (!have_tskey)
+ skb_shinfo(skb)->tskey = key - 1;
+
+ bpf_skops_tx_timestamping(sk, skb,
+ BPF_SOCK_OPS_TSTAMP_SENDMSG_CB);
+
}
}
@@ -3105,7 +3121,7 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb)
bool track = false;
/* Emit SND now, ie. just before sending to driver */
- if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP)
+ if (skb_shinfo(skb)->tx_flags & (SKBTX_SW_TSTAMP | SKBTX_BPF))
__skb_tstamp_tx(skb, NULL, NULL, skb->sk, SCM_TSTAMP_SND);
/* COMPLETION tstamp is emitted for tracked skb later in Number of
@@ -3127,7 +3143,8 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb)
return;
}
- if (skb->sk && (skb_shinfo(skb)->tx_flags & SKBTX_COMPLETION_TSTAMP))
+ if (skb->sk && (skb_shinfo(skb)->tx_flags &
+ (SKBTX_COMPLETION_TSTAMP | SKBTX_BPF)))
track = true;
/* If nothing is tracked, just count extra skbs at the queue head */