Re: [bpf, xdp] headroom - was: Re: Question about to KMSAN: uninit-value in can_receive

From: Oliver Hartkopp

Date: Tue Jan 06 2026 - 07:07:49 EST


On 06.01.26 00:26, Jakub Kicinski wrote:
On Mon, 5 Jan 2026 14:47:08 +0100 Oliver Hartkopp wrote:
For the ifindex I would propose to store it in struct skb_shared_info:

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 86737076101d..f7233b8f461c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -604,10 +604,15 @@ struct skb_shared_info {
struct xsk_tx_metadata_compl xsk_meta;
};
unsigned int gso_type;
u32 tskey;

+#if IS_ENABLED(CONFIG_CAN)
+ /* initial CAN iif to avoid routing back to it (can-gw) */
+ int can_iif;
+#endif
+
/*
* Warning : all fields before dataref are cleared in __alloc_skb()
*/
atomic_t dataref;

Would this be a suitable approach to get rid of struct can_skb_priv in
your opinion?

Possibly a naive question but why is skb_iif not working here?

With the CAN gateway (net/can/gw.c) incoming CAN frames can be modified and forwarded to other CAN interfaces via dev_queue_xmit(skb).

When such skb is echo'ed back after successful transmission via netif_rx() this leads to skb->skb_iif = skb->dev->ifindex;

To prevent a loopback the CAN frame must not be sent back to the originating interface - even when it has been routed to different CAN interfaces in the meantime (which always overwrites skb_iif).

Therefore we need to maintain the "real original" incoming interface.

can_iif could also be named skb_initial_iif when someone else would need such an information too.

Best regards,
Oliver