Linux-Can Archive on lore.kernel.org
 help / color / Atom feed
From: Oliver Hartkopp <socketcan@hartkopp.net>
To: Vincent MAILHOL <mailhol.vincent@wanadoo.fr>,
	Marc Kleine-Budde <mkl@pengutronix.de>
Cc: linux-can@vger.kernel.org, kernel@pengutronix.de,
	"Stéphane Grosjean" <s.grosjean@peak-system.com>
Subject: Re: [net-rfc 04/16] can: dev: can_get_len(): add a helper function to get the correct length of Classical frames
Date: Wed, 21 Oct 2020 19:52:55 +0200
Message-ID: <727e4845-63bd-659b-5344-97eb54121624@hartkopp.net> (raw)
In-Reply-To: <CAMZ6RqK2RCGLFmjiHTQAxZSGn-HQaAh_nHHGwKdODanZK5oJbg@mail.gmail.com>

On 21.10.20 13:55, Vincent MAILHOL wrote:
>> On 21.10.20 18:48, Oliver Hartkopp wrote:

>> To be more compatible to non raw dlc CAN frame sources the tx handling
>> could also be like this:
>>
>> if ((can_dlc == CAN_MAX_DLEN) &&
>>       (raw_dlc >= CAN_MAX_DLC && raw_dlc <= CAN_MAX_RAW_DLC))
>> => use raw_dlc
>>

(..)

> 
> If I understand well, the idea would be not to use a setsockopt() but
> instead rely on some logic on the can_dlc and raw_dlc to determine
> which one to use.
> 
> Unfortunately, this approach has one issue in the TX path that could
> break existing applications.
> 
> Consider below code (which I think is fairly realistic):
> 
> void send_frame (int soc, canid_t can_id, char *data, size_t len)
> {
>      struct can_frame cf;
>      size_t dlc = len > sizeof(cf.data) ? sizeof(cf.data) : len;
> 
>      cf.can_id = can_id;
>      cf.can_dlc = dlc;
>      memcpy(cf.data, data, dlc);
> 
>      write(soc, &cf, sizeof(cf));
> }
> 
> Here, the user did not initialize the can frame (cf) but assigned all
> the relevant fields manually. Because cf is not initialized, the newly
> introduced cf.dlc_raw field would have any of the values which was
> present on the stack at the moment (rationale: the C standard does not
> guarantee zero initialization). If 9 <= raw_dlc <= 15, the can frame
> will be transmitted with a bad DLC value. If raw_dlc > 15, the can
> frame will be discarded.

No, this is not what I wrote. With my suggestion you need to populate 
both dlc elements to use the new "raw dlc" feature.

if (can_dlc == 8) && (9 <= raw_dlc <= 15)
=> put raw_dlc value into the controller register
else
=> put can_dlc value into the controller register

When you have a test system to make security tests and you enable 
CAN_CTRLMODE_RAW_DLC on a specific CAN interface - which applications 
would you run to send CAN frames on this interface?

I assume only the test application which is really aware of setting 
can_dlc and raw_dlc correctly.

CAN_CTRLMODE_RAW_DLC is no 'standard' option. It's a testing facility 
and only used, when people want to play with raw DLCs.

An option could be to introduce a sockopt CAN_RAW_RAW_DLC that only 
forwards the raw_dlc element for classic CAN frames when enabled, and 
clears the raw_dlc field otherwise.

But again: Who ever enables CAN_CTRLMODE_RAW_DLC has a specific use-case 
in mind and knows what he's doing.

> I think that it is mandatory to have the application declare that it
> wants to use raw DLCs (this way, we know that the code is "DLC
> aware"). I can not think of any transparent approach.
> 
> Next, we might think of using the netlink CAN_CTRLMODE_RAW_DLC and
> the CAN_RAW_RAW_DLC socket option and the raw_dlc field. But I think
> that this is overkill.
> 
> If not introducing new dlc_raw field, the drawback, as you pointed
> out, will be that we would lose the backward compatibility of
> canfd_frame with can_frame and that can_dlc field can not be used
> directly as a length.
> 
> For userland, I think that this is acceptable because the very instant
> the user calls setsockopt() with the CAN_RAW_RAW_DLC, he should be
> aware of the consequences and should resign to use can_dlc field as a
> plain length.

Not filling can_dlc would cause tons of changes for sanity checks and 
feature switches.

Therefore everything should remain as-is and ONLY in the case of 
CAN_CTRLMODE_RAW_DLC and can_dlc == 8 the CAN driver validates the 
raw_dlc value element and uses it for transmission.

> That of course means that this should be clearly
> highlighted when updating the documentation. And users not interested
> by this feature can continue to use it as they did before.
> 
> Inside the kernel, all drivers advertising CAN_CTRLMODE_RAW_DLC will
> also resign the right to use can_dlc as plain length.

As explained before. This would cause effort without any need for the 
can_dlc handling.

> Drivers not
> using it are safe with their existing code. Finally, the TX and RX
> path would both need to be inspected in detail.

Yep.

> TLDR; socket options seem mandatory in all cases. We then have to
> choose between breaking the can_dlc plain length property or
> introducing a new raw_dlc field. My choice goes to the first option of
> breaking the can_dlc plain length property.

The 14 year old documentation in can.h says:
@can_dlc: frame payload length in byte (0 .. 8)

I will not break this established rule for a testing feature. The 
question from Joakim clearly showed: Don't touch this!

At the end it would have made more sense to call it can_frame.len in the 
first place. But this first came into our mind when CAN FD showed up. 
The discussion about the can_dlc meaning can be closed IMO. It is a 
plain length from 0..8 which is unfortunately named can_dlc.

Regards,
Oliver

  reply index

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-19 19:05 [RFC]: can 2020-10-19 Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 01/16] can: proc: can_remove_proc(): silence remove_proc_entry warning Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 02/16] can: rx-offload: don't call kfree_skb() from IRQ context Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 03/16] can: dev: can_get_echo_skb(): prevent call to kfree_skb() in hard " Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 04/16] can: dev: can_get_len(): add a helper function to get the correct length of Classical frames Marc Kleine-Budde
2020-10-19 20:35   ` Oliver Hartkopp
2020-10-20  6:35     ` Marc Kleine-Budde
2020-10-20 11:30       ` Vincent Mailhol
2020-10-20 11:48         ` Marc Kleine-Budde
2020-10-20 12:38         ` Oliver Hartkopp
2020-10-20 15:02           ` Marc Kleine-Budde
2020-10-20 16:07           ` Vincent Mailhol
2020-10-20 17:04             ` Oliver Hartkopp
2020-10-20 18:50               ` Marc Kleine-Budde
2020-10-21  0:52               ` Vincent Mailhol
2020-10-21  6:23                 ` Vincent MAILHOL
2020-10-21  7:11                   ` Joakim Zhang
2020-10-21  7:21                     ` Marc Kleine-Budde
2020-10-21  7:48                       ` Joakim Zhang
2020-10-21  9:21                   ` Oliver Hartkopp
2020-10-21  9:48                     ` Oliver Hartkopp
2020-10-21 11:55                     ` Vincent MAILHOL
2020-10-21 17:52                       ` Oliver Hartkopp [this message]
2020-10-22  3:30                         ` Vincent MAILHOL
2020-10-22  7:15                           ` Oliver Hartkopp
2020-10-22 12:23                             ` Vincent MAILHOL
2020-10-22 13:28                               ` Oliver Hartkopp
2020-10-22 15:46                                 ` Vincent MAILHOL
2020-10-22 17:06                                   ` Oliver Hartkopp
2020-10-23 10:36                                     ` Vincent MAILHOL
2020-10-23 16:47                                       ` Oliver Hartkopp
2020-10-24  5:25                                         ` Vincent MAILHOL
2020-10-24 11:31                                           ` Oliver Hartkopp
2020-10-19 19:05 ` [net-rfc 05/16] can: dev: __can_get_echo_skb(): fix the returned length of CAN frame Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 06/16] can: can_create_echo_skb(): fix echo skb generation: always use skb_clone() Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 07/16] can: j1939: j1939_sk_bind(): return failure if netdev is down Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 08/16] can: isotp: Explain PDU in CAN_ISOTP help text Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 09/16] can: isotp: enable RX timeout handling in listen-only mode Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 10/16] can: ti_hecc: add missed clk_disable_unprepare() in error path Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 11/16] can: xilinx_can: handle failure cases of pm_runtime_get_sync Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 12/16] can: peak_usb: fix timestamp wrapping Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 13/16] can: peak_canfd: fix echo management when loopback is on Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 14/16] can: mcp251xfd: mcp251xfd_regmap_crc_read(): increase severity of CRC read error messages Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 15/16] can: mcp251xfd: mcp251xfd_regmap_nocrc_read(): fix semicolon.cocci warnings Marc Kleine-Budde
2020-10-19 19:05 ` [net-rfc 16/16] can: mcp251xfd: remove unneeded break Marc Kleine-Budde

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=727e4845-63bd-659b-5344-97eb54121624@hartkopp.net \
    --to=socketcan@hartkopp.net \
    --cc=kernel@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=mailhol.vincent@wanadoo.fr \
    --cc=mkl@pengutronix.de \
    --cc=s.grosjean@peak-system.com \
    /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

Linux-Can Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-can/0 linux-can/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-can linux-can/ https://lore.kernel.org/linux-can \
		linux-can@vger.kernel.org
	public-inbox-index linux-can

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-can


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git