diff options
author | Oliver Hartkopp <oliver@hartkopp.net> | 2010-01-12 05:00:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-12 05:00:46 -0500 |
commit | 3ccd4c6167d3b39d52631767ebbf8b5677c5855d (patch) | |
tree | bfcb801edebd00e8b30e897038bad7fee39625cc /drivers/net/can | |
parent | d218d11133d888f9745802146a50255a4781d37a (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.c | 3 | ||||
-rw-r--r-- | drivers/net/can/bfin_can.c | 3 | ||||
-rw-r--r-- | drivers/net/can/mcp251x.c | 6 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.c | 5 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 3 | ||||
-rw-r--r-- | drivers/net/can/ti_hecc.c | 4 | ||||
-rw-r--r-- | drivers/net/can/usb/ems_usb.c | 3 | ||||
-rw-r--r-- | drivers/net/can/vcan.c | 12 |
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(®s->cantier, 0); | 210 | out_8(®s->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 | ||
52 | static __initdata const char banner[] = | 53 | static __initdata const char banner[] = |
@@ -70,10 +71,11 @@ MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)"); | |||
70 | 71 | ||
71 | static void vcan_rx(struct sk_buff *skb, struct net_device *dev) | 72 | static 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 | ||
86 | static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) | 88 | static 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; |