lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <cd26154c-a5a5-f83c-0c8e-5bf65b50b278@hartkopp.net>
Date:   Mon, 9 Nov 2020 16:51:46 +0100
From:   Oliver Hartkopp <socketcan@...tkopp.net>
To:     Vincent MAILHOL <mailhol.vincent@...adoo.fr>
Cc:     linux-can <linux-can@...r.kernel.org>,
        Marc Kleine-Budde <mkl@...gutronix.de>,
        netdev <netdev@...r.kernel.org>
Subject: Re: [PATCH v4 5/7] can: update documentation for DLC usage in
 Classical CAN



On 09.11.20 15:50, Vincent MAILHOL wrote:
> On Mon. 9 Nov 2020 at 19:26, Oliver Hartkopp wrote:
>>
>> The extension of struct can_frame with the len8_dlc element and the
>> can_dlc naming issue required an update of the documentation.
>>
>> Additionally introduce the term 'Classical CAN' which has been established
>> by CAN in Automation to separate the original CAN2.0 A/B from CAN FD.
>>
>> Updated some data structures and flags.
>>
>> Signed-off-by: Oliver Hartkopp <socketcan@...tkopp.net>
>> ---
>>   Documentation/networking/can.rst | 68 ++++++++++++++++++++++++--------
>>   1 file changed, 52 insertions(+), 16 deletions(-)
>>
>> diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst
>> index ff05cbd05e0d..e17c6427bb3a 100644
>> --- a/Documentation/networking/can.rst
>> +++ b/Documentation/networking/can.rst
>> @@ -226,24 +226,40 @@ interface (which is different from TCP/IP due to different addressing
>>   the socket, you can read(2) and write(2) from/to the socket or use
>>   send(2), sendto(2), sendmsg(2) and the recv* counterpart operations
>>   on the socket as usual. There are also CAN specific socket options
>>   described below.
>>
>> -The basic CAN frame structure and the sockaddr structure are defined
>> -in include/linux/can.h:
>> +The Classical CAN frame structure (aka CAN 2.0B), the CAN FD frame structure
>> +and the sockaddr structure are defined in include/linux/can.h:
>>
>>   .. code-block:: C
>>
>>       struct can_frame {
>>               canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
>> -            __u8    can_dlc; /* frame payload length in byte (0 .. 8) */
>> +            union {
>> +                    /* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
>> +                     * was previously named can_dlc so we need to carry that
>> +                     * name for legacy support
>> +                     */
>> +                    __u8 len;
>> +                    __u8 can_dlc; /* deprecated */
>> +            };
>>               __u8    __pad;   /* padding */
>>               __u8    __res0;  /* reserved / padding */
>> -            __u8    __res1;  /* reserved / padding */
>> +            __u8    len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */
>>               __u8    data[8] __attribute__((aligned(8)));
>>       };
>>
>> +Remark: The len element contains the payload length in bytes and should be
>> +used instead of can_dlc. The deprecated can_dlc was misleadingly named as
>> +it always contained the plain payload length in bytes and not the so called
>> +'data length code' (DLC).
>> +
>> +To pass the raw DLC from/to a Classical CAN network device the len8_dlc
>> +element can contain values 9 .. 15 when the len element is 8 (the real
>> +payload length for all DLC values greater or equal to 8).
> 
> The "Classical CAN network device" part could make the reader
> misunderstand that FD capable controllers can not handle Classical CAN
> frames with DLC greater than 8. All the CAN-FD controllers I am aware
> of can emit both Classical and FD frames. On the contrary, some
> Classical CAN controllers might not support sending DLCs greater than
> 8. Propose to add the nuance that this depends on the device property:
> 
>   +To pass the raw DLC from/to a capable network device
>   +(c.f. cc-len8-dlc CAN device property), the len8_dlc element can
>   +contain values 9 .. 15 when the len element is 8 (the real payload
>   +length for all DLC values greater or equal to 8).
> 

This section only describes the Classical CAN data structure. I also 
thought about it - but I did not want to overload it with device properties.

>> +
>>   The alignment of the (linear) payload data[] to a 64bit boundary
>>   allows the user to define their own structs and unions to easily access
>>   the CAN payload. There is no given byteorder on the CAN bus by
>>   default. A read(2) system call on a CAN_RAW socket transfers a
>>   struct can_frame to the user space.
>> @@ -258,10 +274,27 @@ PF_PACKET socket, that also binds to a specific interface:
>>               int         can_ifindex;
>>               union {
>>                       /* transport protocol class address info (e.g. ISOTP) */
>>                       struct { canid_t rx_id, tx_id; } tp;
>>
>> +                    /* J1939 address information */
>> +                    struct {
>> +                            /* 8 byte name when using dynamic addressing */
>> +                            __u64 name;
>> +
>> +                            /* pgn:
>> +                             * 8 bit: PS in PDU2 case, else 0
>> +                             * 8 bit: PF
>> +                             * 1 bit: DP
>> +                             * 1 bit: reserved
>> +                             */
>> +                            __u32 pgn;
>> +
>> +                            /* 1 byte address */
>> +                            __u8 addr;
>> +                    } j1939;
>> +
>>                       /* reserved for future CAN protocols address information */
>>               } can_addr;
>>       };
> 
> This looks like some J1939 code. Did you mix your patches?
> 

This belongs to "update data structures" in the commit message ;-)

>>   To determine the interface index an appropriate ioctl() has to
>> @@ -369,11 +402,11 @@ bitrates for the arbitration phase and the payload phase of the CAN FD frame
>>   and up to 64 bytes of payload. This extended payload length breaks all the
>>   kernel interfaces (ABI) which heavily rely on the CAN frame with fixed eight
>>   bytes of payload (struct can_frame) like the CAN_RAW socket. Therefore e.g.
>>   the CAN_RAW socket supports a new socket option CAN_RAW_FD_FRAMES that
>>   switches the socket into a mode that allows the handling of CAN FD frames
>> -and (legacy) CAN frames simultaneously (see :ref:`socketcan-rawfd`).
>> +and Classical CAN frames simultaneously (see :ref:`socketcan-rawfd`).
>>
>>   The struct canfd_frame is defined in include/linux/can.h:
>>
>>   .. code-block:: C
>>
>> @@ -395,21 +428,21 @@ all structure elements can be used as-is - only the data[] becomes extended.
> 
> In below paragraph, needs to add an exception for can_frame.len8_dlc:
> 
>   The struct canfd_frame and the existing struct can_frame have the can_id,
>   the payload length and the payload data at the same offset inside their
>   structures. This allows to handle the different structures very similar.
>   When the content of a struct can_frame is copied into a struct canfd_frame
>   -all structure elements can be used as-is - only the data[] becomes extended.
>   +all structure elements (except the len8_dlc field) can be used as-is and the
>   +data[] becomes extended.
> 

This section tells about the mapping of "the can_id, the payload length 
and the payload data"

Intentionally nothing about flags and len8_dlc.

>>   When introducing the struct canfd_frame it turned out that the data length
>>   code (DLC) of the struct can_frame was used as a length information as the
>>   length and the DLC has a 1:1 mapping in the range of 0 .. 8. To preserve
>>   the easy handling of the length information the canfd_frame.len element
>>   contains a plain length value from 0 .. 64. So both canfd_frame.len and
>> -can_frame.can_dlc are equal and contain a length information and no DLC.
>> +can_frame.len are equal and contain a length information and no DLC.
>>   For details about the distinction of CAN and CAN FD capable devices and
>>   the mapping to the bus-relevant data length code (DLC), see :ref:`socketcan-can-fd-driver`.
> 
> Now that the field has been renamed, the "1:1 mapping" explanation
> becomes obsolete. I propose to drastically reduce the paragraph:
> 

I would suggest to send a patch when the patch set has been applied. The 
process is slightly wrong, when you dictate your suggestions and I 
re-post version by version.

Thanks,
Oliver

>   +Despite being formerly named can_dlc, the len field of both struct
>   +can_frame and struct canfd_frame are equal and contain a plain length
>   +value from 0 .. 64; no DLC.  For details about the distinction of CAN
>   +and CAN FD capable devices and the mapping to the bus-relevant data
>   +length code (DLC), see :ref:`socketcan-can-fd-driver`.
> 
>>   The length of the two CAN(FD) frame structures define the maximum transfer
>>   unit (MTU) of the CAN(FD) network interface and skbuff data length. Two
>>   definitions are specified for CAN specific MTUs in include/linux/can.h:
>>
>>   .. code-block:: C
>>
>> -  #define CAN_MTU   (sizeof(struct can_frame))   == 16  => 'legacy' CAN frame
>> +  #define CAN_MTU   (sizeof(struct can_frame))   == 16  => Classical CAN frame
>>     #define CANFD_MTU (sizeof(struct canfd_frame)) == 72  => CAN FD frame
>>
>>
>>   .. _socketcan-raw-sockets:
>>
>> @@ -607,11 +640,11 @@ Example:
>>
>>       if (nbytes == CANFD_MTU) {
>>               printf("got CAN FD frame with length %d\n", cfd.len);
>>               /* cfd.flags contains valid data */
>>       } else if (nbytes == CAN_MTU) {
>> -            printf("got legacy CAN frame with length %d\n", cfd.len);
>> +            printf("got Classical CAN frame with length %d\n", cfd.len);
>>               /* cfd.flags is undefined */
>>       } else {
>>               fprintf(stderr, "read: invalid CAN(FD) frame\n");
>>               return 1;
>>       }
>> @@ -621,21 +654,21 @@ Example:
>>       printf("can_id: %X data length: %d data: ", cfd.can_id, cfd.len);
>>       for (i = 0; i < cfd.len; i++)
>>               printf("%02X ", cfd.data[i]);
>>
>>   When reading with size CANFD_MTU only returns CAN_MTU bytes that have
>> -been received from the socket a legacy CAN frame has been read into the
>> +been received from the socket a Classical CAN frame has been read into the
>>   provided CAN FD structure. Note that the canfd_frame.flags data field is
>>   not specified in the struct can_frame and therefore it is only valid in
>>   CANFD_MTU sized CAN FD frames.
>>
>>   Implementation hint for new CAN applications:
>>
>>   To build a CAN FD aware application use struct canfd_frame as basic CAN
>>   data structure for CAN_RAW based applications. When the application is
>>   executed on an older Linux kernel and switching the CAN_RAW_FD_FRAMES
>> -socket option returns an error: No problem. You'll get legacy CAN frames
>> +socket option returns an error: No problem. You'll get Classical CAN frames
>>   or CAN FD frames and can process them the same way.
>>
>>   When sending to CAN devices make sure that the device is capable to handle
>>   CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
>>   The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
>> @@ -840,10 +873,12 @@ TX_RESET_MULTI_IDX:
>>          Reset the index for the multiple frame transmission.
>>
>>   RX_RTR_FRAME:
>>          Send reply for RTR-request (placed in op->frames[0]).
>>
>> +CAN_FD_FRAME:
>> +       The CAN frames following the bcm_msg_head are struct canfd_frame's
>>
>>   Broadcast Manager Transmission Timers
>>   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>
>>   Periodic transmission configurations may use up to two interval timers.
>> @@ -1024,11 +1059,11 @@ In this example an application requests any CAN traffic from vcan0::
>>
>>   Additional procfs files in /proc/net/can::
>>
>>       stats       - SocketCAN core statistics (rx/tx frames, match ratios, ...)
>>       reset_stats - manual statistic reset
>> -    version     - prints the SocketCAN core version and the ABI version
>> +    version     - prints SocketCAN core and ABI version (removed in Linux 5.10)
>>
>>
>>   Writing Own CAN Protocol Modules
>>   --------------------------------
>>
>> @@ -1068,11 +1103,11 @@ General Settings
>>   .. code-block:: C
>>
>>       dev->type  = ARPHRD_CAN; /* the netdevice hardware type */
>>       dev->flags = IFF_NOARP;  /* CAN has no arp */
>>
>> -    dev->mtu = CAN_MTU; /* sizeof(struct can_frame) -> legacy CAN interface */
>> +    dev->mtu = CAN_MTU; /* sizeof(struct can_frame) -> Classical CAN interface */
>>
>>       or alternative, when the controller supports CAN with flexible data rate:
>>       dev->mtu = CANFD_MTU; /* sizeof(struct canfd_frame) -> CAN FD interface */
>>
>>   The struct can_frame or struct canfd_frame is the payload of each socket
>> @@ -1182,10 +1217,11 @@ Setting CAN device properties::
>>           [ one-shot { on | off } ]
>>           [ berr-reporting { on | off } ]
>>           [ fd { on | off } ]
>>           [ fd-non-iso { on | off } ]
>>           [ presume-ack { on | off } ]
>> +        [ cc-len8-dlc { on | off } ]
>>
>>           [ restart-ms TIME-MS ]
>>           [ restart ]
>>
>>           Where: BITRATE       := { 1..1000000 }
>> @@ -1324,26 +1360,26 @@ CAN FD (Flexible Data Rate) Driver Support
>>   CAN FD capable CAN controllers support two different bitrates for the
>>   arbitration phase and the payload phase of the CAN FD frame. Therefore a
>>   second bit timing has to be specified in order to enable the CAN FD bitrate.
>>
>>   Additionally CAN FD capable CAN controllers support up to 64 bytes of
>> -payload. The representation of this length in can_frame.can_dlc and
>> +payload. The representation of this length in can_frame.len and
>>   canfd_frame.len for userspace applications and inside the Linux network
>>   layer is a plain value from 0 .. 64 instead of the CAN 'data length code'.
>> -The data length code was a 1:1 mapping to the payload length in the legacy
>> +The data length code was a 1:1 mapping to the payload length in the Classical
>>   CAN frames anyway. The payload length to the bus-relevant DLC mapping is
>>   only performed inside the CAN drivers, preferably with the helper
>>   functions can_dlc2len() and can_len2dlc().
> 
> Same as above: the "1:1 mapping" part is obsolete. Now that can_dlc
> has been renamed to length, no need to cover this matter in further
> details. I propose to replace it by below paragraph:
> 
>   +Additionally CAN FD capable CAN controllers support up to 64 bytes of
>   +payload. The representation of this length in can_frame.len and
>   +canfd_frame.len for userspace applications and inside the Linux
>   +network layer is a plain value from 0 .. 64.
> 
> In addition, I propose to add a sentence about the two new DLC helper
> functions:
> 
>   +The payload length to the bus-relevant DLC mapping is only performed
>   +inside the CAN drivers, preferably with the helper functions
>   +can_dlc2len() and can_len2dlc(). If the controller handles Classical
>   +CAN frames with DLC greater than 8, helper functions
>   +can_get_len8_dlc() and can_get_cc_dlc() can be used to respectively
>   +fill the len8_dlc fill during reception and get the DLC value during
> 
>>
>>   The CAN netdevice driver capabilities can be distinguished by the network
>>   devices maximum transfer unit (MTU)::
>>
>> -  MTU = 16 (CAN_MTU)   => sizeof(struct can_frame)   => 'legacy' CAN device
>> +  MTU = 16 (CAN_MTU)   => sizeof(struct can_frame)   => Classical CAN device
>>     MTU = 72 (CANFD_MTU) => sizeof(struct canfd_frame) => CAN FD capable device
>>
>>   The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
>> -N.B. CAN FD capable devices can also handle and send legacy CAN frames.
>> +N.B. CAN FD capable devices can also handle and send Classical CAN frames.
>>
>>   When configuring CAN FD capable CAN controllers an additional 'data' bitrate
>>   has to be set. This bitrate for the data phase of the CAN FD frame has to be
>>   at least the bitrate which was configured for the arbitration phase. This
>>   second bitrate is specified analogue to the first bitrate but the bitrate

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ