]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
156c2bb9 OH |
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 | ||
42193e3e OH |
11 | #ifndef _CAN_SKB_H |
12 | #define _CAN_SKB_H | |
156c2bb9 OH |
13 | |
14 | #include <linux/types.h> | |
0ae89beb | 15 | #include <linux/skbuff.h> |
156c2bb9 | 16 | #include <linux/can.h> |
0ae89beb | 17 | #include <net/sock.h> |
156c2bb9 OH |
18 | |
19 | /* | |
20 | * The struct can_skb_priv is used to transport additional information along | |
21 | * with the stored struct can(fd)_frame that can not be contained in existing | |
22 | * struct sk_buff elements. | |
23 | * N.B. that this information must not be modified in cloned CAN sk_buffs. | |
24 | * To modify the CAN frame content or the struct can_skb_priv content | |
25 | * skb_copy() needs to be used instead of skb_clone(). | |
26 | */ | |
27 | ||
28 | /** | |
29 | * struct can_skb_priv - private additional data inside CAN sk_buffs | |
30 | * @ifindex: ifindex of the first interface the CAN frame appeared on | |
d3b58c47 | 31 | * @skbcnt: atomic counter to have an unique id together with skb pointer |
156c2bb9 OH |
32 | * @cf: align to the following CAN frame at skb->data |
33 | */ | |
34 | struct can_skb_priv { | |
35 | int ifindex; | |
d3b58c47 | 36 | int skbcnt; |
156c2bb9 OH |
37 | struct can_frame cf[0]; |
38 | }; | |
39 | ||
2bf3440d OH |
40 | static inline struct can_skb_priv *can_skb_prv(struct sk_buff *skb) |
41 | { | |
42 | return (struct can_skb_priv *)(skb->head); | |
43 | } | |
44 | ||
45 | static inline void can_skb_reserve(struct sk_buff *skb) | |
46 | { | |
47 | skb_reserve(skb, sizeof(struct can_skb_priv)); | |
48 | } | |
49 | ||
0ae89beb OH |
50 | static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) |
51 | { | |
52 | if (sk) { | |
53 | sock_hold(sk); | |
2b290bbb | 54 | skb->destructor = sock_efree; |
0ae89beb OH |
55 | skb->sk = sk; |
56 | } | |
57 | } | |
58 | ||
59 | /* | |
60 | * returns an unshared skb owned by the original sock to be echo'ed back | |
61 | */ | |
62 | static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb) | |
63 | { | |
64 | if (skb_shared(skb)) { | |
65 | struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); | |
66 | ||
67 | if (likely(nskb)) { | |
68 | can_skb_set_owner(nskb, skb->sk); | |
69 | consume_skb(skb); | |
70 | return nskb; | |
71 | } else { | |
72 | kfree_skb(skb); | |
73 | return NULL; | |
74 | } | |
75 | } | |
76 | ||
77 | /* we can assume to have an unshared skb with proper owner */ | |
78 | return skb; | |
79 | } | |
80 | ||
42193e3e | 81 | #endif /* !_CAN_SKB_H */ |