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);
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");
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);
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;
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(®s->cantier, 0);
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;
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);
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) {
#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
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
#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;
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
#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;
* 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;
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);