From: Jason Xing <kernelxing@xxxxxxxxxxx> Introduce BPF_SOCK_OPS_TS_SCHED_OPT_CB flag so that we can decide to print timestamps when the skb just passes the dev layer. Signed-off-by: Jason Xing <kernelxing@xxxxxxxxxxx> --- include/uapi/linux/bpf.h | 5 +++++ net/core/skbuff.c | 31 ++++++++++++++++++++++++++++++- tools/include/uapi/linux/bpf.h | 5 +++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index e8241b320c6d..324e9e40969c 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -7013,6 +7013,11 @@ enum { * by the kernel or the * earlier bpf-progs. */ + BPF_SOCK_OPS_TS_SCHED_OPT_CB, /* Called when skb is passing through + * dev layer when SO_TIMESTAMPING + * feature is on. It indicates the + * recorded timestamp. + */ }; /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 39309f75e105..e6a5c883bdc6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -64,6 +64,7 @@ #include <linux/mpls.h> #include <linux/kcov.h> #include <linux/iov_iter.h> +#include <linux/bpf-cgroup.h> #include <net/protocol.h> #include <net/dst.h> @@ -5621,13 +5622,41 @@ static void skb_tstamp_tx_output(struct sk_buff *orig_skb, __skb_complete_tx_timestamp(skb, sk, tstype, opt_stats); } +static void timestamp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args) +{ + struct bpf_sock_ops_kern sock_ops; + + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); + if (sk_fullsock(sk)) { + sock_ops.is_fullsock = 1; + sock_owned_by_me(sk); + } + + sock_ops.sk = sk; + sock_ops.op = op; + if (nargs > 0) + memcpy(sock_ops.args, args, nargs * sizeof(*args)); + + BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(&sock_ops, sk); +} + static void skb_tstamp_tx_output_bpf(struct sock *sk, int tstype) { - u32 tsflags; + u32 tsflags, cb_flag; tsflags = READ_ONCE(sk->sk_tsflags_bpf); if (!sk_tstamp_tx_flags(sk, tsflags, tstype)) return; + + switch (tstype) { + case SCM_TSTAMP_SCHED: + cb_flag = BPF_SOCK_OPS_TS_SCHED_OPT_CB; + break; + default: + return; + } + + timestamp_call_bpf(sk, cb_flag, 0, NULL); } void __skb_tstamp_tx(struct sk_buff *orig_skb, diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index e8241b320c6d..324e9e40969c 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -7013,6 +7013,11 @@ enum { * by the kernel or the * earlier bpf-progs. */ + BPF_SOCK_OPS_TS_SCHED_OPT_CB, /* Called when skb is passing through + * dev layer when SO_TIMESTAMPING + * feature is on. It indicates the + * recorded timestamp. + */ }; /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect -- 2.37.3