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 unsigned int *len_ptr, 24 unsigned int *frame_len_ptr); 25 unsigned int __must_check can_get_echo_skb(struct net_device *dev, 26 unsigned int idx, 27 unsigned int *frame_len_ptr); 28 void can_free_echo_skb(struct net_device *dev, unsigned int idx, 29 unsigned int *frame_len_ptr); 30 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); 31 struct sk_buff *alloc_canfd_skb(struct net_device *dev, 32 struct canfd_frame **cfd); 33 struct sk_buff *alloc_canxl_skb(struct net_device *dev, 34 struct canxl_frame **cxl, 35 unsigned int data_len); 36 struct sk_buff *alloc_can_err_skb(struct net_device *dev, 37 struct can_frame **cf); 38 bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb); 39 40 /* 41 * The struct can_skb_priv is used to transport additional information along 42 * with the stored struct can(fd)_frame that can not be contained in existing 43 * struct sk_buff elements. 44 * N.B. that this information must not be modified in cloned CAN sk_buffs. 45 * To modify the CAN frame content or the struct can_skb_priv content 46 * skb_copy() needs to be used instead of skb_clone(). 47 */ 48 49 /** 50 * struct can_skb_priv - private additional data inside CAN sk_buffs 51 * @ifindex: ifindex of the first interface the CAN frame appeared on 52 * @skbcnt: atomic counter to have an unique id together with skb pointer 53 * @frame_len: length of CAN frame in data link layer 54 * @cf: align to the following CAN frame at skb->data 55 */ 56 struct can_skb_priv { 57 int ifindex; 58 int skbcnt; 59 unsigned int frame_len; 60 struct can_frame cf[]; 61 }; 62 63 static inline struct can_skb_priv *can_skb_prv(struct sk_buff *skb) 64 { 65 return (struct can_skb_priv *)(skb->head); 66 } 67 68 static inline void can_skb_reserve(struct sk_buff *skb) 69 { 70 skb_reserve(skb, sizeof(struct can_skb_priv)); 71 } 72 73 static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) 74 { 75 /* If the socket has already been closed by user space, the 76 * refcount may already be 0 (and the socket will be freed 77 * after the last TX skb has been freed). So only increase 78 * socket refcount if the refcount is > 0. 79 */ 80 if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { 81 skb->destructor = sock_efree; 82 skb->sk = sk; 83 } 84 } 85 86 /* 87 * returns an unshared skb owned by the original sock to be echo'ed back 88 */ 89 static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb) 90 { 91 struct sk_buff *nskb; 92 93 nskb = skb_clone(skb, GFP_ATOMIC); 94 if (unlikely(!nskb)) { 95 kfree_skb(skb); 96 return NULL; 97 } 98 99 can_skb_set_owner(nskb, skb->sk); 100 consume_skb(skb); 101 return nskb; 102 } 103 104 static inline bool can_is_can_skb(const struct sk_buff *skb) 105 { 106 struct can_frame *cf = (struct can_frame *)skb->data; 107 108 /* the CAN specific type of skb is identified by its data length */ 109 return (skb->len == CAN_MTU && cf->len <= CAN_MAX_DLEN); 110 } 111 112 static inline bool can_is_canfd_skb(const struct sk_buff *skb) 113 { 114 struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 115 116 /* the CAN specific type of skb is identified by its data length */ 117 return (skb->len == CANFD_MTU && cfd->len <= CANFD_MAX_DLEN); 118 } 119 120 static inline bool can_is_canxl_skb(const struct sk_buff *skb) 121 { 122 const struct canxl_frame *cxl = (struct canxl_frame *)skb->data; 123 124 if (skb->len < CANXL_HDR_SIZE + CANXL_MIN_DLEN || skb->len > CANXL_MTU) 125 return false; 126 127 /* this also checks valid CAN XL data length boundaries */ 128 if (skb->len != CANXL_HDR_SIZE + cxl->len) 129 return false; 130 131 return cxl->flags & CANXL_XLF; 132 } 133 134 /* get length element value from can[|fd|xl]_frame structure */ 135 static inline unsigned int can_skb_get_len_val(struct sk_buff *skb) 136 { 137 const struct canxl_frame *cxl = (struct canxl_frame *)skb->data; 138 const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 139 140 if (can_is_canxl_skb(skb)) 141 return cxl->len; 142 143 return cfd->len; 144 } 145 146 /* get needed data length inside CAN frame for all frame types (RTR aware) */ 147 static inline unsigned int can_skb_get_data_len(struct sk_buff *skb) 148 { 149 unsigned int len = can_skb_get_len_val(skb); 150 const struct can_frame *cf = (struct can_frame *)skb->data; 151 152 /* RTR frames have an actual length of zero */ 153 if (can_is_can_skb(skb) && cf->can_id & CAN_RTR_FLAG) 154 return 0; 155 156 return len; 157 } 158 159 #endif /* !_CAN_SKB_H */ 160
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.