~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/can/skb.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php