149ed6e97SBjoern A. Zeeb /*-
22ab4a419SBjoern A. Zeeb * Copyright (c) 2020-2025 The FreeBSD Foundation
3bc222e96SBjoern A. Zeeb * Copyright (c) 2021-2025 Bjoern A. Zeeb
449ed6e97SBjoern A. Zeeb *
549ed6e97SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from
649ed6e97SBjoern A. Zeeb * the FreeBSD Foundation.
749ed6e97SBjoern A. Zeeb *
849ed6e97SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without
949ed6e97SBjoern A. Zeeb * modification, are permitted provided that the following conditions
1049ed6e97SBjoern A. Zeeb * are met:
1149ed6e97SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright
1249ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer.
1349ed6e97SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright
1449ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the
1549ed6e97SBjoern A. Zeeb * documentation and/or other materials provided with the distribution.
1649ed6e97SBjoern A. Zeeb *
1749ed6e97SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1849ed6e97SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1949ed6e97SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2049ed6e97SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2149ed6e97SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2249ed6e97SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2349ed6e97SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2449ed6e97SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2549ed6e97SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2649ed6e97SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2749ed6e97SBjoern A. Zeeb * SUCH DAMAGE.
2849ed6e97SBjoern A. Zeeb */
2949ed6e97SBjoern A. Zeeb
3049ed6e97SBjoern A. Zeeb /*
3149ed6e97SBjoern A. Zeeb * NOTE: this socket buffer compatibility code is highly EXPERIMENTAL.
3249ed6e97SBjoern A. Zeeb * Do not rely on the internals of this implementation. They are highly
3349ed6e97SBjoern A. Zeeb * likely to change as we will improve the integration to FreeBSD mbufs.
3449ed6e97SBjoern A. Zeeb */
3549ed6e97SBjoern A. Zeeb
3649ed6e97SBjoern A. Zeeb #ifndef _LINUXKPI_LINUX_SKBUFF_H
3749ed6e97SBjoern A. Zeeb #define _LINUXKPI_LINUX_SKBUFF_H
3849ed6e97SBjoern A. Zeeb
399df5f29cSBjoern A. Zeeb #include <linux/kernel.h>
4049ed6e97SBjoern A. Zeeb #include <linux/page.h>
4149ed6e97SBjoern A. Zeeb #include <linux/dma-mapping.h>
4249ed6e97SBjoern A. Zeeb #include <linux/netdev_features.h>
4349ed6e97SBjoern A. Zeeb #include <linux/list.h>
4449ed6e97SBjoern A. Zeeb #include <linux/gfp.h>
456baea331SBjoern A. Zeeb #include <linux/compiler.h>
466baea331SBjoern A. Zeeb #include <linux/spinlock.h>
47262c5e81SBjoern A. Zeeb #include <linux/ktime.h>
482ab4a419SBjoern A. Zeeb #include <linux/compiler.h>
4949ed6e97SBjoern A. Zeeb
50bc222e96SBjoern A. Zeeb /*
51bc222e96SBjoern A. Zeeb * At least the net/intel-irdma-kmod port pulls this header in; likely through
52bc222e96SBjoern A. Zeeb * if_ether.h (see PR289268). This means we no longer can rely on
53bc222e96SBjoern A. Zeeb * IEEE80211_DEBUG (opt_wlan.h) to automatically set SKB_DEBUG.
54bc222e96SBjoern A. Zeeb */
5549ed6e97SBjoern A. Zeeb /* #define SKB_DEBUG */
5659d262feSBjoern A. Zeeb
5749ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
5849ed6e97SBjoern A. Zeeb #define DSKB_TODO 0x01
596baea331SBjoern A. Zeeb #define DSKB_IMPROVE 0x02
606baea331SBjoern A. Zeeb #define DSKB_TRACE 0x10
616baea331SBjoern A. Zeeb #define DSKB_TRACEX 0x20
626baea331SBjoern A. Zeeb extern int linuxkpi_debug_skb;
6349ed6e97SBjoern A. Zeeb
646baea331SBjoern A. Zeeb #define SKB_TODO() \
656baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TODO) \
6649ed6e97SBjoern A. Zeeb printf("SKB_TODO %s:%d\n", __func__, __LINE__)
676baea331SBjoern A. Zeeb #define SKB_IMPROVE(...) \
686baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_IMPROVE) \
696baea331SBjoern A. Zeeb printf("SKB_IMPROVE %s:%d\n", __func__, __LINE__)
706baea331SBjoern A. Zeeb #define SKB_TRACE(_s) \
716baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \
726baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p\n", __func__, __LINE__, _s)
736baea331SBjoern A. Zeeb #define SKB_TRACE2(_s, _p) \
746baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \
756baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p, %p\n", __func__, __LINE__, _s, _p)
766baea331SBjoern A. Zeeb #define SKB_TRACE_FMT(_s, _fmt, ...) \
776baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \
786baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p " _fmt "\n", __func__, __LINE__, _s, \
796baea331SBjoern A. Zeeb __VA_ARGS__)
8049ed6e97SBjoern A. Zeeb #else
816baea331SBjoern A. Zeeb #define SKB_TODO() do { } while(0)
826baea331SBjoern A. Zeeb #define SKB_IMPROVE(...) do { } while(0)
8349ed6e97SBjoern A. Zeeb #define SKB_TRACE(_s) do { } while(0)
8449ed6e97SBjoern A. Zeeb #define SKB_TRACE2(_s, _p) do { } while(0)
8549ed6e97SBjoern A. Zeeb #define SKB_TRACE_FMT(_s, ...) do { } while(0)
8649ed6e97SBjoern A. Zeeb #endif
8749ed6e97SBjoern A. Zeeb
8849ed6e97SBjoern A. Zeeb enum sk_buff_pkt_type {
8949ed6e97SBjoern A. Zeeb PACKET_BROADCAST,
9049ed6e97SBjoern A. Zeeb PACKET_MULTICAST,
9149ed6e97SBjoern A. Zeeb PACKET_OTHERHOST,
9249ed6e97SBjoern A. Zeeb };
9349ed6e97SBjoern A. Zeeb
94262c5e81SBjoern A. Zeeb struct skb_shared_hwtstamps {
95262c5e81SBjoern A. Zeeb ktime_t hwtstamp;
96262c5e81SBjoern A. Zeeb };
97262c5e81SBjoern A. Zeeb
989df5f29cSBjoern A. Zeeb #define NET_SKB_PAD max(CACHE_LINE_SIZE, 32)
993d3ec178SBjoern A. Zeeb #define SKB_DATA_ALIGN(_x) roundup2(_x, CACHE_LINE_SIZE)
10049ed6e97SBjoern A. Zeeb
10149ed6e97SBjoern A. Zeeb struct sk_buff_head {
10249ed6e97SBjoern A. Zeeb /* XXX TODO */
103b2dcb848SBjoern A. Zeeb union {
104b2dcb848SBjoern A. Zeeb struct {
10549ed6e97SBjoern A. Zeeb struct sk_buff *next;
10649ed6e97SBjoern A. Zeeb struct sk_buff *prev;
107b2dcb848SBjoern A. Zeeb };
108b2dcb848SBjoern A. Zeeb struct sk_buff_head_l {
109b2dcb848SBjoern A. Zeeb struct sk_buff *next;
110b2dcb848SBjoern A. Zeeb struct sk_buff *prev;
111b2dcb848SBjoern A. Zeeb } list;
112b2dcb848SBjoern A. Zeeb };
11349ed6e97SBjoern A. Zeeb size_t qlen;
1146baea331SBjoern A. Zeeb spinlock_t lock;
11549ed6e97SBjoern A. Zeeb };
11649ed6e97SBjoern A. Zeeb
11749ed6e97SBjoern A. Zeeb enum sk_checksum_flags {
11849ed6e97SBjoern A. Zeeb CHECKSUM_NONE = 0x00,
11949ed6e97SBjoern A. Zeeb CHECKSUM_UNNECESSARY = 0x01,
12049ed6e97SBjoern A. Zeeb CHECKSUM_PARTIAL = 0x02,
121343f8f71SBjoern A. Zeeb CHECKSUM_COMPLETE = 0x03,
12249ed6e97SBjoern A. Zeeb };
12349ed6e97SBjoern A. Zeeb
12449ed6e97SBjoern A. Zeeb struct skb_frag {
12549ed6e97SBjoern A. Zeeb /* XXX TODO */
12649ed6e97SBjoern A. Zeeb struct page *page; /* XXX-BZ These three are a wild guess so far! */
12749ed6e97SBjoern A. Zeeb off_t offset;
12849ed6e97SBjoern A. Zeeb size_t size;
12949ed6e97SBjoern A. Zeeb };
13049ed6e97SBjoern A. Zeeb typedef struct skb_frag skb_frag_t;
13149ed6e97SBjoern A. Zeeb
13249ed6e97SBjoern A. Zeeb enum skb_shared_info_gso_type {
13349ed6e97SBjoern A. Zeeb SKB_GSO_TCPV4,
13449ed6e97SBjoern A. Zeeb SKB_GSO_TCPV6,
13549ed6e97SBjoern A. Zeeb };
13649ed6e97SBjoern A. Zeeb
13749ed6e97SBjoern A. Zeeb struct skb_shared_info {
13849ed6e97SBjoern A. Zeeb enum skb_shared_info_gso_type gso_type;
13949ed6e97SBjoern A. Zeeb uint16_t gso_size;
14049ed6e97SBjoern A. Zeeb uint16_t nr_frags;
1416baea331SBjoern A. Zeeb struct sk_buff *frag_list;
14249ed6e97SBjoern A. Zeeb skb_frag_t frags[64]; /* XXX TODO, 16xpage? */
14349ed6e97SBjoern A. Zeeb };
14449ed6e97SBjoern A. Zeeb
14549ed6e97SBjoern A. Zeeb struct sk_buff {
14649ed6e97SBjoern A. Zeeb /* XXX TODO */
14789c32dafSBjoern A. Zeeb union {
14849ed6e97SBjoern A. Zeeb /* struct sk_buff_head */
14989c32dafSBjoern A. Zeeb struct {
15049ed6e97SBjoern A. Zeeb struct sk_buff *next;
15149ed6e97SBjoern A. Zeeb struct sk_buff *prev;
15289c32dafSBjoern A. Zeeb };
15389c32dafSBjoern A. Zeeb struct list_head list;
15489c32dafSBjoern A. Zeeb };
15549ed6e97SBjoern A. Zeeb
15649ed6e97SBjoern A. Zeeb uint8_t *head; /* Head of buffer. */
15749ed6e97SBjoern A. Zeeb uint8_t *data; /* Head of data. */
15849ed6e97SBjoern A. Zeeb uint8_t *tail; /* End of data. */
15949ed6e97SBjoern A. Zeeb uint8_t *end; /* End of buffer. */
16049ed6e97SBjoern A. Zeeb
16159481c7dSBjoern A. Zeeb uint32_t len; /* ? */
16259481c7dSBjoern A. Zeeb uint32_t data_len; /* ? If we have frags? */
16359481c7dSBjoern A. Zeeb union {
16459481c7dSBjoern A. Zeeb __wsum csum;
16559481c7dSBjoern A. Zeeb struct {
16659481c7dSBjoern A. Zeeb uint16_t csum_offset;
16759481c7dSBjoern A. Zeeb uint16_t csum_start;
16859481c7dSBjoern A. Zeeb };
16959481c7dSBjoern A. Zeeb };
17059481c7dSBjoern A. Zeeb uint16_t protocol;
171343f8f71SBjoern A. Zeeb uint8_t ip_summed; /* 2 bit only. */
17259481c7dSBjoern A. Zeeb /* uint8_t */
17359481c7dSBjoern A. Zeeb
17459481c7dSBjoern A. Zeeb /* "Scratch" area for layers to store metadata. */
17559481c7dSBjoern A. Zeeb /* ??? I see sizeof() operations so probably an array. */
17659481c7dSBjoern A. Zeeb uint8_t cb[64] __aligned(CACHE_LINE_SIZE);
17759481c7dSBjoern A. Zeeb
17859481c7dSBjoern A. Zeeb struct skb_shared_info *shinfo __aligned(CACHE_LINE_SIZE);
17959481c7dSBjoern A. Zeeb
18059481c7dSBjoern A. Zeeb uint32_t truesize; /* The total size of all buffers, incl. frags. */
18159481c7dSBjoern A. Zeeb uint32_t priority;
18259481c7dSBjoern A. Zeeb uint16_t qmap; /* queue mapping */
18359481c7dSBjoern A. Zeeb uint16_t _flags; /* Internal flags. */
18459481c7dSBjoern A. Zeeb #define _SKB_FLAGS_SKBEXTFRAG 0x0001
18559481c7dSBjoern A. Zeeb uint16_t l3hdroff; /* network header offset from *head */
18659481c7dSBjoern A. Zeeb uint16_t l4hdroff; /* transport header offset from *head */
18759481c7dSBjoern A. Zeeb uint16_t mac_header; /* offset of mac_header */
18859481c7dSBjoern A. Zeeb uint16_t mac_len; /* Link-layer header length. */
18959481c7dSBjoern A. Zeeb enum sk_buff_pkt_type pkt_type;
19059481c7dSBjoern A. Zeeb refcount_t refcnt;
19159481c7dSBjoern A. Zeeb
19259481c7dSBjoern A. Zeeb struct net_device *dev;
19359481c7dSBjoern A. Zeeb void *sk; /* XXX net/sock.h? */
19449ed6e97SBjoern A. Zeeb
19549ed6e97SBjoern A. Zeeb /* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
19649ed6e97SBjoern A. Zeeb void *m;
19749ed6e97SBjoern A. Zeeb void(*m_free_func)(void *);
19849ed6e97SBjoern A. Zeeb
19949ed6e97SBjoern A. Zeeb /* Force padding to CACHE_LINE_SIZE. */
20049ed6e97SBjoern A. Zeeb uint8_t __scratch[0] __aligned(CACHE_LINE_SIZE);
20149ed6e97SBjoern A. Zeeb };
20249ed6e97SBjoern A. Zeeb
20349ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
20449ed6e97SBjoern A. Zeeb
20549ed6e97SBjoern A. Zeeb struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
2069df5f29cSBjoern A. Zeeb struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
2075504bd59SBjoern A. Zeeb struct sk_buff *linuxkpi_build_skb(void *, size_t);
20849ed6e97SBjoern A. Zeeb void linuxkpi_kfree_skb(struct sk_buff *);
20949ed6e97SBjoern A. Zeeb
2102ab4a419SBjoern A. Zeeb struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t);
211349b042bSBjoern A. Zeeb
21249ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
21349ed6e97SBjoern A. Zeeb
21449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
alloc_skb(size_t size,gfp_t gfp)21549ed6e97SBjoern A. Zeeb alloc_skb(size_t size, gfp_t gfp)
21649ed6e97SBjoern A. Zeeb {
21749ed6e97SBjoern A. Zeeb struct sk_buff *skb;
21849ed6e97SBjoern A. Zeeb
21949ed6e97SBjoern A. Zeeb skb = linuxkpi_alloc_skb(size, gfp);
22049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
22149ed6e97SBjoern A. Zeeb return (skb);
22249ed6e97SBjoern A. Zeeb }
22349ed6e97SBjoern A. Zeeb
22449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
__dev_alloc_skb(size_t len,gfp_t gfp)2256baea331SBjoern A. Zeeb __dev_alloc_skb(size_t len, gfp_t gfp)
2266baea331SBjoern A. Zeeb {
2276baea331SBjoern A. Zeeb struct sk_buff *skb;
2286baea331SBjoern A. Zeeb
2299df5f29cSBjoern A. Zeeb skb = linuxkpi_dev_alloc_skb(len, gfp);
2306baea331SBjoern A. Zeeb SKB_IMPROVE();
2316baea331SBjoern A. Zeeb SKB_TRACE(skb);
2326baea331SBjoern A. Zeeb return (skb);
2336baea331SBjoern A. Zeeb }
2346baea331SBjoern A. Zeeb
2356baea331SBjoern A. Zeeb static inline struct sk_buff *
dev_alloc_skb(size_t len)23649ed6e97SBjoern A. Zeeb dev_alloc_skb(size_t len)
23749ed6e97SBjoern A. Zeeb {
23849ed6e97SBjoern A. Zeeb struct sk_buff *skb;
23949ed6e97SBjoern A. Zeeb
2409df5f29cSBjoern A. Zeeb skb = __dev_alloc_skb(len, GFP_NOWAIT);
2416baea331SBjoern A. Zeeb SKB_IMPROVE();
24249ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
24349ed6e97SBjoern A. Zeeb return (skb);
24449ed6e97SBjoern A. Zeeb }
24549ed6e97SBjoern A. Zeeb
24649ed6e97SBjoern A. Zeeb static inline void
kfree_skb(struct sk_buff * skb)24749ed6e97SBjoern A. Zeeb kfree_skb(struct sk_buff *skb)
24849ed6e97SBjoern A. Zeeb {
24949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
25049ed6e97SBjoern A. Zeeb linuxkpi_kfree_skb(skb);
25149ed6e97SBjoern A. Zeeb }
25249ed6e97SBjoern A. Zeeb
25349ed6e97SBjoern A. Zeeb static inline void
consume_skb(struct sk_buff * skb)2542ab4a419SBjoern A. Zeeb consume_skb(struct sk_buff *skb)
2552ab4a419SBjoern A. Zeeb {
2562ab4a419SBjoern A. Zeeb SKB_TRACE(skb);
2572ab4a419SBjoern A. Zeeb kfree_skb(skb);
2582ab4a419SBjoern A. Zeeb }
2592ab4a419SBjoern A. Zeeb
2602ab4a419SBjoern A. Zeeb static inline void
dev_kfree_skb(struct sk_buff * skb)26149ed6e97SBjoern A. Zeeb dev_kfree_skb(struct sk_buff *skb)
26249ed6e97SBjoern A. Zeeb {
26349ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
26449ed6e97SBjoern A. Zeeb kfree_skb(skb);
26549ed6e97SBjoern A. Zeeb }
26649ed6e97SBjoern A. Zeeb
26749ed6e97SBjoern A. Zeeb static inline void
dev_kfree_skb_any(struct sk_buff * skb)26849ed6e97SBjoern A. Zeeb dev_kfree_skb_any(struct sk_buff *skb)
26949ed6e97SBjoern A. Zeeb {
27049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
27149ed6e97SBjoern A. Zeeb dev_kfree_skb(skb);
27249ed6e97SBjoern A. Zeeb }
27349ed6e97SBjoern A. Zeeb
27449ed6e97SBjoern A. Zeeb static inline void
dev_kfree_skb_irq(struct sk_buff * skb)27549ed6e97SBjoern A. Zeeb dev_kfree_skb_irq(struct sk_buff *skb)
27649ed6e97SBjoern A. Zeeb {
27749ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
278952643eaSBjoern A. Zeeb SKB_IMPROVE("Do we have to defer this?");
279952643eaSBjoern A. Zeeb dev_kfree_skb(skb);
28049ed6e97SBjoern A. Zeeb }
28149ed6e97SBjoern A. Zeeb
2825504bd59SBjoern A. Zeeb static inline struct sk_buff *
build_skb(void * data,unsigned int fragsz)2835504bd59SBjoern A. Zeeb build_skb(void *data, unsigned int fragsz)
2845504bd59SBjoern A. Zeeb {
2855504bd59SBjoern A. Zeeb struct sk_buff *skb;
2865504bd59SBjoern A. Zeeb
2875504bd59SBjoern A. Zeeb skb = linuxkpi_build_skb(data, fragsz);
2885504bd59SBjoern A. Zeeb SKB_TRACE(skb);
2895504bd59SBjoern A. Zeeb return (skb);
2905504bd59SBjoern A. Zeeb }
2915504bd59SBjoern A. Zeeb
29249ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
29349ed6e97SBjoern A. Zeeb
2942ab4a419SBjoern A. Zeeb static inline bool
skb_is_nonlinear(struct sk_buff * skb)2952ab4a419SBjoern A. Zeeb skb_is_nonlinear(struct sk_buff *skb)
2962ab4a419SBjoern A. Zeeb {
2972ab4a419SBjoern A. Zeeb SKB_TRACE(skb);
2982ab4a419SBjoern A. Zeeb return ((skb->data_len > 0) ? true : false);
2992ab4a419SBjoern A. Zeeb }
30049ed6e97SBjoern A. Zeeb
30149ed6e97SBjoern A. Zeeb /* Add headroom; cannot do once there is data in there. */
30249ed6e97SBjoern A. Zeeb static inline void
skb_reserve(struct sk_buff * skb,size_t len)30349ed6e97SBjoern A. Zeeb skb_reserve(struct sk_buff *skb, size_t len)
30449ed6e97SBjoern A. Zeeb {
30549ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
3066baea331SBjoern A. Zeeb #if 0
3076baea331SBjoern A. Zeeb /* Apparently it is allowed to call skb_reserve multiple times in a row. */
30849ed6e97SBjoern A. Zeeb KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p "
30949ed6e97SBjoern A. Zeeb "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail));
3106baea331SBjoern A. Zeeb #else
3116baea331SBjoern A. Zeeb KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not "
3126baea331SBjoern A. Zeeb "empty head %p data %p tail %p len %u\n", __func__, skb,
3136baea331SBjoern A. Zeeb skb->head, skb->data, skb->tail, skb->len));
3146baea331SBjoern A. Zeeb #endif
31549ed6e97SBjoern A. Zeeb skb->data += len;
31649ed6e97SBjoern A. Zeeb skb->tail += len;
31749ed6e97SBjoern A. Zeeb }
31849ed6e97SBjoern A. Zeeb
31949ed6e97SBjoern A. Zeeb /*
32049ed6e97SBjoern A. Zeeb * Remove headroom; return new data pointer; basically make space at the
32149ed6e97SBjoern A. Zeeb * front to copy data in (manually).
32249ed6e97SBjoern A. Zeeb */
32349ed6e97SBjoern A. Zeeb static inline void *
__skb_push(struct sk_buff * skb,size_t len)32489c32dafSBjoern A. Zeeb __skb_push(struct sk_buff *skb, size_t len)
32549ed6e97SBjoern A. Zeeb {
32649ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
32749ed6e97SBjoern A. Zeeb KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - "
32849ed6e97SBjoern A. Zeeb "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data));
32949ed6e97SBjoern A. Zeeb skb->len += len;
33049ed6e97SBjoern A. Zeeb skb->data -= len;
33149ed6e97SBjoern A. Zeeb return (skb->data);
33249ed6e97SBjoern A. Zeeb }
33349ed6e97SBjoern A. Zeeb
33489c32dafSBjoern A. Zeeb static inline void *
skb_push(struct sk_buff * skb,size_t len)33589c32dafSBjoern A. Zeeb skb_push(struct sk_buff *skb, size_t len)
33689c32dafSBjoern A. Zeeb {
33789c32dafSBjoern A. Zeeb
33889c32dafSBjoern A. Zeeb SKB_TRACE(skb);
33989c32dafSBjoern A. Zeeb return (__skb_push(skb, len));
34089c32dafSBjoern A. Zeeb }
34189c32dafSBjoern A. Zeeb
34249ed6e97SBjoern A. Zeeb /*
34349ed6e97SBjoern A. Zeeb * Length of the data on the skb (without any frags)???
34449ed6e97SBjoern A. Zeeb */
34549ed6e97SBjoern A. Zeeb static inline size_t
skb_headlen(struct sk_buff * skb)34649ed6e97SBjoern A. Zeeb skb_headlen(struct sk_buff *skb)
34749ed6e97SBjoern A. Zeeb {
34849ed6e97SBjoern A. Zeeb
34949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
35049ed6e97SBjoern A. Zeeb return (skb->len - skb->data_len);
35149ed6e97SBjoern A. Zeeb }
35249ed6e97SBjoern A. Zeeb
35349ed6e97SBjoern A. Zeeb
35449ed6e97SBjoern A. Zeeb /* Return the end of data (tail pointer). */
35549ed6e97SBjoern A. Zeeb static inline uint8_t *
skb_tail_pointer(struct sk_buff * skb)35649ed6e97SBjoern A. Zeeb skb_tail_pointer(struct sk_buff *skb)
35749ed6e97SBjoern A. Zeeb {
35849ed6e97SBjoern A. Zeeb
35949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
36049ed6e97SBjoern A. Zeeb return (skb->tail);
36149ed6e97SBjoern A. Zeeb }
36249ed6e97SBjoern A. Zeeb
36349ed6e97SBjoern A. Zeeb /* Return number of bytes available at end of buffer. */
36449ed6e97SBjoern A. Zeeb static inline unsigned int
skb_tailroom(struct sk_buff * skb)36549ed6e97SBjoern A. Zeeb skb_tailroom(struct sk_buff *skb)
36649ed6e97SBjoern A. Zeeb {
36749ed6e97SBjoern A. Zeeb
36849ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
36949ed6e97SBjoern A. Zeeb KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, "
37049ed6e97SBjoern A. Zeeb "end %p tail %p\n", __func__, skb, skb->end, skb->tail));
3712ab4a419SBjoern A. Zeeb if (unlikely(skb_is_nonlinear(skb)))
3722ab4a419SBjoern A. Zeeb return (0);
37349ed6e97SBjoern A. Zeeb return (skb->end - skb->tail);
37449ed6e97SBjoern A. Zeeb }
37549ed6e97SBjoern A. Zeeb
3762ab4a419SBjoern A. Zeeb /* Return number of bytes available at the beginning of buffer. */
37749ed6e97SBjoern A. Zeeb static inline unsigned int
skb_headroom(const struct sk_buff * skb)3782ab4a419SBjoern A. Zeeb skb_headroom(const struct sk_buff *skb)
37949ed6e97SBjoern A. Zeeb {
38049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
38149ed6e97SBjoern A. Zeeb KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, "
38249ed6e97SBjoern A. Zeeb "data %p head %p\n", __func__, skb, skb->data, skb->head));
38349ed6e97SBjoern A. Zeeb return (skb->data - skb->head);
38449ed6e97SBjoern A. Zeeb }
38549ed6e97SBjoern A. Zeeb
38649ed6e97SBjoern A. Zeeb
38749ed6e97SBjoern A. Zeeb /*
38849ed6e97SBjoern A. Zeeb * Remove tailroom; return the old tail pointer; basically make space at
38949ed6e97SBjoern A. Zeeb * the end to copy data in (manually). See also skb_put_data() below.
39049ed6e97SBjoern A. Zeeb */
39149ed6e97SBjoern A. Zeeb static inline void *
__skb_put(struct sk_buff * skb,size_t len)39289c32dafSBjoern A. Zeeb __skb_put(struct sk_buff *skb, size_t len)
39349ed6e97SBjoern A. Zeeb {
39449ed6e97SBjoern A. Zeeb void *s;
39549ed6e97SBjoern A. Zeeb
39649ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
39749ed6e97SBjoern A. Zeeb KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + "
39849ed6e97SBjoern A. Zeeb "len %zu) > end %p, head %p data %p len %u\n", __func__,
39949ed6e97SBjoern A. Zeeb skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len));
40049ed6e97SBjoern A. Zeeb
40149ed6e97SBjoern A. Zeeb s = skb_tail_pointer(skb);
402952643eaSBjoern A. Zeeb if (len == 0)
403952643eaSBjoern A. Zeeb return (s);
40449ed6e97SBjoern A. Zeeb skb->tail += len;
40549ed6e97SBjoern A. Zeeb skb->len += len;
40649ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
4076baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACEX)
40849ed6e97SBjoern A. Zeeb printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n",
40949ed6e97SBjoern A. Zeeb __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end,
41049ed6e97SBjoern A. Zeeb s, len);
41149ed6e97SBjoern A. Zeeb #endif
41249ed6e97SBjoern A. Zeeb return (s);
41349ed6e97SBjoern A. Zeeb }
41449ed6e97SBjoern A. Zeeb
41589c32dafSBjoern A. Zeeb static inline void *
skb_put(struct sk_buff * skb,size_t len)41689c32dafSBjoern A. Zeeb skb_put(struct sk_buff *skb, size_t len)
41789c32dafSBjoern A. Zeeb {
41889c32dafSBjoern A. Zeeb
41989c32dafSBjoern A. Zeeb SKB_TRACE(skb);
42089c32dafSBjoern A. Zeeb return (__skb_put(skb, len));
42189c32dafSBjoern A. Zeeb }
42289c32dafSBjoern A. Zeeb
42349ed6e97SBjoern A. Zeeb /* skb_put() + copying data in. */
42449ed6e97SBjoern A. Zeeb static inline void *
skb_put_data(struct sk_buff * skb,const void * buf,size_t len)42549ed6e97SBjoern A. Zeeb skb_put_data(struct sk_buff *skb, const void *buf, size_t len)
42649ed6e97SBjoern A. Zeeb {
42749ed6e97SBjoern A. Zeeb void *s;
42849ed6e97SBjoern A. Zeeb
42949ed6e97SBjoern A. Zeeb SKB_TRACE2(skb, buf);
43049ed6e97SBjoern A. Zeeb s = skb_put(skb, len);
431952643eaSBjoern A. Zeeb if (len == 0)
432952643eaSBjoern A. Zeeb return (s);
43349ed6e97SBjoern A. Zeeb memcpy(s, buf, len);
43449ed6e97SBjoern A. Zeeb return (s);
43549ed6e97SBjoern A. Zeeb }
43649ed6e97SBjoern A. Zeeb
43749ed6e97SBjoern A. Zeeb /* skb_put() + filling with zeros. */
43849ed6e97SBjoern A. Zeeb static inline void *
skb_put_zero(struct sk_buff * skb,size_t len)43949ed6e97SBjoern A. Zeeb skb_put_zero(struct sk_buff *skb, size_t len)
44049ed6e97SBjoern A. Zeeb {
44149ed6e97SBjoern A. Zeeb void *s;
44249ed6e97SBjoern A. Zeeb
44349ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
44449ed6e97SBjoern A. Zeeb s = skb_put(skb, len);
44549ed6e97SBjoern A. Zeeb memset(s, '\0', len);
44649ed6e97SBjoern A. Zeeb return (s);
44749ed6e97SBjoern A. Zeeb }
44849ed6e97SBjoern A. Zeeb
44949ed6e97SBjoern A. Zeeb /*
45049ed6e97SBjoern A. Zeeb * Remove len bytes from beginning of data.
45149ed6e97SBjoern A. Zeeb *
45249ed6e97SBjoern A. Zeeb * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic;
45349ed6e97SBjoern A. Zeeb * we return the advanced data pointer so we don't have to keep a temp, correct?
45449ed6e97SBjoern A. Zeeb */
45549ed6e97SBjoern A. Zeeb static inline void *
skb_pull(struct sk_buff * skb,size_t len)45649ed6e97SBjoern A. Zeeb skb_pull(struct sk_buff *skb, size_t len)
45749ed6e97SBjoern A. Zeeb {
45849ed6e97SBjoern A. Zeeb
45949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
46049ed6e97SBjoern A. Zeeb #if 0 /* Apparently this doesn't barf... */
46149ed6e97SBjoern A. Zeeb KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n",
46249ed6e97SBjoern A. Zeeb __func__, skb, skb->len, len, skb->data));
46349ed6e97SBjoern A. Zeeb #endif
46449ed6e97SBjoern A. Zeeb if (skb->len < len)
46549ed6e97SBjoern A. Zeeb return (NULL);
46649ed6e97SBjoern A. Zeeb skb->len -= len;
46749ed6e97SBjoern A. Zeeb skb->data += len;
46849ed6e97SBjoern A. Zeeb return (skb->data);
46949ed6e97SBjoern A. Zeeb }
47049ed6e97SBjoern A. Zeeb
47149ed6e97SBjoern A. Zeeb /* Reduce skb data to given length or do nothing if smaller already. */
47249ed6e97SBjoern A. Zeeb static inline void
__skb_trim(struct sk_buff * skb,unsigned int len)47349ed6e97SBjoern A. Zeeb __skb_trim(struct sk_buff *skb, unsigned int len)
47449ed6e97SBjoern A. Zeeb {
47549ed6e97SBjoern A. Zeeb
47649ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
47749ed6e97SBjoern A. Zeeb if (skb->len < len)
47849ed6e97SBjoern A. Zeeb return;
47949ed6e97SBjoern A. Zeeb
48049ed6e97SBjoern A. Zeeb skb->len = len;
48149ed6e97SBjoern A. Zeeb skb->tail = skb->data + skb->len;
48249ed6e97SBjoern A. Zeeb }
48349ed6e97SBjoern A. Zeeb
48449ed6e97SBjoern A. Zeeb static inline void
skb_trim(struct sk_buff * skb,unsigned int len)48549ed6e97SBjoern A. Zeeb skb_trim(struct sk_buff *skb, unsigned int len)
48649ed6e97SBjoern A. Zeeb {
48749ed6e97SBjoern A. Zeeb
48849ed6e97SBjoern A. Zeeb return (__skb_trim(skb, len));
48949ed6e97SBjoern A. Zeeb }
49049ed6e97SBjoern A. Zeeb
49149ed6e97SBjoern A. Zeeb static inline struct skb_shared_info *
skb_shinfo(struct sk_buff * skb)49249ed6e97SBjoern A. Zeeb skb_shinfo(struct sk_buff *skb)
49349ed6e97SBjoern A. Zeeb {
49449ed6e97SBjoern A. Zeeb
49549ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
49649ed6e97SBjoern A. Zeeb return (skb->shinfo);
49749ed6e97SBjoern A. Zeeb }
49849ed6e97SBjoern A. Zeeb
49949ed6e97SBjoern A. Zeeb static inline void
skb_add_rx_frag(struct sk_buff * skb,int fragno,struct page * page,off_t offset,size_t size,unsigned int truesize)50049ed6e97SBjoern A. Zeeb skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
50149ed6e97SBjoern A. Zeeb off_t offset, size_t size, unsigned int truesize)
50249ed6e97SBjoern A. Zeeb {
50349ed6e97SBjoern A. Zeeb struct skb_shared_info *shinfo;
50449ed6e97SBjoern A. Zeeb
50549ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
50649ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
5076baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACEX)
50849ed6e97SBjoern A. Zeeb printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d "
50949ed6e97SBjoern A. Zeeb "page %#jx offset %ju size %zu truesize %u\n", __func__,
51049ed6e97SBjoern A. Zeeb skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno,
51149ed6e97SBjoern A. Zeeb (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset,
51249ed6e97SBjoern A. Zeeb size, truesize);
51349ed6e97SBjoern A. Zeeb #endif
51449ed6e97SBjoern A. Zeeb
51549ed6e97SBjoern A. Zeeb shinfo = skb_shinfo(skb);
51649ed6e97SBjoern A. Zeeb KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p "
51749ed6e97SBjoern A. Zeeb "fragno %d too big\n", __func__, skb, fragno));
51849ed6e97SBjoern A. Zeeb shinfo->frags[fragno].page = page;
51949ed6e97SBjoern A. Zeeb shinfo->frags[fragno].offset = offset;
52049ed6e97SBjoern A. Zeeb shinfo->frags[fragno].size = size;
52149ed6e97SBjoern A. Zeeb shinfo->nr_frags = fragno + 1;
52249ed6e97SBjoern A. Zeeb skb->len += size;
5235504bd59SBjoern A. Zeeb skb->data_len += size;
52449ed6e97SBjoern A. Zeeb skb->truesize += truesize;
52549ed6e97SBjoern A. Zeeb }
52649ed6e97SBjoern A. Zeeb
52749ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
52849ed6e97SBjoern A. Zeeb
52949ed6e97SBjoern A. Zeeb #define skb_queue_walk(_q, skb) \
53049ed6e97SBjoern A. Zeeb for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q); \
53149ed6e97SBjoern A. Zeeb (skb) = (skb)->next)
53249ed6e97SBjoern A. Zeeb
53349ed6e97SBjoern A. Zeeb #define skb_queue_walk_safe(_q, skb, tmp) \
53449ed6e97SBjoern A. Zeeb for ((skb) = (_q)->next, (tmp) = (skb)->next; \
53549ed6e97SBjoern A. Zeeb (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next)
53649ed6e97SBjoern A. Zeeb
5372ab4a419SBjoern A. Zeeb #define skb_list_walk_safe(_q, skb, tmp) \
5382ab4a419SBjoern A. Zeeb for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \
5392ab4a419SBjoern A. Zeeb ((skb) != NULL); \
5402ab4a419SBjoern A. Zeeb (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL)
54149ed6e97SBjoern A. Zeeb
5422ab4a419SBjoern A. Zeeb static inline bool
skb_queue_empty(const struct sk_buff_head * q)5432ab4a419SBjoern A. Zeeb skb_queue_empty(const struct sk_buff_head *q)
5442ab4a419SBjoern A. Zeeb {
54549ed6e97SBjoern A. Zeeb SKB_TRACE(q);
5462ab4a419SBjoern A. Zeeb return (q->next == (const struct sk_buff *)q);
5472ab4a419SBjoern A. Zeeb }
5482ab4a419SBjoern A. Zeeb
5492ab4a419SBjoern A. Zeeb static inline bool
skb_queue_empty_lockless(const struct sk_buff_head * q)5502ab4a419SBjoern A. Zeeb skb_queue_empty_lockless(const struct sk_buff_head *q)
5512ab4a419SBjoern A. Zeeb {
5522ab4a419SBjoern A. Zeeb SKB_TRACE(q);
5532ab4a419SBjoern A. Zeeb return (READ_ONCE(q->next) == (const struct sk_buff *)q);
55449ed6e97SBjoern A. Zeeb }
55549ed6e97SBjoern A. Zeeb
55649ed6e97SBjoern A. Zeeb static inline void
__skb_queue_head_init(struct sk_buff_head * q)55749ed6e97SBjoern A. Zeeb __skb_queue_head_init(struct sk_buff_head *q)
55849ed6e97SBjoern A. Zeeb {
55949ed6e97SBjoern A. Zeeb SKB_TRACE(q);
56049ed6e97SBjoern A. Zeeb q->prev = q->next = (struct sk_buff *)q;
56149ed6e97SBjoern A. Zeeb q->qlen = 0;
56249ed6e97SBjoern A. Zeeb }
56349ed6e97SBjoern A. Zeeb
56449ed6e97SBjoern A. Zeeb static inline void
skb_queue_head_init(struct sk_buff_head * q)56549ed6e97SBjoern A. Zeeb skb_queue_head_init(struct sk_buff_head *q)
56649ed6e97SBjoern A. Zeeb {
56749ed6e97SBjoern A. Zeeb SKB_TRACE(q);
5682ab4a419SBjoern A. Zeeb __skb_queue_head_init(q);
5692ab4a419SBjoern A. Zeeb spin_lock_init(&q->lock);
57049ed6e97SBjoern A. Zeeb }
57149ed6e97SBjoern A. Zeeb
57249ed6e97SBjoern A. Zeeb static inline void
__skb_insert(struct sk_buff * new,struct sk_buff * prev,struct sk_buff * next,struct sk_buff_head * q)57349ed6e97SBjoern A. Zeeb __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next,
57449ed6e97SBjoern A. Zeeb struct sk_buff_head *q)
57549ed6e97SBjoern A. Zeeb {
57649ed6e97SBjoern A. Zeeb
57749ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q);
5782ab4a419SBjoern A. Zeeb WRITE_ONCE(new->prev, prev);
5792ab4a419SBjoern A. Zeeb WRITE_ONCE(new->next, next);
5802ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new);
5812ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new);
5822ab4a419SBjoern A. Zeeb WRITE_ONCE(q->qlen, q->qlen + 1);
58349ed6e97SBjoern A. Zeeb }
58449ed6e97SBjoern A. Zeeb
58549ed6e97SBjoern A. Zeeb static inline void
__skb_queue_after(struct sk_buff_head * q,struct sk_buff * skb,struct sk_buff * new)58649ed6e97SBjoern A. Zeeb __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb,
58749ed6e97SBjoern A. Zeeb struct sk_buff *new)
58849ed6e97SBjoern A. Zeeb {
58949ed6e97SBjoern A. Zeeb
59049ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
591b2dcb848SBjoern A. Zeeb __skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q);
59249ed6e97SBjoern A. Zeeb }
59349ed6e97SBjoern A. Zeeb
59449ed6e97SBjoern A. Zeeb static inline void
__skb_queue_before(struct sk_buff_head * q,struct sk_buff * skb,struct sk_buff * new)59549ed6e97SBjoern A. Zeeb __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb,
59649ed6e97SBjoern A. Zeeb struct sk_buff *new)
59749ed6e97SBjoern A. Zeeb {
59849ed6e97SBjoern A. Zeeb
59949ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
60049ed6e97SBjoern A. Zeeb __skb_insert(new, skb->prev, skb, q);
60149ed6e97SBjoern A. Zeeb }
60249ed6e97SBjoern A. Zeeb
60349ed6e97SBjoern A. Zeeb static inline void
__skb_queue_tail(struct sk_buff_head * q,struct sk_buff * new)604b2dcb848SBjoern A. Zeeb __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
60549ed6e97SBjoern A. Zeeb {
60649ed6e97SBjoern A. Zeeb
607b2dcb848SBjoern A. Zeeb SKB_TRACE2(q, new);
608d3befb53STom Coldrick __skb_queue_before(q, (struct sk_buff *)q, new);
60949ed6e97SBjoern A. Zeeb }
61049ed6e97SBjoern A. Zeeb
61149ed6e97SBjoern A. Zeeb static inline void
skb_queue_tail(struct sk_buff_head * q,struct sk_buff * new)612b2dcb848SBjoern A. Zeeb skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
61349ed6e97SBjoern A. Zeeb {
6142ab4a419SBjoern A. Zeeb unsigned long flags;
6152ab4a419SBjoern A. Zeeb
616149c457dSBjoern A. Zeeb SKB_TRACE2(q, new);
6172ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
6182ab4a419SBjoern A. Zeeb __skb_queue_tail(q, new);
6192ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
62049ed6e97SBjoern A. Zeeb }
62149ed6e97SBjoern A. Zeeb
62249ed6e97SBjoern A. Zeeb static inline struct sk_buff *
skb_peek(const struct sk_buff_head * q)6232ab4a419SBjoern A. Zeeb skb_peek(const struct sk_buff_head *q)
624ce9f3661SBjoern A. Zeeb {
625ce9f3661SBjoern A. Zeeb struct sk_buff *skb;
626ce9f3661SBjoern A. Zeeb
627ce9f3661SBjoern A. Zeeb skb = q->next;
628ce9f3661SBjoern A. Zeeb SKB_TRACE2(q, skb);
6292ab4a419SBjoern A. Zeeb if (skb == (const struct sk_buff *)q)
630ce9f3661SBjoern A. Zeeb return (NULL);
631ce9f3661SBjoern A. Zeeb return (skb);
632ce9f3661SBjoern A. Zeeb }
633ce9f3661SBjoern A. Zeeb
634ce9f3661SBjoern A. Zeeb static inline struct sk_buff *
skb_peek_tail(const struct sk_buff_head * q)6352ab4a419SBjoern A. Zeeb skb_peek_tail(const struct sk_buff_head *q)
63649ed6e97SBjoern A. Zeeb {
63749ed6e97SBjoern A. Zeeb struct sk_buff *skb;
63849ed6e97SBjoern A. Zeeb
6392ab4a419SBjoern A. Zeeb skb = READ_ONCE(q->prev);
64049ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb);
6412ab4a419SBjoern A. Zeeb if (skb == (const struct sk_buff *)q)
64249ed6e97SBjoern A. Zeeb return (NULL);
64349ed6e97SBjoern A. Zeeb return (skb);
64449ed6e97SBjoern A. Zeeb }
64549ed6e97SBjoern A. Zeeb
64649ed6e97SBjoern A. Zeeb static inline void
__skb_unlink(struct sk_buff * skb,struct sk_buff_head * q)6472ab4a419SBjoern A. Zeeb __skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
64849ed6e97SBjoern A. Zeeb {
649b4856b8eSZhenlei Huang struct sk_buff *p, *n;
65049ed6e97SBjoern A. Zeeb
6512ab4a419SBjoern A. Zeeb SKB_TRACE2(skb, q);
6522ab4a419SBjoern A. Zeeb
6532ab4a419SBjoern A. Zeeb WRITE_ONCE(q->qlen, q->qlen - 1);
65449ed6e97SBjoern A. Zeeb p = skb->prev;
65549ed6e97SBjoern A. Zeeb n = skb->next;
6562ab4a419SBjoern A. Zeeb WRITE_ONCE(n->prev, p);
6572ab4a419SBjoern A. Zeeb WRITE_ONCE(p->next, n);
65849ed6e97SBjoern A. Zeeb skb->prev = skb->next = NULL;
65949ed6e97SBjoern A. Zeeb }
66049ed6e97SBjoern A. Zeeb
66149ed6e97SBjoern A. Zeeb static inline void
skb_unlink(struct sk_buff * skb,struct sk_buff_head * q)6622ab4a419SBjoern A. Zeeb skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
66349ed6e97SBjoern A. Zeeb {
6642ab4a419SBjoern A. Zeeb unsigned long flags;
6652ab4a419SBjoern A. Zeeb
6662ab4a419SBjoern A. Zeeb SKB_TRACE2(skb, q);
6672ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
6682ab4a419SBjoern A. Zeeb __skb_unlink(skb, q);
6692ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
67049ed6e97SBjoern A. Zeeb }
67149ed6e97SBjoern A. Zeeb
67249ed6e97SBjoern A. Zeeb static inline struct sk_buff *
__skb_dequeue(struct sk_buff_head * q)67349ed6e97SBjoern A. Zeeb __skb_dequeue(struct sk_buff_head *q)
67449ed6e97SBjoern A. Zeeb {
67549ed6e97SBjoern A. Zeeb struct sk_buff *skb;
67649ed6e97SBjoern A. Zeeb
6772ab4a419SBjoern A. Zeeb skb = skb_peek(q);
67849ed6e97SBjoern A. Zeeb if (skb != NULL)
67949ed6e97SBjoern A. Zeeb __skb_unlink(skb, q);
6802ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb);
68149ed6e97SBjoern A. Zeeb return (skb);
68249ed6e97SBjoern A. Zeeb }
68349ed6e97SBjoern A. Zeeb
68449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
skb_dequeue(struct sk_buff_head * q)68549ed6e97SBjoern A. Zeeb skb_dequeue(struct sk_buff_head *q)
68649ed6e97SBjoern A. Zeeb {
6872ab4a419SBjoern A. Zeeb unsigned long flags;
6882ab4a419SBjoern A. Zeeb struct sk_buff *skb;
6892ab4a419SBjoern A. Zeeb
6902ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
6912ab4a419SBjoern A. Zeeb skb = __skb_dequeue(q);
6922ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
6932ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb);
6942ab4a419SBjoern A. Zeeb return (skb);
69549ed6e97SBjoern A. Zeeb }
69649ed6e97SBjoern A. Zeeb
69749ed6e97SBjoern A. Zeeb static inline struct sk_buff *
__skb_dequeue_tail(struct sk_buff_head * q)6982ab4a419SBjoern A. Zeeb __skb_dequeue_tail(struct sk_buff_head *q)
69949ed6e97SBjoern A. Zeeb {
70049ed6e97SBjoern A. Zeeb struct sk_buff *skb;
70149ed6e97SBjoern A. Zeeb
70249ed6e97SBjoern A. Zeeb skb = skb_peek_tail(q);
70349ed6e97SBjoern A. Zeeb if (skb != NULL)
70449ed6e97SBjoern A. Zeeb __skb_unlink(skb, q);
7052ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb);
7062ab4a419SBjoern A. Zeeb return (skb);
7072ab4a419SBjoern A. Zeeb }
70849ed6e97SBjoern A. Zeeb
7092ab4a419SBjoern A. Zeeb static inline struct sk_buff *
skb_dequeue_tail(struct sk_buff_head * q)7102ab4a419SBjoern A. Zeeb skb_dequeue_tail(struct sk_buff_head *q)
7112ab4a419SBjoern A. Zeeb {
7122ab4a419SBjoern A. Zeeb unsigned long flags;
7132ab4a419SBjoern A. Zeeb struct sk_buff *skb;
7142ab4a419SBjoern A. Zeeb
7152ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
7162ab4a419SBjoern A. Zeeb skb = __skb_dequeue_tail(q);
7172ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
71849ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb);
71949ed6e97SBjoern A. Zeeb return (skb);
72049ed6e97SBjoern A. Zeeb }
72149ed6e97SBjoern A. Zeeb
72249ed6e97SBjoern A. Zeeb static inline void
__skb_queue_head(struct sk_buff_head * q,struct sk_buff * skb)7236baea331SBjoern A. Zeeb __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
7246baea331SBjoern A. Zeeb {
7256baea331SBjoern A. Zeeb
7266baea331SBjoern A. Zeeb SKB_TRACE2(q, skb);
7276baea331SBjoern A. Zeeb __skb_queue_after(q, (struct sk_buff *)q, skb);
7286baea331SBjoern A. Zeeb }
7296baea331SBjoern A. Zeeb
7306baea331SBjoern A. Zeeb static inline void
skb_queue_head(struct sk_buff_head * q,struct sk_buff * skb)73149ed6e97SBjoern A. Zeeb skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
73249ed6e97SBjoern A. Zeeb {
7332ab4a419SBjoern A. Zeeb unsigned long flags;
73449ed6e97SBjoern A. Zeeb
73549ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb);
7362ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
7372ab4a419SBjoern A. Zeeb __skb_queue_head(q, skb);
7382ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
73949ed6e97SBjoern A. Zeeb }
74049ed6e97SBjoern A. Zeeb
74149ed6e97SBjoern A. Zeeb static inline uint32_t
skb_queue_len(const struct sk_buff_head * q)7422ab4a419SBjoern A. Zeeb skb_queue_len(const struct sk_buff_head *q)
74349ed6e97SBjoern A. Zeeb {
7446baea331SBjoern A. Zeeb
7452ab4a419SBjoern A. Zeeb SKB_TRACE(q);
7462ab4a419SBjoern A. Zeeb return (q->qlen);
74749ed6e97SBjoern A. Zeeb }
74849ed6e97SBjoern A. Zeeb
7496baea331SBjoern A. Zeeb static inline uint32_t
skb_queue_len_lockless(const struct sk_buff_head * q)7502ab4a419SBjoern A. Zeeb skb_queue_len_lockless(const struct sk_buff_head *q)
7516baea331SBjoern A. Zeeb {
7526baea331SBjoern A. Zeeb
7532ab4a419SBjoern A. Zeeb SKB_TRACE(q);
7542ab4a419SBjoern A. Zeeb return (READ_ONCE(q->qlen));
7556baea331SBjoern A. Zeeb }
7566baea331SBjoern A. Zeeb
75749ed6e97SBjoern A. Zeeb static inline void
___skb_queue_splice(const struct sk_buff_head * from,struct sk_buff * p,struct sk_buff * n)7582ab4a419SBjoern A. Zeeb ___skb_queue_splice(const struct sk_buff_head *from,
7592ab4a419SBjoern A. Zeeb struct sk_buff *p, struct sk_buff *n)
7602ab4a419SBjoern A. Zeeb {
7612ab4a419SBjoern A. Zeeb struct sk_buff *b, *e;
7622ab4a419SBjoern A. Zeeb
7632ab4a419SBjoern A. Zeeb b = from->next;
7642ab4a419SBjoern A. Zeeb e = from->prev;
7652ab4a419SBjoern A. Zeeb
7662ab4a419SBjoern A. Zeeb WRITE_ONCE(b->prev, p);
7672ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b);
7682ab4a419SBjoern A. Zeeb WRITE_ONCE(e->next, n);
7692ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e);
7702ab4a419SBjoern A. Zeeb }
7712ab4a419SBjoern A. Zeeb
7722ab4a419SBjoern A. Zeeb static inline void
skb_queue_splice_init(struct sk_buff_head * from,struct sk_buff_head * to)7732ab4a419SBjoern A. Zeeb skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
7742ab4a419SBjoern A. Zeeb {
7752ab4a419SBjoern A. Zeeb
7762ab4a419SBjoern A. Zeeb SKB_TRACE2(from, to);
7772ab4a419SBjoern A. Zeeb
7782ab4a419SBjoern A. Zeeb if (skb_queue_empty(from))
7792ab4a419SBjoern A. Zeeb return;
7802ab4a419SBjoern A. Zeeb
7812ab4a419SBjoern A. Zeeb ___skb_queue_splice(from, (struct sk_buff *)to, to->next);
7822ab4a419SBjoern A. Zeeb to->qlen += from->qlen;
7832ab4a419SBjoern A. Zeeb __skb_queue_head_init(from);
7842ab4a419SBjoern A. Zeeb }
7852ab4a419SBjoern A. Zeeb
7862ab4a419SBjoern A. Zeeb static inline void
skb_queue_splice_tail_init(struct sk_buff_head * from,struct sk_buff_head * to)7872ab4a419SBjoern A. Zeeb skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to)
7882ab4a419SBjoern A. Zeeb {
7892ab4a419SBjoern A. Zeeb
7902ab4a419SBjoern A. Zeeb SKB_TRACE2(from, to);
7912ab4a419SBjoern A. Zeeb
7922ab4a419SBjoern A. Zeeb if (skb_queue_empty(from))
7932ab4a419SBjoern A. Zeeb return;
7942ab4a419SBjoern A. Zeeb
7952ab4a419SBjoern A. Zeeb ___skb_queue_splice(from, to->prev, (struct sk_buff *)to);
7962ab4a419SBjoern A. Zeeb to->qlen += from->qlen;
7972ab4a419SBjoern A. Zeeb __skb_queue_head_init(from);
7982ab4a419SBjoern A. Zeeb }
7992ab4a419SBjoern A. Zeeb
8002ab4a419SBjoern A. Zeeb
8012ab4a419SBjoern A. Zeeb static inline void
__skb_queue_purge(struct sk_buff_head * q)80249ed6e97SBjoern A. Zeeb __skb_queue_purge(struct sk_buff_head *q)
80349ed6e97SBjoern A. Zeeb {
80449ed6e97SBjoern A. Zeeb struct sk_buff *skb;
80549ed6e97SBjoern A. Zeeb
80649ed6e97SBjoern A. Zeeb SKB_TRACE(q);
80749ed6e97SBjoern A. Zeeb while ((skb = __skb_dequeue(q)) != NULL)
80849ed6e97SBjoern A. Zeeb kfree_skb(skb);
809bcf1d8eeSBjoern A. Zeeb WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u",
810bcf1d8eeSBjoern A. Zeeb __func__, q, skb_queue_len(q));
81149ed6e97SBjoern A. Zeeb }
81249ed6e97SBjoern A. Zeeb
81349ed6e97SBjoern A. Zeeb static inline void
skb_queue_purge(struct sk_buff_head * q)81449ed6e97SBjoern A. Zeeb skb_queue_purge(struct sk_buff_head *q)
81549ed6e97SBjoern A. Zeeb {
8162ab4a419SBjoern A. Zeeb struct sk_buff_head _q;
8172ab4a419SBjoern A. Zeeb unsigned long flags;
8182ab4a419SBjoern A. Zeeb
81949ed6e97SBjoern A. Zeeb SKB_TRACE(q);
8202ab4a419SBjoern A. Zeeb
8212ab4a419SBjoern A. Zeeb if (skb_queue_empty_lockless(q))
8222ab4a419SBjoern A. Zeeb return;
8232ab4a419SBjoern A. Zeeb
8242ab4a419SBjoern A. Zeeb __skb_queue_head_init(&_q);
8252ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags);
8262ab4a419SBjoern A. Zeeb skb_queue_splice_init(q, &_q);
8272ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags);
8282ab4a419SBjoern A. Zeeb __skb_queue_purge(&_q);
82949ed6e97SBjoern A. Zeeb }
83049ed6e97SBjoern A. Zeeb
83149ed6e97SBjoern A. Zeeb static inline struct sk_buff *
skb_queue_prev(struct sk_buff_head * q,struct sk_buff * skb)83249ed6e97SBjoern A. Zeeb skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
83349ed6e97SBjoern A. Zeeb {
83449ed6e97SBjoern A. Zeeb
83549ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb);
83649ed6e97SBjoern A. Zeeb /* XXX what is the q argument good for? */
83749ed6e97SBjoern A. Zeeb return (skb->prev);
83849ed6e97SBjoern A. Zeeb }
83949ed6e97SBjoern A. Zeeb
84049ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
84149ed6e97SBjoern A. Zeeb
84249ed6e97SBjoern A. Zeeb static inline struct sk_buff *
skb_copy(const struct sk_buff * skb,gfp_t gfp)8432ab4a419SBjoern A. Zeeb skb_copy(const struct sk_buff *skb, gfp_t gfp)
84449ed6e97SBjoern A. Zeeb {
845349b042bSBjoern A. Zeeb struct sk_buff *new;
846349b042bSBjoern A. Zeeb
847349b042bSBjoern A. Zeeb new = linuxkpi_skb_copy(skb, gfp);
848349b042bSBjoern A. Zeeb SKB_TRACE2(skb, new);
849349b042bSBjoern A. Zeeb return (new);
85049ed6e97SBjoern A. Zeeb }
85149ed6e97SBjoern A. Zeeb
85249ed6e97SBjoern A. Zeeb static inline uint16_t
skb_checksum(struct sk_buff * skb,int offs,size_t len,int x)85349ed6e97SBjoern A. Zeeb skb_checksum(struct sk_buff *skb, int offs, size_t len, int x)
85449ed6e97SBjoern A. Zeeb {
85549ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
85649ed6e97SBjoern A. Zeeb SKB_TODO();
85749ed6e97SBjoern A. Zeeb return (0xffff);
85849ed6e97SBjoern A. Zeeb }
85949ed6e97SBjoern A. Zeeb
86049ed6e97SBjoern A. Zeeb static inline int
skb_checksum_start_offset(struct sk_buff * skb)86149ed6e97SBjoern A. Zeeb skb_checksum_start_offset(struct sk_buff *skb)
86249ed6e97SBjoern A. Zeeb {
86349ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
86449ed6e97SBjoern A. Zeeb SKB_TODO();
86549ed6e97SBjoern A. Zeeb return (-1);
86649ed6e97SBjoern A. Zeeb }
86749ed6e97SBjoern A. Zeeb
86849ed6e97SBjoern A. Zeeb static inline dma_addr_t
skb_frag_dma_map(struct device * dev,const skb_frag_t * frag,int x,size_t fragsz,enum dma_data_direction dir)86949ed6e97SBjoern A. Zeeb skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x,
87049ed6e97SBjoern A. Zeeb size_t fragsz, enum dma_data_direction dir)
87149ed6e97SBjoern A. Zeeb {
87249ed6e97SBjoern A. Zeeb SKB_TRACE2(frag, dev);
87349ed6e97SBjoern A. Zeeb SKB_TODO();
87449ed6e97SBjoern A. Zeeb return (-1);
87549ed6e97SBjoern A. Zeeb }
87649ed6e97SBjoern A. Zeeb
87749ed6e97SBjoern A. Zeeb static inline size_t
skb_frag_size(const skb_frag_t * frag)87849ed6e97SBjoern A. Zeeb skb_frag_size(const skb_frag_t *frag)
87949ed6e97SBjoern A. Zeeb {
88049ed6e97SBjoern A. Zeeb SKB_TRACE(frag);
8812ab4a419SBjoern A. Zeeb return (frag->size);
88249ed6e97SBjoern A. Zeeb }
88349ed6e97SBjoern A. Zeeb
88449ed6e97SBjoern A. Zeeb #define skb_walk_frags(_skb, _frag) \
88549ed6e97SBjoern A. Zeeb for ((_frag) = (_skb); false; (_frag)++)
88649ed6e97SBjoern A. Zeeb
88749ed6e97SBjoern A. Zeeb static inline void
skb_checksum_help(struct sk_buff * skb)88849ed6e97SBjoern A. Zeeb skb_checksum_help(struct sk_buff *skb)
88949ed6e97SBjoern A. Zeeb {
89049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
89149ed6e97SBjoern A. Zeeb SKB_TODO();
89249ed6e97SBjoern A. Zeeb }
89349ed6e97SBjoern A. Zeeb
89449ed6e97SBjoern A. Zeeb static inline bool
skb_ensure_writable(struct sk_buff * skb,size_t off)89549ed6e97SBjoern A. Zeeb skb_ensure_writable(struct sk_buff *skb, size_t off)
89649ed6e97SBjoern A. Zeeb {
89749ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
89849ed6e97SBjoern A. Zeeb SKB_TODO();
89949ed6e97SBjoern A. Zeeb return (false);
90049ed6e97SBjoern A. Zeeb }
90149ed6e97SBjoern A. Zeeb
90249ed6e97SBjoern A. Zeeb static inline void *
skb_frag_address(const skb_frag_t * frag)90349ed6e97SBjoern A. Zeeb skb_frag_address(const skb_frag_t *frag)
90449ed6e97SBjoern A. Zeeb {
90549ed6e97SBjoern A. Zeeb SKB_TRACE(frag);
9062ab4a419SBjoern A. Zeeb return (page_address(frag->page + frag->offset));
90749ed6e97SBjoern A. Zeeb }
90849ed6e97SBjoern A. Zeeb
90989c32dafSBjoern A. Zeeb static inline void
skb_free_frag(void * frag)91089c32dafSBjoern A. Zeeb skb_free_frag(void *frag)
91189c32dafSBjoern A. Zeeb {
91289c32dafSBjoern A. Zeeb
913dbbf46ebSBjoern A. Zeeb page_frag_free(frag);
91489c32dafSBjoern A. Zeeb }
91589c32dafSBjoern A. Zeeb
91649ed6e97SBjoern A. Zeeb static inline struct sk_buff *
skb_gso_segment(struct sk_buff * skb,netdev_features_t netdev_flags)91749ed6e97SBjoern A. Zeeb skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags)
91849ed6e97SBjoern A. Zeeb {
91949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
92049ed6e97SBjoern A. Zeeb SKB_TODO();
92149ed6e97SBjoern A. Zeeb return (NULL);
92249ed6e97SBjoern A. Zeeb }
92349ed6e97SBjoern A. Zeeb
92449ed6e97SBjoern A. Zeeb static inline bool
skb_is_gso(struct sk_buff * skb)92549ed6e97SBjoern A. Zeeb skb_is_gso(struct sk_buff *skb)
92649ed6e97SBjoern A. Zeeb {
92749ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
928952643eaSBjoern A. Zeeb SKB_IMPROVE("Really a TODO but get it away from logging");
92949ed6e97SBjoern A. Zeeb return (false);
93049ed6e97SBjoern A. Zeeb }
93149ed6e97SBjoern A. Zeeb
93249ed6e97SBjoern A. Zeeb static inline void
skb_mark_not_on_list(struct sk_buff * skb)93349ed6e97SBjoern A. Zeeb skb_mark_not_on_list(struct sk_buff *skb)
93449ed6e97SBjoern A. Zeeb {
93549ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
9362ab4a419SBjoern A. Zeeb skb->next = NULL;
93749ed6e97SBjoern A. Zeeb }
93849ed6e97SBjoern A. Zeeb
93949ed6e97SBjoern A. Zeeb static inline void
skb_reset_transport_header(struct sk_buff * skb)94049ed6e97SBjoern A. Zeeb skb_reset_transport_header(struct sk_buff *skb)
94149ed6e97SBjoern A. Zeeb {
94249ed6e97SBjoern A. Zeeb
94349ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
94449ed6e97SBjoern A. Zeeb skb->l4hdroff = skb->data - skb->head;
94549ed6e97SBjoern A. Zeeb }
94649ed6e97SBjoern A. Zeeb
94749ed6e97SBjoern A. Zeeb static inline uint8_t *
skb_transport_header(struct sk_buff * skb)94849ed6e97SBjoern A. Zeeb skb_transport_header(struct sk_buff *skb)
94949ed6e97SBjoern A. Zeeb {
95049ed6e97SBjoern A. Zeeb
95149ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
95249ed6e97SBjoern A. Zeeb return (skb->head + skb->l4hdroff);
95349ed6e97SBjoern A. Zeeb }
95449ed6e97SBjoern A. Zeeb
95549ed6e97SBjoern A. Zeeb static inline uint8_t *
skb_network_header(struct sk_buff * skb)95649ed6e97SBjoern A. Zeeb skb_network_header(struct sk_buff *skb)
95749ed6e97SBjoern A. Zeeb {
95849ed6e97SBjoern A. Zeeb
95949ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
96049ed6e97SBjoern A. Zeeb return (skb->head + skb->l3hdroff);
96149ed6e97SBjoern A. Zeeb }
96249ed6e97SBjoern A. Zeeb
96349ed6e97SBjoern A. Zeeb static inline int
__skb_linearize(struct sk_buff * skb)96449ed6e97SBjoern A. Zeeb __skb_linearize(struct sk_buff *skb)
96549ed6e97SBjoern A. Zeeb {
96649ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
96749ed6e97SBjoern A. Zeeb SKB_TODO();
9682ab4a419SBjoern A. Zeeb return (-ENXIO);
96949ed6e97SBjoern A. Zeeb }
97049ed6e97SBjoern A. Zeeb
9716baea331SBjoern A. Zeeb static inline int
skb_linearize(struct sk_buff * skb)9725504bd59SBjoern A. Zeeb skb_linearize(struct sk_buff *skb)
9735504bd59SBjoern A. Zeeb {
9745504bd59SBjoern A. Zeeb return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0);
9755504bd59SBjoern A. Zeeb }
9765504bd59SBjoern A. Zeeb
9775504bd59SBjoern A. Zeeb static inline int
pskb_expand_head(struct sk_buff * skb,int x,int len,gfp_t gfp)97849ed6e97SBjoern A. Zeeb pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp)
97949ed6e97SBjoern A. Zeeb {
98049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
98149ed6e97SBjoern A. Zeeb SKB_TODO();
9826baea331SBjoern A. Zeeb return (-ENXIO);
98349ed6e97SBjoern A. Zeeb }
98449ed6e97SBjoern A. Zeeb
98549ed6e97SBjoern A. Zeeb /* Not really seen this one but need it as symmetric accessor function. */
98649ed6e97SBjoern A. Zeeb static inline void
skb_set_queue_mapping(struct sk_buff * skb,uint16_t qmap)98749ed6e97SBjoern A. Zeeb skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap)
98849ed6e97SBjoern A. Zeeb {
98949ed6e97SBjoern A. Zeeb
99049ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(skb, "qmap %u", qmap);
99149ed6e97SBjoern A. Zeeb skb->qmap = qmap;
99249ed6e97SBjoern A. Zeeb }
99349ed6e97SBjoern A. Zeeb
99449ed6e97SBjoern A. Zeeb static inline uint16_t
skb_get_queue_mapping(struct sk_buff * skb)99549ed6e97SBjoern A. Zeeb skb_get_queue_mapping(struct sk_buff *skb)
99649ed6e97SBjoern A. Zeeb {
99749ed6e97SBjoern A. Zeeb
99849ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(skb, "qmap %u", skb->qmap);
99949ed6e97SBjoern A. Zeeb return (skb->qmap);
100049ed6e97SBjoern A. Zeeb }
100149ed6e97SBjoern A. Zeeb
100284c5998cSBjoern A. Zeeb static inline void
skb_copy_header(struct sk_buff * to,const struct sk_buff * from)100384c5998cSBjoern A. Zeeb skb_copy_header(struct sk_buff *to, const struct sk_buff *from)
100484c5998cSBjoern A. Zeeb {
100584c5998cSBjoern A. Zeeb SKB_TRACE2(to, from);
100684c5998cSBjoern A. Zeeb SKB_TODO();
100784c5998cSBjoern A. Zeeb }
100884c5998cSBjoern A. Zeeb
100949ed6e97SBjoern A. Zeeb static inline bool
skb_header_cloned(struct sk_buff * skb)101049ed6e97SBjoern A. Zeeb skb_header_cloned(struct sk_buff *skb)
101149ed6e97SBjoern A. Zeeb {
101249ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
101349ed6e97SBjoern A. Zeeb SKB_TODO();
10142ab4a419SBjoern A. Zeeb return (true);
101549ed6e97SBjoern A. Zeeb }
101649ed6e97SBjoern A. Zeeb
101749ed6e97SBjoern A. Zeeb static inline uint8_t *
skb_mac_header(const struct sk_buff * skb)1018262c5e81SBjoern A. Zeeb skb_mac_header(const struct sk_buff *skb)
1019262c5e81SBjoern A. Zeeb {
1020262c5e81SBjoern A. Zeeb SKB_TRACE(skb);
1021262c5e81SBjoern A. Zeeb return (skb->head + skb->mac_header);
1022262c5e81SBjoern A. Zeeb }
1023f0e59b69SBjoern A. Zeeb
1024262c5e81SBjoern A. Zeeb static inline void
skb_reset_mac_header(struct sk_buff * skb)1025262c5e81SBjoern A. Zeeb skb_reset_mac_header(struct sk_buff *skb)
1026262c5e81SBjoern A. Zeeb {
1027262c5e81SBjoern A. Zeeb SKB_TRACE(skb);
1028262c5e81SBjoern A. Zeeb skb->mac_header = skb->data - skb->head;
1029262c5e81SBjoern A. Zeeb }
1030262c5e81SBjoern A. Zeeb
1031262c5e81SBjoern A. Zeeb static inline void
skb_set_mac_header(struct sk_buff * skb,const size_t len)1032262c5e81SBjoern A. Zeeb skb_set_mac_header(struct sk_buff *skb, const size_t len)
1033262c5e81SBjoern A. Zeeb {
1034262c5e81SBjoern A. Zeeb SKB_TRACE(skb);
1035262c5e81SBjoern A. Zeeb skb_reset_mac_header(skb);
1036262c5e81SBjoern A. Zeeb skb->mac_header += len;
1037262c5e81SBjoern A. Zeeb }
1038262c5e81SBjoern A. Zeeb
1039262c5e81SBjoern A. Zeeb static inline struct skb_shared_hwtstamps *
skb_hwtstamps(struct sk_buff * skb)1040262c5e81SBjoern A. Zeeb skb_hwtstamps(struct sk_buff *skb)
104149ed6e97SBjoern A. Zeeb {
104249ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
104349ed6e97SBjoern A. Zeeb SKB_TODO();
104449ed6e97SBjoern A. Zeeb return (NULL);
104549ed6e97SBjoern A. Zeeb }
104649ed6e97SBjoern A. Zeeb
104749ed6e97SBjoern A. Zeeb static inline void
skb_orphan(struct sk_buff * skb)104849ed6e97SBjoern A. Zeeb skb_orphan(struct sk_buff *skb)
104949ed6e97SBjoern A. Zeeb {
105049ed6e97SBjoern A. Zeeb SKB_TRACE(skb);
105149ed6e97SBjoern A. Zeeb SKB_TODO();
105249ed6e97SBjoern A. Zeeb }
105349ed6e97SBjoern A. Zeeb
105436ca2172SBjoern A. Zeeb static inline __wsum
csum_unfold(__sum16 sum)105549ed6e97SBjoern A. Zeeb csum_unfold(__sum16 sum)
105649ed6e97SBjoern A. Zeeb {
105749ed6e97SBjoern A. Zeeb return (sum);
105849ed6e97SBjoern A. Zeeb }
105949ed6e97SBjoern A. Zeeb
1060a3e07b6eSBjoern A. Zeeb static __inline void
skb_postpush_rcsum(struct sk_buff * skb,const void * data,size_t len)1061a3e07b6eSBjoern A. Zeeb skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len)
1062a3e07b6eSBjoern A. Zeeb {
1063a3e07b6eSBjoern A. Zeeb SKB_TODO();
1064a3e07b6eSBjoern A. Zeeb }
1065a3e07b6eSBjoern A. Zeeb
10666baea331SBjoern A. Zeeb static inline void
skb_reset_tail_pointer(struct sk_buff * skb)10676baea331SBjoern A. Zeeb skb_reset_tail_pointer(struct sk_buff *skb)
10686baea331SBjoern A. Zeeb {
10696baea331SBjoern A. Zeeb
10706baea331SBjoern A. Zeeb SKB_TRACE(skb);
10715504bd59SBjoern A. Zeeb #ifdef SKB_DOING_OFFSETS_US_NOT
10726baea331SBjoern A. Zeeb skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head);
10735504bd59SBjoern A. Zeeb #endif
10745504bd59SBjoern A. Zeeb skb->tail = skb->data;
10756baea331SBjoern A. Zeeb SKB_TRACE(skb);
10766baea331SBjoern A. Zeeb }
10776baea331SBjoern A. Zeeb
10786baea331SBjoern A. Zeeb static inline struct sk_buff *
skb_get(struct sk_buff * skb)10796baea331SBjoern A. Zeeb skb_get(struct sk_buff *skb)
10806baea331SBjoern A. Zeeb {
10816baea331SBjoern A. Zeeb
10822ab4a419SBjoern A. Zeeb SKB_TRACE(skb);
10832ab4a419SBjoern A. Zeeb refcount_inc(&skb->refcnt);
10846baea331SBjoern A. Zeeb return (skb);
10856baea331SBjoern A. Zeeb }
10866baea331SBjoern A. Zeeb
10876baea331SBjoern A. Zeeb static inline struct sk_buff *
skb_realloc_headroom(struct sk_buff * skb,unsigned int headroom)10886baea331SBjoern A. Zeeb skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
10896baea331SBjoern A. Zeeb {
10906baea331SBjoern A. Zeeb
10916baea331SBjoern A. Zeeb SKB_TODO();
10926baea331SBjoern A. Zeeb return (NULL);
10936baea331SBjoern A. Zeeb }
10946baea331SBjoern A. Zeeb
10956baea331SBjoern A. Zeeb static inline void
skb_copy_from_linear_data(const struct sk_buff * skb,void * dst,size_t len)10966baea331SBjoern A. Zeeb skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len)
10976baea331SBjoern A. Zeeb {
10986baea331SBjoern A. Zeeb
10996baea331SBjoern A. Zeeb SKB_TRACE(skb);
11006baea331SBjoern A. Zeeb /* Let us just hope the destination has len space ... */
11016baea331SBjoern A. Zeeb memcpy(dst, skb->data, len);
11026baea331SBjoern A. Zeeb }
11036baea331SBjoern A. Zeeb
110489c32dafSBjoern A. Zeeb static inline int
skb_pad(struct sk_buff * skb,int pad)110589c32dafSBjoern A. Zeeb skb_pad(struct sk_buff *skb, int pad)
110689c32dafSBjoern A. Zeeb {
110789c32dafSBjoern A. Zeeb
110889c32dafSBjoern A. Zeeb SKB_TRACE(skb);
110989c32dafSBjoern A. Zeeb SKB_TODO();
111089c32dafSBjoern A. Zeeb return (-1);
111189c32dafSBjoern A. Zeeb }
111289c32dafSBjoern A. Zeeb
111389c32dafSBjoern A. Zeeb static inline void
skb_list_del_init(struct sk_buff * skb)111489c32dafSBjoern A. Zeeb skb_list_del_init(struct sk_buff *skb)
111589c32dafSBjoern A. Zeeb {
111689c32dafSBjoern A. Zeeb
111789c32dafSBjoern A. Zeeb SKB_TRACE(skb);
11182ab4a419SBjoern A. Zeeb __list_del_entry(&skb->list);
11192ab4a419SBjoern A. Zeeb skb_mark_not_on_list(skb);
112089c32dafSBjoern A. Zeeb }
112189c32dafSBjoern A. Zeeb
112289c32dafSBjoern A. Zeeb static inline void
napi_consume_skb(struct sk_buff * skb,int budget)112389c32dafSBjoern A. Zeeb napi_consume_skb(struct sk_buff *skb, int budget)
112489c32dafSBjoern A. Zeeb {
112589c32dafSBjoern A. Zeeb
112689c32dafSBjoern A. Zeeb SKB_TRACE(skb);
112789c32dafSBjoern A. Zeeb SKB_TODO();
112889c32dafSBjoern A. Zeeb }
112989c32dafSBjoern A. Zeeb
11301213a6beSBjoern A. Zeeb static inline struct sk_buff *
napi_build_skb(void * data,size_t len)11311213a6beSBjoern A. Zeeb napi_build_skb(void *data, size_t len)
11321213a6beSBjoern A. Zeeb {
11331213a6beSBjoern A. Zeeb
11341213a6beSBjoern A. Zeeb SKB_TODO();
11351213a6beSBjoern A. Zeeb return (NULL);
11361213a6beSBjoern A. Zeeb }
11371213a6beSBjoern A. Zeeb
1138369264acSBjoern A. Zeeb static inline uint32_t
skb_get_hash(struct sk_buff * skb)1139369264acSBjoern A. Zeeb skb_get_hash(struct sk_buff *skb)
1140369264acSBjoern A. Zeeb {
1141369264acSBjoern A. Zeeb SKB_TRACE(skb);
1142369264acSBjoern A. Zeeb SKB_TODO();
1143369264acSBjoern A. Zeeb return (0);
1144369264acSBjoern A. Zeeb }
1145369264acSBjoern A. Zeeb
11461213a6beSBjoern A. Zeeb static inline void
skb_mark_for_recycle(struct sk_buff * skb)11471213a6beSBjoern A. Zeeb skb_mark_for_recycle(struct sk_buff *skb)
11481213a6beSBjoern A. Zeeb {
11491213a6beSBjoern A. Zeeb SKB_TRACE(skb);
11502ab4a419SBjoern A. Zeeb /* page_pool */
11511213a6beSBjoern A. Zeeb SKB_TODO();
11521213a6beSBjoern A. Zeeb }
11531213a6beSBjoern A. Zeeb
1154e039b38dSBjoern A. Zeeb static inline int
skb_cow_head(struct sk_buff * skb,unsigned int headroom)1155e039b38dSBjoern A. Zeeb skb_cow_head(struct sk_buff *skb, unsigned int headroom)
1156e039b38dSBjoern A. Zeeb {
1157e039b38dSBjoern A. Zeeb SKB_TRACE(skb);
1158e039b38dSBjoern A. Zeeb SKB_TODO();
1159e039b38dSBjoern A. Zeeb return (-1);
1160e039b38dSBjoern A. Zeeb }
1161e039b38dSBjoern A. Zeeb
1162*88dbf833SBjoern A. Zeeb /* Misplaced here really but sock comes from skbuff. */
1163*88dbf833SBjoern A. Zeeb #define sk_pacing_shift_update(sock, n)
1164*88dbf833SBjoern A. Zeeb
116589c32dafSBjoern A. Zeeb #define SKB_WITH_OVERHEAD(_s) \
116689c32dafSBjoern A. Zeeb (_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
116789c32dafSBjoern A. Zeeb
116849ed6e97SBjoern A. Zeeb #endif /* _LINUXKPI_LINUX_SKBUFF_H */
1169