diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-03-08 00:54:04 +0100 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-03-08 00:54:04 +0100 |
commit | f2c1392ff3473a396e4d177ff5ad368b9d6cd211 (patch) | |
tree | 2111e8c1e50e3fa56fc46bd4e80e5a577459e768 /include/linux/can/dev.h | |
parent | b16d3d60b112c8cb90ebcd7ae97a5d2207d6f43c (diff) | |
parent | e0f8b8a65a473a8baa439cf865a694bbeb83fe90 (diff) |
Merge tag 'v4.14.170' into 4.14-2.3.x-imx
This is the 4.14.170 stable release
Conflicts:
drivers/net/phy/phy_device.c
drivers/tty/serial/imx.c
include/linux/platform_data/dma-imx-sdma.h
net/wireless/util.c
Diffstat (limited to 'include/linux/can/dev.h')
-rw-r--r-- | include/linux/can/dev.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index c0c0b992210e..995903c7055b 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -18,6 +18,7 @@ #include <linux/can/error.h> #include <linux/can/led.h> #include <linux/can/netlink.h> +#include <linux/can/skb.h> #include <linux/netdevice.h> /* @@ -90,6 +91,36 @@ struct can_priv { #define get_can_dlc(i) (min_t(__u8, (i), CAN_MAX_DLC)) #define get_canfd_dlc(i) (min_t(__u8, (i), CANFD_MAX_DLC)) +/* Check for outgoing skbs that have not been created by the CAN subsystem */ +static inline bool can_skb_headroom_valid(struct net_device *dev, + struct sk_buff *skb) +{ + /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */ + if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv))) + return false; + + /* af_packet does not apply CAN skb specific settings */ + if (skb->ip_summed == CHECKSUM_NONE) { + /* init headroom */ + can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; + + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* preform proper loopback on capable devices */ + if (dev->flags & IFF_ECHO) + skb->pkt_type = PACKET_LOOPBACK; + else + skb->pkt_type = PACKET_HOST; + + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + } + + return true; +} + /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ static inline bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) @@ -107,6 +138,9 @@ static inline bool can_dropped_invalid_skb(struct net_device *dev, } else goto inval_skb; + if (!can_skb_headroom_valid(dev, skb)) + goto inval_skb; + return false; inval_skb: |