xref: /freebsd/sys/compat/linuxkpi/common/include/linux/skbuff.h (revision 36ca21722c2700e00e41444a29aeabf246eea90d)
149ed6e97SBjoern A. Zeeb /*-
22ab4a419SBjoern A. Zeeb  * Copyright (c) 2020-2025 The FreeBSD Foundation
31213a6beSBjoern A. Zeeb  * Copyright (c) 2021-2023 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 
5059d262feSBjoern A. Zeeb #include "opt_wlan.h"
5159d262feSBjoern A. Zeeb 
5259d262feSBjoern A. Zeeb /* Currently this is only used for wlan so we can depend on that. */
5359d262feSBjoern A. Zeeb #if defined(IEEE80211_DEBUG) && !defined(SKB_DEBUG)
5459d262feSBjoern A. Zeeb #define	SKB_DEBUG
5559d262feSBjoern A. Zeeb #endif
5659d262feSBjoern A. Zeeb 
5749ed6e97SBjoern A. Zeeb /* #define	SKB_DEBUG */
5859d262feSBjoern A. Zeeb 
5949ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
6049ed6e97SBjoern A. Zeeb #define	DSKB_TODO	0x01
616baea331SBjoern A. Zeeb #define	DSKB_IMPROVE	0x02
626baea331SBjoern A. Zeeb #define	DSKB_TRACE	0x10
636baea331SBjoern A. Zeeb #define	DSKB_TRACEX	0x20
646baea331SBjoern A. Zeeb extern int linuxkpi_debug_skb;
6549ed6e97SBjoern A. Zeeb 
666baea331SBjoern A. Zeeb #define	SKB_TODO()							\
676baea331SBjoern A. Zeeb     if (linuxkpi_debug_skb & DSKB_TODO)					\
6849ed6e97SBjoern A. Zeeb 	printf("SKB_TODO %s:%d\n", __func__, __LINE__)
696baea331SBjoern A. Zeeb #define	SKB_IMPROVE(...)						\
706baea331SBjoern A. Zeeb     if (linuxkpi_debug_skb & DSKB_IMPROVE)				\
716baea331SBjoern A. Zeeb 	printf("SKB_IMPROVE %s:%d\n", __func__, __LINE__)
726baea331SBjoern A. Zeeb #define	SKB_TRACE(_s)							\
736baea331SBjoern A. Zeeb     if (linuxkpi_debug_skb & DSKB_TRACE)				\
746baea331SBjoern A. Zeeb 	printf("SKB_TRACE %s:%d %p\n", __func__, __LINE__, _s)
756baea331SBjoern A. Zeeb #define	SKB_TRACE2(_s, _p)						\
766baea331SBjoern A. Zeeb     if (linuxkpi_debug_skb & DSKB_TRACE)				\
776baea331SBjoern A. Zeeb 	printf("SKB_TRACE %s:%d %p, %p\n", __func__, __LINE__, _s, _p)
786baea331SBjoern A. Zeeb #define	SKB_TRACE_FMT(_s, _fmt, ...)					\
796baea331SBjoern A. Zeeb    if (linuxkpi_debug_skb & DSKB_TRACE)					\
806baea331SBjoern A. Zeeb 	printf("SKB_TRACE %s:%d %p " _fmt "\n", __func__, __LINE__, _s,	\
816baea331SBjoern A. Zeeb 	    __VA_ARGS__)
8249ed6e97SBjoern A. Zeeb #else
836baea331SBjoern A. Zeeb #define	SKB_TODO()		do { } while(0)
846baea331SBjoern A. Zeeb #define	SKB_IMPROVE(...)	do { } while(0)
8549ed6e97SBjoern A. Zeeb #define	SKB_TRACE(_s)		do { } while(0)
8649ed6e97SBjoern A. Zeeb #define	SKB_TRACE2(_s, _p)	do { } while(0)
8749ed6e97SBjoern A. Zeeb #define	SKB_TRACE_FMT(_s, ...)	do { } while(0)
8849ed6e97SBjoern A. Zeeb #endif
8949ed6e97SBjoern A. Zeeb 
9049ed6e97SBjoern A. Zeeb enum sk_buff_pkt_type {
9149ed6e97SBjoern A. Zeeb 	PACKET_BROADCAST,
9249ed6e97SBjoern A. Zeeb 	PACKET_MULTICAST,
9349ed6e97SBjoern A. Zeeb 	PACKET_OTHERHOST,
9449ed6e97SBjoern A. Zeeb };
9549ed6e97SBjoern A. Zeeb 
96262c5e81SBjoern A. Zeeb struct skb_shared_hwtstamps {
97262c5e81SBjoern A. Zeeb 	ktime_t			hwtstamp;
98262c5e81SBjoern A. Zeeb };
99262c5e81SBjoern A. Zeeb 
1009df5f29cSBjoern A. Zeeb #define	NET_SKB_PAD		max(CACHE_LINE_SIZE, 32)
1013d3ec178SBjoern A. Zeeb #define	SKB_DATA_ALIGN(_x)	roundup2(_x, CACHE_LINE_SIZE)
10249ed6e97SBjoern A. Zeeb 
10349ed6e97SBjoern A. Zeeb struct sk_buff_head {
10449ed6e97SBjoern A. Zeeb 		/* XXX TODO */
105b2dcb848SBjoern A. Zeeb 	union {
106b2dcb848SBjoern A. Zeeb 		struct {
10749ed6e97SBjoern A. Zeeb 			struct sk_buff		*next;
10849ed6e97SBjoern A. Zeeb 			struct sk_buff		*prev;
109b2dcb848SBjoern A. Zeeb 		};
110b2dcb848SBjoern A. Zeeb 		struct sk_buff_head_l {
111b2dcb848SBjoern A. Zeeb 			struct sk_buff		*next;
112b2dcb848SBjoern A. Zeeb 			struct sk_buff		*prev;
113b2dcb848SBjoern A. Zeeb 		} list;
114b2dcb848SBjoern A. Zeeb 	};
11549ed6e97SBjoern A. Zeeb 	size_t			qlen;
1166baea331SBjoern A. Zeeb 	spinlock_t		lock;
11749ed6e97SBjoern A. Zeeb };
11849ed6e97SBjoern A. Zeeb 
11949ed6e97SBjoern A. Zeeb enum sk_checksum_flags {
12049ed6e97SBjoern A. Zeeb 	CHECKSUM_NONE			= 0x00,
12149ed6e97SBjoern A. Zeeb 	CHECKSUM_UNNECESSARY		= 0x01,
12249ed6e97SBjoern A. Zeeb 	CHECKSUM_PARTIAL		= 0x02,
12349ed6e97SBjoern A. Zeeb 	CHECKSUM_COMPLETE		= 0x04,
12449ed6e97SBjoern A. Zeeb };
12549ed6e97SBjoern A. Zeeb 
12649ed6e97SBjoern A. Zeeb struct skb_frag {
12749ed6e97SBjoern A. Zeeb 		/* XXX TODO */
12849ed6e97SBjoern A. Zeeb 	struct page		*page;		/* XXX-BZ These three are a wild guess so far! */
12949ed6e97SBjoern A. Zeeb 	off_t			offset;
13049ed6e97SBjoern A. Zeeb 	size_t			size;
13149ed6e97SBjoern A. Zeeb };
13249ed6e97SBjoern A. Zeeb typedef	struct skb_frag	skb_frag_t;
13349ed6e97SBjoern A. Zeeb 
13449ed6e97SBjoern A. Zeeb enum skb_shared_info_gso_type {
13549ed6e97SBjoern A. Zeeb 	SKB_GSO_TCPV4,
13649ed6e97SBjoern A. Zeeb 	SKB_GSO_TCPV6,
13749ed6e97SBjoern A. Zeeb };
13849ed6e97SBjoern A. Zeeb 
13949ed6e97SBjoern A. Zeeb struct skb_shared_info {
14049ed6e97SBjoern A. Zeeb 	enum skb_shared_info_gso_type	gso_type;
14149ed6e97SBjoern A. Zeeb 	uint16_t			gso_size;
14249ed6e97SBjoern A. Zeeb 	uint16_t			nr_frags;
1436baea331SBjoern A. Zeeb 	struct sk_buff			*frag_list;
14449ed6e97SBjoern A. Zeeb 	skb_frag_t			frags[64];	/* XXX TODO, 16xpage? */
14549ed6e97SBjoern A. Zeeb };
14649ed6e97SBjoern A. Zeeb 
14749ed6e97SBjoern A. Zeeb struct sk_buff {
14849ed6e97SBjoern A. Zeeb 	/* XXX TODO */
14989c32dafSBjoern A. Zeeb 	union {
15049ed6e97SBjoern A. Zeeb 		/* struct sk_buff_head */
15189c32dafSBjoern A. Zeeb 		struct {
15249ed6e97SBjoern A. Zeeb 			struct sk_buff		*next;
15349ed6e97SBjoern A. Zeeb 			struct sk_buff		*prev;
15489c32dafSBjoern A. Zeeb 		};
15589c32dafSBjoern A. Zeeb 		struct list_head	list;
15689c32dafSBjoern A. Zeeb 	};
15749ed6e97SBjoern A. Zeeb 
15849ed6e97SBjoern A. Zeeb 	uint8_t			*head;			/* Head of buffer. */
15949ed6e97SBjoern A. Zeeb 	uint8_t			*data;			/* Head of data. */
16049ed6e97SBjoern A. Zeeb 	uint8_t			*tail;			/* End of data. */
16149ed6e97SBjoern A. Zeeb 	uint8_t			*end;			/* End of buffer. */
16249ed6e97SBjoern A. Zeeb 
16359481c7dSBjoern A. Zeeb 	uint32_t		len;		/* ? */
16459481c7dSBjoern A. Zeeb 	uint32_t		data_len;	/* ? If we have frags? */
16559481c7dSBjoern A. Zeeb 	union {
16659481c7dSBjoern A. Zeeb 		__wsum			csum;
16759481c7dSBjoern A. Zeeb 		struct {
16859481c7dSBjoern A. Zeeb 			uint16_t	csum_offset;
16959481c7dSBjoern A. Zeeb 			uint16_t	csum_start;
17059481c7dSBjoern A. Zeeb 		};
17159481c7dSBjoern A. Zeeb 	};
17259481c7dSBjoern A. Zeeb 	uint16_t		protocol;
17359481c7dSBjoern A. Zeeb 	uint8_t			ip_summed;
17459481c7dSBjoern A. Zeeb 	/* uint8_t */
17559481c7dSBjoern A. Zeeb 
17659481c7dSBjoern A. Zeeb 	/* "Scratch" area for layers to store metadata. */
17759481c7dSBjoern A. Zeeb 	/* ??? I see sizeof() operations so probably an array. */
17859481c7dSBjoern A. Zeeb 	uint8_t			cb[64] __aligned(CACHE_LINE_SIZE);
17959481c7dSBjoern A. Zeeb 
18059481c7dSBjoern A. Zeeb 	struct skb_shared_info	*shinfo	__aligned(CACHE_LINE_SIZE);
18159481c7dSBjoern A. Zeeb 
18259481c7dSBjoern A. Zeeb 	uint32_t		truesize;	/* The total size of all buffers, incl. frags. */
18359481c7dSBjoern A. Zeeb 	uint32_t		priority;
18459481c7dSBjoern A. Zeeb 	uint16_t		qmap;		/* queue mapping */
18559481c7dSBjoern A. Zeeb 	uint16_t		_flags;		/* Internal flags. */
18659481c7dSBjoern A. Zeeb #define	_SKB_FLAGS_SKBEXTFRAG	0x0001
18759481c7dSBjoern A. Zeeb 	uint16_t		l3hdroff;	/* network header offset from *head */
18859481c7dSBjoern A. Zeeb 	uint16_t		l4hdroff;	/* transport header offset from *head */
18959481c7dSBjoern A. Zeeb 	uint16_t		mac_header;	/* offset of mac_header */
19059481c7dSBjoern A. Zeeb 	uint16_t		mac_len;	/* Link-layer header length. */
19159481c7dSBjoern A. Zeeb 	enum sk_buff_pkt_type	pkt_type;
19259481c7dSBjoern A. Zeeb 	refcount_t		refcnt;
19359481c7dSBjoern A. Zeeb 
19459481c7dSBjoern A. Zeeb 	struct net_device	*dev;
19559481c7dSBjoern A. Zeeb 	void			*sk;		/* XXX net/sock.h? */
19649ed6e97SBjoern A. Zeeb 
19749ed6e97SBjoern A. Zeeb 	/* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
19849ed6e97SBjoern A. Zeeb 	void			*m;
19949ed6e97SBjoern A. Zeeb 	void(*m_free_func)(void *);
20049ed6e97SBjoern A. Zeeb 
20149ed6e97SBjoern A. Zeeb 	/* Force padding to CACHE_LINE_SIZE. */
20249ed6e97SBjoern A. Zeeb 	uint8_t			__scratch[0] __aligned(CACHE_LINE_SIZE);
20349ed6e97SBjoern A. Zeeb };
20449ed6e97SBjoern A. Zeeb 
20549ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
20649ed6e97SBjoern A. Zeeb 
20749ed6e97SBjoern A. Zeeb struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
2089df5f29cSBjoern A. Zeeb struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
2095504bd59SBjoern A. Zeeb struct sk_buff *linuxkpi_build_skb(void *, size_t);
21049ed6e97SBjoern A. Zeeb void linuxkpi_kfree_skb(struct sk_buff *);
21149ed6e97SBjoern A. Zeeb 
2122ab4a419SBjoern A. Zeeb struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t);
213349b042bSBjoern A. Zeeb 
21449ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
21549ed6e97SBjoern A. Zeeb 
21649ed6e97SBjoern A. Zeeb static inline struct sk_buff *
21749ed6e97SBjoern A. Zeeb alloc_skb(size_t size, gfp_t gfp)
21849ed6e97SBjoern A. Zeeb {
21949ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
22049ed6e97SBjoern A. Zeeb 
22149ed6e97SBjoern A. Zeeb 	skb = linuxkpi_alloc_skb(size, gfp);
22249ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
22349ed6e97SBjoern A. Zeeb 	return (skb);
22449ed6e97SBjoern A. Zeeb }
22549ed6e97SBjoern A. Zeeb 
22649ed6e97SBjoern A. Zeeb static inline struct sk_buff *
2276baea331SBjoern A. Zeeb __dev_alloc_skb(size_t len, gfp_t gfp)
2286baea331SBjoern A. Zeeb {
2296baea331SBjoern A. Zeeb 	struct sk_buff *skb;
2306baea331SBjoern A. Zeeb 
2319df5f29cSBjoern A. Zeeb 	skb = linuxkpi_dev_alloc_skb(len, gfp);
2326baea331SBjoern A. Zeeb 	SKB_IMPROVE();
2336baea331SBjoern A. Zeeb 	SKB_TRACE(skb);
2346baea331SBjoern A. Zeeb 	return (skb);
2356baea331SBjoern A. Zeeb }
2366baea331SBjoern A. Zeeb 
2376baea331SBjoern A. Zeeb static inline struct sk_buff *
23849ed6e97SBjoern A. Zeeb dev_alloc_skb(size_t len)
23949ed6e97SBjoern A. Zeeb {
24049ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
24149ed6e97SBjoern A. Zeeb 
2429df5f29cSBjoern A. Zeeb 	skb = __dev_alloc_skb(len, GFP_NOWAIT);
2436baea331SBjoern A. Zeeb 	SKB_IMPROVE();
24449ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
24549ed6e97SBjoern A. Zeeb 	return (skb);
24649ed6e97SBjoern A. Zeeb }
24749ed6e97SBjoern A. Zeeb 
24849ed6e97SBjoern A. Zeeb static inline void
24949ed6e97SBjoern A. Zeeb kfree_skb(struct sk_buff *skb)
25049ed6e97SBjoern A. Zeeb {
25149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
25249ed6e97SBjoern A. Zeeb 	linuxkpi_kfree_skb(skb);
25349ed6e97SBjoern A. Zeeb }
25449ed6e97SBjoern A. Zeeb 
25549ed6e97SBjoern A. Zeeb static inline void
2562ab4a419SBjoern A. Zeeb consume_skb(struct sk_buff *skb)
2572ab4a419SBjoern A. Zeeb {
2582ab4a419SBjoern A. Zeeb 	SKB_TRACE(skb);
2592ab4a419SBjoern A. Zeeb 	kfree_skb(skb);
2602ab4a419SBjoern A. Zeeb }
2612ab4a419SBjoern A. Zeeb 
2622ab4a419SBjoern A. Zeeb static inline void
26349ed6e97SBjoern A. Zeeb dev_kfree_skb(struct sk_buff *skb)
26449ed6e97SBjoern A. Zeeb {
26549ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
26649ed6e97SBjoern A. Zeeb 	kfree_skb(skb);
26749ed6e97SBjoern A. Zeeb }
26849ed6e97SBjoern A. Zeeb 
26949ed6e97SBjoern A. Zeeb static inline void
27049ed6e97SBjoern A. Zeeb dev_kfree_skb_any(struct sk_buff *skb)
27149ed6e97SBjoern A. Zeeb {
27249ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
27349ed6e97SBjoern A. Zeeb 	dev_kfree_skb(skb);
27449ed6e97SBjoern A. Zeeb }
27549ed6e97SBjoern A. Zeeb 
27649ed6e97SBjoern A. Zeeb static inline void
27749ed6e97SBjoern A. Zeeb dev_kfree_skb_irq(struct sk_buff *skb)
27849ed6e97SBjoern A. Zeeb {
27949ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
280952643eaSBjoern A. Zeeb 	SKB_IMPROVE("Do we have to defer this?");
281952643eaSBjoern A. Zeeb 	dev_kfree_skb(skb);
28249ed6e97SBjoern A. Zeeb }
28349ed6e97SBjoern A. Zeeb 
2845504bd59SBjoern A. Zeeb static inline struct sk_buff *
2855504bd59SBjoern A. Zeeb build_skb(void *data, unsigned int fragsz)
2865504bd59SBjoern A. Zeeb {
2875504bd59SBjoern A. Zeeb 	struct sk_buff *skb;
2885504bd59SBjoern A. Zeeb 
2895504bd59SBjoern A. Zeeb 	skb = linuxkpi_build_skb(data, fragsz);
2905504bd59SBjoern A. Zeeb 	SKB_TRACE(skb);
2915504bd59SBjoern A. Zeeb 	return (skb);
2925504bd59SBjoern A. Zeeb }
2935504bd59SBjoern A. Zeeb 
29449ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
29549ed6e97SBjoern A. Zeeb 
2962ab4a419SBjoern A. Zeeb static inline bool
2972ab4a419SBjoern A. Zeeb skb_is_nonlinear(struct sk_buff *skb)
2982ab4a419SBjoern A. Zeeb {
2992ab4a419SBjoern A. Zeeb 	SKB_TRACE(skb);
3002ab4a419SBjoern A. Zeeb 	return ((skb->data_len > 0) ? true : false);
3012ab4a419SBjoern A. Zeeb }
30249ed6e97SBjoern A. Zeeb 
30349ed6e97SBjoern A. Zeeb /* Add headroom; cannot do once there is data in there. */
30449ed6e97SBjoern A. Zeeb static inline void
30549ed6e97SBjoern A. Zeeb skb_reserve(struct sk_buff *skb, size_t len)
30649ed6e97SBjoern A. Zeeb {
30749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
3086baea331SBjoern A. Zeeb #if 0
3096baea331SBjoern A. Zeeb 	/* Apparently it is allowed to call skb_reserve multiple times in a row. */
31049ed6e97SBjoern A. Zeeb 	KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p "
31149ed6e97SBjoern A. Zeeb 	    "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail));
3126baea331SBjoern A. Zeeb #else
3136baea331SBjoern A. Zeeb 	KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not "
3146baea331SBjoern A. Zeeb 	    "empty head %p data %p tail %p len %u\n", __func__, skb,
3156baea331SBjoern A. Zeeb 	    skb->head, skb->data, skb->tail, skb->len));
3166baea331SBjoern A. Zeeb #endif
31749ed6e97SBjoern A. Zeeb 	skb->data += len;
31849ed6e97SBjoern A. Zeeb 	skb->tail += len;
31949ed6e97SBjoern A. Zeeb }
32049ed6e97SBjoern A. Zeeb 
32149ed6e97SBjoern A. Zeeb /*
32249ed6e97SBjoern A. Zeeb  * Remove headroom; return new data pointer; basically make space at the
32349ed6e97SBjoern A. Zeeb  * front to copy data in (manually).
32449ed6e97SBjoern A. Zeeb  */
32549ed6e97SBjoern A. Zeeb static inline void *
32689c32dafSBjoern A. Zeeb __skb_push(struct sk_buff *skb, size_t len)
32749ed6e97SBjoern A. Zeeb {
32849ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
32949ed6e97SBjoern A. Zeeb 	KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - "
33049ed6e97SBjoern A. Zeeb 	    "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data));
33149ed6e97SBjoern A. Zeeb 	skb->len  += len;
33249ed6e97SBjoern A. Zeeb 	skb->data -= len;
33349ed6e97SBjoern A. Zeeb 	return (skb->data);
33449ed6e97SBjoern A. Zeeb }
33549ed6e97SBjoern A. Zeeb 
33689c32dafSBjoern A. Zeeb static inline void *
33789c32dafSBjoern A. Zeeb skb_push(struct sk_buff *skb, size_t len)
33889c32dafSBjoern A. Zeeb {
33989c32dafSBjoern A. Zeeb 
34089c32dafSBjoern A. Zeeb 	SKB_TRACE(skb);
34189c32dafSBjoern A. Zeeb 	return (__skb_push(skb, len));
34289c32dafSBjoern A. Zeeb }
34389c32dafSBjoern A. Zeeb 
34449ed6e97SBjoern A. Zeeb /*
34549ed6e97SBjoern A. Zeeb  * Length of the data on the skb (without any frags)???
34649ed6e97SBjoern A. Zeeb  */
34749ed6e97SBjoern A. Zeeb static inline size_t
34849ed6e97SBjoern A. Zeeb skb_headlen(struct sk_buff *skb)
34949ed6e97SBjoern A. Zeeb {
35049ed6e97SBjoern A. Zeeb 
35149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
35249ed6e97SBjoern A. Zeeb 	return (skb->len - skb->data_len);
35349ed6e97SBjoern A. Zeeb }
35449ed6e97SBjoern A. Zeeb 
35549ed6e97SBjoern A. Zeeb 
35649ed6e97SBjoern A. Zeeb /* Return the end of data (tail pointer). */
35749ed6e97SBjoern A. Zeeb static inline uint8_t *
35849ed6e97SBjoern A. Zeeb skb_tail_pointer(struct sk_buff *skb)
35949ed6e97SBjoern A. Zeeb {
36049ed6e97SBjoern A. Zeeb 
36149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
36249ed6e97SBjoern A. Zeeb 	return (skb->tail);
36349ed6e97SBjoern A. Zeeb }
36449ed6e97SBjoern A. Zeeb 
36549ed6e97SBjoern A. Zeeb /* Return number of bytes available at end of buffer. */
36649ed6e97SBjoern A. Zeeb static inline unsigned int
36749ed6e97SBjoern A. Zeeb skb_tailroom(struct sk_buff *skb)
36849ed6e97SBjoern A. Zeeb {
36949ed6e97SBjoern A. Zeeb 
37049ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
37149ed6e97SBjoern A. Zeeb 	KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, "
37249ed6e97SBjoern A. Zeeb 	    "end %p tail %p\n", __func__, skb, skb->end, skb->tail));
3732ab4a419SBjoern A. Zeeb 	if (unlikely(skb_is_nonlinear(skb)))
3742ab4a419SBjoern A. Zeeb 		return (0);
37549ed6e97SBjoern A. Zeeb 	return (skb->end - skb->tail);
37649ed6e97SBjoern A. Zeeb }
37749ed6e97SBjoern A. Zeeb 
3782ab4a419SBjoern A. Zeeb /* Return number of bytes available at the beginning of buffer. */
37949ed6e97SBjoern A. Zeeb static inline unsigned int
3802ab4a419SBjoern A. Zeeb skb_headroom(const struct sk_buff *skb)
38149ed6e97SBjoern A. Zeeb {
38249ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
38349ed6e97SBjoern A. Zeeb 	KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, "
38449ed6e97SBjoern A. Zeeb 	    "data %p head %p\n", __func__, skb, skb->data, skb->head));
38549ed6e97SBjoern A. Zeeb 	return (skb->data - skb->head);
38649ed6e97SBjoern A. Zeeb }
38749ed6e97SBjoern A. Zeeb 
38849ed6e97SBjoern A. Zeeb 
38949ed6e97SBjoern A. Zeeb /*
39049ed6e97SBjoern A. Zeeb  * Remove tailroom; return the old tail pointer; basically make space at
39149ed6e97SBjoern A. Zeeb  * the end to copy data in (manually).  See also skb_put_data() below.
39249ed6e97SBjoern A. Zeeb  */
39349ed6e97SBjoern A. Zeeb static inline void *
39489c32dafSBjoern A. Zeeb __skb_put(struct sk_buff *skb, size_t len)
39549ed6e97SBjoern A. Zeeb {
39649ed6e97SBjoern A. Zeeb 	void *s;
39749ed6e97SBjoern A. Zeeb 
39849ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
39949ed6e97SBjoern A. Zeeb 	KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + "
40049ed6e97SBjoern A. Zeeb 	    "len %zu) > end %p, head %p data %p len %u\n", __func__,
40149ed6e97SBjoern A. Zeeb 	    skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len));
40249ed6e97SBjoern A. Zeeb 
40349ed6e97SBjoern A. Zeeb 	s = skb_tail_pointer(skb);
404952643eaSBjoern A. Zeeb 	if (len == 0)
405952643eaSBjoern A. Zeeb 		return (s);
40649ed6e97SBjoern A. Zeeb 	skb->tail += len;
40749ed6e97SBjoern A. Zeeb 	skb->len += len;
40849ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
4096baea331SBjoern A. Zeeb 	if (linuxkpi_debug_skb & DSKB_TRACEX)
41049ed6e97SBjoern A. Zeeb 	printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n",
41149ed6e97SBjoern A. Zeeb 	    __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end,
41249ed6e97SBjoern A. Zeeb 	    s, len);
41349ed6e97SBjoern A. Zeeb #endif
41449ed6e97SBjoern A. Zeeb 	return (s);
41549ed6e97SBjoern A. Zeeb }
41649ed6e97SBjoern A. Zeeb 
41789c32dafSBjoern A. Zeeb static inline void *
41889c32dafSBjoern A. Zeeb skb_put(struct sk_buff *skb, size_t len)
41989c32dafSBjoern A. Zeeb {
42089c32dafSBjoern A. Zeeb 
42189c32dafSBjoern A. Zeeb 	SKB_TRACE(skb);
42289c32dafSBjoern A. Zeeb 	return (__skb_put(skb, len));
42389c32dafSBjoern A. Zeeb }
42489c32dafSBjoern A. Zeeb 
42549ed6e97SBjoern A. Zeeb /* skb_put() + copying data in. */
42649ed6e97SBjoern A. Zeeb static inline void *
42749ed6e97SBjoern A. Zeeb skb_put_data(struct sk_buff *skb, const void *buf, size_t len)
42849ed6e97SBjoern A. Zeeb {
42949ed6e97SBjoern A. Zeeb 	void *s;
43049ed6e97SBjoern A. Zeeb 
43149ed6e97SBjoern A. Zeeb 	SKB_TRACE2(skb, buf);
43249ed6e97SBjoern A. Zeeb 	s = skb_put(skb, len);
433952643eaSBjoern A. Zeeb 	if (len == 0)
434952643eaSBjoern A. Zeeb 		return (s);
43549ed6e97SBjoern A. Zeeb 	memcpy(s, buf, len);
43649ed6e97SBjoern A. Zeeb 	return (s);
43749ed6e97SBjoern A. Zeeb }
43849ed6e97SBjoern A. Zeeb 
43949ed6e97SBjoern A. Zeeb /* skb_put() + filling with zeros. */
44049ed6e97SBjoern A. Zeeb static inline void *
44149ed6e97SBjoern A. Zeeb skb_put_zero(struct sk_buff *skb, size_t len)
44249ed6e97SBjoern A. Zeeb {
44349ed6e97SBjoern A. Zeeb 	void *s;
44449ed6e97SBjoern A. Zeeb 
44549ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
44649ed6e97SBjoern A. Zeeb 	s = skb_put(skb, len);
44749ed6e97SBjoern A. Zeeb 	memset(s, '\0', len);
44849ed6e97SBjoern A. Zeeb 	return (s);
44949ed6e97SBjoern A. Zeeb }
45049ed6e97SBjoern A. Zeeb 
45149ed6e97SBjoern A. Zeeb /*
45249ed6e97SBjoern A. Zeeb  * Remove len bytes from beginning of data.
45349ed6e97SBjoern A. Zeeb  *
45449ed6e97SBjoern A. Zeeb  * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic;
45549ed6e97SBjoern A. Zeeb  * we return the advanced data pointer so we don't have to keep a temp, correct?
45649ed6e97SBjoern A. Zeeb  */
45749ed6e97SBjoern A. Zeeb static inline void *
45849ed6e97SBjoern A. Zeeb skb_pull(struct sk_buff *skb, size_t len)
45949ed6e97SBjoern A. Zeeb {
46049ed6e97SBjoern A. Zeeb 
46149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
46249ed6e97SBjoern A. Zeeb #if 0	/* Apparently this doesn't barf... */
46349ed6e97SBjoern A. Zeeb 	KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n",
46449ed6e97SBjoern A. Zeeb 	    __func__, skb, skb->len, len, skb->data));
46549ed6e97SBjoern A. Zeeb #endif
46649ed6e97SBjoern A. Zeeb 	if (skb->len < len)
46749ed6e97SBjoern A. Zeeb 		return (NULL);
46849ed6e97SBjoern A. Zeeb 	skb->len -= len;
46949ed6e97SBjoern A. Zeeb 	skb->data += len;
47049ed6e97SBjoern A. Zeeb 	return (skb->data);
47149ed6e97SBjoern A. Zeeb }
47249ed6e97SBjoern A. Zeeb 
47349ed6e97SBjoern A. Zeeb /* Reduce skb data to given length or do nothing if smaller already. */
47449ed6e97SBjoern A. Zeeb static inline void
47549ed6e97SBjoern A. Zeeb __skb_trim(struct sk_buff *skb, unsigned int len)
47649ed6e97SBjoern A. Zeeb {
47749ed6e97SBjoern A. Zeeb 
47849ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
47949ed6e97SBjoern A. Zeeb 	if (skb->len < len)
48049ed6e97SBjoern A. Zeeb 		return;
48149ed6e97SBjoern A. Zeeb 
48249ed6e97SBjoern A. Zeeb 	skb->len = len;
48349ed6e97SBjoern A. Zeeb 	skb->tail = skb->data + skb->len;
48449ed6e97SBjoern A. Zeeb }
48549ed6e97SBjoern A. Zeeb 
48649ed6e97SBjoern A. Zeeb static inline void
48749ed6e97SBjoern A. Zeeb skb_trim(struct sk_buff *skb, unsigned int len)
48849ed6e97SBjoern A. Zeeb {
48949ed6e97SBjoern A. Zeeb 
49049ed6e97SBjoern A. Zeeb 	return (__skb_trim(skb, len));
49149ed6e97SBjoern A. Zeeb }
49249ed6e97SBjoern A. Zeeb 
49349ed6e97SBjoern A. Zeeb static inline struct skb_shared_info *
49449ed6e97SBjoern A. Zeeb skb_shinfo(struct sk_buff *skb)
49549ed6e97SBjoern A. Zeeb {
49649ed6e97SBjoern A. Zeeb 
49749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
49849ed6e97SBjoern A. Zeeb 	return (skb->shinfo);
49949ed6e97SBjoern A. Zeeb }
50049ed6e97SBjoern A. Zeeb 
50149ed6e97SBjoern A. Zeeb static inline void
50249ed6e97SBjoern A. Zeeb skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
50349ed6e97SBjoern A. Zeeb     off_t offset, size_t size, unsigned int truesize)
50449ed6e97SBjoern A. Zeeb {
50549ed6e97SBjoern A. Zeeb 	struct skb_shared_info *shinfo;
50649ed6e97SBjoern A. Zeeb 
50749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
50849ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG
5096baea331SBjoern A. Zeeb 	if (linuxkpi_debug_skb & DSKB_TRACEX)
51049ed6e97SBjoern A. Zeeb 	printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d "
51149ed6e97SBjoern A. Zeeb 	    "page %#jx offset %ju size %zu truesize %u\n", __func__,
51249ed6e97SBjoern A. Zeeb 	    skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno,
51349ed6e97SBjoern A. Zeeb 	    (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset,
51449ed6e97SBjoern A. Zeeb 	    size, truesize);
51549ed6e97SBjoern A. Zeeb #endif
51649ed6e97SBjoern A. Zeeb 
51749ed6e97SBjoern A. Zeeb 	shinfo = skb_shinfo(skb);
51849ed6e97SBjoern A. Zeeb 	KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p "
51949ed6e97SBjoern A. Zeeb 	    "fragno %d too big\n", __func__, skb, fragno));
52049ed6e97SBjoern A. Zeeb 	shinfo->frags[fragno].page = page;
52149ed6e97SBjoern A. Zeeb 	shinfo->frags[fragno].offset = offset;
52249ed6e97SBjoern A. Zeeb 	shinfo->frags[fragno].size = size;
52349ed6e97SBjoern A. Zeeb 	shinfo->nr_frags = fragno + 1;
52449ed6e97SBjoern A. Zeeb         skb->len += size;
5255504bd59SBjoern A. Zeeb 	skb->data_len += size;
52649ed6e97SBjoern A. Zeeb         skb->truesize += truesize;
52749ed6e97SBjoern A. Zeeb }
52849ed6e97SBjoern A. Zeeb 
52949ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
53049ed6e97SBjoern A. Zeeb 
53149ed6e97SBjoern A. Zeeb #define	skb_queue_walk(_q, skb)						\
53249ed6e97SBjoern A. Zeeb 	for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q);	\
53349ed6e97SBjoern A. Zeeb 	    (skb) = (skb)->next)
53449ed6e97SBjoern A. Zeeb 
53549ed6e97SBjoern A. Zeeb #define	skb_queue_walk_safe(_q, skb, tmp)				\
53649ed6e97SBjoern A. Zeeb 	for ((skb) = (_q)->next, (tmp) = (skb)->next;			\
53749ed6e97SBjoern A. Zeeb 	    (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next)
53849ed6e97SBjoern A. Zeeb 
5392ab4a419SBjoern A. Zeeb #define	skb_list_walk_safe(_q, skb, tmp)				\
5402ab4a419SBjoern A. Zeeb 	for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \
5412ab4a419SBjoern A. Zeeb 	    ((skb) != NULL);						\
5422ab4a419SBjoern A. Zeeb 	    (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL)
54349ed6e97SBjoern A. Zeeb 
5442ab4a419SBjoern A. Zeeb static inline bool
5452ab4a419SBjoern A. Zeeb skb_queue_empty(const struct sk_buff_head *q)
5462ab4a419SBjoern A. Zeeb {
54749ed6e97SBjoern A. Zeeb 	SKB_TRACE(q);
5482ab4a419SBjoern A. Zeeb 	return (q->next == (const struct sk_buff *)q);
5492ab4a419SBjoern A. Zeeb }
5502ab4a419SBjoern A. Zeeb 
5512ab4a419SBjoern A. Zeeb static inline bool
5522ab4a419SBjoern A. Zeeb skb_queue_empty_lockless(const struct sk_buff_head *q)
5532ab4a419SBjoern A. Zeeb {
5542ab4a419SBjoern A. Zeeb 	SKB_TRACE(q);
5552ab4a419SBjoern A. Zeeb 	return (READ_ONCE(q->next) == (const struct sk_buff *)q);
55649ed6e97SBjoern A. Zeeb }
55749ed6e97SBjoern A. Zeeb 
55849ed6e97SBjoern A. Zeeb static inline void
55949ed6e97SBjoern A. Zeeb __skb_queue_head_init(struct sk_buff_head *q)
56049ed6e97SBjoern A. Zeeb {
56149ed6e97SBjoern A. Zeeb 	SKB_TRACE(q);
56249ed6e97SBjoern A. Zeeb 	q->prev = q->next = (struct sk_buff *)q;
56349ed6e97SBjoern A. Zeeb 	q->qlen = 0;
56449ed6e97SBjoern A. Zeeb }
56549ed6e97SBjoern A. Zeeb 
56649ed6e97SBjoern A. Zeeb static inline void
56749ed6e97SBjoern A. Zeeb skb_queue_head_init(struct sk_buff_head *q)
56849ed6e97SBjoern A. Zeeb {
56949ed6e97SBjoern A. Zeeb 	SKB_TRACE(q);
5702ab4a419SBjoern A. Zeeb 	__skb_queue_head_init(q);
5712ab4a419SBjoern A. Zeeb 	spin_lock_init(&q->lock);
57249ed6e97SBjoern A. Zeeb }
57349ed6e97SBjoern A. Zeeb 
57449ed6e97SBjoern A. Zeeb static inline void
57549ed6e97SBjoern A. Zeeb __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next,
57649ed6e97SBjoern A. Zeeb     struct sk_buff_head *q)
57749ed6e97SBjoern A. Zeeb {
57849ed6e97SBjoern A. Zeeb 
57949ed6e97SBjoern A. Zeeb 	SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q);
5802ab4a419SBjoern A. Zeeb 	WRITE_ONCE(new->prev, prev);
5812ab4a419SBjoern A. Zeeb 	WRITE_ONCE(new->next, next);
5822ab4a419SBjoern A. Zeeb 	WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new);
5832ab4a419SBjoern A. Zeeb 	WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new);
5842ab4a419SBjoern A. Zeeb 	WRITE_ONCE(q->qlen, q->qlen + 1);
58549ed6e97SBjoern A. Zeeb }
58649ed6e97SBjoern A. Zeeb 
58749ed6e97SBjoern A. Zeeb static inline void
58849ed6e97SBjoern A. Zeeb __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb,
58949ed6e97SBjoern A. Zeeb     struct sk_buff *new)
59049ed6e97SBjoern A. Zeeb {
59149ed6e97SBjoern A. Zeeb 
59249ed6e97SBjoern A. Zeeb 	SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
593b2dcb848SBjoern A. Zeeb 	__skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q);
59449ed6e97SBjoern A. Zeeb }
59549ed6e97SBjoern A. Zeeb 
59649ed6e97SBjoern A. Zeeb static inline void
59749ed6e97SBjoern A. Zeeb __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb,
59849ed6e97SBjoern A. Zeeb     struct sk_buff *new)
59949ed6e97SBjoern A. Zeeb {
60049ed6e97SBjoern A. Zeeb 
60149ed6e97SBjoern A. Zeeb 	SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
60249ed6e97SBjoern A. Zeeb 	__skb_insert(new, skb->prev, skb, q);
60349ed6e97SBjoern A. Zeeb }
60449ed6e97SBjoern A. Zeeb 
60549ed6e97SBjoern A. Zeeb static inline void
606b2dcb848SBjoern A. Zeeb __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
60749ed6e97SBjoern A. Zeeb {
60849ed6e97SBjoern A. Zeeb 
609b2dcb848SBjoern A. Zeeb 	SKB_TRACE2(q, new);
610d3befb53STom Coldrick 	__skb_queue_before(q, (struct sk_buff *)q, new);
61149ed6e97SBjoern A. Zeeb }
61249ed6e97SBjoern A. Zeeb 
61349ed6e97SBjoern A. Zeeb static inline void
614b2dcb848SBjoern A. Zeeb skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
61549ed6e97SBjoern A. Zeeb {
6162ab4a419SBjoern A. Zeeb 	unsigned long flags;
6172ab4a419SBjoern A. Zeeb 
618149c457dSBjoern A. Zeeb 	SKB_TRACE2(q, new);
6192ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
6202ab4a419SBjoern A. Zeeb 	__skb_queue_tail(q, new);
6212ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
62249ed6e97SBjoern A. Zeeb }
62349ed6e97SBjoern A. Zeeb 
62449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
6252ab4a419SBjoern A. Zeeb skb_peek(const struct sk_buff_head *q)
626ce9f3661SBjoern A. Zeeb {
627ce9f3661SBjoern A. Zeeb 	struct sk_buff *skb;
628ce9f3661SBjoern A. Zeeb 
629ce9f3661SBjoern A. Zeeb 	skb = q->next;
630ce9f3661SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
6312ab4a419SBjoern A. Zeeb 	if (skb == (const struct sk_buff *)q)
632ce9f3661SBjoern A. Zeeb 		return (NULL);
633ce9f3661SBjoern A. Zeeb 	return (skb);
634ce9f3661SBjoern A. Zeeb }
635ce9f3661SBjoern A. Zeeb 
636ce9f3661SBjoern A. Zeeb static inline struct sk_buff *
6372ab4a419SBjoern A. Zeeb skb_peek_tail(const struct sk_buff_head *q)
63849ed6e97SBjoern A. Zeeb {
63949ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
64049ed6e97SBjoern A. Zeeb 
6412ab4a419SBjoern A. Zeeb 	skb = READ_ONCE(q->prev);
64249ed6e97SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
6432ab4a419SBjoern A. Zeeb 	if (skb == (const struct sk_buff *)q)
64449ed6e97SBjoern A. Zeeb 		return (NULL);
64549ed6e97SBjoern A. Zeeb 	return (skb);
64649ed6e97SBjoern A. Zeeb }
64749ed6e97SBjoern A. Zeeb 
64849ed6e97SBjoern A. Zeeb static inline void
6492ab4a419SBjoern A. Zeeb __skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
65049ed6e97SBjoern A. Zeeb {
651b4856b8eSZhenlei Huang 	struct sk_buff *p, *n;
65249ed6e97SBjoern A. Zeeb 
6532ab4a419SBjoern A. Zeeb 	SKB_TRACE2(skb, q);
6542ab4a419SBjoern A. Zeeb 
6552ab4a419SBjoern A. Zeeb 	WRITE_ONCE(q->qlen, q->qlen - 1);
65649ed6e97SBjoern A. Zeeb 	p = skb->prev;
65749ed6e97SBjoern A. Zeeb 	n = skb->next;
6582ab4a419SBjoern A. Zeeb 	WRITE_ONCE(n->prev, p);
6592ab4a419SBjoern A. Zeeb 	WRITE_ONCE(p->next, n);
66049ed6e97SBjoern A. Zeeb 	skb->prev = skb->next = NULL;
66149ed6e97SBjoern A. Zeeb }
66249ed6e97SBjoern A. Zeeb 
66349ed6e97SBjoern A. Zeeb static inline void
6642ab4a419SBjoern A. Zeeb skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
66549ed6e97SBjoern A. Zeeb {
6662ab4a419SBjoern A. Zeeb 	unsigned long flags;
6672ab4a419SBjoern A. Zeeb 
6682ab4a419SBjoern A. Zeeb 	SKB_TRACE2(skb, q);
6692ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
6702ab4a419SBjoern A. Zeeb 	__skb_unlink(skb, q);
6712ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
67249ed6e97SBjoern A. Zeeb }
67349ed6e97SBjoern A. Zeeb 
67449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
67549ed6e97SBjoern A. Zeeb __skb_dequeue(struct sk_buff_head *q)
67649ed6e97SBjoern A. Zeeb {
67749ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
67849ed6e97SBjoern A. Zeeb 
6792ab4a419SBjoern A. Zeeb 	skb = skb_peek(q);
68049ed6e97SBjoern A. Zeeb 	if (skb != NULL)
68149ed6e97SBjoern A. Zeeb 		__skb_unlink(skb, q);
6822ab4a419SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
68349ed6e97SBjoern A. Zeeb 	return (skb);
68449ed6e97SBjoern A. Zeeb }
68549ed6e97SBjoern A. Zeeb 
68649ed6e97SBjoern A. Zeeb static inline struct sk_buff *
68749ed6e97SBjoern A. Zeeb skb_dequeue(struct sk_buff_head *q)
68849ed6e97SBjoern A. Zeeb {
6892ab4a419SBjoern A. Zeeb 	unsigned long flags;
6902ab4a419SBjoern A. Zeeb 	struct sk_buff *skb;
6912ab4a419SBjoern A. Zeeb 
6922ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
6932ab4a419SBjoern A. Zeeb 	skb = __skb_dequeue(q);
6942ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
6952ab4a419SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
6962ab4a419SBjoern A. Zeeb 	return (skb);
69749ed6e97SBjoern A. Zeeb }
69849ed6e97SBjoern A. Zeeb 
69949ed6e97SBjoern A. Zeeb static inline struct sk_buff *
7002ab4a419SBjoern A. Zeeb __skb_dequeue_tail(struct sk_buff_head *q)
70149ed6e97SBjoern A. Zeeb {
70249ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
70349ed6e97SBjoern A. Zeeb 
70449ed6e97SBjoern A. Zeeb 	skb = skb_peek_tail(q);
70549ed6e97SBjoern A. Zeeb 	if (skb != NULL)
70649ed6e97SBjoern A. Zeeb 		__skb_unlink(skb, q);
7072ab4a419SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
7082ab4a419SBjoern A. Zeeb 	return (skb);
7092ab4a419SBjoern A. Zeeb }
71049ed6e97SBjoern A. Zeeb 
7112ab4a419SBjoern A. Zeeb static inline struct sk_buff *
7122ab4a419SBjoern A. Zeeb skb_dequeue_tail(struct sk_buff_head *q)
7132ab4a419SBjoern A. Zeeb {
7142ab4a419SBjoern A. Zeeb 	unsigned long flags;
7152ab4a419SBjoern A. Zeeb 	struct sk_buff *skb;
7162ab4a419SBjoern A. Zeeb 
7172ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
7182ab4a419SBjoern A. Zeeb 	skb = __skb_dequeue_tail(q);
7192ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
72049ed6e97SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
72149ed6e97SBjoern A. Zeeb 	return (skb);
72249ed6e97SBjoern A. Zeeb }
72349ed6e97SBjoern A. Zeeb 
72449ed6e97SBjoern A. Zeeb static inline void
7256baea331SBjoern A. Zeeb __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
7266baea331SBjoern A. Zeeb {
7276baea331SBjoern A. Zeeb 
7286baea331SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
7296baea331SBjoern A. Zeeb 	__skb_queue_after(q, (struct sk_buff *)q, skb);
7306baea331SBjoern A. Zeeb }
7316baea331SBjoern A. Zeeb 
7326baea331SBjoern A. Zeeb static inline void
73349ed6e97SBjoern A. Zeeb skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
73449ed6e97SBjoern A. Zeeb {
7352ab4a419SBjoern A. Zeeb 	unsigned long flags;
73649ed6e97SBjoern A. Zeeb 
73749ed6e97SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
7382ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
7392ab4a419SBjoern A. Zeeb 	__skb_queue_head(q, skb);
7402ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
74149ed6e97SBjoern A. Zeeb }
74249ed6e97SBjoern A. Zeeb 
74349ed6e97SBjoern A. Zeeb static inline uint32_t
7442ab4a419SBjoern A. Zeeb skb_queue_len(const struct sk_buff_head *q)
74549ed6e97SBjoern A. Zeeb {
7466baea331SBjoern A. Zeeb 
7472ab4a419SBjoern A. Zeeb 	SKB_TRACE(q);
7482ab4a419SBjoern A. Zeeb 	return (q->qlen);
74949ed6e97SBjoern A. Zeeb }
75049ed6e97SBjoern A. Zeeb 
7516baea331SBjoern A. Zeeb static inline uint32_t
7522ab4a419SBjoern A. Zeeb skb_queue_len_lockless(const struct sk_buff_head *q)
7536baea331SBjoern A. Zeeb {
7546baea331SBjoern A. Zeeb 
7552ab4a419SBjoern A. Zeeb 	SKB_TRACE(q);
7562ab4a419SBjoern A. Zeeb 	return (READ_ONCE(q->qlen));
7576baea331SBjoern A. Zeeb }
7586baea331SBjoern A. Zeeb 
75949ed6e97SBjoern A. Zeeb static inline void
7602ab4a419SBjoern A. Zeeb ___skb_queue_splice(const struct sk_buff_head *from,
7612ab4a419SBjoern A. Zeeb     struct sk_buff *p, struct sk_buff *n)
7622ab4a419SBjoern A. Zeeb {
7632ab4a419SBjoern A. Zeeb 	struct sk_buff *b, *e;
7642ab4a419SBjoern A. Zeeb 
7652ab4a419SBjoern A. Zeeb 	b = from->next;
7662ab4a419SBjoern A. Zeeb 	e = from->prev;
7672ab4a419SBjoern A. Zeeb 
7682ab4a419SBjoern A. Zeeb 	WRITE_ONCE(b->prev, p);
7692ab4a419SBjoern A. Zeeb 	WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b);
7702ab4a419SBjoern A. Zeeb 	WRITE_ONCE(e->next, n);
7712ab4a419SBjoern A. Zeeb 	WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e);
7722ab4a419SBjoern A. Zeeb }
7732ab4a419SBjoern A. Zeeb 
7742ab4a419SBjoern A. Zeeb static inline void
7752ab4a419SBjoern A. Zeeb skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
7762ab4a419SBjoern A. Zeeb {
7772ab4a419SBjoern A. Zeeb 
7782ab4a419SBjoern A. Zeeb 	SKB_TRACE2(from, to);
7792ab4a419SBjoern A. Zeeb 
7802ab4a419SBjoern A. Zeeb 	if (skb_queue_empty(from))
7812ab4a419SBjoern A. Zeeb 		return;
7822ab4a419SBjoern A. Zeeb 
7832ab4a419SBjoern A. Zeeb 	___skb_queue_splice(from, (struct sk_buff *)to, to->next);
7842ab4a419SBjoern A. Zeeb 	to->qlen += from->qlen;
7852ab4a419SBjoern A. Zeeb 	__skb_queue_head_init(from);
7862ab4a419SBjoern A. Zeeb }
7872ab4a419SBjoern A. Zeeb 
7882ab4a419SBjoern A. Zeeb static inline void
7892ab4a419SBjoern A. Zeeb skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to)
7902ab4a419SBjoern A. Zeeb {
7912ab4a419SBjoern A. Zeeb 
7922ab4a419SBjoern A. Zeeb 	SKB_TRACE2(from, to);
7932ab4a419SBjoern A. Zeeb 
7942ab4a419SBjoern A. Zeeb 	if (skb_queue_empty(from))
7952ab4a419SBjoern A. Zeeb 		return;
7962ab4a419SBjoern A. Zeeb 
7972ab4a419SBjoern A. Zeeb 	___skb_queue_splice(from, to->prev, (struct sk_buff *)to);
7982ab4a419SBjoern A. Zeeb 	to->qlen += from->qlen;
7992ab4a419SBjoern A. Zeeb 	__skb_queue_head_init(from);
8002ab4a419SBjoern A. Zeeb }
8012ab4a419SBjoern A. Zeeb 
8022ab4a419SBjoern A. Zeeb 
8032ab4a419SBjoern A. Zeeb static inline void
80449ed6e97SBjoern A. Zeeb __skb_queue_purge(struct sk_buff_head *q)
80549ed6e97SBjoern A. Zeeb {
80649ed6e97SBjoern A. Zeeb 	struct sk_buff *skb;
80749ed6e97SBjoern A. Zeeb 
80849ed6e97SBjoern A. Zeeb 	SKB_TRACE(q);
80949ed6e97SBjoern A. Zeeb         while ((skb = __skb_dequeue(q)) != NULL)
81049ed6e97SBjoern A. Zeeb 		kfree_skb(skb);
811bcf1d8eeSBjoern A. Zeeb 	WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u",
812bcf1d8eeSBjoern A. Zeeb 	    __func__, q, skb_queue_len(q));
81349ed6e97SBjoern A. Zeeb }
81449ed6e97SBjoern A. Zeeb 
81549ed6e97SBjoern A. Zeeb static inline void
81649ed6e97SBjoern A. Zeeb skb_queue_purge(struct sk_buff_head *q)
81749ed6e97SBjoern A. Zeeb {
8182ab4a419SBjoern A. Zeeb 	struct sk_buff_head _q;
8192ab4a419SBjoern A. Zeeb 	unsigned long flags;
8202ab4a419SBjoern A. Zeeb 
82149ed6e97SBjoern A. Zeeb 	SKB_TRACE(q);
8222ab4a419SBjoern A. Zeeb 
8232ab4a419SBjoern A. Zeeb 	if (skb_queue_empty_lockless(q))
8242ab4a419SBjoern A. Zeeb 		return;
8252ab4a419SBjoern A. Zeeb 
8262ab4a419SBjoern A. Zeeb 	__skb_queue_head_init(&_q);
8272ab4a419SBjoern A. Zeeb 	spin_lock_irqsave(&q->lock, flags);
8282ab4a419SBjoern A. Zeeb 	skb_queue_splice_init(q, &_q);
8292ab4a419SBjoern A. Zeeb 	spin_unlock_irqrestore(&q->lock, flags);
8302ab4a419SBjoern A. Zeeb 	__skb_queue_purge(&_q);
83149ed6e97SBjoern A. Zeeb }
83249ed6e97SBjoern A. Zeeb 
83349ed6e97SBjoern A. Zeeb static inline struct sk_buff *
83449ed6e97SBjoern A. Zeeb skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
83549ed6e97SBjoern A. Zeeb {
83649ed6e97SBjoern A. Zeeb 
83749ed6e97SBjoern A. Zeeb 	SKB_TRACE2(q, skb);
83849ed6e97SBjoern A. Zeeb 	/* XXX what is the q argument good for? */
83949ed6e97SBjoern A. Zeeb 	return (skb->prev);
84049ed6e97SBjoern A. Zeeb }
84149ed6e97SBjoern A. Zeeb 
84249ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */
84349ed6e97SBjoern A. Zeeb 
84449ed6e97SBjoern A. Zeeb static inline struct sk_buff *
8452ab4a419SBjoern A. Zeeb skb_copy(const struct sk_buff *skb, gfp_t gfp)
84649ed6e97SBjoern A. Zeeb {
847349b042bSBjoern A. Zeeb 	struct sk_buff *new;
848349b042bSBjoern A. Zeeb 
849349b042bSBjoern A. Zeeb 	new = linuxkpi_skb_copy(skb, gfp);
850349b042bSBjoern A. Zeeb 	SKB_TRACE2(skb, new);
851349b042bSBjoern A. Zeeb 	return (new);
85249ed6e97SBjoern A. Zeeb }
85349ed6e97SBjoern A. Zeeb 
85449ed6e97SBjoern A. Zeeb static inline uint16_t
85549ed6e97SBjoern A. Zeeb skb_checksum(struct sk_buff *skb, int offs, size_t len, int x)
85649ed6e97SBjoern A. Zeeb {
85749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
85849ed6e97SBjoern A. Zeeb 	SKB_TODO();
85949ed6e97SBjoern A. Zeeb 	return (0xffff);
86049ed6e97SBjoern A. Zeeb }
86149ed6e97SBjoern A. Zeeb 
86249ed6e97SBjoern A. Zeeb static inline int
86349ed6e97SBjoern A. Zeeb skb_checksum_start_offset(struct sk_buff *skb)
86449ed6e97SBjoern A. Zeeb {
86549ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
86649ed6e97SBjoern A. Zeeb 	SKB_TODO();
86749ed6e97SBjoern A. Zeeb 	return (-1);
86849ed6e97SBjoern A. Zeeb }
86949ed6e97SBjoern A. Zeeb 
87049ed6e97SBjoern A. Zeeb static inline dma_addr_t
87149ed6e97SBjoern A. Zeeb skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x,
87249ed6e97SBjoern A. Zeeb     size_t fragsz, enum dma_data_direction dir)
87349ed6e97SBjoern A. Zeeb {
87449ed6e97SBjoern A. Zeeb 	SKB_TRACE2(frag, dev);
87549ed6e97SBjoern A. Zeeb 	SKB_TODO();
87649ed6e97SBjoern A. Zeeb 	return (-1);
87749ed6e97SBjoern A. Zeeb }
87849ed6e97SBjoern A. Zeeb 
87949ed6e97SBjoern A. Zeeb static inline size_t
88049ed6e97SBjoern A. Zeeb skb_frag_size(const skb_frag_t *frag)
88149ed6e97SBjoern A. Zeeb {
88249ed6e97SBjoern A. Zeeb 	SKB_TRACE(frag);
8832ab4a419SBjoern A. Zeeb 	return (frag->size);
88449ed6e97SBjoern A. Zeeb }
88549ed6e97SBjoern A. Zeeb 
88649ed6e97SBjoern A. Zeeb #define	skb_walk_frags(_skb, _frag)					\
88749ed6e97SBjoern A. Zeeb 	for ((_frag) = (_skb); false; (_frag)++)
88849ed6e97SBjoern A. Zeeb 
88949ed6e97SBjoern A. Zeeb static inline void
89049ed6e97SBjoern A. Zeeb skb_checksum_help(struct sk_buff *skb)
89149ed6e97SBjoern A. Zeeb {
89249ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
89349ed6e97SBjoern A. Zeeb 	SKB_TODO();
89449ed6e97SBjoern A. Zeeb }
89549ed6e97SBjoern A. Zeeb 
89649ed6e97SBjoern A. Zeeb static inline bool
89749ed6e97SBjoern A. Zeeb skb_ensure_writable(struct sk_buff *skb, size_t off)
89849ed6e97SBjoern A. Zeeb {
89949ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
90049ed6e97SBjoern A. Zeeb 	SKB_TODO();
90149ed6e97SBjoern A. Zeeb 	return (false);
90249ed6e97SBjoern A. Zeeb }
90349ed6e97SBjoern A. Zeeb 
90449ed6e97SBjoern A. Zeeb static inline void *
90549ed6e97SBjoern A. Zeeb skb_frag_address(const skb_frag_t *frag)
90649ed6e97SBjoern A. Zeeb {
90749ed6e97SBjoern A. Zeeb 	SKB_TRACE(frag);
9082ab4a419SBjoern A. Zeeb 	return (page_address(frag->page + frag->offset));
90949ed6e97SBjoern A. Zeeb }
91049ed6e97SBjoern A. Zeeb 
91189c32dafSBjoern A. Zeeb static inline void
91289c32dafSBjoern A. Zeeb skb_free_frag(void *frag)
91389c32dafSBjoern A. Zeeb {
91489c32dafSBjoern A. Zeeb 
915dbbf46ebSBjoern A. Zeeb 	page_frag_free(frag);
91689c32dafSBjoern A. Zeeb }
91789c32dafSBjoern A. Zeeb 
91849ed6e97SBjoern A. Zeeb static inline struct sk_buff *
91949ed6e97SBjoern A. Zeeb skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags)
92049ed6e97SBjoern A. Zeeb {
92149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
92249ed6e97SBjoern A. Zeeb 	SKB_TODO();
92349ed6e97SBjoern A. Zeeb 	return (NULL);
92449ed6e97SBjoern A. Zeeb }
92549ed6e97SBjoern A. Zeeb 
92649ed6e97SBjoern A. Zeeb static inline bool
92749ed6e97SBjoern A. Zeeb skb_is_gso(struct sk_buff *skb)
92849ed6e97SBjoern A. Zeeb {
92949ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
930952643eaSBjoern A. Zeeb 	SKB_IMPROVE("Really a TODO but get it away from logging");
93149ed6e97SBjoern A. Zeeb 	return (false);
93249ed6e97SBjoern A. Zeeb }
93349ed6e97SBjoern A. Zeeb 
93449ed6e97SBjoern A. Zeeb static inline void
93549ed6e97SBjoern A. Zeeb skb_mark_not_on_list(struct sk_buff *skb)
93649ed6e97SBjoern A. Zeeb {
93749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
9382ab4a419SBjoern A. Zeeb 	skb->next = NULL;
93949ed6e97SBjoern A. Zeeb }
94049ed6e97SBjoern A. Zeeb 
94149ed6e97SBjoern A. Zeeb static inline void
94249ed6e97SBjoern A. Zeeb skb_reset_transport_header(struct sk_buff *skb)
94349ed6e97SBjoern A. Zeeb {
94449ed6e97SBjoern A. Zeeb 
94549ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
94649ed6e97SBjoern A. Zeeb 	skb->l4hdroff = skb->data - skb->head;
94749ed6e97SBjoern A. Zeeb }
94849ed6e97SBjoern A. Zeeb 
94949ed6e97SBjoern A. Zeeb static inline uint8_t *
95049ed6e97SBjoern A. Zeeb skb_transport_header(struct sk_buff *skb)
95149ed6e97SBjoern A. Zeeb {
95249ed6e97SBjoern A. Zeeb 
95349ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
95449ed6e97SBjoern A. Zeeb         return (skb->head + skb->l4hdroff);
95549ed6e97SBjoern A. Zeeb }
95649ed6e97SBjoern A. Zeeb 
95749ed6e97SBjoern A. Zeeb static inline uint8_t *
95849ed6e97SBjoern A. Zeeb skb_network_header(struct sk_buff *skb)
95949ed6e97SBjoern A. Zeeb {
96049ed6e97SBjoern A. Zeeb 
96149ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
96249ed6e97SBjoern A. Zeeb         return (skb->head + skb->l3hdroff);
96349ed6e97SBjoern A. Zeeb }
96449ed6e97SBjoern A. Zeeb 
96549ed6e97SBjoern A. Zeeb static inline int
96649ed6e97SBjoern A. Zeeb __skb_linearize(struct sk_buff *skb)
96749ed6e97SBjoern A. Zeeb {
96849ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
96949ed6e97SBjoern A. Zeeb 	SKB_TODO();
9702ab4a419SBjoern A. Zeeb 	return (-ENXIO);
97149ed6e97SBjoern A. Zeeb }
97249ed6e97SBjoern A. Zeeb 
9736baea331SBjoern A. Zeeb static inline int
9745504bd59SBjoern A. Zeeb skb_linearize(struct sk_buff *skb)
9755504bd59SBjoern A. Zeeb {
9765504bd59SBjoern A. Zeeb 	return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0);
9775504bd59SBjoern A. Zeeb }
9785504bd59SBjoern A. Zeeb 
9795504bd59SBjoern A. Zeeb static inline int
98049ed6e97SBjoern A. Zeeb pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp)
98149ed6e97SBjoern A. Zeeb {
98249ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
98349ed6e97SBjoern A. Zeeb 	SKB_TODO();
9846baea331SBjoern A. Zeeb 	return (-ENXIO);
98549ed6e97SBjoern A. Zeeb }
98649ed6e97SBjoern A. Zeeb 
98749ed6e97SBjoern A. Zeeb /* Not really seen this one but need it as symmetric accessor function. */
98849ed6e97SBjoern A. Zeeb static inline void
98949ed6e97SBjoern A. Zeeb skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap)
99049ed6e97SBjoern A. Zeeb {
99149ed6e97SBjoern A. Zeeb 
99249ed6e97SBjoern A. Zeeb 	SKB_TRACE_FMT(skb, "qmap %u", qmap);
99349ed6e97SBjoern A. Zeeb 	skb->qmap = qmap;
99449ed6e97SBjoern A. Zeeb }
99549ed6e97SBjoern A. Zeeb 
99649ed6e97SBjoern A. Zeeb static inline uint16_t
99749ed6e97SBjoern A. Zeeb skb_get_queue_mapping(struct sk_buff *skb)
99849ed6e97SBjoern A. Zeeb {
99949ed6e97SBjoern A. Zeeb 
100049ed6e97SBjoern A. Zeeb 	SKB_TRACE_FMT(skb, "qmap %u", skb->qmap);
100149ed6e97SBjoern A. Zeeb 	return (skb->qmap);
100249ed6e97SBjoern A. Zeeb }
100349ed6e97SBjoern A. Zeeb 
100449ed6e97SBjoern A. Zeeb static inline bool
100549ed6e97SBjoern A. Zeeb skb_header_cloned(struct sk_buff *skb)
100649ed6e97SBjoern A. Zeeb {
100749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
100849ed6e97SBjoern A. Zeeb 	SKB_TODO();
10092ab4a419SBjoern A. Zeeb 	return (true);
101049ed6e97SBjoern A. Zeeb }
101149ed6e97SBjoern A. Zeeb 
101249ed6e97SBjoern A. Zeeb static inline uint8_t *
1013262c5e81SBjoern A. Zeeb skb_mac_header(const struct sk_buff *skb)
1014262c5e81SBjoern A. Zeeb {
1015262c5e81SBjoern A. Zeeb 	SKB_TRACE(skb);
1016262c5e81SBjoern A. Zeeb 	return (skb->head + skb->mac_header);
1017262c5e81SBjoern A. Zeeb }
1018f0e59b69SBjoern A. Zeeb 
1019262c5e81SBjoern A. Zeeb static inline void
1020262c5e81SBjoern A. Zeeb skb_reset_mac_header(struct sk_buff *skb)
1021262c5e81SBjoern A. Zeeb {
1022262c5e81SBjoern A. Zeeb 	SKB_TRACE(skb);
1023262c5e81SBjoern A. Zeeb 	skb->mac_header = skb->data - skb->head;
1024262c5e81SBjoern A. Zeeb }
1025262c5e81SBjoern A. Zeeb 
1026262c5e81SBjoern A. Zeeb static inline void
1027262c5e81SBjoern A. Zeeb skb_set_mac_header(struct sk_buff *skb, const size_t len)
1028262c5e81SBjoern A. Zeeb {
1029262c5e81SBjoern A. Zeeb 	SKB_TRACE(skb);
1030262c5e81SBjoern A. Zeeb 	skb_reset_mac_header(skb);
1031262c5e81SBjoern A. Zeeb 	skb->mac_header += len;
1032262c5e81SBjoern A. Zeeb }
1033262c5e81SBjoern A. Zeeb 
1034262c5e81SBjoern A. Zeeb static inline struct skb_shared_hwtstamps *
1035262c5e81SBjoern A. Zeeb skb_hwtstamps(struct sk_buff *skb)
103649ed6e97SBjoern A. Zeeb {
103749ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
103849ed6e97SBjoern A. Zeeb 	SKB_TODO();
103949ed6e97SBjoern A. Zeeb 	return (NULL);
104049ed6e97SBjoern A. Zeeb }
104149ed6e97SBjoern A. Zeeb 
104249ed6e97SBjoern A. Zeeb static inline void
104349ed6e97SBjoern A. Zeeb skb_orphan(struct sk_buff *skb)
104449ed6e97SBjoern A. Zeeb {
104549ed6e97SBjoern A. Zeeb 	SKB_TRACE(skb);
104649ed6e97SBjoern A. Zeeb 	SKB_TODO();
104749ed6e97SBjoern A. Zeeb }
104849ed6e97SBjoern A. Zeeb 
1049*36ca2172SBjoern A. Zeeb static inline __wsum
105049ed6e97SBjoern A. Zeeb csum_unfold(__sum16 sum)
105149ed6e97SBjoern A. Zeeb {
105249ed6e97SBjoern A. Zeeb 	return (sum);
105349ed6e97SBjoern A. Zeeb }
105449ed6e97SBjoern A. Zeeb 
1055a3e07b6eSBjoern A. Zeeb static __inline void
1056a3e07b6eSBjoern A. Zeeb skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len)
1057a3e07b6eSBjoern A. Zeeb {
1058a3e07b6eSBjoern A. Zeeb 	SKB_TODO();
1059a3e07b6eSBjoern A. Zeeb }
1060a3e07b6eSBjoern A. Zeeb 
10616baea331SBjoern A. Zeeb static inline void
10626baea331SBjoern A. Zeeb skb_reset_tail_pointer(struct sk_buff *skb)
10636baea331SBjoern A. Zeeb {
10646baea331SBjoern A. Zeeb 
10656baea331SBjoern A. Zeeb 	SKB_TRACE(skb);
10665504bd59SBjoern A. Zeeb #ifdef SKB_DOING_OFFSETS_US_NOT
10676baea331SBjoern A. Zeeb 	skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head);
10685504bd59SBjoern A. Zeeb #endif
10695504bd59SBjoern A. Zeeb 	skb->tail = skb->data;
10706baea331SBjoern A. Zeeb 	SKB_TRACE(skb);
10716baea331SBjoern A. Zeeb }
10726baea331SBjoern A. Zeeb 
10736baea331SBjoern A. Zeeb static inline struct sk_buff *
10746baea331SBjoern A. Zeeb skb_get(struct sk_buff *skb)
10756baea331SBjoern A. Zeeb {
10766baea331SBjoern A. Zeeb 
10772ab4a419SBjoern A. Zeeb 	SKB_TRACE(skb);
10782ab4a419SBjoern A. Zeeb 	refcount_inc(&skb->refcnt);
10796baea331SBjoern A. Zeeb 	return (skb);
10806baea331SBjoern A. Zeeb }
10816baea331SBjoern A. Zeeb 
10826baea331SBjoern A. Zeeb static inline struct sk_buff *
10836baea331SBjoern A. Zeeb skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
10846baea331SBjoern A. Zeeb {
10856baea331SBjoern A. Zeeb 
10866baea331SBjoern A. Zeeb 	SKB_TODO();
10876baea331SBjoern A. Zeeb 	return (NULL);
10886baea331SBjoern A. Zeeb }
10896baea331SBjoern A. Zeeb 
10906baea331SBjoern A. Zeeb static inline void
10916baea331SBjoern A. Zeeb skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len)
10926baea331SBjoern A. Zeeb {
10936baea331SBjoern A. Zeeb 
10946baea331SBjoern A. Zeeb 	SKB_TRACE(skb);
10956baea331SBjoern A. Zeeb 	/* Let us just hope the destination has len space ... */
10966baea331SBjoern A. Zeeb 	memcpy(dst, skb->data, len);
10976baea331SBjoern A. Zeeb }
10986baea331SBjoern A. Zeeb 
109989c32dafSBjoern A. Zeeb static inline int
110089c32dafSBjoern A. Zeeb skb_pad(struct sk_buff *skb, int pad)
110189c32dafSBjoern A. Zeeb {
110289c32dafSBjoern A. Zeeb 
110389c32dafSBjoern A. Zeeb 	SKB_TRACE(skb);
110489c32dafSBjoern A. Zeeb 	SKB_TODO();
110589c32dafSBjoern A. Zeeb 	return (-1);
110689c32dafSBjoern A. Zeeb }
110789c32dafSBjoern A. Zeeb 
110889c32dafSBjoern A. Zeeb static inline void
110989c32dafSBjoern A. Zeeb skb_list_del_init(struct sk_buff *skb)
111089c32dafSBjoern A. Zeeb {
111189c32dafSBjoern A. Zeeb 
111289c32dafSBjoern A. Zeeb 	SKB_TRACE(skb);
11132ab4a419SBjoern A. Zeeb 	__list_del_entry(&skb->list);
11142ab4a419SBjoern A. Zeeb 	skb_mark_not_on_list(skb);
111589c32dafSBjoern A. Zeeb }
111689c32dafSBjoern A. Zeeb 
111789c32dafSBjoern A. Zeeb static inline void
111889c32dafSBjoern A. Zeeb napi_consume_skb(struct sk_buff *skb, int budget)
111989c32dafSBjoern A. Zeeb {
112089c32dafSBjoern A. Zeeb 
112189c32dafSBjoern A. Zeeb 	SKB_TRACE(skb);
112289c32dafSBjoern A. Zeeb 	SKB_TODO();
112389c32dafSBjoern A. Zeeb }
112489c32dafSBjoern A. Zeeb 
11251213a6beSBjoern A. Zeeb static inline struct sk_buff *
11261213a6beSBjoern A. Zeeb napi_build_skb(void *data, size_t len)
11271213a6beSBjoern A. Zeeb {
11281213a6beSBjoern A. Zeeb 
11291213a6beSBjoern A. Zeeb 	SKB_TODO();
11301213a6beSBjoern A. Zeeb 	return (NULL);
11311213a6beSBjoern A. Zeeb }
11321213a6beSBjoern A. Zeeb 
1133369264acSBjoern A. Zeeb static inline uint32_t
1134369264acSBjoern A. Zeeb skb_get_hash(struct sk_buff *skb)
1135369264acSBjoern A. Zeeb {
1136369264acSBjoern A. Zeeb 	SKB_TRACE(skb);
1137369264acSBjoern A. Zeeb 	SKB_TODO();
1138369264acSBjoern A. Zeeb 	return (0);
1139369264acSBjoern A. Zeeb }
1140369264acSBjoern A. Zeeb 
11411213a6beSBjoern A. Zeeb static inline void
11421213a6beSBjoern A. Zeeb skb_mark_for_recycle(struct sk_buff *skb)
11431213a6beSBjoern A. Zeeb {
11441213a6beSBjoern A. Zeeb 	SKB_TRACE(skb);
11452ab4a419SBjoern A. Zeeb 	/* page_pool */
11461213a6beSBjoern A. Zeeb 	SKB_TODO();
11471213a6beSBjoern A. Zeeb }
11481213a6beSBjoern A. Zeeb 
1149e039b38dSBjoern A. Zeeb static inline int
1150e039b38dSBjoern A. Zeeb skb_cow_head(struct sk_buff *skb, unsigned int headroom)
1151e039b38dSBjoern A. Zeeb {
1152e039b38dSBjoern A. Zeeb 	SKB_TRACE(skb);
1153e039b38dSBjoern A. Zeeb 	SKB_TODO();
1154e039b38dSBjoern A. Zeeb 	return (-1);
1155e039b38dSBjoern A. Zeeb }
1156e039b38dSBjoern A. Zeeb 
115789c32dafSBjoern A. Zeeb #define	SKB_WITH_OVERHEAD(_s)						\
115889c32dafSBjoern A. Zeeb 	(_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
115989c32dafSBjoern A. Zeeb 
116049ed6e97SBjoern A. Zeeb #endif	/* _LINUXKPI_LINUX_SKBUFF_H */
1161