aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorOliver Hartkopp <oliver@hartkopp.net>2010-01-12 05:00:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-12 05:00:46 -0500
commit3ccd4c6167d3b39d52631767ebbf8b5677c5855d (patch)
treebfcb801edebd00e8b30e897038bad7fee39625cc /drivers/net/can
parentd218d11133d888f9745802146a50255a4781d37a (diff)
can: Unify droping of invalid tx skbs and netdev stats
To prevent the CAN drivers to operate on invalid socketbuffers the skbs are now checked and silently dropped at the xmit-function consistently. Also the netdev stats are consistently using the CAN data length code (dlc) for [rx|tx]_bytes now. Signed-off-by: Oliver Hartkopp <oliver@hartkopp.net> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/at91_can.c3
-rw-r--r--drivers/net/can/bfin_can.c3
-rw-r--r--drivers/net/can/mcp251x.c6
-rw-r--r--drivers/net/can/mscan/mscan.c5
-rw-r--r--drivers/net/can/sja1000/sja1000.c3
-rw-r--r--drivers/net/can/ti_hecc.c4
-rw-r--r--drivers/net/can/usb/ems_usb.c3
-rw-r--r--drivers/net/can/vcan.c12
8 files changed, 26 insertions, 13 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 166cc7e579c0..f7287497ba6e 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -342,6 +342,9 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
342 unsigned int mb, prio; 342 unsigned int mb, prio;
343 u32 reg_mid, reg_mcr; 343 u32 reg_mid, reg_mcr;
344 344
345 if (can_dropped_invalid_skb(dev, skb))
346 return NETDEV_TX_OK;
347
345 mb = get_tx_next_mb(priv); 348 mb = get_tx_next_mb(priv);
346 prio = get_tx_next_prio(priv); 349 prio = get_tx_next_prio(priv);
347 350
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
index 0ec1524523cc..7e1926e79e98 100644
--- a/drivers/net/can/bfin_can.c
+++ b/drivers/net/can/bfin_can.c
@@ -318,6 +318,9 @@ static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev)
318 u16 val; 318 u16 val;
319 int i; 319 int i;
320 320
321 if (can_dropped_invalid_skb(dev, skb))
322 return NETDEV_TX_OK;
323
321 netif_stop_queue(dev); 324 netif_stop_queue(dev);
322 325
323 /* fill id */ 326 /* fill id */
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index 1a72ca066a17..afa2fa45fed9 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -494,12 +494,8 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
494 return NETDEV_TX_BUSY; 494 return NETDEV_TX_BUSY;
495 } 495 }
496 496
497 if (skb->len != sizeof(struct can_frame)) { 497 if (can_dropped_invalid_skb(net, skb))
498 dev_err(&spi->dev, "dropping packet - bad length\n");
499 dev_kfree_skb(skb);
500 net->stats.tx_dropped++;
501 return NETDEV_TX_OK; 498 return NETDEV_TX_OK;
502 }
503 499
504 netif_stop_queue(net); 500 netif_stop_queue(net);
505 priv->tx_skb = skb; 501 priv->tx_skb = skb;
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 500d18918bd5..40827c128b65 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -204,11 +204,8 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
204 int i, rtr, buf_id; 204 int i, rtr, buf_id;
205 u32 can_id; 205 u32 can_id;
206 206
207 if (skb->len != sizeof(*frame) || frame->can_dlc > 8) { 207 if (can_dropped_invalid_skb(dev, skb))
208 kfree_skb(skb);
209 dev->stats.tx_dropped++;
210 return NETDEV_TX_OK; 208 return NETDEV_TX_OK;
211 }
212 209
213 out_8(&regs->cantier, 0); 210 out_8(&regs->cantier, 0);
214 211
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 542a4f7255b4..345304d779b9 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -249,6 +249,9 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
249 uint8_t dreg; 249 uint8_t dreg;
250 int i; 250 int i;
251 251
252 if (can_dropped_invalid_skb(dev, skb))
253 return NETDEV_TX_OK;
254
252 netif_stop_queue(dev); 255 netif_stop_queue(dev);
253 256
254 fi = dlc = cf->can_dlc; 257 fi = dlc = cf->can_dlc;
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 5c993c2da528..7d370e32a7a8 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -477,6 +477,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
477 u32 mbxno, mbx_mask, data; 477 u32 mbxno, mbx_mask, data;
478 unsigned long flags; 478 unsigned long flags;
479 479
480 if (can_dropped_invalid_skb(ndev, skb))
481 return NETDEV_TX_OK;
482
480 mbxno = get_tx_head_mb(priv); 483 mbxno = get_tx_head_mb(priv);
481 mbx_mask = BIT(mbxno); 484 mbx_mask = BIT(mbxno);
482 spin_lock_irqsave(&priv->mbx_lock, flags); 485 spin_lock_irqsave(&priv->mbx_lock, flags);
@@ -491,7 +494,6 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
491 spin_unlock_irqrestore(&priv->mbx_lock, flags); 494 spin_unlock_irqrestore(&priv->mbx_lock, flags);
492 495
493 /* Prepare mailbox for transmission */ 496 /* Prepare mailbox for transmission */
494 data = min_t(u8, cf->can_dlc, 8);
495 if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */ 497 if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
496 data |= HECC_CANMCF_RTR; 498 data |= HECC_CANMCF_RTR;
497 data |= get_tx_head_prio(priv) << 8; 499 data |= get_tx_head_prio(priv) << 8;
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index efbb05c71bf4..ddb17e256656 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -767,6 +767,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
767 size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN 767 size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
768 + sizeof(struct cpc_can_msg); 768 + sizeof(struct cpc_can_msg);
769 769
770 if (can_dropped_invalid_skb(netdev, skb))
771 return NETDEV_TX_OK;
772
770 /* create a URB, and a buffer for it, and copy the data to the URB */ 773 /* create a URB, and a buffer for it, and copy the data to the URB */
771 urb = usb_alloc_urb(0, GFP_ATOMIC); 774 urb = usb_alloc_urb(0, GFP_ATOMIC);
772 if (!urb) { 775 if (!urb) {
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 80ac56313981..d124d837ae58 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -47,6 +47,7 @@
47#include <linux/if_arp.h> 47#include <linux/if_arp.h>
48#include <linux/if_ether.h> 48#include <linux/if_ether.h>
49#include <linux/can.h> 49#include <linux/can.h>
50#include <linux/can/dev.h>
50#include <net/rtnetlink.h> 51#include <net/rtnetlink.h>
51 52
52static __initdata const char banner[] = 53static __initdata const char banner[] =
@@ -70,10 +71,11 @@ MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
70 71
71static void vcan_rx(struct sk_buff *skb, struct net_device *dev) 72static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
72{ 73{
74 struct can_frame *cf = (struct can_frame *)skb->data;
73 struct net_device_stats *stats = &dev->stats; 75 struct net_device_stats *stats = &dev->stats;
74 76
75 stats->rx_packets++; 77 stats->rx_packets++;
76 stats->rx_bytes += skb->len; 78 stats->rx_bytes += cf->can_dlc;
77 79
78 skb->protocol = htons(ETH_P_CAN); 80 skb->protocol = htons(ETH_P_CAN);
79 skb->pkt_type = PACKET_BROADCAST; 81 skb->pkt_type = PACKET_BROADCAST;
@@ -85,11 +87,15 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
85 87
86static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) 88static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
87{ 89{
90 struct can_frame *cf = (struct can_frame *)skb->data;
88 struct net_device_stats *stats = &dev->stats; 91 struct net_device_stats *stats = &dev->stats;
89 int loop; 92 int loop;
90 93
94 if (can_dropped_invalid_skb(dev, skb))
95 return NETDEV_TX_OK;
96
91 stats->tx_packets++; 97 stats->tx_packets++;
92 stats->tx_bytes += skb->len; 98 stats->tx_bytes += cf->can_dlc;
93 99
94 /* set flag whether this packet has to be looped back */ 100 /* set flag whether this packet has to be looped back */
95 loop = skb->pkt_type == PACKET_LOOPBACK; 101 loop = skb->pkt_type == PACKET_LOOPBACK;
@@ -103,7 +109,7 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
103 * CAN core already did the echo for us 109 * CAN core already did the echo for us
104 */ 110 */
105 stats->rx_packets++; 111 stats->rx_packets++;
106 stats->rx_bytes += skb->len; 112 stats->rx_bytes += cf->can_dlc;
107 } 113 }
108 kfree_skb(skb); 114 kfree_skb(skb);
109 return NETDEV_TX_OK; 115 return NETDEV_TX_OK;