diff options
| author | Oliver Hartkopp <socketcan@hartkopp.net> | 2026-02-01 15:33:17 +0100 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-02-05 11:58:39 +0100 |
| commit | 96ea3a1e2d317e7ecb6b65dc65c9dd917905a6a8 (patch) | |
| tree | 2780347dd8e2aea4538e15f43a207e193edf7ab7 /include/linux | |
| parent | d4fb6514ff8ed6912a71294e6b66a5d59ee88007 (diff) | |
can: add CAN skb extension infrastructure
To remove the private CAN bus skb headroom infrastructure 8 bytes need to
be stored in the skb. The skb extensions are a common pattern and an easy
and efficient way to hold private data travelling along with the skb. We
only need the skb_ext_add() and skb_ext_find() functions to allocate and
access CAN specific content as the skb helpers to copy/clone/free skbs
automatically take care of skb extensions and their final removal.
This patch introduces the complete CAN skb extensions infrastructure:
- add struct can_skb_ext in new file include/net/can.h
- add include/net/can.h in MAINTAINERS
- add SKB_EXT_CAN to skbuff.c and skbuff.h
- select SKB_EXTENSIONS in Kconfig when CONFIG_CAN is enabled
- check for existing CAN skb extensions in can_rcv() in af_can.c
- add CAN skb extensions allocation at every skb_alloc() location
- duplicate the skb extensions if cloning outgoing skbs (framelen/gw_hops)
- introduce can_skb_ext_add() and can_skb_ext_find() helpers
The patch also corrects an indention issue in the original code from 2018:
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202602010426.PnGrYAk3-lkp@intel.com/
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20260201-can_skb_ext-v8-2-3635d790fe8b@hartkopp.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/can/skb.h | 17 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 3 |
2 files changed, 20 insertions, 0 deletions
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h index 869ea574a40a..68c0f24e6914 100644 --- a/include/linux/can/skb.h +++ b/include/linux/can/skb.h @@ -14,6 +14,7 @@ #include <linux/types.h> #include <linux/skbuff.h> #include <linux/can.h> +#include <net/can.h> #include <net/sock.h> void can_flush_echo_skb(struct net_device *dev); @@ -68,6 +69,22 @@ static inline void can_skb_reserve(struct sk_buff *skb) skb_reserve(skb, sizeof(struct can_skb_priv)); } +static inline struct can_skb_ext *can_skb_ext_add(struct sk_buff *skb) +{ + struct can_skb_ext *csx = skb_ext_add(skb, SKB_EXT_CAN); + + /* skb_ext_add() returns uninitialized space */ + if (csx) + csx->can_gw_hops = 0; + + return csx; +} + +static inline struct can_skb_ext *can_skb_ext_find(struct sk_buff *skb) +{ + return skb_ext_find(skb, SKB_EXT_CAN); +} + static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) { /* If the socket has already been closed by user space, the diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8b399ddf1b9b..ef56dc6318d3 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -4990,6 +4990,9 @@ enum skb_ext_id { #if IS_ENABLED(CONFIG_INET_PSP) SKB_EXT_PSP, #endif +#if IS_ENABLED(CONFIG_CAN) + SKB_EXT_CAN, +#endif SKB_EXT_NUM, /* must be last */ }; |
