linux/net/can
Oliver Hartkopp 7093c3b831 can: fix unique skb identifier regression under RPS
Commit d4fb6514ff ("can: use skb hash instead of private variable in
headroom") moved the per-skb unique identifier used for raw_rcv()
duplicate detection into skb->hash.

With RPS enabled, get_rps_cpu() calls skb_get_hash() before the frame
reaches the CAN subsystem. Since CAN skbs have no L3/L4 headers, the
flow dissector assigns every CAN frame the same non-zero software
hash. can_set_skb_uid() only generated a new identifier when
skb->hash was 0, so it kept this constant hash. When the SLAB
allocator later reused the same skb address, raw_rcv() mistook the
next legitimate frame for a duplicate and dropped it.

Fix this by storing the CAN UID in the CAN skb extension
(struct can_skb_ext::can_skb_uid) instead of skb->hash, decoupling it
from any hash the network stack may compute. can_set_skb_uid() keeps
its "assign only if unset" behaviour, which preserves UIDs set before
transmission (e.g. by isotp to identify echo frames) across the local
loopback path.

Frames whose extension is shared with another clone (e.g. via tc mirred
or netem duplicate) are given a private extension copy before the UID
is assigned, so that independently received skb clones from real CAN
interfaces (can_skb_uid = 0) don't end up with the same UID.
The limitation that tc mirred/netem skb duplicates might be dropped in
raw_rcv for looped back isotp echo frame skbs is accepted. There is no
valid use-case for tc mirred or netem together with isotp which is not
capable to operate on different CAN interfaces simultaneously.
For routing and modifying CAN frames together with isotp use can-gw.

can-gw and vxcan additionally clear the UID of forwarded/duplicated
frames so each newly routed frame gets its own unique identifier.

Fixes: d4fb6514ff ("can: use skb hash instead of private variable in headroom")
Reported-by: Joerg Willmann <joe@clnt.de>
Closes: https://lore.kernel.org/linux-can/2859AD3D-C805-41A0-9036-C5E8EE152419@clnt.de/
Cc: stable@vger.kernel.org
Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
Tested-by: Joerg Willmann <joe@clnt.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261001115724.27192-1-socketcan@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
2026-10-01 17:05:03 +02:00
..
j1939 can: j1939: transport: j1939_session_fresh_new(): initialize receive buffer 2026-07-29 10:15:33 +02:00
af_can.c can: fix unique skb identifier regression under RPS 2026-10-01 17:05:03 +02:00
af_can.h can: statistics: add missing atomic access in hot path 2026-03-19 14:53:19 +01:00
bcm.c can: bcm: track a single source interface for ANYDEV timeout/throttle ops 2026-07-16 10:02:20 +02:00
gw.c can: fix unique skb identifier regression under RPS 2026-10-01 17:05:03 +02:00
isotp.c can: fix unique skb identifier regression under RPS 2026-10-01 17:05:03 +02:00
Kconfig can: add CAN skb extension infrastructure 2026-02-05 11:58:39 +01:00
Makefile can: add ISO 15765-2:2016 transport protocol 2020-10-07 23:18:33 +02:00
proc.c can: statistics: add missing atomic access in hot path 2026-03-19 14:53:19 +01:00
raw.c can: fix unique skb identifier regression under RPS 2026-10-01 17:05:03 +02:00