| 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, len: 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(r: &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(skb: nskb, sk: 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 | |