From: Arthur Fabre <afabre@xxxxxxxxxxxxxx> Use a bit in sk_buff to track whether or not an skb stores traits in it's headroom. It's tempting to store it in skb_shared_info like the XDP metadata, but storing it in the skb allows us to more easily handle cases such as skb clones in a few patches. (I couldn't find an existing hole to use in sk_buff, so this makes a 4 byte hole... any pointers to a free bit?) The following patches add support for handful of drivers, in the final form we'd like to cover all drivers that currently support XDP metadata. Signed-off-by: Arthur Fabre <afabre@xxxxxxxxxxxxxx> --- include/linux/skbuff.h | 7 +++++++ include/net/xdp.h | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 03553c2200ab1c3750b799edb94fa3b94e11a5f1..d7dfee152ebd26ce87a230222e94076aca793adc 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -725,6 +725,12 @@ enum skb_tstamp_type { __SKB_CLOCK_MAX = SKB_CLOCK_TAI, }; +enum skb_traits_type { + SKB_TRAITS_NONE, + /* Trait store in headroom, offset by sizeof(struct xdp_frame) */ + SKB_TRAITS_AFTER_XDP, +}; + /** * DOC: Basic sk_buff geometry * @@ -1023,6 +1029,7 @@ struct sk_buff { __u8 csum_not_inet:1; #endif __u8 unreadable:1; + __u8 traits_type:1; /* See enum skb_traits_type */ #if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS) __u16 tc_index; /* traffic control index */ #endif diff --git a/include/net/xdp.h b/include/net/xdp.h index 84afe07d09efdb2ab0cb78b904f02cb74f9a56b6..e2e7c270efa3cbd11bddd234010b91daee5009a2 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -119,6 +119,12 @@ static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp) static bool xdp_data_meta_unsupported(const struct xdp_buff *xdp); static void xdp_set_data_meta_invalid(struct xdp_buff *xdp); +static __always_inline void xdp_buff_update_skb(struct xdp_buff *xdp, struct sk_buff *skb) +{ + if (!xdp_data_meta_unsupported(xdp)) + skb->traits_type = SKB_TRAITS_AFTER_XDP; +} + static __always_inline void *xdp_buff_traits(const struct xdp_buff *xdp) { return xdp->data_hard_start + _XDP_FRAME_SIZE; @@ -298,6 +304,12 @@ xdp_frame_is_frag_pfmemalloc(const struct xdp_frame *frame) return !!(frame->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC); } +static __always_inline void xdp_frame_update_skb(struct xdp_frame *frame, struct sk_buff *skb) +{ + if (!frame->meta_unsupported) + skb->traits_type = SKB_TRAITS_AFTER_XDP; +} + #define XDP_BULK_QUEUE_SIZE 16 struct xdp_frame_bulk { int count; -- 2.43.0