]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
To prevent the CAN drivers to operate on invalid socketbuffers the skbs are
authorhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Tue, 12 Jan 2010 11:06:55 +0000 (11:06 +0000)
committerhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Tue, 12 Jan 2010 11:06:55 +0000 (11:06 +0000)
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>
git-svn-id: svn://svn.berlios.de//socketcan/trunk@1109 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/drivers/net/can/at91_can.c
kernel/2.6/drivers/net/can/cc770/cc770.c
kernel/2.6/drivers/net/can/esd_pci331.c
kernel/2.6/drivers/net/can/mcp251x.c
kernel/2.6/drivers/net/can/mscan/mscan.c
kernel/2.6/drivers/net/can/sja1000/sja1000.c
kernel/2.6/drivers/net/can/softing/softing_main.c
kernel/2.6/drivers/net/can/usb/ems_usb.c
kernel/2.6/drivers/net/can/vcan.c
kernel/2.6/include/socketcan/can/dev.h

index 72c27ac556e2072310b71d9381228ed4ea5a9b89..02f9f778dded300b3fac94d8142194ec818f260e 100644 (file)
@@ -346,6 +346,9 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned int mb, prio;
        u32 reg_mid, reg_mcr;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        mb = get_tx_next_mb(priv);
        prio = get_tx_next_prio(priv);
 
index f0e97c3c4377406bc24d5ee4d21a1b77a3f4adc5..259492386180dfad6f52abc1275ec7b3c9f0a64b 100644 (file)
@@ -440,6 +440,9 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u32 id;
        int i;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        if ((cc770_read_reg(priv,
                            msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
                dev_err(ND2D(dev), "TX register is still occupied!\n");
index f6b9e0a61b798355005ef8382af9e3de805c968f..7099811d265112582b379316b4827415e63203e4 100644 (file)
@@ -671,6 +671,9 @@ static netdev_tx_t esd331_start_xmit(struct sk_buff *skb,
        struct esd331_can_msg msg;
        int i;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        if ((cf->can_id & CAN_EFF_FLAG) && (priv->board->eff_supp == 0)) {
                stats->tx_dropped++;
                kfree_skb(skb);
index 1f6d772f8c9b41e73ea78e7e8f0de141759a9713..cda2b3f806ac74f5d7c07d43bbd7e13332312bd5 100644 (file)
@@ -502,12 +502,8 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-       if (skb->len != sizeof(struct can_frame)) {
-               dev_err(&spi->dev, "dropping packet - bad length\n");
-               dev_kfree_skb(skb);
-               net->stats.tx_dropped++;
+       if (can_dropped_invalid_skb(net, skb))
                return NETDEV_TX_OK;
-       }
 
        netif_stop_queue(net);
        priv->tx_skb = skb;
index c1299a358e6cef627b63b020b9ecafcc93bbaa74..bbdc633ba42aea4f1c6d478b20e02953c048e056 100644 (file)
@@ -215,11 +215,8 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
        int i, rtr, buf_id;
        u32 can_id;
 
-       if (skb->len != sizeof(*frame) || frame->can_dlc > 8) {
-               kfree_skb(skb);
-               dev->stats.tx_dropped++;
+       if (can_dropped_invalid_skb(dev, skb))
                return NETDEV_TX_OK;
-       }
 
        out_8(&regs->cantier, 0);
 
index c7946848eb871fcc167573456cb3f745e01bd19c..df2690ea89f94343e8fc71661d0c11ad8f86965d 100644 (file)
@@ -257,6 +257,9 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
        uint8_t dreg;
        int i;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        netif_stop_queue(dev);
 
        fi = dlc = cf->can_dlc;
index 03bb27058e7e14fcc1bdc1e6e1c222afa543642b..9bb3642d20b00fc883e0a90612155d6d19f1c64c 100644 (file)
@@ -64,6 +64,9 @@ static netdev_tx_t netdev_start_xmit(struct sk_buff *skb,
        unsigned int fifo_wr;
        struct can_frame msg;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        if (in_interrupt()) {
                bhlock = 0;
                spin_lock(&card->spin);
index d5ca8e2b8680b05480796ec41f5416cd57ef6220..613852b5b1c60266081e183a0939eceb0c9a686a 100644 (file)
@@ -777,6 +777,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
        size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
                        + sizeof(struct cpc_can_msg);
 
+       if (can_dropped_invalid_skb(netdev, skb))
+               return NETDEV_TX_OK;
+
        /* create a URB, and a buffer for it, and copy the data to the URB */
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
index 4fdcaa3e1485b5adff2205072a97def02f53b73b..dc82af6271715ba50caec28920e0fde2ca10f555 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <socketcan/can.h>
+#include <socketcan/can/dev.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
 #include <net/rtnetlink.h>
 #endif
@@ -102,6 +103,7 @@ static struct net_device **vcan_devs; /* root pointer to netdevice structs */
 
 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 {
+       struct can_frame *cf = (struct can_frame *)skb->data;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
        struct net_device_stats *stats = &dev->stats;
 #else
@@ -109,7 +111,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 #endif
 
        stats->rx_packets++;
-       stats->rx_bytes += skb->len;
+       stats->rx_bytes += cf->can_dlc;
 
        skb->protocol  = htons(ETH_P_CAN);
        skb->pkt_type  = PACKET_BROADCAST;
@@ -121,6 +123,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 
 static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
 {
+       struct can_frame *cf = (struct can_frame *)skb->data;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
        struct net_device_stats *stats = &dev->stats;
 #else
@@ -128,8 +131,11 @@ static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
 #endif
        int loop;
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
        stats->tx_packets++;
-       stats->tx_bytes += skb->len;
+       stats->tx_bytes += cf->can_dlc;
 
        /* set flag whether this packet has to be looped back */
        loop = skb->pkt_type == PACKET_LOOPBACK;
@@ -143,7 +149,7 @@ static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
                         * CAN core already did the echo for us
                         */
                        stats->rx_packets++;
-                       stats->rx_bytes += skb->len;
+                       stats->rx_bytes += cf->can_dlc;
                }
                kfree_skb(skb);
                return NETDEV_TX_OK;
index eaf1a9dddbcd0de79c07127ced3d3cbac45921b8..4e6da7f6cf2627a1dc12f32fb9a3b84879e25233 100644 (file)
@@ -80,6 +80,21 @@ struct can_priv {
 struct net_device_stats *can_get_stats(struct net_device *dev);
 #endif
 
+/* Drop a given socketbuffer if it does not contain a valid CAN frame. */
+static inline int can_dropped_invalid_skb(struct net_device *dev,
+                                         struct sk_buff *skb)
+{
+       const struct can_frame *cf = (struct can_frame *)skb->data;
+
+       if (unlikely(skb->len != sizeof(*cf) || cf->can_dlc > 8)) {
+               kfree_skb(skb);
+               dev->stats.tx_dropped++;
+               return 1;
+       }
+
+       return 0;
+}
+
 struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max);
 void free_candev(struct net_device *dev);