summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2026-02-01 15:33:17 +0100
committerPaolo Abeni <pabeni@redhat.com>2026-02-05 11:58:39 +0100
commit96ea3a1e2d317e7ecb6b65dc65c9dd917905a6a8 (patch)
tree2780347dd8e2aea4538e15f43a207e193edf7ab7 /include
parentd4fb6514ff8ed6912a71294e6b66a5d59ee88007 (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')
-rw-r--r--include/linux/can/skb.h17
-rw-r--r--include/linux/skbuff.h3
-rw-r--r--include/net/can.h28
3 files changed, 48 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 */
};
diff --git a/include/net/can.h b/include/net/can.h
new file mode 100644
index 000000000000..6db9e826f0e0
--- /dev/null
+++ b/include/net/can.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/*
+ * net/can.h
+ *
+ * Definitions for the CAN network socket buffer extensions
+ *
+ * Copyright (C) 2026 Oliver Hartkopp <socketcan@hartkopp.net>
+ *
+ */
+
+#ifndef _NET_CAN_H
+#define _NET_CAN_H
+
+/**
+ * struct can_skb_ext - skb extensions for CAN specific content
+ * @can_iif: ifindex of the first interface the CAN frame appeared on
+ * @can_framelen: cached echo CAN frame length for bql
+ * @can_gw_hops: can-gw CAN frame time-to-live counter
+ * @can_ext_flags: CAN skb extensions flags
+ */
+struct can_skb_ext {
+ int can_iif;
+ u16 can_framelen;
+ u8 can_gw_hops;
+ u8 can_ext_flags;
+};
+
+#endif /* _NET_CAN_H */