1 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 /* 3 * linux/can/skb.h 4 * 5 * Definitions for the CAN network socket buffer 6 * 7 * Copyright (C) 2012 Oliver Hartkopp <socketcan@hartkopp.net> 8 * 9 */ 10 11 #ifndef _CAN_SKB_H 12 #define _CAN_SKB_H 13 14 #include <linux/types.h> 15 #include <linux/skbuff.h> 16 #include <linux/can.h> 17 #include <net/sock.h> 18 19 void can_flush_echo_skb(struct net_device *dev); 20 int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, 21 unsigned int idx, unsigned int frame_len); 22 struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, 23 u8 *len_ptr, unsigned int *frame_len_ptr); 24 unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx, 25 unsigned int *frame_len_ptr); 26 void can_free_echo_skb(struct net_device *dev, unsigned int idx); 27 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); 28 struct sk_buff *alloc_canfd_skb(struct net_device *dev, 29 struct canfd_frame **cfd); 30 struct sk_buff *alloc_can_err_skb(struct net_device *dev, 31 struct can_frame **cf); 32 33 /* 34 * The struct can_skb_priv is used to transport additional information along 35 * with the stored struct can(fd)_frame that can not be contained in existing 36 * struct sk_buff elements. 37 * N.B. that this information must not be modified in cloned CAN sk_buffs. 38 * To modify the CAN frame content or the struct can_skb_priv content 39 * skb_copy() needs to be used instead of skb_clone(). 40 */ 41 42 /** 43 * struct can_skb_priv - private additional data inside CAN sk_buffs 44 * @ifindex: ifindex of the first interface the CAN frame appeared on 45 * @skbcnt: atomic counter to have an unique id together with skb pointer 46 * @frame_len: length of CAN frame in data link layer 47 * @cf: align to the following CAN frame at skb->data 48 */ 49 struct can_skb_priv { 50 int ifindex; 51 int skbcnt; 52 unsigned int frame_len; 53 struct can_frame cf[]; 54 }; 55 56 static inline struct can_skb_priv *can_skb_prv(struct sk_buff *skb) 57 { 58 return (struct can_skb_priv *)(skb->head); 59 } 60 61 static inline void can_skb_reserve(struct sk_buff *skb) 62 { 63 skb_reserve(skb, sizeof(struct can_skb_priv)); 64 } 65 66 static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) 67 { 68 /* If the socket has already been closed by user space, the 69 * refcount may already be 0 (and the socket will be freed 70 * after the last TX skb has been freed). So only increase 71 * socket refcount if the refcount is > 0. 72 */ 73 if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { 74 skb->destructor = sock_efree; 75 skb->sk = sk; 76 } 77 } 78 79 /* 80 * returns an unshared skb owned by the original sock to be echo'ed back 81 */ 82 static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb) 83 { 84 struct sk_buff *nskb; 85 86 nskb = skb_clone(skb, GFP_ATOMIC); 87 if (unlikely(!nskb)) { 88 kfree_skb(skb); 89 return NULL; 90 } 91 92 can_skb_set_owner(nskb, skb->sk); 93 consume_skb(skb); 94 return nskb; 95 } 96 97 /* Check for outgoing skbs that have not been created by the CAN subsystem */ 98 static inline bool can_skb_headroom_valid(struct net_device *dev, 99 struct sk_buff *skb) 100 { 101 /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */ 102 if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv))) 103 return false; 104 105 /* af_packet does not apply CAN skb specific settings */ 106 if (skb->ip_summed == CHECKSUM_NONE) { 107 /* init headroom */ 108 can_skb_prv(skb)->ifindex = dev->ifindex; 109 can_skb_prv(skb)->skbcnt = 0; 110 111 skb->ip_summed = CHECKSUM_UNNECESSARY; 112 113 /* perform proper loopback on capable devices */ 114 if (dev->flags & IFF_ECHO) 115 skb->pkt_type = PACKET_LOOPBACK; 116 else 117 skb->pkt_type = PACKET_HOST; 118 119 skb_reset_mac_header(skb); 120 skb_reset_network_header(skb); 121 skb_reset_transport_header(skb); 122 } 123 124 return true; 125 } 126 127 /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ 128 static inline bool can_dropped_invalid_skb(struct net_device *dev, 129 struct sk_buff *skb) 130 { 131 const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 132 133 if (skb->protocol == htons(ETH_P_CAN)) { 134 if (unlikely(skb->len != CAN_MTU || 135 cfd->len > CAN_MAX_DLEN)) 136 goto inval_skb; 137 } else if (skb->protocol == htons(ETH_P_CANFD)) { 138 if (unlikely(skb->len != CANFD_MTU || 139 cfd->len > CANFD_MAX_DLEN)) 140 goto inval_skb; 141 } else 142 goto inval_skb; 143 144 if (!can_skb_headroom_valid(dev, skb)) 145 goto inval_skb; 146 147 return false; 148 149 inval_skb: 150 kfree_skb(skb); 151 dev->stats.tx_dropped++; 152 return true; 153 } 154 155 static inline bool can_is_canfd_skb(const struct sk_buff *skb) 156 { 157 /* the CAN specific type of skb is identified by its data length */ 158 return skb->len == CANFD_MTU; 159 } 160 161 #endif /* !_CAN_SKB_H */ 162