All of lore.kernel.org
 help / color / mirror / 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	[thread overview]
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	other threads:[~2020-10-21 17:53 UTC|newest]

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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.