From: Oliver Hartkopp Date: Fri, 9 Jan 2026 14:41:33 +0000 (+0100) Subject: Revert "can: raw: instantly reject unsupported CAN frames" X-Git-Tag: v6.19-rc6~34^2^2~1^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4650ff58a1b9ee68b2d3a207047998dd42e939b2;p=thirdparty%2Flinux.git Revert "can: raw: instantly reject unsupported CAN frames" This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8 and its follow-up fixes for the introduced dependency issues. commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames") commit cb2dc6d2869a ("can: Kconfig: select CAN driver infrastructure by default") commit 6abd4577bccc ("can: fix build dependency") commit 5a5aff6338c0 ("can: fix build dependency") The entire problem was caused by the requirement that a new network layer feature needed to know about the protocol capabilities of the CAN devices. Instead of accessing CAN device internal data structures which caused the dependency problems a better approach has been developed which makes use of CAN specific ml_priv data which is accessible from both sides. Cc: Marc Kleine-Budde Cc: Arnd Bergmann Cc: Vincent Mailhol Signed-off-by: Oliver Hartkopp Link: https://patch.msgid.link/20260109144135.8495-2-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde --- diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index cfaea6178a71..e15e320db476 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig CAN_DEV - bool "CAN Device Drivers" + tristate "CAN Device Drivers" default y depends on CAN help @@ -17,7 +17,10 @@ menuconfig CAN_DEV virtual ones. If you own such devices or plan to use the virtual CAN interfaces to develop applications, say Y here. -if CAN_DEV && CAN + To compile as a module, choose M here: the module will be called + can-dev. + +if CAN_DEV config CAN_VCAN tristate "Virtual Local CAN Interface (vcan)" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 37e2f1a2faec..d7bc10a6b8ea 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o obj-$(CONFIG_CAN_VXCAN) += vxcan.o obj-$(CONFIG_CAN_SLCAN) += slcan/ -obj-$(CONFIG_CAN_DEV) += dev/ +obj-y += dev/ obj-y += esd/ obj-y += rcar/ obj-y += rockchip/ diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile index 64226acf0f3d..633687d6b6c0 100644 --- a/drivers/net/can/dev/Makefile +++ b/drivers/net/can/dev/Makefile @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CAN) += can-dev.o +obj-$(CONFIG_CAN_DEV) += can-dev.o + +can-dev-y += skb.o -can-dev-$(CONFIG_CAN_DEV) += skb.o can-dev-$(CONFIG_CAN_CALC_BITTIMING) += calc_bittiming.o can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o can-dev-$(CONFIG_CAN_NETLINK) += dev.o diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index f6416a56e95d..52c8be5c160e 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -111,14 +111,7 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, void free_candev(struct net_device *dev); /* a candev safe wrapper around netdev_priv */ -#if IS_ENABLED(CONFIG_CAN_NETLINK) struct can_priv *safe_candev_priv(struct net_device *dev); -#else -static inline struct can_priv *safe_candev_priv(struct net_device *dev) -{ - return NULL; -} -#endif int open_candev(struct net_device *dev); void close_candev(struct net_device *dev); diff --git a/net/can/raw.c b/net/can/raw.c index be1ef7cf4204..f36a83d3447c 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -892,58 +892,20 @@ static void raw_put_canxl_vcid(struct raw_sock *ro, struct sk_buff *skb) } } -static inline bool raw_dev_cc_enabled(struct net_device *dev, - struct can_priv *priv) +static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb, int mtu) { - /* The CANXL-only mode disables error-signalling on the CAN bus - * which is needed to send CAN CC/FD frames - */ - if (priv) - return !can_dev_in_xl_only_mode(priv); - - /* virtual CAN interfaces always support CAN CC */ - return true; -} - -static inline bool raw_dev_fd_enabled(struct net_device *dev, - struct can_priv *priv) -{ - /* check FD ctrlmode on real CAN interfaces */ - if (priv) - return (priv->ctrlmode & CAN_CTRLMODE_FD); - - /* check MTU for virtual CAN FD interfaces */ - return (READ_ONCE(dev->mtu) >= CANFD_MTU); -} - -static inline bool raw_dev_xl_enabled(struct net_device *dev, - struct can_priv *priv) -{ - /* check XL ctrlmode on real CAN interfaces */ - if (priv) - return (priv->ctrlmode & CAN_CTRLMODE_XL); - - /* check MTU for virtual CAN XL interfaces */ - return can_is_canxl_dev_mtu(READ_ONCE(dev->mtu)); -} - -static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb, - struct net_device *dev) -{ - struct can_priv *priv = safe_candev_priv(dev); - - /* Classical CAN */ - if (can_is_can_skb(skb) && raw_dev_cc_enabled(dev, priv)) + /* Classical CAN -> no checks for flags and device capabilities */ + if (can_is_can_skb(skb)) return CAN_MTU; - /* CAN FD */ + /* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */ if (ro->fd_frames && can_is_canfd_skb(skb) && - raw_dev_fd_enabled(dev, priv)) + (mtu == CANFD_MTU || can_is_canxl_dev_mtu(mtu))) return CANFD_MTU; - /* CAN XL */ + /* CAN XL -> needs to be enabled and a CAN XL device */ if (ro->xl_frames && can_is_canxl_skb(skb) && - raw_dev_xl_enabled(dev, priv)) + can_is_canxl_dev_mtu(mtu)) return CANXL_MTU; return 0; @@ -999,7 +961,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) err = -EINVAL; /* check for valid CAN (CC/FD/XL) frame content */ - txmtu = raw_check_txframe(ro, skb, dev); + txmtu = raw_check_txframe(ro, skb, READ_ONCE(dev->mtu)); if (!txmtu) goto free_skb;