xref: /freebsd/sys/compat/linuxkpi/common/include/linux/skbuff.h (revision e4795d3dbee71c463429e2901dad111fbc2d08fc)
1 /*-
2  * Copyright (c) 2020-2026 The FreeBSD Foundation
3  * Copyright (c) 2021-2025 Bjoern A. Zeeb
4  *
5  * This software was developed by Björn Zeeb under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * NOTE: this socket buffer compatibility code is highly EXPERIMENTAL.
32  *       Do not rely on the internals of this implementation.  They are highly
33  *       likely to change as we will improve the integration to FreeBSD mbufs.
34  */
35 
36 #ifndef	_LINUXKPI_LINUX_SKBUFF_H
37 #define	_LINUXKPI_LINUX_SKBUFF_H
38 
39 #include <linux/kernel.h>
40 #include <linux/page.h>
41 #include <linux/dma-mapping.h>
42 #include <linux/netdev_features.h>
43 #include <linux/list.h>
44 #include <linux/gfp.h>
45 #include <linux/compiler.h>
46 #include <linux/spinlock.h>
47 #include <linux/ktime.h>
48 #include <linux/compiler.h>
49 
50 /*
51  * At least the net/intel-irdma-kmod port pulls this header in; likely through
52  * if_ether.h (see PR289268).  This means we no longer can rely on
53  * IEEE80211_DEBUG (opt_wlan.h) to automatically set SKB_DEBUG.
54  */
55 /* #define	SKB_DEBUG */
56 
57 #ifdef SKB_DEBUG
58 #define	DSKB_TODO	0x01
59 #define	DSKB_IMPROVE	0x02
60 #define	DSKB_TRACE	0x10
61 #define	DSKB_TRACEX	0x20
62 extern int linuxkpi_debug_skb;
63 
64 #define	SKB_TODO()							\
65     if (linuxkpi_debug_skb & DSKB_TODO)					\
66 	printf("SKB_TODO %s:%d\n", __func__, __LINE__)
67 #define	SKB_IMPROVE(...)						\
68     if (linuxkpi_debug_skb & DSKB_IMPROVE)				\
69 	printf("SKB_IMPROVE %s:%d\n", __func__, __LINE__)
70 #define	SKB_TRACE(_s)							\
71     if (linuxkpi_debug_skb & DSKB_TRACE)				\
72 	printf("SKB_TRACE %s:%d %p\n", __func__, __LINE__, _s)
73 #define	SKB_TRACE2(_s, _p)						\
74     if (linuxkpi_debug_skb & DSKB_TRACE)				\
75 	printf("SKB_TRACE %s:%d %p, %p\n", __func__, __LINE__, _s, _p)
76 #define	SKB_TRACE_FMT(_s, _fmt, ...)					\
77     if ((linuxkpi_debug_skb & DSKB_TRACE) != 0)				\
78 	printf("SKB_TRACE %s:%d %p " _fmt "\n", __func__, __LINE__, _s,	\
79 	    ##__VA_ARGS__)
80 #else
81 #define	SKB_TODO()		do { } while(0)
82 #define	SKB_IMPROVE(...)	do { } while(0)
83 #define	SKB_TRACE(_s)		do { } while(0)
84 #define	SKB_TRACE2(_s, _p)	do { } while(0)
85 #define	SKB_TRACE_FMT(_s, ...)	do { } while(0)
86 #endif
87 
88 enum sk_buff_pkt_type {
89 	PACKET_BROADCAST,
90 	PACKET_MULTICAST,
91 	PACKET_OTHERHOST,
92 };
93 
94 struct skb_shared_hwtstamps {
95 	ktime_t			hwtstamp;
96 };
97 
98 #define	NET_SKB_PAD		max(CACHE_LINE_SIZE, 32)
99 #define	SKB_DATA_ALIGN(_x)	roundup2(_x, CACHE_LINE_SIZE)
100 
101 struct sk_buff_head {
102 		/* XXX TODO */
103 	union {
104 		struct {
105 			struct sk_buff		*next;
106 			struct sk_buff		*prev;
107 		};
108 		struct sk_buff_head_l {
109 			struct sk_buff		*next;
110 			struct sk_buff		*prev;
111 		} list;
112 	};
113 	size_t			qlen;
114 	spinlock_t		lock;
115 };
116 
117 enum sk_checksum_flags {
118 	CHECKSUM_NONE			= 0x00,
119 	CHECKSUM_UNNECESSARY		= 0x01,
120 	CHECKSUM_PARTIAL		= 0x02,
121 	CHECKSUM_COMPLETE		= 0x03,
122 };
123 
124 struct skb_frag {
125 		/* XXX TODO */
126 	struct page		*page;		/* XXX-BZ These three are a wild guess so far! */
127 	off_t			offset;
128 	size_t			size;
129 };
130 typedef	struct skb_frag	skb_frag_t;
131 
132 enum skb_shared_info_gso_type {
133 	SKB_GSO_TCPV4,
134 	SKB_GSO_TCPV6,
135 };
136 
137 struct skb_shared_info {
138 	enum skb_shared_info_gso_type	gso_type;
139 	uint16_t			gso_size;
140 	uint16_t			nr_frags;
141 	struct sk_buff			*frag_list;
142 	skb_frag_t			frags[64];	/* XXX TODO, 16xpage? */
143 };
144 
145 struct sk_buff {
146 	/* XXX TODO */
147 	union {
148 		/* struct sk_buff_head */
149 		struct {
150 			struct sk_buff		*next;
151 			struct sk_buff		*prev;
152 		};
153 		struct list_head	list;
154 	};
155 
156 	uint8_t			*head;			/* Head of buffer. */
157 	uint8_t			*data;			/* Head of data. */
158 	uint8_t			*tail;			/* End of data. */
159 	uint8_t			*end;			/* End of buffer. */
160 
161 	uint32_t		len;		/* ? */
162 	uint32_t		data_len;	/* ? If we have frags? */
163 	union {
164 		__wsum			csum;
165 		struct {
166 			uint16_t	csum_offset;
167 			uint16_t	csum_start;
168 		};
169 	};
170 	uint16_t		protocol;
171 	uint8_t			ip_summed;		/* 2 bit only. */
172 	/* uint8_t */
173 
174 	/* "Scratch" area for layers to store metadata. */
175 	/* ??? I see sizeof() operations so probably an array. */
176 	uint8_t			cb[64] __aligned(CACHE_LINE_SIZE);
177 
178 	struct skb_shared_info	*shinfo	__aligned(CACHE_LINE_SIZE);
179 
180 	uint32_t		truesize;	/* The total size of all buffers, incl. frags. */
181 	uint32_t		priority;
182 	uint16_t		qmap;		/* queue mapping */
183 	uint16_t		_flags;		/* Internal flags. */
184 #define	_SKB_FLAGS_SKBEXTFRAG	0x0001
185 #define	_SKB_PP_RECYCLE		0x0010
186 	uint16_t		l3hdroff;	/* network header offset from *head */
187 	uint16_t		l4hdroff;	/* transport header offset from *head */
188 	uint16_t		mac_header;	/* offset of mac_header */
189 	uint16_t		mac_len;	/* Link-layer header length. */
190 	enum sk_buff_pkt_type	pkt_type;
191 	refcount_t		refcnt;
192 
193 	struct net_device	*dev;
194 	void			*sk;		/* XXX net/sock.h? */
195 
196 	/* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
197 	void			*m;
198 	void(*m_free_func)(void *);
199 
200 	/* Force padding to CACHE_LINE_SIZE. */
201 	uint8_t			__scratch[0] __aligned(CACHE_LINE_SIZE);
202 };
203 
204 /* -------------------------------------------------------------------------- */
205 
206 struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
207 struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
208 struct sk_buff *linuxkpi_build_skb(void *, size_t);
209 void linuxkpi_kfree_skb(struct sk_buff *);
210 
211 struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t);
212 
213 int lkpi___skb_linearize(struct sk_buff *);
214 
215 /* -------------------------------------------------------------------------- */
216 
217 static inline struct sk_buff *
alloc_skb(size_t size,gfp_t gfp)218 alloc_skb(size_t size, gfp_t gfp)
219 {
220 	struct sk_buff *skb;
221 
222 	skb = linuxkpi_alloc_skb(size, gfp);
223 	SKB_TRACE(skb);
224 	return (skb);
225 }
226 
227 static inline struct sk_buff *
__dev_alloc_skb(size_t len,gfp_t gfp)228 __dev_alloc_skb(size_t len, gfp_t gfp)
229 {
230 	struct sk_buff *skb;
231 
232 	skb = linuxkpi_dev_alloc_skb(len, gfp);
233 	SKB_IMPROVE();
234 	SKB_TRACE(skb);
235 	return (skb);
236 }
237 
238 static inline struct sk_buff *
dev_alloc_skb(size_t len)239 dev_alloc_skb(size_t len)
240 {
241 	struct sk_buff *skb;
242 
243 	skb = __dev_alloc_skb(len, GFP_NOWAIT);
244 	SKB_IMPROVE();
245 	SKB_TRACE(skb);
246 	return (skb);
247 }
248 
249 static inline void
kfree_skb(struct sk_buff * skb)250 kfree_skb(struct sk_buff *skb)
251 {
252 	SKB_TRACE(skb);
253 	linuxkpi_kfree_skb(skb);
254 }
255 
256 static inline void
consume_skb(struct sk_buff * skb)257 consume_skb(struct sk_buff *skb)
258 {
259 	SKB_TRACE(skb);
260 	kfree_skb(skb);
261 }
262 
263 static inline void
dev_kfree_skb(struct sk_buff * skb)264 dev_kfree_skb(struct sk_buff *skb)
265 {
266 	SKB_TRACE(skb);
267 	SKB_IMPROVE("Need to be able to deal with page_pool");
268 	kfree_skb(skb);
269 }
270 
271 static inline void
dev_kfree_skb_any(struct sk_buff * skb)272 dev_kfree_skb_any(struct sk_buff *skb)
273 {
274 	SKB_TRACE(skb);
275 	dev_kfree_skb(skb);
276 }
277 
278 static inline void
dev_kfree_skb_irq(struct sk_buff * skb)279 dev_kfree_skb_irq(struct sk_buff *skb)
280 {
281 	SKB_TRACE(skb);
282 	SKB_IMPROVE("Do we have to defer this?");
283 	dev_kfree_skb(skb);
284 }
285 
286 static inline struct sk_buff *
build_skb(void * data,unsigned int fragsz)287 build_skb(void *data, unsigned int fragsz)
288 {
289 	struct sk_buff *skb;
290 
291 	skb = linuxkpi_build_skb(data, fragsz);
292 	SKB_TRACE(skb);
293 	return (skb);
294 }
295 
296 /* -------------------------------------------------------------------------- */
297 
298 static inline bool
skb_is_nonlinear(struct sk_buff * skb)299 skb_is_nonlinear(struct sk_buff *skb)
300 {
301 	SKB_TRACE(skb);
302 	return ((skb->data_len > 0) ? true : false);
303 }
304 
305 /* Add headroom; cannot do once there is data in there. */
306 static inline void
skb_reserve(struct sk_buff * skb,size_t len)307 skb_reserve(struct sk_buff *skb, size_t len)
308 {
309 	SKB_TRACE(skb);
310 #if 0
311 	/* Apparently it is allowed to call skb_reserve multiple times in a row. */
312 	KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p "
313 	    "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail));
314 #else
315 	KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not "
316 	    "empty head %p data %p tail %p len %u\n", __func__, skb,
317 	    skb->head, skb->data, skb->tail, skb->len));
318 #endif
319 	skb->data += len;
320 	skb->tail += len;
321 }
322 
323 /*
324  * Remove headroom; return new data pointer; basically make space at the
325  * front to copy data in (manually).
326  */
327 static inline void *
__skb_push(struct sk_buff * skb,size_t len)328 __skb_push(struct sk_buff *skb, size_t len)
329 {
330 	SKB_TRACE(skb);
331 	KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - "
332 	    "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data));
333 	skb->len  += len;
334 	skb->data -= len;
335 	return (skb->data);
336 }
337 
338 static inline void *
skb_push(struct sk_buff * skb,size_t len)339 skb_push(struct sk_buff *skb, size_t len)
340 {
341 
342 	SKB_TRACE(skb);
343 	return (__skb_push(skb, len));
344 }
345 
346 /*
347  * Length of the data on the skb (without any frags)???
348  */
349 static inline size_t
skb_headlen(struct sk_buff * skb)350 skb_headlen(struct sk_buff *skb)
351 {
352 
353 	SKB_TRACE(skb);
354 	return (skb->len - skb->data_len);
355 }
356 
357 
358 /* Return the end of data (tail pointer). */
359 static inline uint8_t *
skb_tail_pointer(struct sk_buff * skb)360 skb_tail_pointer(struct sk_buff *skb)
361 {
362 
363 	SKB_TRACE(skb);
364 	return (skb->tail);
365 }
366 
367 /* Return number of bytes available at end of buffer. */
368 static inline unsigned int
skb_tailroom(struct sk_buff * skb)369 skb_tailroom(struct sk_buff *skb)
370 {
371 
372 	SKB_TRACE(skb);
373 	KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, "
374 	    "end %p tail %p\n", __func__, skb, skb->end, skb->tail));
375 	if (unlikely(skb_is_nonlinear(skb)))
376 		return (0);
377 	return (skb->end - skb->tail);
378 }
379 
380 /* Return number of bytes available at the beginning of buffer. */
381 static inline unsigned int
skb_headroom(const struct sk_buff * skb)382 skb_headroom(const struct sk_buff *skb)
383 {
384 	SKB_TRACE(skb);
385 	KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, "
386 	    "data %p head %p\n", __func__, skb, skb->data, skb->head));
387 	return (skb->data - skb->head);
388 }
389 
390 
391 /*
392  * Remove tailroom; return the old tail pointer; basically make space at
393  * the end to copy data in (manually).  See also skb_put_data() below.
394  */
395 static inline void *
__skb_put(struct sk_buff * skb,size_t len)396 __skb_put(struct sk_buff *skb, size_t len)
397 {
398 	void *s;
399 
400 	SKB_TRACE(skb);
401 	KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + "
402 	    "len %zu) > end %p, head %p data %p len %u\n", __func__,
403 	    skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len));
404 
405 	s = skb_tail_pointer(skb);
406 	if (len == 0)
407 		return (s);
408 	skb->tail += len;
409 	skb->len += len;
410 #ifdef SKB_DEBUG
411 	if (linuxkpi_debug_skb & DSKB_TRACEX)
412 	printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n",
413 	    __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end,
414 	    s, len);
415 #endif
416 	return (s);
417 }
418 
419 static inline void *
skb_put(struct sk_buff * skb,size_t len)420 skb_put(struct sk_buff *skb, size_t len)
421 {
422 
423 	SKB_TRACE(skb);
424 	return (__skb_put(skb, len));
425 }
426 
427 /* skb_put() + copying data in. */
428 static inline void *
skb_put_data(struct sk_buff * skb,const void * buf,size_t len)429 skb_put_data(struct sk_buff *skb, const void *buf, size_t len)
430 {
431 	void *s;
432 
433 	SKB_TRACE2(skb, buf);
434 	s = skb_put(skb, len);
435 	if (len == 0)
436 		return (s);
437 	memcpy(s, buf, len);
438 	return (s);
439 }
440 
441 /* skb_put() + filling with zeros. */
442 static inline void *
__skb_put_zero(struct sk_buff * skb,size_t len)443 __skb_put_zero(struct sk_buff *skb, size_t len)
444 {
445 	void *s;
446 
447 	SKB_TRACE(skb);
448 	s = skb_put(skb, len);
449 	memset(s, '\0', len);
450 	return (s);
451 }
452 
453 static inline void *
skb_put_zero(struct sk_buff * skb,size_t len)454 skb_put_zero(struct sk_buff *skb, size_t len)
455 {
456 	return (__skb_put_zero(skb, len));
457 }
458 
459 /*
460  * Remove len bytes from beginning of data.
461  *
462  * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic;
463  * we return the advanced data pointer so we don't have to keep a temp, correct?
464  */
465 static inline void *
skb_pull(struct sk_buff * skb,size_t len)466 skb_pull(struct sk_buff *skb, size_t len)
467 {
468 
469 	SKB_TRACE(skb);
470 #if 0	/* Apparently this doesn't barf... */
471 	KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n",
472 	    __func__, skb, skb->len, len, skb->data));
473 #endif
474 	if (skb->len < len)
475 		return (NULL);
476 	skb->len -= len;
477 	skb->data += len;
478 	return (skb->data);
479 }
480 
481 /* Reduce skb data to given length or do nothing if smaller already. */
482 static inline void
__skb_trim(struct sk_buff * skb,unsigned int len)483 __skb_trim(struct sk_buff *skb, unsigned int len)
484 {
485 
486 	SKB_TRACE(skb);
487 	if (skb->len < len)
488 		return;
489 
490 	skb->len = len;
491 	skb->tail = skb->data + skb->len;
492 }
493 
494 static inline void
skb_trim(struct sk_buff * skb,unsigned int len)495 skb_trim(struct sk_buff *skb, unsigned int len)
496 {
497 
498 	return (__skb_trim(skb, len));
499 }
500 
501 static inline struct skb_shared_info *
skb_shinfo(struct sk_buff * skb)502 skb_shinfo(struct sk_buff *skb)
503 {
504 
505 	SKB_TRACE(skb);
506 	return (skb->shinfo);
507 }
508 
509 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)510 skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
511     off_t offset, size_t size, unsigned int truesize)
512 {
513 	struct skb_shared_info *shinfo;
514 
515 	SKB_TRACE(skb);
516 #ifdef SKB_DEBUG
517 	if (linuxkpi_debug_skb & DSKB_TRACEX)
518 	printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d "
519 	    "page %#jx offset %ju size %zu truesize %u\n", __func__,
520 	    skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno,
521 	    (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset,
522 	    size, truesize);
523 #endif
524 
525 	shinfo = skb_shinfo(skb);
526 	KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p "
527 	    "fragno %d too big\n", __func__, skb, fragno));
528 	shinfo->frags[fragno].page = page;
529 	shinfo->frags[fragno].offset = offset;
530 	shinfo->frags[fragno].size = size;
531 	shinfo->nr_frags = fragno + 1;
532         skb->len += size;
533 	skb->data_len += size;
534         skb->truesize += truesize;
535 }
536 
537 /* -------------------------------------------------------------------------- */
538 
539 #define	skb_queue_walk(_q, skb)						\
540 	for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q);	\
541 	    (skb) = (skb)->next)
542 
543 #define	skb_queue_walk_safe(_q, skb, tmp)				\
544 	for ((skb) = (_q)->next, (tmp) = (skb)->next;			\
545 	    (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next)
546 
547 #define	skb_list_walk_safe(_q, skb, tmp)				\
548 	for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \
549 	    ((skb) != NULL);						\
550 	    (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL)
551 
552 static inline bool
skb_queue_empty(const struct sk_buff_head * q)553 skb_queue_empty(const struct sk_buff_head *q)
554 {
555 	SKB_TRACE(q);
556 	return (q->next == (const struct sk_buff *)q);
557 }
558 
559 static inline bool
skb_queue_empty_lockless(const struct sk_buff_head * q)560 skb_queue_empty_lockless(const struct sk_buff_head *q)
561 {
562 	SKB_TRACE(q);
563 	return (READ_ONCE(q->next) == (const struct sk_buff *)q);
564 }
565 
566 static inline void
__skb_queue_head_init(struct sk_buff_head * q)567 __skb_queue_head_init(struct sk_buff_head *q)
568 {
569 	SKB_TRACE(q);
570 	q->prev = q->next = (struct sk_buff *)q;
571 	q->qlen = 0;
572 }
573 
574 static inline void
skb_queue_head_init(struct sk_buff_head * q)575 skb_queue_head_init(struct sk_buff_head *q)
576 {
577 	SKB_TRACE(q);
578 	__skb_queue_head_init(q);
579 	spin_lock_init(&q->lock);
580 }
581 
582 static inline void
__skb_insert(struct sk_buff * new,struct sk_buff * prev,struct sk_buff * next,struct sk_buff_head * q)583 __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next,
584     struct sk_buff_head *q)
585 {
586 
587 	SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q);
588 	WRITE_ONCE(new->prev, prev);
589 	WRITE_ONCE(new->next, next);
590 	WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new);
591 	WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new);
592 	WRITE_ONCE(q->qlen, q->qlen + 1);
593 }
594 
595 static inline void
__skb_queue_after(struct sk_buff_head * q,struct sk_buff * skb,struct sk_buff * new)596 __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb,
597     struct sk_buff *new)
598 {
599 
600 	SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
601 	__skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q);
602 }
603 
604 static inline void
__skb_queue_before(struct sk_buff_head * q,struct sk_buff * skb,struct sk_buff * new)605 __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb,
606     struct sk_buff *new)
607 {
608 
609 	SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
610 	__skb_insert(new, skb->prev, skb, q);
611 }
612 
613 static inline void
__skb_queue_tail(struct sk_buff_head * q,struct sk_buff * new)614 __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
615 {
616 
617 	SKB_TRACE2(q, new);
618 	__skb_queue_before(q, (struct sk_buff *)q, new);
619 }
620 
621 static inline void
skb_queue_tail(struct sk_buff_head * q,struct sk_buff * new)622 skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new)
623 {
624 	unsigned long flags;
625 
626 	SKB_TRACE2(q, new);
627 	spin_lock_irqsave(&q->lock, flags);
628 	__skb_queue_tail(q, new);
629 	spin_unlock_irqrestore(&q->lock, flags);
630 }
631 
632 static inline struct sk_buff *
skb_peek(const struct sk_buff_head * q)633 skb_peek(const struct sk_buff_head *q)
634 {
635 	struct sk_buff *skb;
636 
637 	skb = q->next;
638 	SKB_TRACE2(q, skb);
639 	if (skb == (const struct sk_buff *)q)
640 		return (NULL);
641 	return (skb);
642 }
643 
644 static inline struct sk_buff *
skb_peek_tail(const struct sk_buff_head * q)645 skb_peek_tail(const struct sk_buff_head *q)
646 {
647 	struct sk_buff *skb;
648 
649 	skb = READ_ONCE(q->prev);
650 	SKB_TRACE2(q, skb);
651 	if (skb == (const struct sk_buff *)q)
652 		return (NULL);
653 	return (skb);
654 }
655 
656 static inline void
__skb_unlink(struct sk_buff * skb,struct sk_buff_head * q)657 __skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
658 {
659 	struct sk_buff *p, *n;
660 
661 	SKB_TRACE2(skb, q);
662 
663 	WRITE_ONCE(q->qlen, q->qlen - 1);
664 	p = skb->prev;
665 	n = skb->next;
666 	KASSERT(p != NULL && n != NULL,
667 	    ("%s: skb %p q %p p %p n %p\n", __func__, skb, q, p, n));
668 	WRITE_ONCE(n->prev, p);
669 	WRITE_ONCE(p->next, n);
670 	skb->prev = skb->next = NULL;
671 }
672 
673 static inline void
skb_unlink(struct sk_buff * skb,struct sk_buff_head * q)674 skb_unlink(struct sk_buff *skb, struct sk_buff_head *q)
675 {
676 	unsigned long flags;
677 
678 	SKB_TRACE2(skb, q);
679 	spin_lock_irqsave(&q->lock, flags);
680 	__skb_unlink(skb, q);
681 	spin_unlock_irqrestore(&q->lock, flags);
682 }
683 
684 static inline struct sk_buff *
__skb_dequeue(struct sk_buff_head * q)685 __skb_dequeue(struct sk_buff_head *q)
686 {
687 	struct sk_buff *skb;
688 
689 	skb = skb_peek(q);
690 	if (skb != NULL)
691 		__skb_unlink(skb, q);
692 	SKB_TRACE2(q, skb);
693 	return (skb);
694 }
695 
696 static inline struct sk_buff *
skb_dequeue(struct sk_buff_head * q)697 skb_dequeue(struct sk_buff_head *q)
698 {
699 	unsigned long flags;
700 	struct sk_buff *skb;
701 
702 	spin_lock_irqsave(&q->lock, flags);
703 	skb = __skb_dequeue(q);
704 	spin_unlock_irqrestore(&q->lock, flags);
705 	SKB_TRACE2(q, skb);
706 	return (skb);
707 }
708 
709 static inline struct sk_buff *
__skb_dequeue_tail(struct sk_buff_head * q)710 __skb_dequeue_tail(struct sk_buff_head *q)
711 {
712 	struct sk_buff *skb;
713 
714 	skb = skb_peek_tail(q);
715 	if (skb != NULL)
716 		__skb_unlink(skb, q);
717 	SKB_TRACE2(q, skb);
718 	return (skb);
719 }
720 
721 static inline struct sk_buff *
skb_dequeue_tail(struct sk_buff_head * q)722 skb_dequeue_tail(struct sk_buff_head *q)
723 {
724 	unsigned long flags;
725 	struct sk_buff *skb;
726 
727 	spin_lock_irqsave(&q->lock, flags);
728 	skb = __skb_dequeue_tail(q);
729 	spin_unlock_irqrestore(&q->lock, flags);
730 	SKB_TRACE2(q, skb);
731 	return (skb);
732 }
733 
734 static inline void
__skb_queue_head(struct sk_buff_head * q,struct sk_buff * skb)735 __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
736 {
737 
738 	SKB_TRACE2(q, skb);
739 	__skb_queue_after(q, (struct sk_buff *)q, skb);
740 }
741 
742 static inline void
skb_queue_head(struct sk_buff_head * q,struct sk_buff * skb)743 skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
744 {
745 	unsigned long flags;
746 
747 	SKB_TRACE2(q, skb);
748 	spin_lock_irqsave(&q->lock, flags);
749 	__skb_queue_head(q, skb);
750 	spin_unlock_irqrestore(&q->lock, flags);
751 }
752 
753 static inline uint32_t
skb_queue_len(const struct sk_buff_head * q)754 skb_queue_len(const struct sk_buff_head *q)
755 {
756 
757 	SKB_TRACE(q);
758 	return (q->qlen);
759 }
760 
761 static inline uint32_t
skb_queue_len_lockless(const struct sk_buff_head * q)762 skb_queue_len_lockless(const struct sk_buff_head *q)
763 {
764 
765 	SKB_TRACE(q);
766 	return (READ_ONCE(q->qlen));
767 }
768 
769 static inline void
___skb_queue_splice(const struct sk_buff_head * from,struct sk_buff * p,struct sk_buff * n)770 ___skb_queue_splice(const struct sk_buff_head *from,
771     struct sk_buff *p, struct sk_buff *n)
772 {
773 	struct sk_buff *b, *e;
774 
775 	b = from->next;
776 	e = from->prev;
777 
778 	WRITE_ONCE(b->prev, p);
779 	WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b);
780 	WRITE_ONCE(e->next, n);
781 	WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e);
782 }
783 
784 static inline void
skb_queue_splice(const struct sk_buff_head * from,struct sk_buff_head * to)785 skb_queue_splice(const struct sk_buff_head *from, struct sk_buff_head *to)
786 {
787 
788 	SKB_TRACE2(from, to);
789 
790 	if (skb_queue_empty(from))
791 		return;
792 
793 	___skb_queue_splice(from, (struct sk_buff *)to, to->next);
794 	to->qlen += from->qlen;
795 }
796 
797 static inline void
skb_queue_splice_init(struct sk_buff_head * from,struct sk_buff_head * to)798 skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
799 {
800 
801 	skb_queue_splice(from, to);
802 	__skb_queue_head_init(from);
803 }
804 
805 static inline void
skb_queue_splice_tail_init(struct sk_buff_head * from,struct sk_buff_head * to)806 skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to)
807 {
808 
809 	SKB_TRACE2(from, to);
810 
811 	if (skb_queue_empty(from))
812 		return;
813 
814 	___skb_queue_splice(from, to->prev, (struct sk_buff *)to);
815 	to->qlen += from->qlen;
816 	__skb_queue_head_init(from);
817 }
818 
819 
820 static inline void
__skb_queue_purge(struct sk_buff_head * q)821 __skb_queue_purge(struct sk_buff_head *q)
822 {
823 	struct sk_buff *skb;
824 
825 	SKB_TRACE(q);
826         while ((skb = __skb_dequeue(q)) != NULL)
827 		kfree_skb(skb);
828 	WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u",
829 	    __func__, q, skb_queue_len(q));
830 }
831 
832 static inline void
skb_queue_purge(struct sk_buff_head * q)833 skb_queue_purge(struct sk_buff_head *q)
834 {
835 	struct sk_buff_head _q;
836 	unsigned long flags;
837 
838 	SKB_TRACE(q);
839 
840 	if (skb_queue_empty_lockless(q))
841 		return;
842 
843 	__skb_queue_head_init(&_q);
844 	spin_lock_irqsave(&q->lock, flags);
845 	skb_queue_splice_init(q, &_q);
846 	spin_unlock_irqrestore(&q->lock, flags);
847 	__skb_queue_purge(&_q);
848 }
849 
850 static inline struct sk_buff *
skb_queue_prev(struct sk_buff_head * q,struct sk_buff * skb)851 skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
852 {
853 
854 	SKB_TRACE2(q, skb);
855 	/* XXX what is the q argument good for? */
856 	return (skb->prev);
857 }
858 
859 /* -------------------------------------------------------------------------- */
860 
861 static inline struct sk_buff *
skb_copy(const struct sk_buff * skb,gfp_t gfp)862 skb_copy(const struct sk_buff *skb, gfp_t gfp)
863 {
864 	struct sk_buff *new;
865 
866 	new = linuxkpi_skb_copy(skb, gfp);
867 	SKB_TRACE2(skb, new);
868 	return (new);
869 }
870 
871 static inline uint16_t
skb_checksum(struct sk_buff * skb,int offs,size_t len,int x)872 skb_checksum(struct sk_buff *skb, int offs, size_t len, int x)
873 {
874 	SKB_TRACE(skb);
875 	SKB_TODO();
876 	return (0xffff);
877 }
878 
879 static inline int
skb_checksum_start_offset(struct sk_buff * skb)880 skb_checksum_start_offset(struct sk_buff *skb)
881 {
882 	SKB_TRACE(skb);
883 	SKB_TODO();
884 	return (-1);
885 }
886 
887 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)888 skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x,
889     size_t fragsz, enum dma_data_direction dir)
890 {
891 	SKB_TRACE2(frag, dev);
892 	SKB_TODO();
893 	return (-1);
894 }
895 
896 static inline size_t
skb_frag_size(const skb_frag_t * frag)897 skb_frag_size(const skb_frag_t *frag)
898 {
899 	SKB_TRACE(frag);
900 	return (frag->size);
901 }
902 
903 #define	skb_walk_frags(_skb, _frag)					\
904 	for ((_frag) = (_skb); false; (_frag)++)
905 
906 static inline void
skb_checksum_help(struct sk_buff * skb)907 skb_checksum_help(struct sk_buff *skb)
908 {
909 	SKB_TRACE(skb);
910 	SKB_TODO();
911 }
912 
913 static inline bool
skb_ensure_writable(struct sk_buff * skb,size_t off)914 skb_ensure_writable(struct sk_buff *skb, size_t off)
915 {
916 	SKB_TRACE(skb);
917 	SKB_TODO();
918 	return (false);
919 }
920 
921 static inline void *
skb_frag_address(const skb_frag_t * frag)922 skb_frag_address(const skb_frag_t *frag)
923 {
924 	SKB_TRACE(frag);
925 	return (page_address(frag->page + frag->offset));
926 }
927 
928 static inline void
skb_free_frag(void * frag)929 skb_free_frag(void *frag)
930 {
931 
932 	page_frag_free(frag);
933 }
934 
935 static inline struct sk_buff *
skb_gso_segment(struct sk_buff * skb,netdev_features_t netdev_flags)936 skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags)
937 {
938 	SKB_TRACE(skb);
939 	SKB_TODO();
940 	return (NULL);
941 }
942 
943 static inline bool
skb_is_gso(struct sk_buff * skb)944 skb_is_gso(struct sk_buff *skb)
945 {
946 	SKB_TRACE(skb);
947 	SKB_IMPROVE("Really a TODO but get it away from logging");
948 	return (false);
949 }
950 
951 static inline void
skb_mark_not_on_list(struct sk_buff * skb)952 skb_mark_not_on_list(struct sk_buff *skb)
953 {
954 	SKB_TRACE(skb);
955 	skb->next = NULL;
956 }
957 
958 static inline void
skb_reset_transport_header(struct sk_buff * skb)959 skb_reset_transport_header(struct sk_buff *skb)
960 {
961 
962 	SKB_TRACE(skb);
963 	skb->l4hdroff = skb->data - skb->head;
964 }
965 
966 static inline uint8_t *
skb_transport_header(struct sk_buff * skb)967 skb_transport_header(struct sk_buff *skb)
968 {
969 
970 	SKB_TRACE(skb);
971         return (skb->head + skb->l4hdroff);
972 }
973 
974 static inline uint8_t *
skb_network_header(struct sk_buff * skb)975 skb_network_header(struct sk_buff *skb)
976 {
977 
978 	SKB_TRACE(skb);
979         return (skb->head + skb->l3hdroff);
980 }
981 
982 static inline int
__skb_linearize(struct sk_buff * skb)983 __skb_linearize(struct sk_buff *skb)
984 {
985 	return (lkpi___skb_linearize(skb));
986 }
987 
988 static inline int
skb_linearize(struct sk_buff * skb)989 skb_linearize(struct sk_buff *skb)
990 {
991 	return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0);
992 }
993 
994 static inline int
pskb_expand_head(struct sk_buff * skb,int x,int len,gfp_t gfp)995 pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp)
996 {
997 	SKB_TRACE(skb);
998 	SKB_TODO();
999 	return (-ENXIO);
1000 }
1001 
1002 /* Not really seen this one but need it as symmetric accessor function. */
1003 static inline void
skb_set_queue_mapping(struct sk_buff * skb,uint16_t qmap)1004 skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap)
1005 {
1006 
1007 	SKB_TRACE_FMT(skb, "qmap %u", qmap);
1008 	skb->qmap = qmap;
1009 }
1010 
1011 static inline uint16_t
skb_get_queue_mapping(struct sk_buff * skb)1012 skb_get_queue_mapping(struct sk_buff *skb)
1013 {
1014 
1015 	SKB_TRACE_FMT(skb, "qmap %u", skb->qmap);
1016 	return (skb->qmap);
1017 }
1018 
1019 static inline void
skb_copy_header(struct sk_buff * to,const struct sk_buff * from)1020 skb_copy_header(struct sk_buff *to, const struct sk_buff *from)
1021 {
1022 	SKB_TRACE2(to, from);
1023 	SKB_TODO();
1024 }
1025 
1026 static inline bool
skb_header_cloned(struct sk_buff * skb)1027 skb_header_cloned(struct sk_buff *skb)
1028 {
1029 	SKB_TRACE(skb);
1030 	SKB_TODO();
1031 	return (true);
1032 }
1033 
1034 static inline uint8_t *
skb_mac_header(const struct sk_buff * skb)1035 skb_mac_header(const struct sk_buff *skb)
1036 {
1037 	SKB_TRACE(skb);
1038 	return (skb->head + skb->mac_header);
1039 }
1040 
1041 static inline void
skb_reset_mac_header(struct sk_buff * skb)1042 skb_reset_mac_header(struct sk_buff *skb)
1043 {
1044 	SKB_TRACE(skb);
1045 	skb->mac_header = skb->data - skb->head;
1046 }
1047 
1048 static inline void
skb_set_mac_header(struct sk_buff * skb,const size_t len)1049 skb_set_mac_header(struct sk_buff *skb, const size_t len)
1050 {
1051 	SKB_TRACE(skb);
1052 	skb_reset_mac_header(skb);
1053 	skb->mac_header += len;
1054 }
1055 
1056 static inline struct skb_shared_hwtstamps *
skb_hwtstamps(struct sk_buff * skb)1057 skb_hwtstamps(struct sk_buff *skb)
1058 {
1059 	SKB_TRACE(skb);
1060 	SKB_TODO();
1061 	return (NULL);
1062 }
1063 
1064 static inline void
skb_orphan(struct sk_buff * skb)1065 skb_orphan(struct sk_buff *skb)
1066 {
1067 	SKB_TRACE(skb);
1068 	SKB_TODO();
1069 }
1070 
1071 static inline __wsum
csum_unfold(__sum16 sum)1072 csum_unfold(__sum16 sum)
1073 {
1074 	return (sum);
1075 }
1076 
1077 static __inline void
skb_postpush_rcsum(struct sk_buff * skb,const void * data,size_t len)1078 skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len)
1079 {
1080 	SKB_TODO();
1081 }
1082 
1083 static inline void
skb_reset_tail_pointer(struct sk_buff * skb)1084 skb_reset_tail_pointer(struct sk_buff *skb)
1085 {
1086 
1087 	SKB_TRACE(skb);
1088 #ifdef SKB_DOING_OFFSETS_US_NOT
1089 	skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head);
1090 #endif
1091 	skb->tail = skb->data;
1092 	SKB_TRACE(skb);
1093 }
1094 
1095 static inline struct sk_buff *
skb_get(struct sk_buff * skb)1096 skb_get(struct sk_buff *skb)
1097 {
1098 
1099 	SKB_TRACE(skb);
1100 	refcount_inc(&skb->refcnt);
1101 	return (skb);
1102 }
1103 
1104 static inline struct sk_buff *
skb_realloc_headroom(struct sk_buff * skb,unsigned int headroom)1105 skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
1106 {
1107 
1108 	SKB_TODO();
1109 	return (NULL);
1110 }
1111 
1112 static inline void
skb_copy_from_linear_data(const struct sk_buff * skb,void * dst,size_t len)1113 skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len)
1114 {
1115 
1116 	SKB_TRACE(skb);
1117 	/* Let us just hope the destination has len space ... */
1118 	memcpy(dst, skb->data, len);
1119 }
1120 
1121 static inline int
skb_pad(struct sk_buff * skb,int pad)1122 skb_pad(struct sk_buff *skb, int pad)
1123 {
1124 
1125 	SKB_TRACE(skb);
1126 	SKB_TODO();
1127 	return (-1);
1128 }
1129 
1130 static inline void
skb_list_del_init(struct sk_buff * skb)1131 skb_list_del_init(struct sk_buff *skb)
1132 {
1133 
1134 	SKB_TRACE(skb);
1135 	__list_del_entry(&skb->list);
1136 	skb_mark_not_on_list(skb);
1137 }
1138 
1139 static inline void
napi_consume_skb(struct sk_buff * skb,int budget)1140 napi_consume_skb(struct sk_buff *skb, int budget)
1141 {
1142 
1143 	SKB_TRACE(skb);
1144 	SKB_TODO();
1145 }
1146 
1147 static inline struct sk_buff *
napi_build_skb(void * data,size_t len)1148 napi_build_skb(void *data, size_t len)
1149 {
1150 	struct sk_buff *skb;
1151 
1152 	SKB_IMPROVE("len and all needs fixing likely");
1153 
1154 	skb = linuxkpi_build_skb(data, len);
1155 	SKB_TRACE(skb);
1156 	return (skb);
1157 }
1158 
1159 static inline uint32_t
skb_get_hash(struct sk_buff * skb)1160 skb_get_hash(struct sk_buff *skb)
1161 {
1162 	SKB_TRACE(skb);
1163 	SKB_TODO();
1164 	return (0);
1165 }
1166 
1167 static inline void
skb_mark_for_recycle(struct sk_buff * skb)1168 skb_mark_for_recycle(struct sk_buff *skb)
1169 {
1170 	SKB_TRACE(skb);
1171 	skb->_flags |= _SKB_PP_RECYCLE;
1172 }
1173 
1174 static inline int
skb_cow_head(struct sk_buff * skb,unsigned int headroom)1175 skb_cow_head(struct sk_buff *skb, unsigned int headroom)
1176 {
1177 	SKB_TRACE(skb);
1178 	SKB_TODO();
1179 	return (-1);
1180 }
1181 
1182 /* Misplaced here really but sock comes from skbuff. */
1183 #define	sk_pacing_shift_update(sock, n)
1184 
1185 #define	SKB_WITH_OVERHEAD(_s)						\
1186 	(_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
1187 
1188 #endif	/* _LINUXKPI_LINUX_SKBUFF_H */
1189