Re: [PATCH 2/2] can: gw: add support for CAN FD frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 7/24/19 8:07 PM, Oliver Hartkopp wrote:
> On 24.07.19 15:36, Marc Kleine-Budde wrote:
> 
>>> @@ -425,23 +502,22 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
>>>   		int max_len = nskb->len - offsetof(struct canfd_frame, data);
>>
>> I know, this is original code...but max_len can either be 8 (for CAN
>> frames) or 64 (for CAN-FD frames)? Because we always have full can_frame
>> or canfd_frame in the skb, right?  I assume a lot more will break if the
>> len neither 8 nor 64.
> 
> Yes. The code has been added recently for commit 0aaa81377c5a0 ("can: 
> gw: ensure DLC boundaries after CAN frame modification") to check the 
> data length after the CAN frame modification.
> 
> And yes, we only have proper CAN (FD) frames in our skbs which have a 
> special ethertype :-)
> 
>>>   		/* dlc may have changed, make sure it fits to the CAN frame */
>>> -		if (cf->len > max_len)
>>> -			goto out_delete;
>>> +		if (cf->len > max_len) {
>>> +			/* delete frame due to misconfiguration */
>>> +			gwj->deleted_frames++;
>>> +			kfree_skb(nskb);
>>> +			return;
>>> +		}
>>>   
>>> -		/* check for checksum updates in classic CAN length only */
>>> -		if (gwj->mod.csumfunc.crc8) {
>>> -			if (cf->len > 8)
>>> -				goto out_delete;
>>> +		/* ensure a valid CAN (FD) frame data length */
>>> +		cf->len = validate_len[cf->len];
>>
>> This looks strange to me, but I cannot say if I don't userstand this or
>> if there really is a potential problem:
>> - first you calculate max_len
>> - the cf->len > max_len is discarded
> 
> Right. In this case the frame modification leads to a length value 
> beyond 8/64 byte, which is then discarded.
> 
>> - but then cf->len is "rounded up" via validate_len[].
>>
>> What's the purpose of the last step?
> 
> Ha, good question :-)
> 
> The reason for this results from the non-linear data length code for CAN 
> FD data length.
> 
> For CAN you can have 0, 1, 2, 3, 4, 5, 6, 7, 8
> 
> For CAN FD it is 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64
> 
> If the CAN FD length was 12 before the modification and the modification 
> was to "set bit 0 in the length field" then you get 13.

ok

> But the length value of 13 is an illegal value for CAN FD length and can 
> not been sent by a CAN FD controller.

ok, but that doesn't matter, because all CAN-FD drivers must convert
from struct canfd_frame::len to the dlc (== their register value)
anyways using the can_len2dlc() function.

> Therefore we need a round-up to get the next valid CAN FD length value 
> (in our example it get's from 13 to 16).

I don't think this is needed, the user space might send such packets and
the drivers have to deal with then anyways.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux