From: Jason Xing <kernelxing@xxxxxxxxxxx> This patch has introduced a separate sk_tsflags_bpf for bpf extension, which helps us let two feature work nearly at the same time. Each feature will finally take effect on skb_shinfo(skb)->tx_flags, say, tcp_tx_timestamp() for TCP or skb_setup_tx_timestamp() for other types, so in __skb_tstamp_tx() we are unable to know which feature is turned on, unless we check each feature's own socket flag field. Signed-off-by: Jason Xing <kernelxing@xxxxxxxxxxx> --- include/net/sock.h | 1 + net/core/skbuff.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/net/sock.h b/include/net/sock.h index 7464e9f9f47c..5384f1e49f5c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -445,6 +445,7 @@ struct sock { u32 sk_reserved_mem; int sk_forward_alloc; u32 sk_tsflags; + u32 sk_tsflags_bpf; __cacheline_group_end(sock_write_rxtx); __cacheline_group_begin(sock_write_tx); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1cf8416f4123..39309f75e105 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5539,6 +5539,32 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, } EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); +/* This function is used to test if application SO_TIMESTAMPING feature + * or bpf SO_TIMESTAMPING feature is loaded by checking its own socket flags. + */ +static bool sk_tstamp_tx_flags(struct sock *sk, u32 tsflags, int tstype) +{ + u32 testflag; + + switch (tstype) { + case SCM_TSTAMP_SCHED: + testflag = SOF_TIMESTAMPING_TX_SCHED; + break; + case SCM_TSTAMP_SND: + testflag = SOF_TIMESTAMPING_TX_SOFTWARE; + break; + case SCM_TSTAMP_ACK: + testflag = SOF_TIMESTAMPING_TX_ACK; + break; + default: + return false; + } + if (tsflags & testflag) + return true; + + return false; +} + static void skb_tstamp_tx_output(struct sk_buff *orig_skb, const struct sk_buff *ack_skb, struct skb_shared_hwtstamps *hwtstamps, @@ -5549,6 +5575,9 @@ static void skb_tstamp_tx_output(struct sk_buff *orig_skb, u32 tsflags; tsflags = READ_ONCE(sk->sk_tsflags); + if (!sk_tstamp_tx_flags(sk, tsflags, tstype)) + return; + if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS) return; @@ -5592,6 +5621,15 @@ static void skb_tstamp_tx_output(struct sk_buff *orig_skb, __skb_complete_tx_timestamp(skb, sk, tstype, opt_stats); } +static void skb_tstamp_tx_output_bpf(struct sock *sk, int tstype) +{ + u32 tsflags; + + tsflags = READ_ONCE(sk->sk_tsflags_bpf); + if (!sk_tstamp_tx_flags(sk, tsflags, tstype)) + return; +} + void __skb_tstamp_tx(struct sk_buff *orig_skb, const struct sk_buff *ack_skb, struct skb_shared_hwtstamps *hwtstamps, @@ -5600,6 +5638,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, if (!sk) return; + skb_tstamp_tx_output_bpf(sk, tstype); skb_tstamp_tx_output(orig_skb, ack_skb, hwtstamps, sk, tstype); } EXPORT_SYMBOL_GPL(__skb_tstamp_tx); -- 2.37.3