public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Oleksij Rempel <o.rempel@pengutronix.de>
To: "Alexander Hölzl" <alexander.hoelzl@gmx.net>
Cc: robin@protonic.nl, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de, linux-can@vger.kernel.org
Subject: Re: [PATCH] Fix J1939 implementation not handling holds correctly
Date: Wed, 6 May 2026 15:21:04 +0200	[thread overview]
Message-ID: <aftAQHcRYhw1PO8B@pengutronix.de> (raw)
In-Reply-To: <20260504221833.53629-1-alexander.hoelzl@gmx.net>

On Tue, May 05, 2026 at 12:18:33AM +0200, Alexander Hölzl wrote:
> The J1939 protocol allows the receiver of directed segemented messages
> to hold the data transfer. The kernel implementation did not handle hold
> messages correctly was not able to resume from a hold.
> Additionally the incorrect timeout for a held open connection was
> changed to 1050ms.
> Some simple tests for the general protocol behavior have been added.
> 
> This is just an initial draft I'm just looking for some feedback
> if the general setup is acceptable.
> 
> Also I still have some points I'm not sure about.
> 1. There is no check for the reception of a CTS during an ongoing data
>    transfer. According to the standard it is illegal, but I dont think
>    the implementation cares about it. J1939_XTP_ABORT_GENERIC is never
>    referenced and the previous check I removed only really prevented
>    consecutive CTS which are legal if they are holds. Should I add a
>    check for this? This seems to be a slightly different problem so I
>    did not address it.

Current I do not have opinion about this. As long as it is in a separate
patch with enough explanation and tests - I'm OK.

> 2. Should userspace be notified about holds? I don't think the standard
>    gives a maximum 'hold open time' so in theory it could be held
>    indefinetly. This might be a situation a user could be intrested in
>    even though it is rather theoretical.

Yes, it will be good to have a user space feedback. But, it would block
resources. Will we get difference scenarios where we still have an open
session which is blocking other transfers?

> Please tell me what you think.
> 
> Signed-off-by: Alexander Hölzl <alexander.hoelzl@gmx.net>
> ---
>  net/can/j1939/transport.c                     |  50 ++--
>  tools/testing/selftests/net/can/.gitignore    |   1 +
>  tools/testing/selftests/net/can/Makefile      |   8 +-
>  tools/testing/selftests/net/can/config        |   1 +
>  .../testing/selftests/net/can/test_cts_hold.c | 269 ++++++++++++++++++
>  .../selftests/net/can/test_cts_hold.sh        |  45 +++
>  6 files changed, 355 insertions(+), 19 deletions(-)
>  create mode 100644 tools/testing/selftests/net/can/test_cts_hold.c
>  create mode 100755 tools/testing/selftests/net/can/test_cts_hold.sh
> 
> diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
> index df93d57907da..e53a9fbe82a9 100644
> --- a/net/can/j1939/transport.c
> +++ b/net/can/j1939/transport.c
> @@ -1442,9 +1442,27 @@ j1939_xtp_rx_cts_one(struct j1939_session *session, struct sk_buff *skb)
>  
>  	netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
>  
> -	if (session->last_cmd == dat[0]) {
> -		err = J1939_XTP_ABORT_DUP_SEQ;
> -		goto out_session_cancel;
> +	session->last_cmd = dat[0];
> +
> +	/* TODO
> +	 *according to the standard it is illegal to send a CTS while data transfer is ongoing.
> +	 * If a CTS is sent while data transfer is ongoing an abort with code 4 should be sent.
> +	 * The previous check I removed was simply (session->last_cmd == dat[0]).
> +	 * This did not check for a invalid CTS after some data frames had already been
> +	 * sent but before all of them were sent.
> +	 * So CTS(0), CTS(5) was illegal. CTS(5), DAT, CTS(5) was legal,
> +	 * even though only one data frame has been sent instead of 5.
> +	 * Should a check for this also be added?
> +	 */
> +	if (!dat[1]) {

We need a helper function or some defines for different CTS variants.

> +		/* CTS(0) */
> +		if (session->transmission) {
> +			/* TODO notify error queue about hold messages? */

Yes. Can be done in a separate patch.

> +			j1939_session_txtimer_cancel(session);
> +		}
> +		j1939_tp_set_rxtimeout(session, 1050);

I guess we need defines for timouts too.

> +		netdev_dbg(session->priv->ndev, "%s: 0x%p received CTS hold\n", __func__, session);
> +		return;
>  	}
>  
....

> diff --git a/tools/testing/selftests/net/can/.gitignore b/tools/testing/selftests/net/can/.gitignore
> index 764a53fc837f..96ef18ae986d 100644
> --- a/tools/testing/selftests/net/can/.gitignore
> +++ b/tools/testing/selftests/net/can/.gitignore
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  test_raw_filter
> +test_cts_hold
> \ No newline at end of file
> diff --git a/tools/testing/selftests/net/can/Makefile b/tools/testing/selftests/net/can/Makefile
> index 5b82e60a03e7..182346682bce 100644
> --- a/tools/testing/selftests/net/can/Makefile
> +++ b/tools/testing/selftests/net/can/Makefile
> @@ -4,8 +4,12 @@ top_srcdir = ../../../../..
>  
>  CFLAGS += -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INCLUDES)
>  
> -TEST_PROGS := test_raw_filter.sh
> +TEST_PROGS := \
> +	test_raw_filter.sh \
> +	test_cts_hold.sh \
>  
> -TEST_GEN_FILES := test_raw_filter
> +TEST_GEN_FILES := \
> +	test_raw_filter \
> +	test_cts_hold \
>  
>  include ../../lib.mk
> diff --git a/tools/testing/selftests/net/can/config b/tools/testing/selftests/net/can/config
> index 188f79796670..cb538ed93ae4 100644
> --- a/tools/testing/selftests/net/can/config
> +++ b/tools/testing/selftests/net/can/config
> @@ -1,3 +1,4 @@
>  CONFIG_CAN=m
>  CONFIG_CAN_DEV=m
>  CONFIG_CAN_VCAN=m
> +CONFIG_CAN_J1939=m
> \ No newline at end of file
> diff --git a/tools/testing/selftests/net/can/test_cts_hold.c b/tools/testing/selftests/net/can/test_cts_hold.c
> new file mode 100644
> index 000000000000..a36efb099522
> --- /dev/null
> +++ b/tools/testing/selftests/net/can/test_cts_hold.c

Sashiko has here some comments for this file.
https://sashiko.dev/#/patchset/20260504221833.53629-1-alexander.hoelzl%40gmx.net

> +/* Test holding RTS/CTS transport on first frame and resuming immediatley */
> +TEST_F(can_env, test_hold_resume_immediate)
> +/* Test send hold in transport session and resuming */
> +TEST_F(can_env, test_hold_resume)
> +/* Test timeout after not resuming hold */
> +TEST_F(can_env, test_hold_timeout)
 
Nice!

It would be good to add usual transfer test as baseline to make sure
stack works as expected. I guess a simple 2 frame TP should be enough.

Best Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

      reply	other threads:[~2026-05-06 13:21 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04 22:18 [PATCH] Fix J1939 implementation not handling holds correctly Alexander Hölzl
2026-05-06 13:21 ` Oleksij Rempel [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aftAQHcRYhw1PO8B@pengutronix.de \
    --to=o.rempel@pengutronix.de \
    --cc=alexander.hoelzl@gmx.net \
    --cc=kernel@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robin@protonic.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox