Skip to content

Commit 36c0124

Browse files
hartkoppmarckleinebudde
authored andcommitted
can: fix loss of CAN frames in raw_rcv
As reported by Manfred Schlaegl here http://marc.info/?l=linux-netdev&m=143482089824232&w=2 commit 514ac99 "can: fix multiple delivery of a single CAN frame for overlapping CAN filters" requires the skb->tstamp to be set to check for identical CAN skbs. As net timestamping is influenced by several players (netstamp_needed and netdev_tstamp_prequeue) Manfred missed a proper timestamp which leads to CAN frame loss. As skb timestamping became now mandatory for CAN related skbs this patch makes sure that received CAN skbs always have a proper timestamp set. Maybe there's a better solution in the future but this patch fixes the CAN frame loss so far. Reported-by: Manfred Schlaegl <manfred.schlaegl@gmx.at> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent 7b48f45 commit 36c0124

File tree

4 files changed

+14
-1
lines changed

4 files changed

+14
-1
lines changed

drivers/net/can/dev.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
440440
struct can_frame *cf = (struct can_frame *)skb->data;
441441
u8 dlc = cf->can_dlc;
442442

443+
if (!(skb->tstamp.tv64))
444+
__net_timestamp(skb);
445+
443446
netif_rx(priv->echo_skb[idx]);
444447
priv->echo_skb[idx] = NULL;
445448

@@ -575,6 +578,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
575578
if (unlikely(!skb))
576579
return NULL;
577580

581+
__net_timestamp(skb);
578582
skb->protocol = htons(ETH_P_CAN);
579583
skb->pkt_type = PACKET_BROADCAST;
580584
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -603,6 +607,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
603607
if (unlikely(!skb))
604608
return NULL;
605609

610+
__net_timestamp(skb);
606611
skb->protocol = htons(ETH_P_CANFD);
607612
skb->pkt_type = PACKET_BROADCAST;
608613
skb->ip_summed = CHECKSUM_UNNECESSARY;

drivers/net/can/slcan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ static void slc_bump(struct slcan *sl)
207207
if (!skb)
208208
return;
209209

210+
__net_timestamp(skb);
210211
skb->dev = sl->dev;
211212
skb->protocol = htons(ETH_P_CAN);
212213
skb->pkt_type = PACKET_BROADCAST;

drivers/net/can/vcan.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
7878
skb->dev = dev;
7979
skb->ip_summed = CHECKSUM_UNNECESSARY;
8080

81+
if (!(skb->tstamp.tv64))
82+
__net_timestamp(skb);
83+
8184
netif_rx_ni(skb);
8285
}
8386

net/can/af_can.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,12 @@ int can_send(struct sk_buff *skb, int loop)
310310
return err;
311311
}
312312

313-
if (newskb)
313+
if (newskb) {
314+
if (!(newskb->tstamp.tv64))
315+
__net_timestamp(newskb);
316+
314317
netif_rx_ni(newskb);
318+
}
315319

316320
/* update statistics */
317321
can_stats.tx_frames++;

0 commit comments

Comments
 (0)