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