1 /*- 2 * Copyright (c) 2020-2025 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) \ 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 uint16_t l3hdroff; /* network header offset from *head */ 186 uint16_t l4hdroff; /* transport header offset from *head */ 187 uint16_t mac_header; /* offset of mac_header */ 188 uint16_t mac_len; /* Link-layer header length. */ 189 enum sk_buff_pkt_type pkt_type; 190 refcount_t refcnt; 191 192 struct net_device *dev; 193 void *sk; /* XXX net/sock.h? */ 194 195 /* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */ 196 void *m; 197 void(*m_free_func)(void *); 198 199 /* Force padding to CACHE_LINE_SIZE. */ 200 uint8_t __scratch[0] __aligned(CACHE_LINE_SIZE); 201 }; 202 203 /* -------------------------------------------------------------------------- */ 204 205 struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t); 206 struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t); 207 struct sk_buff *linuxkpi_build_skb(void *, size_t); 208 void linuxkpi_kfree_skb(struct sk_buff *); 209 210 struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t); 211 212 /* -------------------------------------------------------------------------- */ 213 214 static inline struct sk_buff * 215 alloc_skb(size_t size, gfp_t gfp) 216 { 217 struct sk_buff *skb; 218 219 skb = linuxkpi_alloc_skb(size, gfp); 220 SKB_TRACE(skb); 221 return (skb); 222 } 223 224 static inline struct sk_buff * 225 __dev_alloc_skb(size_t len, gfp_t gfp) 226 { 227 struct sk_buff *skb; 228 229 skb = linuxkpi_dev_alloc_skb(len, gfp); 230 SKB_IMPROVE(); 231 SKB_TRACE(skb); 232 return (skb); 233 } 234 235 static inline struct sk_buff * 236 dev_alloc_skb(size_t len) 237 { 238 struct sk_buff *skb; 239 240 skb = __dev_alloc_skb(len, GFP_NOWAIT); 241 SKB_IMPROVE(); 242 SKB_TRACE(skb); 243 return (skb); 244 } 245 246 static inline void 247 kfree_skb(struct sk_buff *skb) 248 { 249 SKB_TRACE(skb); 250 linuxkpi_kfree_skb(skb); 251 } 252 253 static inline void 254 consume_skb(struct sk_buff *skb) 255 { 256 SKB_TRACE(skb); 257 kfree_skb(skb); 258 } 259 260 static inline void 261 dev_kfree_skb(struct sk_buff *skb) 262 { 263 SKB_TRACE(skb); 264 kfree_skb(skb); 265 } 266 267 static inline void 268 dev_kfree_skb_any(struct sk_buff *skb) 269 { 270 SKB_TRACE(skb); 271 dev_kfree_skb(skb); 272 } 273 274 static inline void 275 dev_kfree_skb_irq(struct sk_buff *skb) 276 { 277 SKB_TRACE(skb); 278 SKB_IMPROVE("Do we have to defer this?"); 279 dev_kfree_skb(skb); 280 } 281 282 static inline struct sk_buff * 283 build_skb(void *data, unsigned int fragsz) 284 { 285 struct sk_buff *skb; 286 287 skb = linuxkpi_build_skb(data, fragsz); 288 SKB_TRACE(skb); 289 return (skb); 290 } 291 292 /* -------------------------------------------------------------------------- */ 293 294 static inline bool 295 skb_is_nonlinear(struct sk_buff *skb) 296 { 297 SKB_TRACE(skb); 298 return ((skb->data_len > 0) ? true : false); 299 } 300 301 /* Add headroom; cannot do once there is data in there. */ 302 static inline void 303 skb_reserve(struct sk_buff *skb, size_t len) 304 { 305 SKB_TRACE(skb); 306 #if 0 307 /* Apparently it is allowed to call skb_reserve multiple times in a row. */ 308 KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p " 309 "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail)); 310 #else 311 KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not " 312 "empty head %p data %p tail %p len %u\n", __func__, skb, 313 skb->head, skb->data, skb->tail, skb->len)); 314 #endif 315 skb->data += len; 316 skb->tail += len; 317 } 318 319 /* 320 * Remove headroom; return new data pointer; basically make space at the 321 * front to copy data in (manually). 322 */ 323 static inline void * 324 __skb_push(struct sk_buff *skb, size_t len) 325 { 326 SKB_TRACE(skb); 327 KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - " 328 "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data)); 329 skb->len += len; 330 skb->data -= len; 331 return (skb->data); 332 } 333 334 static inline void * 335 skb_push(struct sk_buff *skb, size_t len) 336 { 337 338 SKB_TRACE(skb); 339 return (__skb_push(skb, len)); 340 } 341 342 /* 343 * Length of the data on the skb (without any frags)??? 344 */ 345 static inline size_t 346 skb_headlen(struct sk_buff *skb) 347 { 348 349 SKB_TRACE(skb); 350 return (skb->len - skb->data_len); 351 } 352 353 354 /* Return the end of data (tail pointer). */ 355 static inline uint8_t * 356 skb_tail_pointer(struct sk_buff *skb) 357 { 358 359 SKB_TRACE(skb); 360 return (skb->tail); 361 } 362 363 /* Return number of bytes available at end of buffer. */ 364 static inline unsigned int 365 skb_tailroom(struct sk_buff *skb) 366 { 367 368 SKB_TRACE(skb); 369 KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, " 370 "end %p tail %p\n", __func__, skb, skb->end, skb->tail)); 371 if (unlikely(skb_is_nonlinear(skb))) 372 return (0); 373 return (skb->end - skb->tail); 374 } 375 376 /* Return number of bytes available at the beginning of buffer. */ 377 static inline unsigned int 378 skb_headroom(const struct sk_buff *skb) 379 { 380 SKB_TRACE(skb); 381 KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, " 382 "data %p head %p\n", __func__, skb, skb->data, skb->head)); 383 return (skb->data - skb->head); 384 } 385 386 387 /* 388 * Remove tailroom; return the old tail pointer; basically make space at 389 * the end to copy data in (manually). See also skb_put_data() below. 390 */ 391 static inline void * 392 __skb_put(struct sk_buff *skb, size_t len) 393 { 394 void *s; 395 396 SKB_TRACE(skb); 397 KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + " 398 "len %zu) > end %p, head %p data %p len %u\n", __func__, 399 skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len)); 400 401 s = skb_tail_pointer(skb); 402 if (len == 0) 403 return (s); 404 skb->tail += len; 405 skb->len += len; 406 #ifdef SKB_DEBUG 407 if (linuxkpi_debug_skb & DSKB_TRACEX) 408 printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n", 409 __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end, 410 s, len); 411 #endif 412 return (s); 413 } 414 415 static inline void * 416 skb_put(struct sk_buff *skb, size_t len) 417 { 418 419 SKB_TRACE(skb); 420 return (__skb_put(skb, len)); 421 } 422 423 /* skb_put() + copying data in. */ 424 static inline void * 425 skb_put_data(struct sk_buff *skb, const void *buf, size_t len) 426 { 427 void *s; 428 429 SKB_TRACE2(skb, buf); 430 s = skb_put(skb, len); 431 if (len == 0) 432 return (s); 433 memcpy(s, buf, len); 434 return (s); 435 } 436 437 /* skb_put() + filling with zeros. */ 438 static inline void * 439 skb_put_zero(struct sk_buff *skb, size_t len) 440 { 441 void *s; 442 443 SKB_TRACE(skb); 444 s = skb_put(skb, len); 445 memset(s, '\0', len); 446 return (s); 447 } 448 449 /* 450 * Remove len bytes from beginning of data. 451 * 452 * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic; 453 * we return the advanced data pointer so we don't have to keep a temp, correct? 454 */ 455 static inline void * 456 skb_pull(struct sk_buff *skb, size_t len) 457 { 458 459 SKB_TRACE(skb); 460 #if 0 /* Apparently this doesn't barf... */ 461 KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n", 462 __func__, skb, skb->len, len, skb->data)); 463 #endif 464 if (skb->len < len) 465 return (NULL); 466 skb->len -= len; 467 skb->data += len; 468 return (skb->data); 469 } 470 471 /* Reduce skb data to given length or do nothing if smaller already. */ 472 static inline void 473 __skb_trim(struct sk_buff *skb, unsigned int len) 474 { 475 476 SKB_TRACE(skb); 477 if (skb->len < len) 478 return; 479 480 skb->len = len; 481 skb->tail = skb->data + skb->len; 482 } 483 484 static inline void 485 skb_trim(struct sk_buff *skb, unsigned int len) 486 { 487 488 return (__skb_trim(skb, len)); 489 } 490 491 static inline struct skb_shared_info * 492 skb_shinfo(struct sk_buff *skb) 493 { 494 495 SKB_TRACE(skb); 496 return (skb->shinfo); 497 } 498 499 static inline void 500 skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page, 501 off_t offset, size_t size, unsigned int truesize) 502 { 503 struct skb_shared_info *shinfo; 504 505 SKB_TRACE(skb); 506 #ifdef SKB_DEBUG 507 if (linuxkpi_debug_skb & DSKB_TRACEX) 508 printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d " 509 "page %#jx offset %ju size %zu truesize %u\n", __func__, 510 skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno, 511 (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset, 512 size, truesize); 513 #endif 514 515 shinfo = skb_shinfo(skb); 516 KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p " 517 "fragno %d too big\n", __func__, skb, fragno)); 518 shinfo->frags[fragno].page = page; 519 shinfo->frags[fragno].offset = offset; 520 shinfo->frags[fragno].size = size; 521 shinfo->nr_frags = fragno + 1; 522 skb->len += size; 523 skb->data_len += size; 524 skb->truesize += truesize; 525 } 526 527 /* -------------------------------------------------------------------------- */ 528 529 #define skb_queue_walk(_q, skb) \ 530 for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q); \ 531 (skb) = (skb)->next) 532 533 #define skb_queue_walk_safe(_q, skb, tmp) \ 534 for ((skb) = (_q)->next, (tmp) = (skb)->next; \ 535 (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next) 536 537 #define skb_list_walk_safe(_q, skb, tmp) \ 538 for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \ 539 ((skb) != NULL); \ 540 (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL) 541 542 static inline bool 543 skb_queue_empty(const struct sk_buff_head *q) 544 { 545 SKB_TRACE(q); 546 return (q->next == (const struct sk_buff *)q); 547 } 548 549 static inline bool 550 skb_queue_empty_lockless(const struct sk_buff_head *q) 551 { 552 SKB_TRACE(q); 553 return (READ_ONCE(q->next) == (const struct sk_buff *)q); 554 } 555 556 static inline void 557 __skb_queue_head_init(struct sk_buff_head *q) 558 { 559 SKB_TRACE(q); 560 q->prev = q->next = (struct sk_buff *)q; 561 q->qlen = 0; 562 } 563 564 static inline void 565 skb_queue_head_init(struct sk_buff_head *q) 566 { 567 SKB_TRACE(q); 568 __skb_queue_head_init(q); 569 spin_lock_init(&q->lock); 570 } 571 572 static inline void 573 __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next, 574 struct sk_buff_head *q) 575 { 576 577 SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q); 578 WRITE_ONCE(new->prev, prev); 579 WRITE_ONCE(new->next, next); 580 WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new); 581 WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new); 582 WRITE_ONCE(q->qlen, q->qlen + 1); 583 } 584 585 static inline void 586 __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb, 587 struct sk_buff *new) 588 { 589 590 SKB_TRACE_FMT(q, "skb %p new %p", skb, new); 591 __skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q); 592 } 593 594 static inline void 595 __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb, 596 struct sk_buff *new) 597 { 598 599 SKB_TRACE_FMT(q, "skb %p new %p", skb, new); 600 __skb_insert(new, skb->prev, skb, q); 601 } 602 603 static inline void 604 __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) 605 { 606 607 SKB_TRACE2(q, new); 608 __skb_queue_before(q, (struct sk_buff *)q, new); 609 } 610 611 static inline void 612 skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) 613 { 614 unsigned long flags; 615 616 SKB_TRACE2(q, new); 617 spin_lock_irqsave(&q->lock, flags); 618 __skb_queue_tail(q, new); 619 spin_unlock_irqrestore(&q->lock, flags); 620 } 621 622 static inline struct sk_buff * 623 skb_peek(const struct sk_buff_head *q) 624 { 625 struct sk_buff *skb; 626 627 skb = q->next; 628 SKB_TRACE2(q, skb); 629 if (skb == (const struct sk_buff *)q) 630 return (NULL); 631 return (skb); 632 } 633 634 static inline struct sk_buff * 635 skb_peek_tail(const struct sk_buff_head *q) 636 { 637 struct sk_buff *skb; 638 639 skb = READ_ONCE(q->prev); 640 SKB_TRACE2(q, skb); 641 if (skb == (const struct sk_buff *)q) 642 return (NULL); 643 return (skb); 644 } 645 646 static inline void 647 __skb_unlink(struct sk_buff *skb, struct sk_buff_head *q) 648 { 649 struct sk_buff *p, *n; 650 651 SKB_TRACE2(skb, q); 652 653 WRITE_ONCE(q->qlen, q->qlen - 1); 654 p = skb->prev; 655 n = skb->next; 656 WRITE_ONCE(n->prev, p); 657 WRITE_ONCE(p->next, n); 658 skb->prev = skb->next = NULL; 659 } 660 661 static inline void 662 skb_unlink(struct sk_buff *skb, struct sk_buff_head *q) 663 { 664 unsigned long flags; 665 666 SKB_TRACE2(skb, q); 667 spin_lock_irqsave(&q->lock, flags); 668 __skb_unlink(skb, q); 669 spin_unlock_irqrestore(&q->lock, flags); 670 } 671 672 static inline struct sk_buff * 673 __skb_dequeue(struct sk_buff_head *q) 674 { 675 struct sk_buff *skb; 676 677 skb = skb_peek(q); 678 if (skb != NULL) 679 __skb_unlink(skb, q); 680 SKB_TRACE2(q, skb); 681 return (skb); 682 } 683 684 static inline struct sk_buff * 685 skb_dequeue(struct sk_buff_head *q) 686 { 687 unsigned long flags; 688 struct sk_buff *skb; 689 690 spin_lock_irqsave(&q->lock, flags); 691 skb = __skb_dequeue(q); 692 spin_unlock_irqrestore(&q->lock, flags); 693 SKB_TRACE2(q, skb); 694 return (skb); 695 } 696 697 static inline struct sk_buff * 698 __skb_dequeue_tail(struct sk_buff_head *q) 699 { 700 struct sk_buff *skb; 701 702 skb = skb_peek_tail(q); 703 if (skb != NULL) 704 __skb_unlink(skb, q); 705 SKB_TRACE2(q, skb); 706 return (skb); 707 } 708 709 static inline struct sk_buff * 710 skb_dequeue_tail(struct sk_buff_head *q) 711 { 712 unsigned long flags; 713 struct sk_buff *skb; 714 715 spin_lock_irqsave(&q->lock, flags); 716 skb = __skb_dequeue_tail(q); 717 spin_unlock_irqrestore(&q->lock, flags); 718 SKB_TRACE2(q, skb); 719 return (skb); 720 } 721 722 static inline void 723 __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb) 724 { 725 726 SKB_TRACE2(q, skb); 727 __skb_queue_after(q, (struct sk_buff *)q, skb); 728 } 729 730 static inline void 731 skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb) 732 { 733 unsigned long flags; 734 735 SKB_TRACE2(q, skb); 736 spin_lock_irqsave(&q->lock, flags); 737 __skb_queue_head(q, skb); 738 spin_unlock_irqrestore(&q->lock, flags); 739 } 740 741 static inline uint32_t 742 skb_queue_len(const struct sk_buff_head *q) 743 { 744 745 SKB_TRACE(q); 746 return (q->qlen); 747 } 748 749 static inline uint32_t 750 skb_queue_len_lockless(const struct sk_buff_head *q) 751 { 752 753 SKB_TRACE(q); 754 return (READ_ONCE(q->qlen)); 755 } 756 757 static inline void 758 ___skb_queue_splice(const struct sk_buff_head *from, 759 struct sk_buff *p, struct sk_buff *n) 760 { 761 struct sk_buff *b, *e; 762 763 b = from->next; 764 e = from->prev; 765 766 WRITE_ONCE(b->prev, p); 767 WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b); 768 WRITE_ONCE(e->next, n); 769 WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e); 770 } 771 772 static inline void 773 skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) 774 { 775 776 SKB_TRACE2(from, to); 777 778 if (skb_queue_empty(from)) 779 return; 780 781 ___skb_queue_splice(from, (struct sk_buff *)to, to->next); 782 to->qlen += from->qlen; 783 __skb_queue_head_init(from); 784 } 785 786 static inline void 787 skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to) 788 { 789 790 SKB_TRACE2(from, to); 791 792 if (skb_queue_empty(from)) 793 return; 794 795 ___skb_queue_splice(from, to->prev, (struct sk_buff *)to); 796 to->qlen += from->qlen; 797 __skb_queue_head_init(from); 798 } 799 800 801 static inline void 802 __skb_queue_purge(struct sk_buff_head *q) 803 { 804 struct sk_buff *skb; 805 806 SKB_TRACE(q); 807 while ((skb = __skb_dequeue(q)) != NULL) 808 kfree_skb(skb); 809 WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u", 810 __func__, q, skb_queue_len(q)); 811 } 812 813 static inline void 814 skb_queue_purge(struct sk_buff_head *q) 815 { 816 struct sk_buff_head _q; 817 unsigned long flags; 818 819 SKB_TRACE(q); 820 821 if (skb_queue_empty_lockless(q)) 822 return; 823 824 __skb_queue_head_init(&_q); 825 spin_lock_irqsave(&q->lock, flags); 826 skb_queue_splice_init(q, &_q); 827 spin_unlock_irqrestore(&q->lock, flags); 828 __skb_queue_purge(&_q); 829 } 830 831 static inline struct sk_buff * 832 skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb) 833 { 834 835 SKB_TRACE2(q, skb); 836 /* XXX what is the q argument good for? */ 837 return (skb->prev); 838 } 839 840 /* -------------------------------------------------------------------------- */ 841 842 static inline struct sk_buff * 843 skb_copy(const struct sk_buff *skb, gfp_t gfp) 844 { 845 struct sk_buff *new; 846 847 new = linuxkpi_skb_copy(skb, gfp); 848 SKB_TRACE2(skb, new); 849 return (new); 850 } 851 852 static inline uint16_t 853 skb_checksum(struct sk_buff *skb, int offs, size_t len, int x) 854 { 855 SKB_TRACE(skb); 856 SKB_TODO(); 857 return (0xffff); 858 } 859 860 static inline int 861 skb_checksum_start_offset(struct sk_buff *skb) 862 { 863 SKB_TRACE(skb); 864 SKB_TODO(); 865 return (-1); 866 } 867 868 static inline dma_addr_t 869 skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x, 870 size_t fragsz, enum dma_data_direction dir) 871 { 872 SKB_TRACE2(frag, dev); 873 SKB_TODO(); 874 return (-1); 875 } 876 877 static inline size_t 878 skb_frag_size(const skb_frag_t *frag) 879 { 880 SKB_TRACE(frag); 881 return (frag->size); 882 } 883 884 #define skb_walk_frags(_skb, _frag) \ 885 for ((_frag) = (_skb); false; (_frag)++) 886 887 static inline void 888 skb_checksum_help(struct sk_buff *skb) 889 { 890 SKB_TRACE(skb); 891 SKB_TODO(); 892 } 893 894 static inline bool 895 skb_ensure_writable(struct sk_buff *skb, size_t off) 896 { 897 SKB_TRACE(skb); 898 SKB_TODO(); 899 return (false); 900 } 901 902 static inline void * 903 skb_frag_address(const skb_frag_t *frag) 904 { 905 SKB_TRACE(frag); 906 return (page_address(frag->page + frag->offset)); 907 } 908 909 static inline void 910 skb_free_frag(void *frag) 911 { 912 913 page_frag_free(frag); 914 } 915 916 static inline struct sk_buff * 917 skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags) 918 { 919 SKB_TRACE(skb); 920 SKB_TODO(); 921 return (NULL); 922 } 923 924 static inline bool 925 skb_is_gso(struct sk_buff *skb) 926 { 927 SKB_TRACE(skb); 928 SKB_IMPROVE("Really a TODO but get it away from logging"); 929 return (false); 930 } 931 932 static inline void 933 skb_mark_not_on_list(struct sk_buff *skb) 934 { 935 SKB_TRACE(skb); 936 skb->next = NULL; 937 } 938 939 static inline void 940 skb_reset_transport_header(struct sk_buff *skb) 941 { 942 943 SKB_TRACE(skb); 944 skb->l4hdroff = skb->data - skb->head; 945 } 946 947 static inline uint8_t * 948 skb_transport_header(struct sk_buff *skb) 949 { 950 951 SKB_TRACE(skb); 952 return (skb->head + skb->l4hdroff); 953 } 954 955 static inline uint8_t * 956 skb_network_header(struct sk_buff *skb) 957 { 958 959 SKB_TRACE(skb); 960 return (skb->head + skb->l3hdroff); 961 } 962 963 static inline int 964 __skb_linearize(struct sk_buff *skb) 965 { 966 SKB_TRACE(skb); 967 SKB_TODO(); 968 return (-ENXIO); 969 } 970 971 static inline int 972 skb_linearize(struct sk_buff *skb) 973 { 974 return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0); 975 } 976 977 static inline int 978 pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp) 979 { 980 SKB_TRACE(skb); 981 SKB_TODO(); 982 return (-ENXIO); 983 } 984 985 /* Not really seen this one but need it as symmetric accessor function. */ 986 static inline void 987 skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap) 988 { 989 990 SKB_TRACE_FMT(skb, "qmap %u", qmap); 991 skb->qmap = qmap; 992 } 993 994 static inline uint16_t 995 skb_get_queue_mapping(struct sk_buff *skb) 996 { 997 998 SKB_TRACE_FMT(skb, "qmap %u", skb->qmap); 999 return (skb->qmap); 1000 } 1001 1002 static inline void 1003 skb_copy_header(struct sk_buff *to, const struct sk_buff *from) 1004 { 1005 SKB_TRACE2(to, from); 1006 SKB_TODO(); 1007 } 1008 1009 static inline bool 1010 skb_header_cloned(struct sk_buff *skb) 1011 { 1012 SKB_TRACE(skb); 1013 SKB_TODO(); 1014 return (true); 1015 } 1016 1017 static inline uint8_t * 1018 skb_mac_header(const struct sk_buff *skb) 1019 { 1020 SKB_TRACE(skb); 1021 return (skb->head + skb->mac_header); 1022 } 1023 1024 static inline void 1025 skb_reset_mac_header(struct sk_buff *skb) 1026 { 1027 SKB_TRACE(skb); 1028 skb->mac_header = skb->data - skb->head; 1029 } 1030 1031 static inline void 1032 skb_set_mac_header(struct sk_buff *skb, const size_t len) 1033 { 1034 SKB_TRACE(skb); 1035 skb_reset_mac_header(skb); 1036 skb->mac_header += len; 1037 } 1038 1039 static inline struct skb_shared_hwtstamps * 1040 skb_hwtstamps(struct sk_buff *skb) 1041 { 1042 SKB_TRACE(skb); 1043 SKB_TODO(); 1044 return (NULL); 1045 } 1046 1047 static inline void 1048 skb_orphan(struct sk_buff *skb) 1049 { 1050 SKB_TRACE(skb); 1051 SKB_TODO(); 1052 } 1053 1054 static inline __wsum 1055 csum_unfold(__sum16 sum) 1056 { 1057 return (sum); 1058 } 1059 1060 static __inline void 1061 skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len) 1062 { 1063 SKB_TODO(); 1064 } 1065 1066 static inline void 1067 skb_reset_tail_pointer(struct sk_buff *skb) 1068 { 1069 1070 SKB_TRACE(skb); 1071 #ifdef SKB_DOING_OFFSETS_US_NOT 1072 skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head); 1073 #endif 1074 skb->tail = skb->data; 1075 SKB_TRACE(skb); 1076 } 1077 1078 static inline struct sk_buff * 1079 skb_get(struct sk_buff *skb) 1080 { 1081 1082 SKB_TRACE(skb); 1083 refcount_inc(&skb->refcnt); 1084 return (skb); 1085 } 1086 1087 static inline struct sk_buff * 1088 skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) 1089 { 1090 1091 SKB_TODO(); 1092 return (NULL); 1093 } 1094 1095 static inline void 1096 skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len) 1097 { 1098 1099 SKB_TRACE(skb); 1100 /* Let us just hope the destination has len space ... */ 1101 memcpy(dst, skb->data, len); 1102 } 1103 1104 static inline int 1105 skb_pad(struct sk_buff *skb, int pad) 1106 { 1107 1108 SKB_TRACE(skb); 1109 SKB_TODO(); 1110 return (-1); 1111 } 1112 1113 static inline void 1114 skb_list_del_init(struct sk_buff *skb) 1115 { 1116 1117 SKB_TRACE(skb); 1118 __list_del_entry(&skb->list); 1119 skb_mark_not_on_list(skb); 1120 } 1121 1122 static inline void 1123 napi_consume_skb(struct sk_buff *skb, int budget) 1124 { 1125 1126 SKB_TRACE(skb); 1127 SKB_TODO(); 1128 } 1129 1130 static inline struct sk_buff * 1131 napi_build_skb(void *data, size_t len) 1132 { 1133 1134 SKB_TODO(); 1135 return (NULL); 1136 } 1137 1138 static inline uint32_t 1139 skb_get_hash(struct sk_buff *skb) 1140 { 1141 SKB_TRACE(skb); 1142 SKB_TODO(); 1143 return (0); 1144 } 1145 1146 static inline void 1147 skb_mark_for_recycle(struct sk_buff *skb) 1148 { 1149 SKB_TRACE(skb); 1150 /* page_pool */ 1151 SKB_TODO(); 1152 } 1153 1154 static inline int 1155 skb_cow_head(struct sk_buff *skb, unsigned int headroom) 1156 { 1157 SKB_TRACE(skb); 1158 SKB_TODO(); 1159 return (-1); 1160 } 1161 1162 #define SKB_WITH_OVERHEAD(_s) \ 1163 (_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE) 1164 1165 #endif /* _LINUXKPI_LINUX_SKBUFF_H */ 1166