Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
fork
Configure Feed
Select the types of activity you want to include in your feed.
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
19void can_flush_echo_skb(struct net_device *dev);
20int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
21 unsigned int idx, unsigned int frame_len);
22struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx,
23 u8 *len_ptr, unsigned int *frame_len_ptr);
24unsigned int __must_check can_get_echo_skb(struct net_device *dev,
25 unsigned int idx,
26 unsigned int *frame_len_ptr);
27void can_free_echo_skb(struct net_device *dev, unsigned int idx,
28 unsigned int *frame_len_ptr);
29struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
30struct sk_buff *alloc_canfd_skb(struct net_device *dev,
31 struct canfd_frame **cfd);
32struct sk_buff *alloc_can_err_skb(struct net_device *dev,
33 struct can_frame **cf);
34bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb);
35
36/*
37 * The struct can_skb_priv is used to transport additional information along
38 * with the stored struct can(fd)_frame that can not be contained in existing
39 * struct sk_buff elements.
40 * N.B. that this information must not be modified in cloned CAN sk_buffs.
41 * To modify the CAN frame content or the struct can_skb_priv content
42 * skb_copy() needs to be used instead of skb_clone().
43 */
44
45/**
46 * struct can_skb_priv - private additional data inside CAN sk_buffs
47 * @ifindex: ifindex of the first interface the CAN frame appeared on
48 * @skbcnt: atomic counter to have an unique id together with skb pointer
49 * @frame_len: length of CAN frame in data link layer
50 * @cf: align to the following CAN frame at skb->data
51 */
52struct can_skb_priv {
53 int ifindex;
54 int skbcnt;
55 unsigned int frame_len;
56 struct can_frame cf[];
57};
58
59static inline struct can_skb_priv *can_skb_prv(struct sk_buff *skb)
60{
61 return (struct can_skb_priv *)(skb->head);
62}
63
64static inline void can_skb_reserve(struct sk_buff *skb)
65{
66 skb_reserve(skb, sizeof(struct can_skb_priv));
67}
68
69static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
70{
71 /* If the socket has already been closed by user space, the
72 * refcount may already be 0 (and the socket will be freed
73 * after the last TX skb has been freed). So only increase
74 * socket refcount if the refcount is > 0.
75 */
76 if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) {
77 skb->destructor = sock_efree;
78 skb->sk = sk;
79 }
80}
81
82/*
83 * returns an unshared skb owned by the original sock to be echo'ed back
84 */
85static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
86{
87 struct sk_buff *nskb;
88
89 nskb = skb_clone(skb, GFP_ATOMIC);
90 if (unlikely(!nskb)) {
91 kfree_skb(skb);
92 return NULL;
93 }
94
95 can_skb_set_owner(nskb, skb->sk);
96 consume_skb(skb);
97 return nskb;
98}
99
100static inline bool can_is_canfd_skb(const struct sk_buff *skb)
101{
102 /* the CAN specific type of skb is identified by its data length */
103 return skb->len == CANFD_MTU;
104}
105
106#endif /* !_CAN_SKB_H */