Florian Kauer <florian.kauer@xxxxxxxxxxxxx> writes: > On 7/5/24 13:01, Toke Høiland-Jørgensen wrote: >> Florian Kauer <florian.kauer@xxxxxxxxxxxxx> writes: >> >>> Both DEVMAP as well as CPUMAP provide the possibility >>> to attach BPF programs to their entries that will be >>> executed after a redirect was performed. >>> >>> With BPF_F_BROADCAST it is in also possible to execute >>> BPF programs for multiple clones of the same XDP frame >>> which is, for example, useful for establishing redundant >>> traffic paths by setting, for example, different VLAN tags >>> for the replicated XDP frames. >>> >>> Currently, this program itself has no information about >>> the map entry that led to its execution. While egress_ifindex >>> can be used to get this information indirectly and can >>> be used for path dependent processing of the replicated frames, >>> it does not work if multiple entries share the same egress_ifindex. >>> >>> Therefore, extend the xdp_md struct with a map_key >>> that contains the key of the associated map entry >>> after performing a redirect. >>> >>> See >>> https://lore.kernel.org/xdp-newbies/5eb6070c-a12e-4d4c-a9f0-a6a6fafa41d1@xxxxxxxxxxxxx/T/#u >>> for the discussion that led to this patch. >>> >>> Signed-off-by: Florian Kauer <florian.kauer@xxxxxxxxxxxxx> >>> --- >>> include/net/xdp.h | 3 +++ >>> include/uapi/linux/bpf.h | 2 ++ >>> kernel/bpf/devmap.c | 6 +++++- >>> net/core/filter.c | 18 ++++++++++++++++++ >>> 4 files changed, 28 insertions(+), 1 deletion(-) >>> >>> diff --git a/include/net/xdp.h b/include/net/xdp.h >>> index e6770dd40c91..e70f4dfea1a2 100644 >>> --- a/include/net/xdp.h >>> +++ b/include/net/xdp.h >>> @@ -86,6 +86,7 @@ struct xdp_buff { >>> struct xdp_txq_info *txq; >>> u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/ >>> u32 flags; /* supported values defined in xdp_buff_flags */ >>> + u64 map_key; /* set during redirect via a map */ >>> }; >>> >>> static __always_inline bool xdp_buff_has_frags(struct xdp_buff *xdp) >>> @@ -175,6 +176,7 @@ struct xdp_frame { >>> struct net_device *dev_rx; /* used by cpumap */ >>> u32 frame_sz; >>> u32 flags; /* supported values defined in xdp_buff_flags */ >>> + u64 map_key; /* set during redirect via a map */ >>> }; >> >> struct xdp_frame is size constrained, so we shouldn't be using precious >> space on this. Besides, it's not information that should be carried >> along with the packet after transmission. So let's put it into struct >> xdp_txq_info and read it from there the same way we do for egress_ifindex :) > > Very reasonable, but do you really mean struct xdp_frame or xdp_buff? > Only the latter has the xdp_txq_info? Well, we should have the field in neither, but xdp_frame is the one that is size constrained. Whenever a cpumap/devmap program is run (in xdp_bq_bpf_prog_run() and dev_map_bpf_prog_run_skb()), a struct xdp_txq_info is prepared on the stack, so you'll just need to add setting of the new value to that... -Toke