[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250422-afabre-traits-010-rfc2-v2-9-92bcc6b146c9@arthurfabre.com>
Date: Tue, 22 Apr 2025 15:23:38 +0200
From: Arthur Fabre <arthur@...hurfabre.com>
To: netdev@...r.kernel.org, bpf@...r.kernel.org
Cc: jakub@...udflare.com, hawk@...nel.org, yan@...udflare.com,
jbrandeburg@...udflare.com, thoiland@...hat.com, lbiancon@...hat.com,
ast@...nel.org, kuba@...nel.org, edumazet@...gle.com,
Arthur Fabre <arthur@...hurfabre.com>
Subject: [PATCH RFC bpf-next v2 09/17] trait: Store traits in sk_buff
extension
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 <arthur@...hurfabre.com>
---
include/linux/skbuff.h | 11 +++++++++++
include/net/xdp.h | 21 +++++++++++++++++++++
net/core/skbuff.c | 4 ++++
3 files changed, 36 insertions(+)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4f325a1733f8be808345424f737df36e06d4cd98..ae569b1b1af83b586e1be6c69439ef74bac38cf3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -39,6 +39,7 @@
#include <net/net_debug.h>
#include <net/dropreason-core.h>
#include <net/netmem.h>
+#include <net/trait.h>
/**
* DOC: skb checksums
@@ -4835,6 +4836,7 @@ enum skb_ext_id {
#if IS_ENABLED(CONFIG_MCTP_FLOWS)
SKB_EXT_MCTP,
#endif
+ SKB_EXT_TRAITS,
SKB_EXT_NUM, /* must be last */
};
@@ -4949,6 +4951,15 @@ static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {}
static inline bool skb_has_extensions(struct sk_buff *skb) { return false; }
#endif /* CONFIG_SKB_EXTENSIONS */
+static inline void *skb_traits(const struct sk_buff *skb)
+{
+#ifdef CONFIG_SKB_EXTENSIONS
+ return skb_ext_find(skb, SKB_EXT_TRAITS);
+#else
+ return NULL;
+#endif
+}
+
static inline void nf_reset_ct(struct sk_buff *skb)
{
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 0da1e87afdebfd4323d1944de65a6d63438209bf..cddd5b147cf81fa8afd820c9aa4b86d78958ac3d 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -127,6 +127,17 @@ static __always_inline void *xdp_buff_traits(const struct xdp_buff *xdp)
return xdp->data_hard_start + _XDP_FRAME_SIZE;
}
+static __always_inline void __xdp_flags_update_skb(u32 flags, struct sk_buff *skb, void *traits)
+{
+ if (flags & XDP_FLAGS_TRAITS_SUPPORTED)
+ skb_ext_from_headroom(skb, SKB_EXT_TRAITS, _XDP_FRAME_SIZE, traits_size(traits));
+}
+
+static __always_inline void xdp_buff_update_skb(const struct xdp_buff *xdp, struct sk_buff *skb)
+{
+ __xdp_flags_update_skb(xdp->flags, skb, xdp_buff_traits(xdp));
+}
+
static __always_inline void
xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq)
{
@@ -302,6 +313,16 @@ xdp_frame_is_frag_pfmemalloc(const struct xdp_frame *frame)
return !!(frame->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC);
}
+static void *xdp_frame_traits(const struct xdp_frame *frame)
+{
+ return frame->data + _XDP_FRAME_SIZE;
+}
+
+static __always_inline void xdp_frame_update_skb(struct xdp_frame *frame, struct sk_buff *skb)
+{
+ __xdp_flags_update_skb(frame->flags, skb, xdp_frame_traits(frame));
+}
+
#define XDP_BULK_QUEUE_SIZE 16
struct xdp_frame_bulk {
int count;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 34dae26dac4cea448f84dacabdc8fb6f4ac3c1a6..9f27caba82af0be7897b68b5fad087f3e9c62955 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5043,6 +5043,10 @@ static const u8 skb_ext_type_len[] = {
#if IS_ENABLED(CONFIG_MCTP_FLOWS)
[SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow),
#endif
+ /* TODO: skb_ext is slab allocated with room for all extensions,
+ * this makes it a LOT bigger.
+ */
+ [SKB_EXT_TRAITS] = SKB_EXT_CHUNKS(XDP_PACKET_HEADROOM),
};
static __always_inline unsigned int skb_ext_alloc_length(void)
--
2.43.0
Powered by blists - more mailing lists