From nobody Mon Dec 1 23:03:14 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8D94301022 for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=BBG3U+Tw8QyQLVpBIoKZeTfyfBNmwNeyDIB6mJuY0grw+VKFbU231JJKbhO1yED76Xnd5hm4hfL8YQVYJwBsTPvZ0/+rP/XlSyuPBb7Ki2bt4WlIZkbPIA55VfwLBY16GKI2CgDKuU702E0Ki+HLJ+6IX+Ra7KctG/92vASEeyo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=MudyV2+Az6NVUbd0rFJJ79+x63NERXYJcrD/ldU2anA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=umnAX/kg0HrPdbndtoaoxlQllaCX9nh9m8e9+BTl5PzviSpczJSpa7ilAV+CTITlLbFTgg8KnlOdz2afCh+y5yeYNGgXxoHt9jtbito3E27OYIww8Gl2rlDBMYKbzR6Xh3cv8ugGVbMgZu81W/gRXTDeZANEbCt7yMSS+n8JgsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qj-85; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSd-01; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id B60BD4A88D5; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:05 +0100 Subject: [PATCH can-next v8 04/17] can: netlink: add CAN_CTRLMODE_RESTRICTED Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-4-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5361; i=mkl@pengutronix.de; h=from:subject:message-id; bh=vv6La5M2jV8ebLvbWsVz47qHm5ZFMKT4yraL+I9/B4o=; b=owEBbAGT/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN5vlHQdCoZLKWUzHP/d9o6+AHk9+3c2UnmO 3CoyzMLPE+JATIEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTeQAKCRAMdGXf+ZCR nIGAB/UbDw91mU3jusTyWgEFXXOTFggA5ZBUPj2rIM7LYHuLHXXWghTumiHoP3AgrjqrvrLfcs5 V7KCXRJQSmJEjIA+g48MVyLWMccbUkvjQdl0e2YebbsSG7STVUasH12mRqXyjaJgemwa6GXK6fa 0FirW9dPeKtKKESWnxdqrkjlOql7alYpmg8XBeGEwtKX/18fOUQufn7gV+pKPvC/ym06T4CvTg6 kA+TKSWCTeNZU7Abt/dvSGx5yXNsZgYoOLcoig5s9HBIhf7Z5UCQIHBcmrOWKrjtGdWJo7Vk413 PZYm36oZFSCKLZ4ufolDmIt8oT6UDARlYQiScgJHQkcxn80= X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol ISO 11898-1:2024 adds a new restricted operation mode. This mode is added as a mandatory feature for nodes which support CAN XL and is retrofitted as optional for legacy nodes (i.e. the ones which only support Classical CAN and CAN FD). The restricted operation mode is nearly the same as the listen only mode: the node can not send data frames or remote frames and can not send dominant bits if an error occurs. The only exception is that the node shall still send the acknowledgment bit. A second niche exception is that the node may still send a data frame containing a time reference message if the node is a primary time provider, but because the time provider feature is not yet implemented in the kernel, this second exception is not relevant to us at the moment. Add the CAN_CTRLMODE_RESTRICTED control mode flag and update the can_dev_dropped_skb() helper function accordingly. Finally, bail out if both CAN_CTRLMODE_LISTENONLY and CAN_CTRLMODE_RESTRICTED are provided. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 2 ++ drivers/net/can/dev/netlink.c | 7 ++++++ include/linux/can/dev.h | 50 +++++++++++++++++++++---------------= ---- include/uapi/linux/can/netlink.h | 1 + 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index b392483e4499..b6980d32e5b4 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -115,6 +115,8 @@ const char *can_get_ctrlmode_str(u32 ctrlmode) return "TDC-AUTO"; case CAN_CTRLMODE_TDC_MANUAL: return "TDC-MANUAL"; + case CAN_CTRLMODE_RESTRICTED: + return "RESTRICTED"; default: return ""; } diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 6f83b87d54fc..87e731527dd7 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -188,6 +188,13 @@ static int can_validate(struct nlattr *tb[], struct nl= attr *data[], struct can_ctrlmode *cm =3D nla_data(data[IFLA_CAN_CTRLMODE]); =20 flags =3D cm->flags & cm->mask; + + if ((flags & CAN_CTRLMODE_LISTENONLY) && + (flags & CAN_CTRLMODE_RESTRICTED)) { + NL_SET_ERR_MSG(extack, + "LISTEN-ONLY and RESTRICTED modes are mutually exclusive"); + return -EOPNOTSUPP; + } } =20 err =3D can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING); diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index a7a39a6101d9..ab11c0e9111b 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -95,30 +95,6 @@ static inline bool can_is_canxl_dev_mtu(unsigned int mtu) return (mtu >=3D CANXL_MIN_MTU && mtu <=3D CANXL_MAX_MTU); } =20 -/* drop skb if it does not contain a valid CAN frame for sending */ -static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_b= uff *skb) -{ - struct can_priv *priv =3D netdev_priv(dev); - - if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { - netdev_info_once(dev, - "interface in listen only mode, dropping skb\n"); - goto invalid_skb; - } - - if (!(priv->ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { - netdev_info_once(dev, "CAN FD is disabled, dropping skb\n"); - goto invalid_skb; - } - - return can_dropped_invalid_skb(dev, skb); - -invalid_skb: - kfree_skb(skb); - dev->stats.tx_dropped++; - return true; -} - void can_setup(struct net_device *dev); =20 struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb= _max, @@ -154,6 +130,32 @@ void can_bus_off(struct net_device *dev); const char *can_get_state_str(const enum can_state state); const char *can_get_ctrlmode_str(u32 ctrlmode); =20 +/* drop skb if it does not contain a valid CAN frame for sending */ +static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_b= uff *skb) +{ + struct can_priv *priv =3D netdev_priv(dev); + u32 silent_mode =3D priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_RESTRICTED); + + if (silent_mode) { + netdev_info_once(dev, "interface in %s mode, dropping skb\n", + can_get_ctrlmode_str(silent_mode)); + goto invalid_skb; + } + + if (!(priv->ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { + netdev_info_once(dev, "CAN FD is disabled, dropping skb\n"); + goto invalid_skb; + } + + return can_dropped_invalid_skb(dev, skb); + +invalid_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return true; +} + void can_state_get_by_berr_counter(const struct net_device *dev, const struct can_berr_counter *bec, enum can_state *tx_state, diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netl= ink.h index ef62f56eaaef..fafd1cce4798 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -103,6 +103,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */ #define CAN_CTRLMODE_TDC_AUTO 0x200 /* FD transceiver automatically calcu= lates TDCV */ #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* FD TDCV is manually set up by us= er */ +#define CAN_CTRLMODE_RESTRICTED 0x800 /* Restricted operation mode */ =20 /* * CAN device statistics --=20 2.51.0