149ed6e97SBjoern A. Zeeb /*- 22ab4a419SBjoern A. Zeeb * Copyright (c) 2020-2025 The FreeBSD Foundation 3*bc222e96SBjoern A. Zeeb * Copyright (c) 2021-2025 Bjoern A. Zeeb 449ed6e97SBjoern A. Zeeb * 549ed6e97SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from 649ed6e97SBjoern A. Zeeb * the FreeBSD Foundation. 749ed6e97SBjoern A. Zeeb * 849ed6e97SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without 949ed6e97SBjoern A. Zeeb * modification, are permitted provided that the following conditions 1049ed6e97SBjoern A. Zeeb * are met: 1149ed6e97SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright 1249ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer. 1349ed6e97SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright 1449ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the 1549ed6e97SBjoern A. Zeeb * documentation and/or other materials provided with the distribution. 1649ed6e97SBjoern A. Zeeb * 1749ed6e97SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1849ed6e97SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1949ed6e97SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2049ed6e97SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2149ed6e97SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2249ed6e97SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2349ed6e97SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2449ed6e97SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2549ed6e97SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2649ed6e97SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2749ed6e97SBjoern A. Zeeb * SUCH DAMAGE. 2849ed6e97SBjoern A. Zeeb */ 2949ed6e97SBjoern A. Zeeb 3049ed6e97SBjoern A. Zeeb /* 3149ed6e97SBjoern A. Zeeb * NOTE: this socket buffer compatibility code is highly EXPERIMENTAL. 3249ed6e97SBjoern A. Zeeb * Do not rely on the internals of this implementation. They are highly 3349ed6e97SBjoern A. Zeeb * likely to change as we will improve the integration to FreeBSD mbufs. 3449ed6e97SBjoern A. Zeeb */ 3549ed6e97SBjoern A. Zeeb 3649ed6e97SBjoern A. Zeeb #ifndef _LINUXKPI_LINUX_SKBUFF_H 3749ed6e97SBjoern A. Zeeb #define _LINUXKPI_LINUX_SKBUFF_H 3849ed6e97SBjoern A. Zeeb 399df5f29cSBjoern A. Zeeb #include <linux/kernel.h> 4049ed6e97SBjoern A. Zeeb #include <linux/page.h> 4149ed6e97SBjoern A. Zeeb #include <linux/dma-mapping.h> 4249ed6e97SBjoern A. Zeeb #include <linux/netdev_features.h> 4349ed6e97SBjoern A. Zeeb #include <linux/list.h> 4449ed6e97SBjoern A. Zeeb #include <linux/gfp.h> 456baea331SBjoern A. Zeeb #include <linux/compiler.h> 466baea331SBjoern A. Zeeb #include <linux/spinlock.h> 47262c5e81SBjoern A. Zeeb #include <linux/ktime.h> 482ab4a419SBjoern A. Zeeb #include <linux/compiler.h> 4949ed6e97SBjoern A. Zeeb 50*bc222e96SBjoern A. Zeeb /* 51*bc222e96SBjoern A. Zeeb * At least the net/intel-irdma-kmod port pulls this header in; likely through 52*bc222e96SBjoern A. Zeeb * if_ether.h (see PR289268). This means we no longer can rely on 53*bc222e96SBjoern A. Zeeb * IEEE80211_DEBUG (opt_wlan.h) to automatically set SKB_DEBUG. 54*bc222e96SBjoern A. Zeeb */ 5549ed6e97SBjoern A. Zeeb /* #define SKB_DEBUG */ 5659d262feSBjoern A. Zeeb 5749ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG 5849ed6e97SBjoern A. Zeeb #define DSKB_TODO 0x01 596baea331SBjoern A. Zeeb #define DSKB_IMPROVE 0x02 606baea331SBjoern A. Zeeb #define DSKB_TRACE 0x10 616baea331SBjoern A. Zeeb #define DSKB_TRACEX 0x20 626baea331SBjoern A. Zeeb extern int linuxkpi_debug_skb; 6349ed6e97SBjoern A. Zeeb 646baea331SBjoern A. Zeeb #define SKB_TODO() \ 656baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TODO) \ 6649ed6e97SBjoern A. Zeeb printf("SKB_TODO %s:%d\n", __func__, __LINE__) 676baea331SBjoern A. Zeeb #define SKB_IMPROVE(...) \ 686baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_IMPROVE) \ 696baea331SBjoern A. Zeeb printf("SKB_IMPROVE %s:%d\n", __func__, __LINE__) 706baea331SBjoern A. Zeeb #define SKB_TRACE(_s) \ 716baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \ 726baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p\n", __func__, __LINE__, _s) 736baea331SBjoern A. Zeeb #define SKB_TRACE2(_s, _p) \ 746baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \ 756baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p, %p\n", __func__, __LINE__, _s, _p) 766baea331SBjoern A. Zeeb #define SKB_TRACE_FMT(_s, _fmt, ...) \ 776baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACE) \ 786baea331SBjoern A. Zeeb printf("SKB_TRACE %s:%d %p " _fmt "\n", __func__, __LINE__, _s, \ 796baea331SBjoern A. Zeeb __VA_ARGS__) 8049ed6e97SBjoern A. Zeeb #else 816baea331SBjoern A. Zeeb #define SKB_TODO() do { } while(0) 826baea331SBjoern A. Zeeb #define SKB_IMPROVE(...) do { } while(0) 8349ed6e97SBjoern A. Zeeb #define SKB_TRACE(_s) do { } while(0) 8449ed6e97SBjoern A. Zeeb #define SKB_TRACE2(_s, _p) do { } while(0) 8549ed6e97SBjoern A. Zeeb #define SKB_TRACE_FMT(_s, ...) do { } while(0) 8649ed6e97SBjoern A. Zeeb #endif 8749ed6e97SBjoern A. Zeeb 8849ed6e97SBjoern A. Zeeb enum sk_buff_pkt_type { 8949ed6e97SBjoern A. Zeeb PACKET_BROADCAST, 9049ed6e97SBjoern A. Zeeb PACKET_MULTICAST, 9149ed6e97SBjoern A. Zeeb PACKET_OTHERHOST, 9249ed6e97SBjoern A. Zeeb }; 9349ed6e97SBjoern A. Zeeb 94262c5e81SBjoern A. Zeeb struct skb_shared_hwtstamps { 95262c5e81SBjoern A. Zeeb ktime_t hwtstamp; 96262c5e81SBjoern A. Zeeb }; 97262c5e81SBjoern A. Zeeb 989df5f29cSBjoern A. Zeeb #define NET_SKB_PAD max(CACHE_LINE_SIZE, 32) 993d3ec178SBjoern A. Zeeb #define SKB_DATA_ALIGN(_x) roundup2(_x, CACHE_LINE_SIZE) 10049ed6e97SBjoern A. Zeeb 10149ed6e97SBjoern A. Zeeb struct sk_buff_head { 10249ed6e97SBjoern A. Zeeb /* XXX TODO */ 103b2dcb848SBjoern A. Zeeb union { 104b2dcb848SBjoern A. Zeeb struct { 10549ed6e97SBjoern A. Zeeb struct sk_buff *next; 10649ed6e97SBjoern A. Zeeb struct sk_buff *prev; 107b2dcb848SBjoern A. Zeeb }; 108b2dcb848SBjoern A. Zeeb struct sk_buff_head_l { 109b2dcb848SBjoern A. Zeeb struct sk_buff *next; 110b2dcb848SBjoern A. Zeeb struct sk_buff *prev; 111b2dcb848SBjoern A. Zeeb } list; 112b2dcb848SBjoern A. Zeeb }; 11349ed6e97SBjoern A. Zeeb size_t qlen; 1146baea331SBjoern A. Zeeb spinlock_t lock; 11549ed6e97SBjoern A. Zeeb }; 11649ed6e97SBjoern A. Zeeb 11749ed6e97SBjoern A. Zeeb enum sk_checksum_flags { 11849ed6e97SBjoern A. Zeeb CHECKSUM_NONE = 0x00, 11949ed6e97SBjoern A. Zeeb CHECKSUM_UNNECESSARY = 0x01, 12049ed6e97SBjoern A. Zeeb CHECKSUM_PARTIAL = 0x02, 121343f8f71SBjoern A. Zeeb CHECKSUM_COMPLETE = 0x03, 12249ed6e97SBjoern A. Zeeb }; 12349ed6e97SBjoern A. Zeeb 12449ed6e97SBjoern A. Zeeb struct skb_frag { 12549ed6e97SBjoern A. Zeeb /* XXX TODO */ 12649ed6e97SBjoern A. Zeeb struct page *page; /* XXX-BZ These three are a wild guess so far! */ 12749ed6e97SBjoern A. Zeeb off_t offset; 12849ed6e97SBjoern A. Zeeb size_t size; 12949ed6e97SBjoern A. Zeeb }; 13049ed6e97SBjoern A. Zeeb typedef struct skb_frag skb_frag_t; 13149ed6e97SBjoern A. Zeeb 13249ed6e97SBjoern A. Zeeb enum skb_shared_info_gso_type { 13349ed6e97SBjoern A. Zeeb SKB_GSO_TCPV4, 13449ed6e97SBjoern A. Zeeb SKB_GSO_TCPV6, 13549ed6e97SBjoern A. Zeeb }; 13649ed6e97SBjoern A. Zeeb 13749ed6e97SBjoern A. Zeeb struct skb_shared_info { 13849ed6e97SBjoern A. Zeeb enum skb_shared_info_gso_type gso_type; 13949ed6e97SBjoern A. Zeeb uint16_t gso_size; 14049ed6e97SBjoern A. Zeeb uint16_t nr_frags; 1416baea331SBjoern A. Zeeb struct sk_buff *frag_list; 14249ed6e97SBjoern A. Zeeb skb_frag_t frags[64]; /* XXX TODO, 16xpage? */ 14349ed6e97SBjoern A. Zeeb }; 14449ed6e97SBjoern A. Zeeb 14549ed6e97SBjoern A. Zeeb struct sk_buff { 14649ed6e97SBjoern A. Zeeb /* XXX TODO */ 14789c32dafSBjoern A. Zeeb union { 14849ed6e97SBjoern A. Zeeb /* struct sk_buff_head */ 14989c32dafSBjoern A. Zeeb struct { 15049ed6e97SBjoern A. Zeeb struct sk_buff *next; 15149ed6e97SBjoern A. Zeeb struct sk_buff *prev; 15289c32dafSBjoern A. Zeeb }; 15389c32dafSBjoern A. Zeeb struct list_head list; 15489c32dafSBjoern A. Zeeb }; 15549ed6e97SBjoern A. Zeeb 15649ed6e97SBjoern A. Zeeb uint8_t *head; /* Head of buffer. */ 15749ed6e97SBjoern A. Zeeb uint8_t *data; /* Head of data. */ 15849ed6e97SBjoern A. Zeeb uint8_t *tail; /* End of data. */ 15949ed6e97SBjoern A. Zeeb uint8_t *end; /* End of buffer. */ 16049ed6e97SBjoern A. Zeeb 16159481c7dSBjoern A. Zeeb uint32_t len; /* ? */ 16259481c7dSBjoern A. Zeeb uint32_t data_len; /* ? If we have frags? */ 16359481c7dSBjoern A. Zeeb union { 16459481c7dSBjoern A. Zeeb __wsum csum; 16559481c7dSBjoern A. Zeeb struct { 16659481c7dSBjoern A. Zeeb uint16_t csum_offset; 16759481c7dSBjoern A. Zeeb uint16_t csum_start; 16859481c7dSBjoern A. Zeeb }; 16959481c7dSBjoern A. Zeeb }; 17059481c7dSBjoern A. Zeeb uint16_t protocol; 171343f8f71SBjoern A. Zeeb uint8_t ip_summed; /* 2 bit only. */ 17259481c7dSBjoern A. Zeeb /* uint8_t */ 17359481c7dSBjoern A. Zeeb 17459481c7dSBjoern A. Zeeb /* "Scratch" area for layers to store metadata. */ 17559481c7dSBjoern A. Zeeb /* ??? I see sizeof() operations so probably an array. */ 17659481c7dSBjoern A. Zeeb uint8_t cb[64] __aligned(CACHE_LINE_SIZE); 17759481c7dSBjoern A. Zeeb 17859481c7dSBjoern A. Zeeb struct skb_shared_info *shinfo __aligned(CACHE_LINE_SIZE); 17959481c7dSBjoern A. Zeeb 18059481c7dSBjoern A. Zeeb uint32_t truesize; /* The total size of all buffers, incl. frags. */ 18159481c7dSBjoern A. Zeeb uint32_t priority; 18259481c7dSBjoern A. Zeeb uint16_t qmap; /* queue mapping */ 18359481c7dSBjoern A. Zeeb uint16_t _flags; /* Internal flags. */ 18459481c7dSBjoern A. Zeeb #define _SKB_FLAGS_SKBEXTFRAG 0x0001 18559481c7dSBjoern A. Zeeb uint16_t l3hdroff; /* network header offset from *head */ 18659481c7dSBjoern A. Zeeb uint16_t l4hdroff; /* transport header offset from *head */ 18759481c7dSBjoern A. Zeeb uint16_t mac_header; /* offset of mac_header */ 18859481c7dSBjoern A. Zeeb uint16_t mac_len; /* Link-layer header length. */ 18959481c7dSBjoern A. Zeeb enum sk_buff_pkt_type pkt_type; 19059481c7dSBjoern A. Zeeb refcount_t refcnt; 19159481c7dSBjoern A. Zeeb 19259481c7dSBjoern A. Zeeb struct net_device *dev; 19359481c7dSBjoern A. Zeeb void *sk; /* XXX net/sock.h? */ 19449ed6e97SBjoern A. Zeeb 19549ed6e97SBjoern A. Zeeb /* FreeBSD specific bandaid (see linuxkpi_kfree_skb). */ 19649ed6e97SBjoern A. Zeeb void *m; 19749ed6e97SBjoern A. Zeeb void(*m_free_func)(void *); 19849ed6e97SBjoern A. Zeeb 19949ed6e97SBjoern A. Zeeb /* Force padding to CACHE_LINE_SIZE. */ 20049ed6e97SBjoern A. Zeeb uint8_t __scratch[0] __aligned(CACHE_LINE_SIZE); 20149ed6e97SBjoern A. Zeeb }; 20249ed6e97SBjoern A. Zeeb 20349ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */ 20449ed6e97SBjoern A. Zeeb 20549ed6e97SBjoern A. Zeeb struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t); 2069df5f29cSBjoern A. Zeeb struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t); 2075504bd59SBjoern A. Zeeb struct sk_buff *linuxkpi_build_skb(void *, size_t); 20849ed6e97SBjoern A. Zeeb void linuxkpi_kfree_skb(struct sk_buff *); 20949ed6e97SBjoern A. Zeeb 2102ab4a419SBjoern A. Zeeb struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t); 211349b042bSBjoern A. Zeeb 21249ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */ 21349ed6e97SBjoern A. Zeeb 21449ed6e97SBjoern A. Zeeb static inline struct sk_buff * 21549ed6e97SBjoern A. Zeeb alloc_skb(size_t size, gfp_t gfp) 21649ed6e97SBjoern A. Zeeb { 21749ed6e97SBjoern A. Zeeb struct sk_buff *skb; 21849ed6e97SBjoern A. Zeeb 21949ed6e97SBjoern A. Zeeb skb = linuxkpi_alloc_skb(size, gfp); 22049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 22149ed6e97SBjoern A. Zeeb return (skb); 22249ed6e97SBjoern A. Zeeb } 22349ed6e97SBjoern A. Zeeb 22449ed6e97SBjoern A. Zeeb static inline struct sk_buff * 2256baea331SBjoern A. Zeeb __dev_alloc_skb(size_t len, gfp_t gfp) 2266baea331SBjoern A. Zeeb { 2276baea331SBjoern A. Zeeb struct sk_buff *skb; 2286baea331SBjoern A. Zeeb 2299df5f29cSBjoern A. Zeeb skb = linuxkpi_dev_alloc_skb(len, gfp); 2306baea331SBjoern A. Zeeb SKB_IMPROVE(); 2316baea331SBjoern A. Zeeb SKB_TRACE(skb); 2326baea331SBjoern A. Zeeb return (skb); 2336baea331SBjoern A. Zeeb } 2346baea331SBjoern A. Zeeb 2356baea331SBjoern A. Zeeb static inline struct sk_buff * 23649ed6e97SBjoern A. Zeeb dev_alloc_skb(size_t len) 23749ed6e97SBjoern A. Zeeb { 23849ed6e97SBjoern A. Zeeb struct sk_buff *skb; 23949ed6e97SBjoern A. Zeeb 2409df5f29cSBjoern A. Zeeb skb = __dev_alloc_skb(len, GFP_NOWAIT); 2416baea331SBjoern A. Zeeb SKB_IMPROVE(); 24249ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 24349ed6e97SBjoern A. Zeeb return (skb); 24449ed6e97SBjoern A. Zeeb } 24549ed6e97SBjoern A. Zeeb 24649ed6e97SBjoern A. Zeeb static inline void 24749ed6e97SBjoern A. Zeeb kfree_skb(struct sk_buff *skb) 24849ed6e97SBjoern A. Zeeb { 24949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 25049ed6e97SBjoern A. Zeeb linuxkpi_kfree_skb(skb); 25149ed6e97SBjoern A. Zeeb } 25249ed6e97SBjoern A. Zeeb 25349ed6e97SBjoern A. Zeeb static inline void 2542ab4a419SBjoern A. Zeeb consume_skb(struct sk_buff *skb) 2552ab4a419SBjoern A. Zeeb { 2562ab4a419SBjoern A. Zeeb SKB_TRACE(skb); 2572ab4a419SBjoern A. Zeeb kfree_skb(skb); 2582ab4a419SBjoern A. Zeeb } 2592ab4a419SBjoern A. Zeeb 2602ab4a419SBjoern A. Zeeb static inline void 26149ed6e97SBjoern A. Zeeb dev_kfree_skb(struct sk_buff *skb) 26249ed6e97SBjoern A. Zeeb { 26349ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 26449ed6e97SBjoern A. Zeeb kfree_skb(skb); 26549ed6e97SBjoern A. Zeeb } 26649ed6e97SBjoern A. Zeeb 26749ed6e97SBjoern A. Zeeb static inline void 26849ed6e97SBjoern A. Zeeb dev_kfree_skb_any(struct sk_buff *skb) 26949ed6e97SBjoern A. Zeeb { 27049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 27149ed6e97SBjoern A. Zeeb dev_kfree_skb(skb); 27249ed6e97SBjoern A. Zeeb } 27349ed6e97SBjoern A. Zeeb 27449ed6e97SBjoern A. Zeeb static inline void 27549ed6e97SBjoern A. Zeeb dev_kfree_skb_irq(struct sk_buff *skb) 27649ed6e97SBjoern A. Zeeb { 27749ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 278952643eaSBjoern A. Zeeb SKB_IMPROVE("Do we have to defer this?"); 279952643eaSBjoern A. Zeeb dev_kfree_skb(skb); 28049ed6e97SBjoern A. Zeeb } 28149ed6e97SBjoern A. Zeeb 2825504bd59SBjoern A. Zeeb static inline struct sk_buff * 2835504bd59SBjoern A. Zeeb build_skb(void *data, unsigned int fragsz) 2845504bd59SBjoern A. Zeeb { 2855504bd59SBjoern A. Zeeb struct sk_buff *skb; 2865504bd59SBjoern A. Zeeb 2875504bd59SBjoern A. Zeeb skb = linuxkpi_build_skb(data, fragsz); 2885504bd59SBjoern A. Zeeb SKB_TRACE(skb); 2895504bd59SBjoern A. Zeeb return (skb); 2905504bd59SBjoern A. Zeeb } 2915504bd59SBjoern A. Zeeb 29249ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */ 29349ed6e97SBjoern A. Zeeb 2942ab4a419SBjoern A. Zeeb static inline bool 2952ab4a419SBjoern A. Zeeb skb_is_nonlinear(struct sk_buff *skb) 2962ab4a419SBjoern A. Zeeb { 2972ab4a419SBjoern A. Zeeb SKB_TRACE(skb); 2982ab4a419SBjoern A. Zeeb return ((skb->data_len > 0) ? true : false); 2992ab4a419SBjoern A. Zeeb } 30049ed6e97SBjoern A. Zeeb 30149ed6e97SBjoern A. Zeeb /* Add headroom; cannot do once there is data in there. */ 30249ed6e97SBjoern A. Zeeb static inline void 30349ed6e97SBjoern A. Zeeb skb_reserve(struct sk_buff *skb, size_t len) 30449ed6e97SBjoern A. Zeeb { 30549ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 3066baea331SBjoern A. Zeeb #if 0 3076baea331SBjoern A. Zeeb /* Apparently it is allowed to call skb_reserve multiple times in a row. */ 30849ed6e97SBjoern A. Zeeb KASSERT(skb->data == skb->head, ("%s: skb %p not empty head %p data %p " 30949ed6e97SBjoern A. Zeeb "tail %p\n", __func__, skb, skb->head, skb->data, skb->tail)); 3106baea331SBjoern A. Zeeb #else 3116baea331SBjoern A. Zeeb KASSERT(skb->len == 0 && skb->data == skb->tail, ("%s: skb %p not " 3126baea331SBjoern A. Zeeb "empty head %p data %p tail %p len %u\n", __func__, skb, 3136baea331SBjoern A. Zeeb skb->head, skb->data, skb->tail, skb->len)); 3146baea331SBjoern A. Zeeb #endif 31549ed6e97SBjoern A. Zeeb skb->data += len; 31649ed6e97SBjoern A. Zeeb skb->tail += len; 31749ed6e97SBjoern A. Zeeb } 31849ed6e97SBjoern A. Zeeb 31949ed6e97SBjoern A. Zeeb /* 32049ed6e97SBjoern A. Zeeb * Remove headroom; return new data pointer; basically make space at the 32149ed6e97SBjoern A. Zeeb * front to copy data in (manually). 32249ed6e97SBjoern A. Zeeb */ 32349ed6e97SBjoern A. Zeeb static inline void * 32489c32dafSBjoern A. Zeeb __skb_push(struct sk_buff *skb, size_t len) 32549ed6e97SBjoern A. Zeeb { 32649ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 32749ed6e97SBjoern A. Zeeb KASSERT(((skb->data - len) >= skb->head), ("%s: skb %p (data %p - " 32849ed6e97SBjoern A. Zeeb "len %zu) < head %p\n", __func__, skb, skb->data, len, skb->data)); 32949ed6e97SBjoern A. Zeeb skb->len += len; 33049ed6e97SBjoern A. Zeeb skb->data -= len; 33149ed6e97SBjoern A. Zeeb return (skb->data); 33249ed6e97SBjoern A. Zeeb } 33349ed6e97SBjoern A. Zeeb 33489c32dafSBjoern A. Zeeb static inline void * 33589c32dafSBjoern A. Zeeb skb_push(struct sk_buff *skb, size_t len) 33689c32dafSBjoern A. Zeeb { 33789c32dafSBjoern A. Zeeb 33889c32dafSBjoern A. Zeeb SKB_TRACE(skb); 33989c32dafSBjoern A. Zeeb return (__skb_push(skb, len)); 34089c32dafSBjoern A. Zeeb } 34189c32dafSBjoern A. Zeeb 34249ed6e97SBjoern A. Zeeb /* 34349ed6e97SBjoern A. Zeeb * Length of the data on the skb (without any frags)??? 34449ed6e97SBjoern A. Zeeb */ 34549ed6e97SBjoern A. Zeeb static inline size_t 34649ed6e97SBjoern A. Zeeb skb_headlen(struct sk_buff *skb) 34749ed6e97SBjoern A. Zeeb { 34849ed6e97SBjoern A. Zeeb 34949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 35049ed6e97SBjoern A. Zeeb return (skb->len - skb->data_len); 35149ed6e97SBjoern A. Zeeb } 35249ed6e97SBjoern A. Zeeb 35349ed6e97SBjoern A. Zeeb 35449ed6e97SBjoern A. Zeeb /* Return the end of data (tail pointer). */ 35549ed6e97SBjoern A. Zeeb static inline uint8_t * 35649ed6e97SBjoern A. Zeeb skb_tail_pointer(struct sk_buff *skb) 35749ed6e97SBjoern A. Zeeb { 35849ed6e97SBjoern A. Zeeb 35949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 36049ed6e97SBjoern A. Zeeb return (skb->tail); 36149ed6e97SBjoern A. Zeeb } 36249ed6e97SBjoern A. Zeeb 36349ed6e97SBjoern A. Zeeb /* Return number of bytes available at end of buffer. */ 36449ed6e97SBjoern A. Zeeb static inline unsigned int 36549ed6e97SBjoern A. Zeeb skb_tailroom(struct sk_buff *skb) 36649ed6e97SBjoern A. Zeeb { 36749ed6e97SBjoern A. Zeeb 36849ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 36949ed6e97SBjoern A. Zeeb KASSERT((skb->end - skb->tail) >= 0, ("%s: skb %p tailroom < 0, " 37049ed6e97SBjoern A. Zeeb "end %p tail %p\n", __func__, skb, skb->end, skb->tail)); 3712ab4a419SBjoern A. Zeeb if (unlikely(skb_is_nonlinear(skb))) 3722ab4a419SBjoern A. Zeeb return (0); 37349ed6e97SBjoern A. Zeeb return (skb->end - skb->tail); 37449ed6e97SBjoern A. Zeeb } 37549ed6e97SBjoern A. Zeeb 3762ab4a419SBjoern A. Zeeb /* Return number of bytes available at the beginning of buffer. */ 37749ed6e97SBjoern A. Zeeb static inline unsigned int 3782ab4a419SBjoern A. Zeeb skb_headroom(const struct sk_buff *skb) 37949ed6e97SBjoern A. Zeeb { 38049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 38149ed6e97SBjoern A. Zeeb KASSERT((skb->data - skb->head) >= 0, ("%s: skb %p headroom < 0, " 38249ed6e97SBjoern A. Zeeb "data %p head %p\n", __func__, skb, skb->data, skb->head)); 38349ed6e97SBjoern A. Zeeb return (skb->data - skb->head); 38449ed6e97SBjoern A. Zeeb } 38549ed6e97SBjoern A. Zeeb 38649ed6e97SBjoern A. Zeeb 38749ed6e97SBjoern A. Zeeb /* 38849ed6e97SBjoern A. Zeeb * Remove tailroom; return the old tail pointer; basically make space at 38949ed6e97SBjoern A. Zeeb * the end to copy data in (manually). See also skb_put_data() below. 39049ed6e97SBjoern A. Zeeb */ 39149ed6e97SBjoern A. Zeeb static inline void * 39289c32dafSBjoern A. Zeeb __skb_put(struct sk_buff *skb, size_t len) 39349ed6e97SBjoern A. Zeeb { 39449ed6e97SBjoern A. Zeeb void *s; 39549ed6e97SBjoern A. Zeeb 39649ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 39749ed6e97SBjoern A. Zeeb KASSERT(((skb->tail + len) <= skb->end), ("%s: skb %p (tail %p + " 39849ed6e97SBjoern A. Zeeb "len %zu) > end %p, head %p data %p len %u\n", __func__, 39949ed6e97SBjoern A. Zeeb skb, skb->tail, len, skb->end, skb->head, skb->data, skb->len)); 40049ed6e97SBjoern A. Zeeb 40149ed6e97SBjoern A. Zeeb s = skb_tail_pointer(skb); 402952643eaSBjoern A. Zeeb if (len == 0) 403952643eaSBjoern A. Zeeb return (s); 40449ed6e97SBjoern A. Zeeb skb->tail += len; 40549ed6e97SBjoern A. Zeeb skb->len += len; 40649ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG 4076baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACEX) 40849ed6e97SBjoern A. Zeeb printf("%s: skb %p (%u) head %p data %p tail %p end %p, s %p len %zu\n", 40949ed6e97SBjoern A. Zeeb __func__, skb, skb->len, skb->head, skb->data, skb->tail, skb->end, 41049ed6e97SBjoern A. Zeeb s, len); 41149ed6e97SBjoern A. Zeeb #endif 41249ed6e97SBjoern A. Zeeb return (s); 41349ed6e97SBjoern A. Zeeb } 41449ed6e97SBjoern A. Zeeb 41589c32dafSBjoern A. Zeeb static inline void * 41689c32dafSBjoern A. Zeeb skb_put(struct sk_buff *skb, size_t len) 41789c32dafSBjoern A. Zeeb { 41889c32dafSBjoern A. Zeeb 41989c32dafSBjoern A. Zeeb SKB_TRACE(skb); 42089c32dafSBjoern A. Zeeb return (__skb_put(skb, len)); 42189c32dafSBjoern A. Zeeb } 42289c32dafSBjoern A. Zeeb 42349ed6e97SBjoern A. Zeeb /* skb_put() + copying data in. */ 42449ed6e97SBjoern A. Zeeb static inline void * 42549ed6e97SBjoern A. Zeeb skb_put_data(struct sk_buff *skb, const void *buf, size_t len) 42649ed6e97SBjoern A. Zeeb { 42749ed6e97SBjoern A. Zeeb void *s; 42849ed6e97SBjoern A. Zeeb 42949ed6e97SBjoern A. Zeeb SKB_TRACE2(skb, buf); 43049ed6e97SBjoern A. Zeeb s = skb_put(skb, len); 431952643eaSBjoern A. Zeeb if (len == 0) 432952643eaSBjoern A. Zeeb return (s); 43349ed6e97SBjoern A. Zeeb memcpy(s, buf, len); 43449ed6e97SBjoern A. Zeeb return (s); 43549ed6e97SBjoern A. Zeeb } 43649ed6e97SBjoern A. Zeeb 43749ed6e97SBjoern A. Zeeb /* skb_put() + filling with zeros. */ 43849ed6e97SBjoern A. Zeeb static inline void * 43949ed6e97SBjoern A. Zeeb skb_put_zero(struct sk_buff *skb, size_t len) 44049ed6e97SBjoern A. Zeeb { 44149ed6e97SBjoern A. Zeeb void *s; 44249ed6e97SBjoern A. Zeeb 44349ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 44449ed6e97SBjoern A. Zeeb s = skb_put(skb, len); 44549ed6e97SBjoern A. Zeeb memset(s, '\0', len); 44649ed6e97SBjoern A. Zeeb return (s); 44749ed6e97SBjoern A. Zeeb } 44849ed6e97SBjoern A. Zeeb 44949ed6e97SBjoern A. Zeeb /* 45049ed6e97SBjoern A. Zeeb * Remove len bytes from beginning of data. 45149ed6e97SBjoern A. Zeeb * 45249ed6e97SBjoern A. Zeeb * XXX-BZ ath10k checks for !NULL conditions so I assume this doesn't panic; 45349ed6e97SBjoern A. Zeeb * we return the advanced data pointer so we don't have to keep a temp, correct? 45449ed6e97SBjoern A. Zeeb */ 45549ed6e97SBjoern A. Zeeb static inline void * 45649ed6e97SBjoern A. Zeeb skb_pull(struct sk_buff *skb, size_t len) 45749ed6e97SBjoern A. Zeeb { 45849ed6e97SBjoern A. Zeeb 45949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 46049ed6e97SBjoern A. Zeeb #if 0 /* Apparently this doesn't barf... */ 46149ed6e97SBjoern A. Zeeb KASSERT(skb->len >= len, ("%s: skb %p skb->len %u < len %u, data %p\n", 46249ed6e97SBjoern A. Zeeb __func__, skb, skb->len, len, skb->data)); 46349ed6e97SBjoern A. Zeeb #endif 46449ed6e97SBjoern A. Zeeb if (skb->len < len) 46549ed6e97SBjoern A. Zeeb return (NULL); 46649ed6e97SBjoern A. Zeeb skb->len -= len; 46749ed6e97SBjoern A. Zeeb skb->data += len; 46849ed6e97SBjoern A. Zeeb return (skb->data); 46949ed6e97SBjoern A. Zeeb } 47049ed6e97SBjoern A. Zeeb 47149ed6e97SBjoern A. Zeeb /* Reduce skb data to given length or do nothing if smaller already. */ 47249ed6e97SBjoern A. Zeeb static inline void 47349ed6e97SBjoern A. Zeeb __skb_trim(struct sk_buff *skb, unsigned int len) 47449ed6e97SBjoern A. Zeeb { 47549ed6e97SBjoern A. Zeeb 47649ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 47749ed6e97SBjoern A. Zeeb if (skb->len < len) 47849ed6e97SBjoern A. Zeeb return; 47949ed6e97SBjoern A. Zeeb 48049ed6e97SBjoern A. Zeeb skb->len = len; 48149ed6e97SBjoern A. Zeeb skb->tail = skb->data + skb->len; 48249ed6e97SBjoern A. Zeeb } 48349ed6e97SBjoern A. Zeeb 48449ed6e97SBjoern A. Zeeb static inline void 48549ed6e97SBjoern A. Zeeb skb_trim(struct sk_buff *skb, unsigned int len) 48649ed6e97SBjoern A. Zeeb { 48749ed6e97SBjoern A. Zeeb 48849ed6e97SBjoern A. Zeeb return (__skb_trim(skb, len)); 48949ed6e97SBjoern A. Zeeb } 49049ed6e97SBjoern A. Zeeb 49149ed6e97SBjoern A. Zeeb static inline struct skb_shared_info * 49249ed6e97SBjoern A. Zeeb skb_shinfo(struct sk_buff *skb) 49349ed6e97SBjoern A. Zeeb { 49449ed6e97SBjoern A. Zeeb 49549ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 49649ed6e97SBjoern A. Zeeb return (skb->shinfo); 49749ed6e97SBjoern A. Zeeb } 49849ed6e97SBjoern A. Zeeb 49949ed6e97SBjoern A. Zeeb static inline void 50049ed6e97SBjoern A. Zeeb skb_add_rx_frag(struct sk_buff *skb, int fragno, struct page *page, 50149ed6e97SBjoern A. Zeeb off_t offset, size_t size, unsigned int truesize) 50249ed6e97SBjoern A. Zeeb { 50349ed6e97SBjoern A. Zeeb struct skb_shared_info *shinfo; 50449ed6e97SBjoern A. Zeeb 50549ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 50649ed6e97SBjoern A. Zeeb #ifdef SKB_DEBUG 5076baea331SBjoern A. Zeeb if (linuxkpi_debug_skb & DSKB_TRACEX) 50849ed6e97SBjoern A. Zeeb printf("%s: skb %p head %p data %p tail %p end %p len %u fragno %d " 50949ed6e97SBjoern A. Zeeb "page %#jx offset %ju size %zu truesize %u\n", __func__, 51049ed6e97SBjoern A. Zeeb skb, skb->head, skb->data, skb->tail, skb->end, skb->len, fragno, 51149ed6e97SBjoern A. Zeeb (uintmax_t)(uintptr_t)linux_page_address(page), (uintmax_t)offset, 51249ed6e97SBjoern A. Zeeb size, truesize); 51349ed6e97SBjoern A. Zeeb #endif 51449ed6e97SBjoern A. Zeeb 51549ed6e97SBjoern A. Zeeb shinfo = skb_shinfo(skb); 51649ed6e97SBjoern A. Zeeb KASSERT(fragno >= 0 && fragno < nitems(shinfo->frags), ("%s: skb %p " 51749ed6e97SBjoern A. Zeeb "fragno %d too big\n", __func__, skb, fragno)); 51849ed6e97SBjoern A. Zeeb shinfo->frags[fragno].page = page; 51949ed6e97SBjoern A. Zeeb shinfo->frags[fragno].offset = offset; 52049ed6e97SBjoern A. Zeeb shinfo->frags[fragno].size = size; 52149ed6e97SBjoern A. Zeeb shinfo->nr_frags = fragno + 1; 52249ed6e97SBjoern A. Zeeb skb->len += size; 5235504bd59SBjoern A. Zeeb skb->data_len += size; 52449ed6e97SBjoern A. Zeeb skb->truesize += truesize; 52549ed6e97SBjoern A. Zeeb } 52649ed6e97SBjoern A. Zeeb 52749ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */ 52849ed6e97SBjoern A. Zeeb 52949ed6e97SBjoern A. Zeeb #define skb_queue_walk(_q, skb) \ 53049ed6e97SBjoern A. Zeeb for ((skb) = (_q)->next; (skb) != (struct sk_buff *)(_q); \ 53149ed6e97SBjoern A. Zeeb (skb) = (skb)->next) 53249ed6e97SBjoern A. Zeeb 53349ed6e97SBjoern A. Zeeb #define skb_queue_walk_safe(_q, skb, tmp) \ 53449ed6e97SBjoern A. Zeeb for ((skb) = (_q)->next, (tmp) = (skb)->next; \ 53549ed6e97SBjoern A. Zeeb (skb) != (struct sk_buff *)(_q); (skb) = (tmp), (tmp) = (skb)->next) 53649ed6e97SBjoern A. Zeeb 5372ab4a419SBjoern A. Zeeb #define skb_list_walk_safe(_q, skb, tmp) \ 5382ab4a419SBjoern A. Zeeb for ((skb) = (_q), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL; \ 5392ab4a419SBjoern A. Zeeb ((skb) != NULL); \ 5402ab4a419SBjoern A. Zeeb (skb) = (tmp), (tmp) = ((skb) != NULL) ? (skb)->next ? NULL) 54149ed6e97SBjoern A. Zeeb 5422ab4a419SBjoern A. Zeeb static inline bool 5432ab4a419SBjoern A. Zeeb skb_queue_empty(const struct sk_buff_head *q) 5442ab4a419SBjoern A. Zeeb { 54549ed6e97SBjoern A. Zeeb SKB_TRACE(q); 5462ab4a419SBjoern A. Zeeb return (q->next == (const struct sk_buff *)q); 5472ab4a419SBjoern A. Zeeb } 5482ab4a419SBjoern A. Zeeb 5492ab4a419SBjoern A. Zeeb static inline bool 5502ab4a419SBjoern A. Zeeb skb_queue_empty_lockless(const struct sk_buff_head *q) 5512ab4a419SBjoern A. Zeeb { 5522ab4a419SBjoern A. Zeeb SKB_TRACE(q); 5532ab4a419SBjoern A. Zeeb return (READ_ONCE(q->next) == (const struct sk_buff *)q); 55449ed6e97SBjoern A. Zeeb } 55549ed6e97SBjoern A. Zeeb 55649ed6e97SBjoern A. Zeeb static inline void 55749ed6e97SBjoern A. Zeeb __skb_queue_head_init(struct sk_buff_head *q) 55849ed6e97SBjoern A. Zeeb { 55949ed6e97SBjoern A. Zeeb SKB_TRACE(q); 56049ed6e97SBjoern A. Zeeb q->prev = q->next = (struct sk_buff *)q; 56149ed6e97SBjoern A. Zeeb q->qlen = 0; 56249ed6e97SBjoern A. Zeeb } 56349ed6e97SBjoern A. Zeeb 56449ed6e97SBjoern A. Zeeb static inline void 56549ed6e97SBjoern A. Zeeb skb_queue_head_init(struct sk_buff_head *q) 56649ed6e97SBjoern A. Zeeb { 56749ed6e97SBjoern A. Zeeb SKB_TRACE(q); 5682ab4a419SBjoern A. Zeeb __skb_queue_head_init(q); 5692ab4a419SBjoern A. Zeeb spin_lock_init(&q->lock); 57049ed6e97SBjoern A. Zeeb } 57149ed6e97SBjoern A. Zeeb 57249ed6e97SBjoern A. Zeeb static inline void 57349ed6e97SBjoern A. Zeeb __skb_insert(struct sk_buff *new, struct sk_buff *prev, struct sk_buff *next, 57449ed6e97SBjoern A. Zeeb struct sk_buff_head *q) 57549ed6e97SBjoern A. Zeeb { 57649ed6e97SBjoern A. Zeeb 57749ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(new, "prev %p next %p q %p", prev, next, q); 5782ab4a419SBjoern A. Zeeb WRITE_ONCE(new->prev, prev); 5792ab4a419SBjoern A. Zeeb WRITE_ONCE(new->next, next); 5802ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)next)->prev, new); 5812ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)prev)->next, new); 5822ab4a419SBjoern A. Zeeb WRITE_ONCE(q->qlen, q->qlen + 1); 58349ed6e97SBjoern A. Zeeb } 58449ed6e97SBjoern A. Zeeb 58549ed6e97SBjoern A. Zeeb static inline void 58649ed6e97SBjoern A. Zeeb __skb_queue_after(struct sk_buff_head *q, struct sk_buff *skb, 58749ed6e97SBjoern A. Zeeb struct sk_buff *new) 58849ed6e97SBjoern A. Zeeb { 58949ed6e97SBjoern A. Zeeb 59049ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(q, "skb %p new %p", skb, new); 591b2dcb848SBjoern A. Zeeb __skb_insert(new, skb, ((struct sk_buff_head_l *)skb)->next, q); 59249ed6e97SBjoern A. Zeeb } 59349ed6e97SBjoern A. Zeeb 59449ed6e97SBjoern A. Zeeb static inline void 59549ed6e97SBjoern A. Zeeb __skb_queue_before(struct sk_buff_head *q, struct sk_buff *skb, 59649ed6e97SBjoern A. Zeeb struct sk_buff *new) 59749ed6e97SBjoern A. Zeeb { 59849ed6e97SBjoern A. Zeeb 59949ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(q, "skb %p new %p", skb, new); 60049ed6e97SBjoern A. Zeeb __skb_insert(new, skb->prev, skb, q); 60149ed6e97SBjoern A. Zeeb } 60249ed6e97SBjoern A. Zeeb 60349ed6e97SBjoern A. Zeeb static inline void 604b2dcb848SBjoern A. Zeeb __skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) 60549ed6e97SBjoern A. Zeeb { 60649ed6e97SBjoern A. Zeeb 607b2dcb848SBjoern A. Zeeb SKB_TRACE2(q, new); 608d3befb53STom Coldrick __skb_queue_before(q, (struct sk_buff *)q, new); 60949ed6e97SBjoern A. Zeeb } 61049ed6e97SBjoern A. Zeeb 61149ed6e97SBjoern A. Zeeb static inline void 612b2dcb848SBjoern A. Zeeb skb_queue_tail(struct sk_buff_head *q, struct sk_buff *new) 61349ed6e97SBjoern A. Zeeb { 6142ab4a419SBjoern A. Zeeb unsigned long flags; 6152ab4a419SBjoern A. Zeeb 616149c457dSBjoern A. Zeeb SKB_TRACE2(q, new); 6172ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 6182ab4a419SBjoern A. Zeeb __skb_queue_tail(q, new); 6192ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 62049ed6e97SBjoern A. Zeeb } 62149ed6e97SBjoern A. Zeeb 62249ed6e97SBjoern A. Zeeb static inline struct sk_buff * 6232ab4a419SBjoern A. Zeeb skb_peek(const struct sk_buff_head *q) 624ce9f3661SBjoern A. Zeeb { 625ce9f3661SBjoern A. Zeeb struct sk_buff *skb; 626ce9f3661SBjoern A. Zeeb 627ce9f3661SBjoern A. Zeeb skb = q->next; 628ce9f3661SBjoern A. Zeeb SKB_TRACE2(q, skb); 6292ab4a419SBjoern A. Zeeb if (skb == (const struct sk_buff *)q) 630ce9f3661SBjoern A. Zeeb return (NULL); 631ce9f3661SBjoern A. Zeeb return (skb); 632ce9f3661SBjoern A. Zeeb } 633ce9f3661SBjoern A. Zeeb 634ce9f3661SBjoern A. Zeeb static inline struct sk_buff * 6352ab4a419SBjoern A. Zeeb skb_peek_tail(const struct sk_buff_head *q) 63649ed6e97SBjoern A. Zeeb { 63749ed6e97SBjoern A. Zeeb struct sk_buff *skb; 63849ed6e97SBjoern A. Zeeb 6392ab4a419SBjoern A. Zeeb skb = READ_ONCE(q->prev); 64049ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb); 6412ab4a419SBjoern A. Zeeb if (skb == (const struct sk_buff *)q) 64249ed6e97SBjoern A. Zeeb return (NULL); 64349ed6e97SBjoern A. Zeeb return (skb); 64449ed6e97SBjoern A. Zeeb } 64549ed6e97SBjoern A. Zeeb 64649ed6e97SBjoern A. Zeeb static inline void 6472ab4a419SBjoern A. Zeeb __skb_unlink(struct sk_buff *skb, struct sk_buff_head *q) 64849ed6e97SBjoern A. Zeeb { 649b4856b8eSZhenlei Huang struct sk_buff *p, *n; 65049ed6e97SBjoern A. Zeeb 6512ab4a419SBjoern A. Zeeb SKB_TRACE2(skb, q); 6522ab4a419SBjoern A. Zeeb 6532ab4a419SBjoern A. Zeeb WRITE_ONCE(q->qlen, q->qlen - 1); 65449ed6e97SBjoern A. Zeeb p = skb->prev; 65549ed6e97SBjoern A. Zeeb n = skb->next; 6562ab4a419SBjoern A. Zeeb WRITE_ONCE(n->prev, p); 6572ab4a419SBjoern A. Zeeb WRITE_ONCE(p->next, n); 65849ed6e97SBjoern A. Zeeb skb->prev = skb->next = NULL; 65949ed6e97SBjoern A. Zeeb } 66049ed6e97SBjoern A. Zeeb 66149ed6e97SBjoern A. Zeeb static inline void 6622ab4a419SBjoern A. Zeeb skb_unlink(struct sk_buff *skb, struct sk_buff_head *q) 66349ed6e97SBjoern A. Zeeb { 6642ab4a419SBjoern A. Zeeb unsigned long flags; 6652ab4a419SBjoern A. Zeeb 6662ab4a419SBjoern A. Zeeb SKB_TRACE2(skb, q); 6672ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 6682ab4a419SBjoern A. Zeeb __skb_unlink(skb, q); 6692ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 67049ed6e97SBjoern A. Zeeb } 67149ed6e97SBjoern A. Zeeb 67249ed6e97SBjoern A. Zeeb static inline struct sk_buff * 67349ed6e97SBjoern A. Zeeb __skb_dequeue(struct sk_buff_head *q) 67449ed6e97SBjoern A. Zeeb { 67549ed6e97SBjoern A. Zeeb struct sk_buff *skb; 67649ed6e97SBjoern A. Zeeb 6772ab4a419SBjoern A. Zeeb skb = skb_peek(q); 67849ed6e97SBjoern A. Zeeb if (skb != NULL) 67949ed6e97SBjoern A. Zeeb __skb_unlink(skb, q); 6802ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb); 68149ed6e97SBjoern A. Zeeb return (skb); 68249ed6e97SBjoern A. Zeeb } 68349ed6e97SBjoern A. Zeeb 68449ed6e97SBjoern A. Zeeb static inline struct sk_buff * 68549ed6e97SBjoern A. Zeeb skb_dequeue(struct sk_buff_head *q) 68649ed6e97SBjoern A. Zeeb { 6872ab4a419SBjoern A. Zeeb unsigned long flags; 6882ab4a419SBjoern A. Zeeb struct sk_buff *skb; 6892ab4a419SBjoern A. Zeeb 6902ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 6912ab4a419SBjoern A. Zeeb skb = __skb_dequeue(q); 6922ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 6932ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb); 6942ab4a419SBjoern A. Zeeb return (skb); 69549ed6e97SBjoern A. Zeeb } 69649ed6e97SBjoern A. Zeeb 69749ed6e97SBjoern A. Zeeb static inline struct sk_buff * 6982ab4a419SBjoern A. Zeeb __skb_dequeue_tail(struct sk_buff_head *q) 69949ed6e97SBjoern A. Zeeb { 70049ed6e97SBjoern A. Zeeb struct sk_buff *skb; 70149ed6e97SBjoern A. Zeeb 70249ed6e97SBjoern A. Zeeb skb = skb_peek_tail(q); 70349ed6e97SBjoern A. Zeeb if (skb != NULL) 70449ed6e97SBjoern A. Zeeb __skb_unlink(skb, q); 7052ab4a419SBjoern A. Zeeb SKB_TRACE2(q, skb); 7062ab4a419SBjoern A. Zeeb return (skb); 7072ab4a419SBjoern A. Zeeb } 70849ed6e97SBjoern A. Zeeb 7092ab4a419SBjoern A. Zeeb static inline struct sk_buff * 7102ab4a419SBjoern A. Zeeb skb_dequeue_tail(struct sk_buff_head *q) 7112ab4a419SBjoern A. Zeeb { 7122ab4a419SBjoern A. Zeeb unsigned long flags; 7132ab4a419SBjoern A. Zeeb struct sk_buff *skb; 7142ab4a419SBjoern A. Zeeb 7152ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 7162ab4a419SBjoern A. Zeeb skb = __skb_dequeue_tail(q); 7172ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 71849ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb); 71949ed6e97SBjoern A. Zeeb return (skb); 72049ed6e97SBjoern A. Zeeb } 72149ed6e97SBjoern A. Zeeb 72249ed6e97SBjoern A. Zeeb static inline void 7236baea331SBjoern A. Zeeb __skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb) 7246baea331SBjoern A. Zeeb { 7256baea331SBjoern A. Zeeb 7266baea331SBjoern A. Zeeb SKB_TRACE2(q, skb); 7276baea331SBjoern A. Zeeb __skb_queue_after(q, (struct sk_buff *)q, skb); 7286baea331SBjoern A. Zeeb } 7296baea331SBjoern A. Zeeb 7306baea331SBjoern A. Zeeb static inline void 73149ed6e97SBjoern A. Zeeb skb_queue_head(struct sk_buff_head *q, struct sk_buff *skb) 73249ed6e97SBjoern A. Zeeb { 7332ab4a419SBjoern A. Zeeb unsigned long flags; 73449ed6e97SBjoern A. Zeeb 73549ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb); 7362ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 7372ab4a419SBjoern A. Zeeb __skb_queue_head(q, skb); 7382ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 73949ed6e97SBjoern A. Zeeb } 74049ed6e97SBjoern A. Zeeb 74149ed6e97SBjoern A. Zeeb static inline uint32_t 7422ab4a419SBjoern A. Zeeb skb_queue_len(const struct sk_buff_head *q) 74349ed6e97SBjoern A. Zeeb { 7446baea331SBjoern A. Zeeb 7452ab4a419SBjoern A. Zeeb SKB_TRACE(q); 7462ab4a419SBjoern A. Zeeb return (q->qlen); 74749ed6e97SBjoern A. Zeeb } 74849ed6e97SBjoern A. Zeeb 7496baea331SBjoern A. Zeeb static inline uint32_t 7502ab4a419SBjoern A. Zeeb skb_queue_len_lockless(const struct sk_buff_head *q) 7516baea331SBjoern A. Zeeb { 7526baea331SBjoern A. Zeeb 7532ab4a419SBjoern A. Zeeb SKB_TRACE(q); 7542ab4a419SBjoern A. Zeeb return (READ_ONCE(q->qlen)); 7556baea331SBjoern A. Zeeb } 7566baea331SBjoern A. Zeeb 75749ed6e97SBjoern A. Zeeb static inline void 7582ab4a419SBjoern A. Zeeb ___skb_queue_splice(const struct sk_buff_head *from, 7592ab4a419SBjoern A. Zeeb struct sk_buff *p, struct sk_buff *n) 7602ab4a419SBjoern A. Zeeb { 7612ab4a419SBjoern A. Zeeb struct sk_buff *b, *e; 7622ab4a419SBjoern A. Zeeb 7632ab4a419SBjoern A. Zeeb b = from->next; 7642ab4a419SBjoern A. Zeeb e = from->prev; 7652ab4a419SBjoern A. Zeeb 7662ab4a419SBjoern A. Zeeb WRITE_ONCE(b->prev, p); 7672ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)p)->next, b); 7682ab4a419SBjoern A. Zeeb WRITE_ONCE(e->next, n); 7692ab4a419SBjoern A. Zeeb WRITE_ONCE(((struct sk_buff_head_l *)n)->prev, e); 7702ab4a419SBjoern A. Zeeb } 7712ab4a419SBjoern A. Zeeb 7722ab4a419SBjoern A. Zeeb static inline void 7732ab4a419SBjoern A. Zeeb skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) 7742ab4a419SBjoern A. Zeeb { 7752ab4a419SBjoern A. Zeeb 7762ab4a419SBjoern A. Zeeb SKB_TRACE2(from, to); 7772ab4a419SBjoern A. Zeeb 7782ab4a419SBjoern A. Zeeb if (skb_queue_empty(from)) 7792ab4a419SBjoern A. Zeeb return; 7802ab4a419SBjoern A. Zeeb 7812ab4a419SBjoern A. Zeeb ___skb_queue_splice(from, (struct sk_buff *)to, to->next); 7822ab4a419SBjoern A. Zeeb to->qlen += from->qlen; 7832ab4a419SBjoern A. Zeeb __skb_queue_head_init(from); 7842ab4a419SBjoern A. Zeeb } 7852ab4a419SBjoern A. Zeeb 7862ab4a419SBjoern A. Zeeb static inline void 7872ab4a419SBjoern A. Zeeb skb_queue_splice_tail_init(struct sk_buff_head *from, struct sk_buff_head *to) 7882ab4a419SBjoern A. Zeeb { 7892ab4a419SBjoern A. Zeeb 7902ab4a419SBjoern A. Zeeb SKB_TRACE2(from, to); 7912ab4a419SBjoern A. Zeeb 7922ab4a419SBjoern A. Zeeb if (skb_queue_empty(from)) 7932ab4a419SBjoern A. Zeeb return; 7942ab4a419SBjoern A. Zeeb 7952ab4a419SBjoern A. Zeeb ___skb_queue_splice(from, to->prev, (struct sk_buff *)to); 7962ab4a419SBjoern A. Zeeb to->qlen += from->qlen; 7972ab4a419SBjoern A. Zeeb __skb_queue_head_init(from); 7982ab4a419SBjoern A. Zeeb } 7992ab4a419SBjoern A. Zeeb 8002ab4a419SBjoern A. Zeeb 8012ab4a419SBjoern A. Zeeb static inline void 80249ed6e97SBjoern A. Zeeb __skb_queue_purge(struct sk_buff_head *q) 80349ed6e97SBjoern A. Zeeb { 80449ed6e97SBjoern A. Zeeb struct sk_buff *skb; 80549ed6e97SBjoern A. Zeeb 80649ed6e97SBjoern A. Zeeb SKB_TRACE(q); 80749ed6e97SBjoern A. Zeeb while ((skb = __skb_dequeue(q)) != NULL) 80849ed6e97SBjoern A. Zeeb kfree_skb(skb); 809bcf1d8eeSBjoern A. Zeeb WARN_ONCE(skb_queue_len(q) != 0, "%s: queue %p not empty: %u", 810bcf1d8eeSBjoern A. Zeeb __func__, q, skb_queue_len(q)); 81149ed6e97SBjoern A. Zeeb } 81249ed6e97SBjoern A. Zeeb 81349ed6e97SBjoern A. Zeeb static inline void 81449ed6e97SBjoern A. Zeeb skb_queue_purge(struct sk_buff_head *q) 81549ed6e97SBjoern A. Zeeb { 8162ab4a419SBjoern A. Zeeb struct sk_buff_head _q; 8172ab4a419SBjoern A. Zeeb unsigned long flags; 8182ab4a419SBjoern A. Zeeb 81949ed6e97SBjoern A. Zeeb SKB_TRACE(q); 8202ab4a419SBjoern A. Zeeb 8212ab4a419SBjoern A. Zeeb if (skb_queue_empty_lockless(q)) 8222ab4a419SBjoern A. Zeeb return; 8232ab4a419SBjoern A. Zeeb 8242ab4a419SBjoern A. Zeeb __skb_queue_head_init(&_q); 8252ab4a419SBjoern A. Zeeb spin_lock_irqsave(&q->lock, flags); 8262ab4a419SBjoern A. Zeeb skb_queue_splice_init(q, &_q); 8272ab4a419SBjoern A. Zeeb spin_unlock_irqrestore(&q->lock, flags); 8282ab4a419SBjoern A. Zeeb __skb_queue_purge(&_q); 82949ed6e97SBjoern A. Zeeb } 83049ed6e97SBjoern A. Zeeb 83149ed6e97SBjoern A. Zeeb static inline struct sk_buff * 83249ed6e97SBjoern A. Zeeb skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb) 83349ed6e97SBjoern A. Zeeb { 83449ed6e97SBjoern A. Zeeb 83549ed6e97SBjoern A. Zeeb SKB_TRACE2(q, skb); 83649ed6e97SBjoern A. Zeeb /* XXX what is the q argument good for? */ 83749ed6e97SBjoern A. Zeeb return (skb->prev); 83849ed6e97SBjoern A. Zeeb } 83949ed6e97SBjoern A. Zeeb 84049ed6e97SBjoern A. Zeeb /* -------------------------------------------------------------------------- */ 84149ed6e97SBjoern A. Zeeb 84249ed6e97SBjoern A. Zeeb static inline struct sk_buff * 8432ab4a419SBjoern A. Zeeb skb_copy(const struct sk_buff *skb, gfp_t gfp) 84449ed6e97SBjoern A. Zeeb { 845349b042bSBjoern A. Zeeb struct sk_buff *new; 846349b042bSBjoern A. Zeeb 847349b042bSBjoern A. Zeeb new = linuxkpi_skb_copy(skb, gfp); 848349b042bSBjoern A. Zeeb SKB_TRACE2(skb, new); 849349b042bSBjoern A. Zeeb return (new); 85049ed6e97SBjoern A. Zeeb } 85149ed6e97SBjoern A. Zeeb 85249ed6e97SBjoern A. Zeeb static inline uint16_t 85349ed6e97SBjoern A. Zeeb skb_checksum(struct sk_buff *skb, int offs, size_t len, int x) 85449ed6e97SBjoern A. Zeeb { 85549ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 85649ed6e97SBjoern A. Zeeb SKB_TODO(); 85749ed6e97SBjoern A. Zeeb return (0xffff); 85849ed6e97SBjoern A. Zeeb } 85949ed6e97SBjoern A. Zeeb 86049ed6e97SBjoern A. Zeeb static inline int 86149ed6e97SBjoern A. Zeeb skb_checksum_start_offset(struct sk_buff *skb) 86249ed6e97SBjoern A. Zeeb { 86349ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 86449ed6e97SBjoern A. Zeeb SKB_TODO(); 86549ed6e97SBjoern A. Zeeb return (-1); 86649ed6e97SBjoern A. Zeeb } 86749ed6e97SBjoern A. Zeeb 86849ed6e97SBjoern A. Zeeb static inline dma_addr_t 86949ed6e97SBjoern A. Zeeb skb_frag_dma_map(struct device *dev, const skb_frag_t *frag, int x, 87049ed6e97SBjoern A. Zeeb size_t fragsz, enum dma_data_direction dir) 87149ed6e97SBjoern A. Zeeb { 87249ed6e97SBjoern A. Zeeb SKB_TRACE2(frag, dev); 87349ed6e97SBjoern A. Zeeb SKB_TODO(); 87449ed6e97SBjoern A. Zeeb return (-1); 87549ed6e97SBjoern A. Zeeb } 87649ed6e97SBjoern A. Zeeb 87749ed6e97SBjoern A. Zeeb static inline size_t 87849ed6e97SBjoern A. Zeeb skb_frag_size(const skb_frag_t *frag) 87949ed6e97SBjoern A. Zeeb { 88049ed6e97SBjoern A. Zeeb SKB_TRACE(frag); 8812ab4a419SBjoern A. Zeeb return (frag->size); 88249ed6e97SBjoern A. Zeeb } 88349ed6e97SBjoern A. Zeeb 88449ed6e97SBjoern A. Zeeb #define skb_walk_frags(_skb, _frag) \ 88549ed6e97SBjoern A. Zeeb for ((_frag) = (_skb); false; (_frag)++) 88649ed6e97SBjoern A. Zeeb 88749ed6e97SBjoern A. Zeeb static inline void 88849ed6e97SBjoern A. Zeeb skb_checksum_help(struct sk_buff *skb) 88949ed6e97SBjoern A. Zeeb { 89049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 89149ed6e97SBjoern A. Zeeb SKB_TODO(); 89249ed6e97SBjoern A. Zeeb } 89349ed6e97SBjoern A. Zeeb 89449ed6e97SBjoern A. Zeeb static inline bool 89549ed6e97SBjoern A. Zeeb skb_ensure_writable(struct sk_buff *skb, size_t off) 89649ed6e97SBjoern A. Zeeb { 89749ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 89849ed6e97SBjoern A. Zeeb SKB_TODO(); 89949ed6e97SBjoern A. Zeeb return (false); 90049ed6e97SBjoern A. Zeeb } 90149ed6e97SBjoern A. Zeeb 90249ed6e97SBjoern A. Zeeb static inline void * 90349ed6e97SBjoern A. Zeeb skb_frag_address(const skb_frag_t *frag) 90449ed6e97SBjoern A. Zeeb { 90549ed6e97SBjoern A. Zeeb SKB_TRACE(frag); 9062ab4a419SBjoern A. Zeeb return (page_address(frag->page + frag->offset)); 90749ed6e97SBjoern A. Zeeb } 90849ed6e97SBjoern A. Zeeb 90989c32dafSBjoern A. Zeeb static inline void 91089c32dafSBjoern A. Zeeb skb_free_frag(void *frag) 91189c32dafSBjoern A. Zeeb { 91289c32dafSBjoern A. Zeeb 913dbbf46ebSBjoern A. Zeeb page_frag_free(frag); 91489c32dafSBjoern A. Zeeb } 91589c32dafSBjoern A. Zeeb 91649ed6e97SBjoern A. Zeeb static inline struct sk_buff * 91749ed6e97SBjoern A. Zeeb skb_gso_segment(struct sk_buff *skb, netdev_features_t netdev_flags) 91849ed6e97SBjoern A. Zeeb { 91949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 92049ed6e97SBjoern A. Zeeb SKB_TODO(); 92149ed6e97SBjoern A. Zeeb return (NULL); 92249ed6e97SBjoern A. Zeeb } 92349ed6e97SBjoern A. Zeeb 92449ed6e97SBjoern A. Zeeb static inline bool 92549ed6e97SBjoern A. Zeeb skb_is_gso(struct sk_buff *skb) 92649ed6e97SBjoern A. Zeeb { 92749ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 928952643eaSBjoern A. Zeeb SKB_IMPROVE("Really a TODO but get it away from logging"); 92949ed6e97SBjoern A. Zeeb return (false); 93049ed6e97SBjoern A. Zeeb } 93149ed6e97SBjoern A. Zeeb 93249ed6e97SBjoern A. Zeeb static inline void 93349ed6e97SBjoern A. Zeeb skb_mark_not_on_list(struct sk_buff *skb) 93449ed6e97SBjoern A. Zeeb { 93549ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 9362ab4a419SBjoern A. Zeeb skb->next = NULL; 93749ed6e97SBjoern A. Zeeb } 93849ed6e97SBjoern A. Zeeb 93949ed6e97SBjoern A. Zeeb static inline void 94049ed6e97SBjoern A. Zeeb skb_reset_transport_header(struct sk_buff *skb) 94149ed6e97SBjoern A. Zeeb { 94249ed6e97SBjoern A. Zeeb 94349ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 94449ed6e97SBjoern A. Zeeb skb->l4hdroff = skb->data - skb->head; 94549ed6e97SBjoern A. Zeeb } 94649ed6e97SBjoern A. Zeeb 94749ed6e97SBjoern A. Zeeb static inline uint8_t * 94849ed6e97SBjoern A. Zeeb skb_transport_header(struct sk_buff *skb) 94949ed6e97SBjoern A. Zeeb { 95049ed6e97SBjoern A. Zeeb 95149ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 95249ed6e97SBjoern A. Zeeb return (skb->head + skb->l4hdroff); 95349ed6e97SBjoern A. Zeeb } 95449ed6e97SBjoern A. Zeeb 95549ed6e97SBjoern A. Zeeb static inline uint8_t * 95649ed6e97SBjoern A. Zeeb skb_network_header(struct sk_buff *skb) 95749ed6e97SBjoern A. Zeeb { 95849ed6e97SBjoern A. Zeeb 95949ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 96049ed6e97SBjoern A. Zeeb return (skb->head + skb->l3hdroff); 96149ed6e97SBjoern A. Zeeb } 96249ed6e97SBjoern A. Zeeb 96349ed6e97SBjoern A. Zeeb static inline int 96449ed6e97SBjoern A. Zeeb __skb_linearize(struct sk_buff *skb) 96549ed6e97SBjoern A. Zeeb { 96649ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 96749ed6e97SBjoern A. Zeeb SKB_TODO(); 9682ab4a419SBjoern A. Zeeb return (-ENXIO); 96949ed6e97SBjoern A. Zeeb } 97049ed6e97SBjoern A. Zeeb 9716baea331SBjoern A. Zeeb static inline int 9725504bd59SBjoern A. Zeeb skb_linearize(struct sk_buff *skb) 9735504bd59SBjoern A. Zeeb { 9745504bd59SBjoern A. Zeeb return (skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0); 9755504bd59SBjoern A. Zeeb } 9765504bd59SBjoern A. Zeeb 9775504bd59SBjoern A. Zeeb static inline int 97849ed6e97SBjoern A. Zeeb pskb_expand_head(struct sk_buff *skb, int x, int len, gfp_t gfp) 97949ed6e97SBjoern A. Zeeb { 98049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 98149ed6e97SBjoern A. Zeeb SKB_TODO(); 9826baea331SBjoern A. Zeeb return (-ENXIO); 98349ed6e97SBjoern A. Zeeb } 98449ed6e97SBjoern A. Zeeb 98549ed6e97SBjoern A. Zeeb /* Not really seen this one but need it as symmetric accessor function. */ 98649ed6e97SBjoern A. Zeeb static inline void 98749ed6e97SBjoern A. Zeeb skb_set_queue_mapping(struct sk_buff *skb, uint16_t qmap) 98849ed6e97SBjoern A. Zeeb { 98949ed6e97SBjoern A. Zeeb 99049ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(skb, "qmap %u", qmap); 99149ed6e97SBjoern A. Zeeb skb->qmap = qmap; 99249ed6e97SBjoern A. Zeeb } 99349ed6e97SBjoern A. Zeeb 99449ed6e97SBjoern A. Zeeb static inline uint16_t 99549ed6e97SBjoern A. Zeeb skb_get_queue_mapping(struct sk_buff *skb) 99649ed6e97SBjoern A. Zeeb { 99749ed6e97SBjoern A. Zeeb 99849ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(skb, "qmap %u", skb->qmap); 99949ed6e97SBjoern A. Zeeb return (skb->qmap); 100049ed6e97SBjoern A. Zeeb } 100149ed6e97SBjoern A. Zeeb 100284c5998cSBjoern A. Zeeb static inline void 100384c5998cSBjoern A. Zeeb skb_copy_header(struct sk_buff *to, const struct sk_buff *from) 100484c5998cSBjoern A. Zeeb { 100584c5998cSBjoern A. Zeeb SKB_TRACE2(to, from); 100684c5998cSBjoern A. Zeeb SKB_TODO(); 100784c5998cSBjoern A. Zeeb } 100884c5998cSBjoern A. Zeeb 100949ed6e97SBjoern A. Zeeb static inline bool 101049ed6e97SBjoern A. Zeeb skb_header_cloned(struct sk_buff *skb) 101149ed6e97SBjoern A. Zeeb { 101249ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 101349ed6e97SBjoern A. Zeeb SKB_TODO(); 10142ab4a419SBjoern A. Zeeb return (true); 101549ed6e97SBjoern A. Zeeb } 101649ed6e97SBjoern A. Zeeb 101749ed6e97SBjoern A. Zeeb static inline uint8_t * 1018262c5e81SBjoern A. Zeeb skb_mac_header(const struct sk_buff *skb) 1019262c5e81SBjoern A. Zeeb { 1020262c5e81SBjoern A. Zeeb SKB_TRACE(skb); 1021262c5e81SBjoern A. Zeeb return (skb->head + skb->mac_header); 1022262c5e81SBjoern A. Zeeb } 1023f0e59b69SBjoern A. Zeeb 1024262c5e81SBjoern A. Zeeb static inline void 1025262c5e81SBjoern A. Zeeb skb_reset_mac_header(struct sk_buff *skb) 1026262c5e81SBjoern A. Zeeb { 1027262c5e81SBjoern A. Zeeb SKB_TRACE(skb); 1028262c5e81SBjoern A. Zeeb skb->mac_header = skb->data - skb->head; 1029262c5e81SBjoern A. Zeeb } 1030262c5e81SBjoern A. Zeeb 1031262c5e81SBjoern A. Zeeb static inline void 1032262c5e81SBjoern A. Zeeb skb_set_mac_header(struct sk_buff *skb, const size_t len) 1033262c5e81SBjoern A. Zeeb { 1034262c5e81SBjoern A. Zeeb SKB_TRACE(skb); 1035262c5e81SBjoern A. Zeeb skb_reset_mac_header(skb); 1036262c5e81SBjoern A. Zeeb skb->mac_header += len; 1037262c5e81SBjoern A. Zeeb } 1038262c5e81SBjoern A. Zeeb 1039262c5e81SBjoern A. Zeeb static inline struct skb_shared_hwtstamps * 1040262c5e81SBjoern A. Zeeb skb_hwtstamps(struct sk_buff *skb) 104149ed6e97SBjoern A. Zeeb { 104249ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 104349ed6e97SBjoern A. Zeeb SKB_TODO(); 104449ed6e97SBjoern A. Zeeb return (NULL); 104549ed6e97SBjoern A. Zeeb } 104649ed6e97SBjoern A. Zeeb 104749ed6e97SBjoern A. Zeeb static inline void 104849ed6e97SBjoern A. Zeeb skb_orphan(struct sk_buff *skb) 104949ed6e97SBjoern A. Zeeb { 105049ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 105149ed6e97SBjoern A. Zeeb SKB_TODO(); 105249ed6e97SBjoern A. Zeeb } 105349ed6e97SBjoern A. Zeeb 105436ca2172SBjoern A. Zeeb static inline __wsum 105549ed6e97SBjoern A. Zeeb csum_unfold(__sum16 sum) 105649ed6e97SBjoern A. Zeeb { 105749ed6e97SBjoern A. Zeeb return (sum); 105849ed6e97SBjoern A. Zeeb } 105949ed6e97SBjoern A. Zeeb 1060a3e07b6eSBjoern A. Zeeb static __inline void 1061a3e07b6eSBjoern A. Zeeb skb_postpush_rcsum(struct sk_buff *skb, const void *data, size_t len) 1062a3e07b6eSBjoern A. Zeeb { 1063a3e07b6eSBjoern A. Zeeb SKB_TODO(); 1064a3e07b6eSBjoern A. Zeeb } 1065a3e07b6eSBjoern A. Zeeb 10666baea331SBjoern A. Zeeb static inline void 10676baea331SBjoern A. Zeeb skb_reset_tail_pointer(struct sk_buff *skb) 10686baea331SBjoern A. Zeeb { 10696baea331SBjoern A. Zeeb 10706baea331SBjoern A. Zeeb SKB_TRACE(skb); 10715504bd59SBjoern A. Zeeb #ifdef SKB_DOING_OFFSETS_US_NOT 10726baea331SBjoern A. Zeeb skb->tail = (uint8_t *)(uintptr_t)(skb->data - skb->head); 10735504bd59SBjoern A. Zeeb #endif 10745504bd59SBjoern A. Zeeb skb->tail = skb->data; 10756baea331SBjoern A. Zeeb SKB_TRACE(skb); 10766baea331SBjoern A. Zeeb } 10776baea331SBjoern A. Zeeb 10786baea331SBjoern A. Zeeb static inline struct sk_buff * 10796baea331SBjoern A. Zeeb skb_get(struct sk_buff *skb) 10806baea331SBjoern A. Zeeb { 10816baea331SBjoern A. Zeeb 10822ab4a419SBjoern A. Zeeb SKB_TRACE(skb); 10832ab4a419SBjoern A. Zeeb refcount_inc(&skb->refcnt); 10846baea331SBjoern A. Zeeb return (skb); 10856baea331SBjoern A. Zeeb } 10866baea331SBjoern A. Zeeb 10876baea331SBjoern A. Zeeb static inline struct sk_buff * 10886baea331SBjoern A. Zeeb skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) 10896baea331SBjoern A. Zeeb { 10906baea331SBjoern A. Zeeb 10916baea331SBjoern A. Zeeb SKB_TODO(); 10926baea331SBjoern A. Zeeb return (NULL); 10936baea331SBjoern A. Zeeb } 10946baea331SBjoern A. Zeeb 10956baea331SBjoern A. Zeeb static inline void 10966baea331SBjoern A. Zeeb skb_copy_from_linear_data(const struct sk_buff *skb, void *dst, size_t len) 10976baea331SBjoern A. Zeeb { 10986baea331SBjoern A. Zeeb 10996baea331SBjoern A. Zeeb SKB_TRACE(skb); 11006baea331SBjoern A. Zeeb /* Let us just hope the destination has len space ... */ 11016baea331SBjoern A. Zeeb memcpy(dst, skb->data, len); 11026baea331SBjoern A. Zeeb } 11036baea331SBjoern A. Zeeb 110489c32dafSBjoern A. Zeeb static inline int 110589c32dafSBjoern A. Zeeb skb_pad(struct sk_buff *skb, int pad) 110689c32dafSBjoern A. Zeeb { 110789c32dafSBjoern A. Zeeb 110889c32dafSBjoern A. Zeeb SKB_TRACE(skb); 110989c32dafSBjoern A. Zeeb SKB_TODO(); 111089c32dafSBjoern A. Zeeb return (-1); 111189c32dafSBjoern A. Zeeb } 111289c32dafSBjoern A. Zeeb 111389c32dafSBjoern A. Zeeb static inline void 111489c32dafSBjoern A. Zeeb skb_list_del_init(struct sk_buff *skb) 111589c32dafSBjoern A. Zeeb { 111689c32dafSBjoern A. Zeeb 111789c32dafSBjoern A. Zeeb SKB_TRACE(skb); 11182ab4a419SBjoern A. Zeeb __list_del_entry(&skb->list); 11192ab4a419SBjoern A. Zeeb skb_mark_not_on_list(skb); 112089c32dafSBjoern A. Zeeb } 112189c32dafSBjoern A. Zeeb 112289c32dafSBjoern A. Zeeb static inline void 112389c32dafSBjoern A. Zeeb napi_consume_skb(struct sk_buff *skb, int budget) 112489c32dafSBjoern A. Zeeb { 112589c32dafSBjoern A. Zeeb 112689c32dafSBjoern A. Zeeb SKB_TRACE(skb); 112789c32dafSBjoern A. Zeeb SKB_TODO(); 112889c32dafSBjoern A. Zeeb } 112989c32dafSBjoern A. Zeeb 11301213a6beSBjoern A. Zeeb static inline struct sk_buff * 11311213a6beSBjoern A. Zeeb napi_build_skb(void *data, size_t len) 11321213a6beSBjoern A. Zeeb { 11331213a6beSBjoern A. Zeeb 11341213a6beSBjoern A. Zeeb SKB_TODO(); 11351213a6beSBjoern A. Zeeb return (NULL); 11361213a6beSBjoern A. Zeeb } 11371213a6beSBjoern A. Zeeb 1138369264acSBjoern A. Zeeb static inline uint32_t 1139369264acSBjoern A. Zeeb skb_get_hash(struct sk_buff *skb) 1140369264acSBjoern A. Zeeb { 1141369264acSBjoern A. Zeeb SKB_TRACE(skb); 1142369264acSBjoern A. Zeeb SKB_TODO(); 1143369264acSBjoern A. Zeeb return (0); 1144369264acSBjoern A. Zeeb } 1145369264acSBjoern A. Zeeb 11461213a6beSBjoern A. Zeeb static inline void 11471213a6beSBjoern A. Zeeb skb_mark_for_recycle(struct sk_buff *skb) 11481213a6beSBjoern A. Zeeb { 11491213a6beSBjoern A. Zeeb SKB_TRACE(skb); 11502ab4a419SBjoern A. Zeeb /* page_pool */ 11511213a6beSBjoern A. Zeeb SKB_TODO(); 11521213a6beSBjoern A. Zeeb } 11531213a6beSBjoern A. Zeeb 1154e039b38dSBjoern A. Zeeb static inline int 1155e039b38dSBjoern A. Zeeb skb_cow_head(struct sk_buff *skb, unsigned int headroom) 1156e039b38dSBjoern A. Zeeb { 1157e039b38dSBjoern A. Zeeb SKB_TRACE(skb); 1158e039b38dSBjoern A. Zeeb SKB_TODO(); 1159e039b38dSBjoern A. Zeeb return (-1); 1160e039b38dSBjoern A. Zeeb } 1161e039b38dSBjoern A. Zeeb 116289c32dafSBjoern A. Zeeb #define SKB_WITH_OVERHEAD(_s) \ 116389c32dafSBjoern A. Zeeb (_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE) 116489c32dafSBjoern A. Zeeb 116549ed6e97SBjoern A. Zeeb #endif /* _LINUXKPI_LINUX_SKBUFF_H */ 1166