1 /*-
2 * Copyright (c) 2020-2022 The FreeBSD Foundation
3 * Copyright (c) 2021-2022 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 * $FreeBSD$
30 */
31
32 /*
33 * NOTE: this socket buffer compatibility code is highly EXPERIMENTAL.
34 * Do not rely on the internals of this implementation. They are highly
35 * likely to change as we will improve the integration to FreeBSD mbufs.
36 */
37
38 #ifndef _LINUXKPI_LINUX_SKBUFF_H
39 #define _LINUXKPI_LINUX_SKBUFF_H
40
41 #include <linux/kernel.h>
42 #include <linux/page.h>
43 #include <linux/dma-mapping.h>
44 #include <linux/netdev_features.h>
45 #include <linux/list.h>
46 #include <linux/gfp.h>
47 #include <linux/compiler.h>
48 #include <linux/spinlock.h>
49
50 /* #define SKB_DEBUG */
51 #ifdef SKB_DEBUG
52 #define DSKB_TODO 0x01
53 #define DSKB_IMPROVE 0x02
54 #define DSKB_TRACE 0x10
55 #define DSKB_TRACEX 0x20
56 extern int linuxkpi_debug_skb;
57
58 #define SKB_TODO() \
59 if (linuxkpi_debug_skb & DSKB_TODO) \
60 printf("SKB_TODO %s:%d\n", __func__, __LINE__)
61 #define SKB_IMPROVE(...) \
62 if (linuxkpi_debug_skb & DSKB_IMPROVE) \
63 printf("SKB_IMPROVE %s:%d\n", __func__, __LINE__)
64 #define SKB_TRACE(_s) \
65 if (linuxkpi_debug_skb & DSKB_TRACE) \
66 printf("SKB_TRACE %s:%d %p\n", __func__, __LINE__, _s)
67 #define SKB_TRACE2(_s, _p) \
68 if (linuxkpi_debug_skb & DSKB_TRACE) \
69 printf("SKB_TRACE %s:%d %p, %p\n", __func__, __LINE__, _s, _p)
70 #define SKB_TRACE_FMT(_s, _fmt, ...) \
71 if (linuxkpi_debug_skb & DSKB_TRACE) \
72 printf("SKB_TRACE %s:%d %p " _fmt "\n", __func__, __LINE__, _s, \
73 __VA_ARGS__)
74 #else
75 #define SKB_TODO() do { } while(0)
76 #define SKB_IMPROVE(...) do { } while(0)
77 #define SKB_TRACE(_s) do { } while(0)
78 #define SKB_TRACE2(_s, _p) do { } while(0)
79 #define SKB_TRACE_FMT(_s, ...) do { } while(0)
80 #endif
81
82 enum sk_buff_pkt_type {
83 PACKET_BROADCAST,
84 PACKET_MULTICAST,
85 PACKET_OTHERHOST,
86 };
87
88 #define NET_SKB_PAD max(CACHE_LINE_SIZE, 32)
89
90 struct sk_buff_head {
91 /* XXX TODO */
92 struct sk_buff *next;
93 struct sk_buff *prev;
94 size_t qlen;
95 spinlock_t lock;
96 };
97
98 enum sk_checksum_flags {
99 CHECKSUM_NONE = 0x00,
100 CHECKSUM_UNNECESSARY = 0x01,
101 CHECKSUM_PARTIAL = 0x02,
102 CHECKSUM_COMPLETE = 0x04,
103 };
104
105 struct skb_frag {
106 /* XXX TODO */
107 struct page *page; /* XXX-BZ These three are a wild guess so far! */
108 off_t offset;
109 size_t size;
110 };
111 typedef struct skb_frag skb_frag_t;
112
113 enum skb_shared_info_gso_type {
114 SKB_GSO_TCPV4,
115 SKB_GSO_TCPV6,
116 };
117
118 struct skb_shared_info {
119 enum skb_shared_info_gso_type gso_type;
120 uint16_t gso_size;
121 uint16_t nr_frags;
122 struct sk_buff *frag_list;
123 skb_frag_t frags[64]; /* XXX TODO, 16xpage? */
124 };
125
126 struct sk_buff {
127 /* XXX TODO */
128 union {
129 /* struct sk_buff_head */
130 struct {
131 struct sk_buff *next;
132 struct sk_buff *prev;
133 };
134 struct list_head list;
135 };
136 uint32_t _alloc_len; /* Length of alloc data-buf. XXX-BZ give up for truesize? */
137 uint32_t len; /* ? */
138 uint32_t data_len; /* ? If we have frags? */
139 uint32_t truesize; /* The total size of all buffers, incl. frags. */
140 uint16_t mac_len; /* Link-layer header length. */
141 __sum16 csum;
142 uint16_t l3hdroff; /* network header offset from *head */
143 uint16_t l4hdroff; /* transport header offset from *head */
144 uint32_t priority;
145 uint16_t qmap; /* queue mapping */
146 uint16_t _flags; /* Internal flags. */
147 #define _SKB_FLAGS_SKBEXTFRAG 0x0001
148 enum sk_buff_pkt_type pkt_type;
149
150 /* "Scratch" area for layers to store metadata. */
151 /* ??? I see sizeof() operations so probably an array. */
152 uint8_t cb[64] __aligned(CACHE_LINE_SIZE);
153
154 struct net_device *dev;
155 void *sk; /* XXX net/sock.h? */
156
157 int csum_offset, csum_start, ip_summed, protocol;
158
159 uint8_t *head; /* Head of buffer. */
160 uint8_t *data; /* Head of data. */
161 uint8_t *tail; /* End of data. */
162 uint8_t *end; /* End of buffer. */
163
164 struct skb_shared_info *shinfo;
165
166 /* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */
167 void *m;
168 void(*m_free_func)(void *);
169
170 /* Force padding to CACHE_LINE_SIZE. */
171 uint8_t __scratch[0] __aligned(CACHE_LINE_SIZE);
172 };
173
174 /* -------------------------------------------------------------------------- */
175
176 struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
177 struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
178 struct sk_buff *linuxkpi_build_skb(void *, size_t);
179 void linuxkpi_kfree_skb(struct sk_buff *);
180
181 struct sk_buff *linuxkpi_skb_copy(struct sk_buff *, gfp_t);
182
183 /* -------------------------------------------------------------------------- */
184
185 static inline struct sk_buff *
186 alloc_skb(size_t size, gfp_t gfp)
187 {
188 struct sk_buff *skb;
189
190 skb = linuxkpi_alloc_skb(size, gfp);
191 SKB_TRACE(skb);
192 return (skb);
193 }
194
195 static inline struct sk_buff *
196 __dev_alloc_skb(size_t len, gfp_t gfp)
197 {
198 struct sk_buff *skb;
199
200 skb = linuxkpi_dev_alloc_skb(len, gfp);
201 SKB_IMPROVE();
202 SKB_TRACE(skb);
203 return (skb);
204 }
205
206 static inline struct sk_buff *
207 dev_alloc_skb(size_t len)
208 {
209 struct sk_buff *skb;
210
211 skb = __dev_alloc_skb(len, GFP_NOWAIT);
212 SKB_IMPROVE();
213 SKB_TRACE(skb);
214 return (skb);
215 }
216
217 static inline void
218 kfree_skb(struct sk_buff *skb)
219 {
220 SKB_TRACE(skb);
221 linuxkpi_kfree_skb(skb);
222 }
223
224 static inline void
225 dev_kfree_skb(struct sk_buff *skb)
226 {
227 SKB_TRACE(skb);
228 kfree_skb(skb);
229 }
230
231 static inline void
232 dev_kfree_skb_any(struct sk_buff *skb)
233 {
234 SKB_TRACE(skb);
235 dev_kfree_skb(skb);
236 }
237
238 static inline void
239 dev_kfree_skb_irq(struct sk_buff *skb)
240 {
241 SKB_TRACE(skb);
242 SKB_IMPROVE("Do we have to defer this?");
243 dev_kfree_skb(skb);
244 }
245
246 static inline struct sk_buff *
247 build_skb(void *data, unsigned int fragsz)
248 {
249 struct sk_buff *skb;
250
251 skb = linuxkpi_build_skb(data, fragsz);
252 SKB_TRACE(skb);
253 return (skb);
254 }
255
256 /* -------------------------------------------------------------------------- */
257
258 /* XXX BZ review this one for terminal condition as Linux "queues" are special. */
259 #define skb_list_walk_safe(_q, skb, tmp) \
260 for ((skb) = (_q)->next; (skb) != NULL && ((tmp) = (skb)->next); (skb) = (tmp))
261
262 /* Add headroom; cannot do once there is data in there. */
263 static inline void
264 skb_reserve(struct sk_buff *skb, size_t len)
265 {
266 SKB_TRACE(skb);
267 #if 0
268 /* Apparently it is allowed to call skb_reserve multiple times in a row. */
269 KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p "
270 "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail));
271 #else
272 KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not "
273 "empty head %p data %p tail %p len %u\n", __func__, skb,
274 skb->head, skb->data, skb->tail, skb->len));
275 #endif
276 skb->data += len;
277 skb->tail += len;
278 }
279
280 /*
281 * Remove headroom; return new data pointer; basically make space at the
282 * front to copy data in (manually).
283 */
284 static inline void *
285 __skb_push(struct sk_buff *skb, size_t len)
286 {
287 SKB_TRACE(skb);
288 KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - "
289 "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data));
290 skb->len += len;
291 skb->data -= len;
292 return (skb->data);
293 }
294
295 static inline void *
296 skb_push(struct sk_buff *skb, size_t len)
297 {
298
299 SKB_TRACE(skb);
300 return (__skb_push(skb, len));
301 }
302
303 /*
304 * Length of the data on the skb (without any frags)???
305 */
306 static inline size_t
307 skb_headlen(struct sk_buff *skb)
308 {
309
310 SKB_TRACE(skb);
311 return (skb->len - skb->data_len);
312 }
313
314
315 /* Return the end of data (tail pointer). */
316 static inline uint8_t *
317 skb_tail_pointer(struct sk_buff *skb)
318 {
319
320 SKB_TRACE(skb);
321 return (skb->tail);
322 }
323
324 /* Return number of bytes available at end of buffer. */
325 static inline unsigned int
326 skb_tailroom(struct sk_buff *skb)
327 {
328
329 SKB_TRACE(skb);
330 KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, "
331 "end %p tail %p\n", __func__, skb, skb->end, skb->tail));
332 return (skb->end - skb->tail);
333 }
334
335 /* Return numer of bytes available at the beginning of buffer. */
336 static inline unsigned int
337 skb_headroom(struct sk_buff *skb)
338 {
339 SKB_TRACE(skb);
340 KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, "
341 "data %p head %p\n", __func__, skb, skb->data, skb->head));
342 return (skb->data - skb->head);
343 }
344
345
346 /*
347 * Remove tailroom; return the old tail pointer; basically make space at
348 * the end to copy data in (manually). See also skb_put_data() below.
349 */
350 static inline void *
351 __skb_put(struct sk_buff *skb, size_t len)
352 {
353 void *s;
354
355 SKB_TRACE(skb);
356 KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + "
357 "len %zu) > end %p, head %p data %p len %u\n", __func__,
358 skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len));
359
360 s = skb_tail_pointer(skb);
361 if (len == 0)
362 return (s);
363 skb->tail += len;
364 skb->len += len;
365 #ifdef SKB_DEBUG
366 if (linuxkpi_debug_skb & DSKB_TRACEX)
367 printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n",
368 __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end,
369 s, len);
370 #endif
371 return (s);
372 }
373
374 static inline void *
375 skb_put(struct sk_buff *skb, size_t len)
376 {
377
378 SKB_TRACE(skb);
379 return (__skb_put(skb, len));
380 }
381
382 /* skb_put() + copying data in. */
383 static inline void *
384 skb_put_data(struct sk_buff *skb, const void *buf, size_t len)
385 {
386 void *s;
387
388 SKB_TRACE2(skb, buf);
389 s = skb_put(skb, len);
390 if (len == 0)
391 return (s);
392 memcpy(s, buf, len);
393 return (s);
394 }
395
396 /* skb_put() + filling with zeros. */
397 static inline void *
398 skb_put_zero(struct sk_buff *skb, size_t len)
399 {
400 void *s;
401
402 SKB_TRACE(skb);
403 s = skb_put(skb, len);
404 memset(s, '\0', len);
405 return (s);
406 }
407
408 /*
409 * Remove len bytes from beginning of data.
410 *
411 * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic;
412 * we return the advanced data pointer so we don't have to keep a temp, correct?
413 */
414 static inline void *
415 skb_pull(struct sk_buff *skb, size_t len)
416 {
417
418 SKB_TRACE(skb);
419 #if 0 /* Apparently this doesn't barf... */
420 KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n",
421 __func__, skb, skb->len, len, skb->data));
422 #endif
423 if (skb->len < len)
424 return (NULL);
425 skb->len -= len;
426 skb->data += len;
427 return (skb->data);
428 }
429
430 /* Reduce skb data to given length or do nothing if smaller already. */
431 static inline void
432 __skb_trim(struct sk_buff *skb, unsigned int len)
433 {
434
435 SKB_TRACE(skb);
436 if (skb->len < len)
437 return;
438
439 skb->len = len;
440 skb->tail = skb->data + skb->len;
441 }
442
443 static inline void
444 skb_trim(struct sk_buff *skb, unsigned int len)
445 {
446
447 return (__skb_trim(skb, len));
448 }
449
450 static inline struct skb_shared_info *
451 skb_shinfo(struct sk_buff *skb)
452 {
453
454 SKB_TRACE(skb);
455 return (skb->shinfo);
456 }
457
458 static inline void
459 skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page,
460 off_t offset, size_t size, unsigned int truesize)
461 {
462 struct skb_shared_info *shinfo;
463
464 SKB_TRACE(skb);
465 #ifdef SKB_DEBUG
466 if (linuxkpi_debug_skb & DSKB_TRACEX)
467 printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d "
468 "page %#jx offset %ju size %zu truesize %u\n", __func__,
469 skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno,
470 (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset,
471 size, truesize);
472 #endif
473
474 shinfo = skb_shinfo(skb);
475 KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p "
476 "fragno %d too big\n", __func__, skb, fragno));
477 shinfo->frags[fragno].page = page;
478 shinfo->frags[fragno].offset = offset;
479 shinfo->frags[fragno].size = size;
480 shinfo->nr_frags = fragno + 1;
481 skb->len += size;
482 skb->data_len += size;
483 skb->truesize += truesize;
484
485 /* XXX TODO EXTEND truesize? */
486 }
487
488 /* -------------------------------------------------------------------------- */
489
490 /* XXX BZ review this one for terminal condition as Linux "queues" are special. */
491 #define skb_queue_walk(_q, skb) \
492 for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q); \
493 (skb) = (skb)->next)
494
495 #define skb_queue_walk_safe(_q, skb, tmp) \
496 for ((skb) = (_q)->next, (tmp) = (skb)->next; \
497 (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next)
498
499 static inline bool
500 skb_queue_empty(struct sk_buff_head *q)
501 {
502
503 SKB_TRACE(q);
504 return (q->qlen == 0);
505 }
506
507 static inline void
508 __skb_queue_head_init(struct sk_buff_head *q)
509 {
510 SKB_TRACE(q);
511 q->prev = q->next = (struct sk_buff *)q;
512 q->qlen = 0;
513 }
514
515 static inline void
516 skb_queue_head_init(struct sk_buff_head *q)
517 {
518 SKB_TRACE(q);
519 return (__skb_queue_head_init(q));
520 }
521
522 static inline void
523 __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next,
524 struct sk_buff_head *q)
525 {
526
527 SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q);
528 new->prev = prev;
529 new->next = next;
530 next->prev = new;
531 prev->next = new;
532 q->qlen++;
533 }
534
535 static inline void
536 __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb,
537 struct sk_buff *new)
538 {
539
540 SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
541 __skb_insert(new, skb, skb->next, q);
542 }
543
544 static inline void
545 __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb,
546 struct sk_buff *new)
547 {
548
549 SKB_TRACE_FMT(q, "skb %p new %p", skb, new);
550 __skb_insert(new, skb->prev, skb, q);
551 }
552
553 static inline void
554 __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb)
555 {
556 struct sk_buff *s;
557
558 SKB_TRACE2(q, skb);
559 q->qlen++;
560 s = (struct sk_buff *)q;
561 s->prev->next = skb;
562 skb->prev = s->prev;
563 skb->next = s;
564 s->prev = skb;
565 }
566
567 static inline void
568 skb_queue_tail(struct sk_buff_head *q, struct sk_buff *skb)
569 {
570 SKB_TRACE2(q, skb);
571 return (__skb_queue_tail(q, skb));
572 }
573
574 static inline struct sk_buff *
575 skb_peek(struct sk_buff_head *q)
576 {
577 struct sk_buff *skb;
578
579 skb = q->next;
580 SKB_TRACE2(q, skb);
581 if (skb == (struct sk_buff *)q)
582 return (NULL);
583 return (skb);
584 }
585
586 static inline struct sk_buff *
587 skb_peek_tail(struct sk_buff_head *q)
588 {
589 struct sk_buff *skb;
590
591 skb = q->prev;
592 SKB_TRACE2(q, skb);
593 if (skb == (struct sk_buff *)q)
594 return (NULL);
595 return (skb);
596 }
597
598 static inline void
599 __skb_unlink(struct sk_buff *skb, struct sk_buff_head *head)
600 {
601 SKB_TRACE2(skb, head);
602 struct sk_buff *p, *n;;
603
604 head->qlen--;
605 p = skb->prev;
606 n = skb->next;
607 p->next = n;
608 n->prev = p;
609 skb->prev = skb->next = NULL;
610 }
611
612 static inline void
613 skb_unlink(struct sk_buff *skb, struct sk_buff_head *head)
614 {
615 SKB_TRACE2(skb, head);
616 return (__skb_unlink(skb, head));
617 }
618
619 static inline struct sk_buff *
620 __skb_dequeue(struct sk_buff_head *q)
621 {
622 struct sk_buff *skb;
623
624 SKB_TRACE(q);
625 skb = q->next;
626 if (skb == (struct sk_buff *)q)
627 return (NULL);
628 if (skb != NULL)
629 __skb_unlink(skb, q);
630 SKB_TRACE(skb);
631 return (skb);
632 }
633
634 static inline struct sk_buff *
635 skb_dequeue(struct sk_buff_head *q)
636 {
637 SKB_TRACE(q);
638 return (__skb_dequeue(q));
639 }
640
641 static inline struct sk_buff *
642 skb_dequeue_tail(struct sk_buff_head *q)
643 {
644 struct sk_buff *skb;
645
646 skb = skb_peek_tail(q);
647 if (skb != NULL)
648 __skb_unlink(skb, q);
649
650 SKB_TRACE2(q, skb);
651 return (skb);
652 }
653
654 static inline void
655 __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
656 {
657
658 SKB_TRACE2(q, skb);
659 __skb_queue_after(q, (struct sk_buff *)q, skb);
660 }
661
662 static inline void
663 skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb)
664 {
665
666 SKB_TRACE2(q, skb);
667 __skb_queue_after(q, (struct sk_buff *)q, skb);
668 }
669
670 static inline uint32_t
671 skb_queue_len(struct sk_buff_head *head)
672 {
673
674 SKB_TRACE(head);
675 return (head->qlen);
676 }
677
678 static inline uint32_t
679 skb_queue_len_lockless(const struct sk_buff_head *head)
680 {
681
682 SKB_TRACE(head);
683 return (READ_ONCE(head->qlen));
684 }
685
686 static inline void
687 __skb_queue_purge(struct sk_buff_head *q)
688 {
689 struct sk_buff *skb;
690
691 SKB_TRACE(q);
692 while ((skb = __skb_dequeue(q)) != NULL)
693 kfree_skb(skb);
694 }
695
696 static inline void
697 skb_queue_purge(struct sk_buff_head *q)
698 {
699 SKB_TRACE(q);
700 return (__skb_queue_purge(q));
701 }
702
703 static inline struct sk_buff *
704 skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
705 {
706
707 SKB_TRACE2(q, skb);
708 /* XXX what is the q argument good for? */
709 return (skb->prev);
710 }
711
712 /* -------------------------------------------------------------------------- */
713
714 static inline struct sk_buff *
715 skb_copy(struct sk_buff *skb, gfp_t gfp)
716 {
717 struct sk_buff *new;
718
719 new = linuxkpi_skb_copy(skb, gfp);
720 SKB_TRACE2(skb, new);
721 return (new);
722 }
723
724 static inline void
725 consume_skb(struct sk_buff *skb)
726 {
727 SKB_TRACE(skb);
728 SKB_TODO();
729 }
730
731 static inline uint16_t
732 skb_checksum(struct sk_buff *skb, int offs, size_t len, int x)
733 {
734 SKB_TRACE(skb);
735 SKB_TODO();
736 return (0xffff);
737 }
738
739 static inline int
740 skb_checksum_start_offset(struct sk_buff *skb)
741 {
742 SKB_TRACE(skb);
743 SKB_TODO();
744 return (-1);
745 }
746
747 static inline dma_addr_t
748 skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x,
749 size_t fragsz, enum dma_data_direction dir)
750 {
751 SKB_TRACE2(frag, dev);
752 SKB_TODO();
753 return (-1);
754 }
755
756 static inline size_t
757 skb_frag_size(const skb_frag_t *frag)
758 {
759 SKB_TRACE(frag);
760 SKB_TODO();
761 return (-1);
762 }
763
764 #define skb_walk_frags(_skb, _frag) \
765 for ((_frag) = (_skb); false; (_frag)++)
766
767 static inline void
768 skb_checksum_help(struct sk_buff *skb)
769 {
770 SKB_TRACE(skb);
771 SKB_TODO();
772 }
773
774 static inline bool
775 skb_ensure_writable(struct sk_buff *skb, size_t off)
776 {
777 SKB_TRACE(skb);
778 SKB_TODO();
779 return (false);
780 }
781
782 static inline void *
783 skb_frag_address(const skb_frag_t *frag)
784 {
785 SKB_TRACE(frag);
786 SKB_TODO();
787 return (NULL);
788 }
789
790 static inline void
791 skb_free_frag(void *frag)
792 {
793
794 page_frag_free(frag);
795 }
796
797 static inline struct sk_buff *
798 skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags)
799 {
800 SKB_TRACE(skb);
801 SKB_TODO();
802 return (NULL);
803 }
804
805 static inline bool
806 skb_is_gso(struct sk_buff *skb)
807 {
808 SKB_TRACE(skb);
809 SKB_IMPROVE("Really a TODO but get it away from logging");
810 return (false);
811 }
812
813 static inline void
814 skb_mark_not_on_list(struct sk_buff *skb)
815 {
816 SKB_TRACE(skb);
817 SKB_TODO();
818 }
819
820 static inline void
821 skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to)
822 {
823 struct sk_buff *b, *e, *n;
824
825 SKB_TRACE2(from, to);
826
827 if (skb_queue_empty(from))
828 return;
829
830 /* XXX do we need a barrier around this? */
831 b = from->next;
832 e = from->prev;
833 n = to->next;
834
835 b->prev = (struct sk_buff *)to;
836 to->next = b;
837 e->next = n;
838 n->prev = e;
839
840 to->qlen += from->qlen;
841 __skb_queue_head_init(from);
842 }
843
844 static inline void
845 skb_reset_transport_header(struct sk_buff *skb)
846 {
847
848 SKB_TRACE(skb);
849 skb->l4hdroff = skb->data - skb->head;
850 }
851
852 static inline uint8_t *
853 skb_transport_header(struct sk_buff *skb)
854 {
855
856 SKB_TRACE(skb);
857 return (skb->head + skb->l4hdroff);
858 }
859
860 static inline uint8_t *
861 skb_network_header(struct sk_buff *skb)
862 {
863
864 SKB_TRACE(skb);
865 return (skb->head + skb->l3hdroff);
866 }
867
868 static inline bool
869 skb_is_nonlinear(struct sk_buff *skb)
870 {
871 SKB_TRACE(skb);
872 return ((skb->data_len > 0) ? true : false);
873 }
874
875 static inline int
876 __skb_linearize(struct sk_buff *skb)
877 {
878 SKB_TRACE(skb);
879 SKB_TODO();
880 return (ENXIO);
881 }
882
883 static inline int
884 skb_linearize(struct sk_buff *skb)
885 {
886
887 return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0);
888 }
889
890 static inline int
891 pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp)
892 {
893 SKB_TRACE(skb);
894 SKB_TODO();
895 return (-ENXIO);
896 }
897
898 /* Not really seen this one but need it as symmetric accessor function. */
899 static inline void
900 skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap)
901 {
902
903 SKB_TRACE_FMT(skb, "qmap %u", qmap);
904 skb->qmap = qmap;
905 }
906
907 static inline uint16_t
908 skb_get_queue_mapping(struct sk_buff *skb)
909 {
910
911 SKB_TRACE_FMT(skb, "qmap %u", skb->qmap);
912 return (skb->qmap);
913 }
914
915 static inline bool
916 skb_header_cloned(struct sk_buff *skb)
917 {
918 SKB_TRACE(skb);
919 SKB_TODO();
920 return (false);
921 }
922
923 static inline uint8_t *
924 skb_mac_header(struct sk_buff *skb)
925 {
926 SKB_TRACE(skb);
927 SKB_TODO();
928 return (NULL);
929 }
930
931 static inline void
932 skb_orphan(struct sk_buff *skb)
933 {
934 SKB_TRACE(skb);
935 SKB_TODO();
936 }
937
938 static inline void
939 skb_reset_mac_header(struct sk_buff *skb)
940 {
941 SKB_TRACE(skb);
942 SKB_TODO();
943 }
944
945 static inline __sum16
946 csum_unfold(__sum16 sum)
947 {
948 SKB_TODO();
949 return (sum);
950 }
951
952 static __inline void
953 skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len)
954 {
955 SKB_TODO();
956 }
957
958 static inline void
959 skb_reset_tail_pointer(struct sk_buff *skb)
960 {
961
962 SKB_TRACE(skb);
963 #ifdef SKB_DOING_OFFSETS_US_NOT
964 skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head);
965 #endif
966 skb->tail = skb->data;
967 SKB_TRACE(skb);
968 }
969
970 static inline struct sk_buff *
971 skb_get(struct sk_buff *skb)
972 {
973
974 SKB_TODO(); /* XXX refcnt? as in get/put_device? */
975 return (skb);
976 }
977
978 static inline struct sk_buff *
979 skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
980 {
981
982 SKB_TODO();
983 return (NULL);
984 }
985
986 static inline void
987 skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len)
988 {
989
990 SKB_TRACE(skb);
991 /* Let us just hope the destination has len space ... */
992 memcpy(dst, skb->data, len);
993 }
994
995 static inline int
996 skb_pad(struct sk_buff *skb, int pad)
997 {
998
999 SKB_TRACE(skb);
1000 SKB_TODO();
1001 return (-1);
1002 }
1003
1004 static inline void
1005 skb_list_del_init(struct sk_buff *skb)
1006 {
1007
1008 SKB_TRACE(skb);
1009 SKB_TODO();
1010 }
1011
1012 static inline void
1013 napi_consume_skb(struct sk_buff *skb, int budget)
1014 {
1015
1016 SKB_TRACE(skb);
1017 SKB_TODO();
1018 }
1019
1020 #define SKB_WITH_OVERHEAD(_s) \
1021 (_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
1022
1023 #endif /* _LINUXKPI_LINUX_SKBUFF_H */
Cache object: 43399b3ee5140497992f1d6066ec6035
|