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 | |