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 * 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 * 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 * 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 250 kfree_skb(struct sk_buff *skb) 251 { 252 SKB_TRACE(skb); 253 linuxkpi_kfree_skb(skb); 254 } 255 256 static inline void 257 consume_skb(struct sk_buff *skb) 258 { 259 SKB_TRACE(skb); 260 kfree_skb(skb); 261 } 262 263 static inline void 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 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 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 * 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 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 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 * 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 * 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 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 * 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 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 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 * 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 * 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 * 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 * 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 * 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 * 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 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 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 * 502 skb_shinfo(struct sk_buff *skb) 503 { 504 505 SKB_TRACE(skb); 506 return (skb->shinfo); 507 } 508 509 static inline void 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 * 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 907 skb_checksum_help(struct sk_buff *skb) 908 { 909 SKB_TRACE(skb); 910 SKB_TODO(); 911 } 912 913 static inline bool 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 * 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 929 skb_free_frag(void *frag) 930 { 931 932 page_frag_free(frag); 933 } 934 935 static inline struct sk_buff * 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 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 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 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 * 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 * 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 983 __skb_linearize(struct sk_buff *skb) 984 { 985 return (lkpi___skb_linearize(skb)); 986 } 987 988 static inline int 989 skb_linearize(struct sk_buff *skb) 990 { 991 return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0); 992 } 993 994 static inline int 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 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 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 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 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 * 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 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 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 * 1057 skb_hwtstamps(struct sk_buff *skb) 1058 { 1059 SKB_TRACE(skb); 1060 SKB_TODO(); 1061 return (NULL); 1062 } 1063 1064 static inline void 1065 skb_orphan(struct sk_buff *skb) 1066 { 1067 SKB_TRACE(skb); 1068 SKB_TODO(); 1069 } 1070 1071 static inline __wsum 1072 csum_unfold(__sum16 sum) 1073 { 1074 return (sum); 1075 } 1076 1077 static __inline void 1078 skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len) 1079 { 1080 SKB_TODO(); 1081 } 1082 1083 static inline void 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 * 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 * 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 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 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 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 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 * 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 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 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 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