From 15e31ad310ec9b245849ec6952c22217167cdf4a Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Thu, 8 May 2008 02:49:55 -0700 Subject: [PATCH] can: Fix can_send() handling on dev_queue_xmit() failures [ Upstream commit: c2ab7ac225e29006b7117d6a9fe8f3be8d98b0c2 ] The tx packet counting and the local loopback of CAN frames should only happen in the case that the CAN frame has been enqueued to the netdevice tx queue successfully. Thanks to Andre Naujoks for reporting this issue. Signed-off-by: Oliver Hartkopp Signed-off-by: Urs Thuermann Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/can/af_can.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/can/af_can.c b/net/can/af_can.c index 36b9f22ed83a..6b956f5fc683 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -208,6 +208,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol) */ int can_send(struct sk_buff *skb, int loop) { + struct sk_buff *newskb = NULL; int err; if (skb->dev->type != ARPHRD_CAN) { @@ -244,8 +245,7 @@ int can_send(struct sk_buff *skb, int loop) * If the interface is not capable to do loopback * itself, we do it here. */ - struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); - + newskb = skb_clone(skb, GFP_ATOMIC); if (!newskb) { kfree_skb(skb); return -ENOMEM; @@ -254,7 +254,6 @@ int can_send(struct sk_buff *skb, int loop) newskb->sk = skb->sk; newskb->ip_summed = CHECKSUM_UNNECESSARY; newskb->pkt_type = PACKET_BROADCAST; - netif_rx(newskb); } } else { /* indication for the CAN driver: no loopback required */ @@ -266,11 +265,20 @@ int can_send(struct sk_buff *skb, int loop) if (err > 0) err = net_xmit_errno(err); + if (err) { + if (newskb) + kfree_skb(newskb); + return err; + } + + if (newskb) + netif_rx(newskb); + /* update statistics */ can_stats.tx_frames++; can_stats.tx_frames_delta++; - return err; + return 0; } EXPORT_SYMBOL(can_send); -- 2.39.5