162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Routines having to do with the 'struct sk_buff' memory handlers. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk> 662306a36Sopenharmony_ci * Florian La Roche <rzsfl@rz.uni-sb.de> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Fixes: 962306a36Sopenharmony_ci * Alan Cox : Fixed the worst of the load 1062306a36Sopenharmony_ci * balancer bugs. 1162306a36Sopenharmony_ci * Dave Platt : Interrupt stacking fix. 1262306a36Sopenharmony_ci * Richard Kooijman : Timestamp fixes. 1362306a36Sopenharmony_ci * Alan Cox : Changed buffer format. 1462306a36Sopenharmony_ci * Alan Cox : destructor hook for AF_UNIX etc. 1562306a36Sopenharmony_ci * Linus Torvalds : Better skb_clone. 1662306a36Sopenharmony_ci * Alan Cox : Added skb_copy. 1762306a36Sopenharmony_ci * Alan Cox : Added all the changed routines Linus 1862306a36Sopenharmony_ci * only put in the headers 1962306a36Sopenharmony_ci * Ray VanTassle : Fixed --skb->lock in free 2062306a36Sopenharmony_ci * Alan Cox : skb_copy copy arp field 2162306a36Sopenharmony_ci * Andi Kleen : slabified it. 2262306a36Sopenharmony_ci * Robert Olsson : Removed skb_head_pool 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * NOTE: 2562306a36Sopenharmony_ci * The __skb_ routines should be called with interrupts 2662306a36Sopenharmony_ci * disabled, or you better be *real* sure that the operation is atomic 2762306a36Sopenharmony_ci * with respect to whatever list is being frobbed (e.g. via lock_sock() 2862306a36Sopenharmony_ci * or via disabling bottom half handlers, etc). 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * The functions in this file will not compile correctly with gcc 2.4.x 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#include <linux/module.h> 3862306a36Sopenharmony_ci#include <linux/types.h> 3962306a36Sopenharmony_ci#include <linux/kernel.h> 4062306a36Sopenharmony_ci#include <linux/mm.h> 4162306a36Sopenharmony_ci#include <linux/interrupt.h> 4262306a36Sopenharmony_ci#include <linux/in.h> 4362306a36Sopenharmony_ci#include <linux/inet.h> 4462306a36Sopenharmony_ci#include <linux/slab.h> 4562306a36Sopenharmony_ci#include <linux/tcp.h> 4662306a36Sopenharmony_ci#include <linux/udp.h> 4762306a36Sopenharmony_ci#include <linux/sctp.h> 4862306a36Sopenharmony_ci#include <linux/netdevice.h> 4962306a36Sopenharmony_ci#ifdef CONFIG_NET_CLS_ACT 5062306a36Sopenharmony_ci#include <net/pkt_sched.h> 5162306a36Sopenharmony_ci#endif 5262306a36Sopenharmony_ci#include <linux/string.h> 5362306a36Sopenharmony_ci#include <linux/skbuff.h> 5462306a36Sopenharmony_ci#include <linux/splice.h> 5562306a36Sopenharmony_ci#include <linux/cache.h> 5662306a36Sopenharmony_ci#include <linux/rtnetlink.h> 5762306a36Sopenharmony_ci#include <linux/init.h> 5862306a36Sopenharmony_ci#include <linux/scatterlist.h> 5962306a36Sopenharmony_ci#include <linux/errqueue.h> 6062306a36Sopenharmony_ci#include <linux/prefetch.h> 6162306a36Sopenharmony_ci#include <linux/bitfield.h> 6262306a36Sopenharmony_ci#include <linux/if_vlan.h> 6362306a36Sopenharmony_ci#include <linux/mpls.h> 6462306a36Sopenharmony_ci#include <linux/kcov.h> 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#include <net/protocol.h> 6762306a36Sopenharmony_ci#include <net/dst.h> 6862306a36Sopenharmony_ci#include <net/sock.h> 6962306a36Sopenharmony_ci#include <net/checksum.h> 7062306a36Sopenharmony_ci#include <net/gso.h> 7162306a36Sopenharmony_ci#include <net/ip6_checksum.h> 7262306a36Sopenharmony_ci#include <net/xfrm.h> 7362306a36Sopenharmony_ci#include <net/mpls.h> 7462306a36Sopenharmony_ci#include <net/mptcp.h> 7562306a36Sopenharmony_ci#include <net/mctp.h> 7662306a36Sopenharmony_ci#include <net/page_pool/helpers.h> 7762306a36Sopenharmony_ci#include <net/dropreason.h> 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#include <linux/uaccess.h> 8062306a36Sopenharmony_ci#include <trace/events/skb.h> 8162306a36Sopenharmony_ci#include <linux/highmem.h> 8262306a36Sopenharmony_ci#include <linux/capability.h> 8362306a36Sopenharmony_ci#include <linux/user_namespace.h> 8462306a36Sopenharmony_ci#include <linux/indirect_call_wrapper.h> 8562306a36Sopenharmony_ci#include <linux/textsearch.h> 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#include "dev.h" 8862306a36Sopenharmony_ci#include "sock_destructor.h" 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistruct kmem_cache *skbuff_cache __ro_after_init; 9162306a36Sopenharmony_cistatic struct kmem_cache *skbuff_fclone_cache __ro_after_init; 9262306a36Sopenharmony_ci#ifdef CONFIG_SKB_EXTENSIONS 9362306a36Sopenharmony_cistatic struct kmem_cache *skbuff_ext_cache __ro_after_init; 9462306a36Sopenharmony_ci#endif 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic struct kmem_cache *skb_small_head_cache __ro_after_init; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#define SKB_SMALL_HEAD_SIZE SKB_HEAD_ALIGN(MAX_TCP_HEADER) 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* We want SKB_SMALL_HEAD_CACHE_SIZE to not be a power of two. 10262306a36Sopenharmony_ci * This should ensure that SKB_SMALL_HEAD_HEADROOM is a unique 10362306a36Sopenharmony_ci * size, and we can differentiate heads from skb_small_head_cache 10462306a36Sopenharmony_ci * vs system slabs by looking at their size (skb_end_offset()). 10562306a36Sopenharmony_ci */ 10662306a36Sopenharmony_ci#define SKB_SMALL_HEAD_CACHE_SIZE \ 10762306a36Sopenharmony_ci (is_power_of_2(SKB_SMALL_HEAD_SIZE) ? \ 10862306a36Sopenharmony_ci (SKB_SMALL_HEAD_SIZE + L1_CACHE_BYTES) : \ 10962306a36Sopenharmony_ci SKB_SMALL_HEAD_SIZE) 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define SKB_SMALL_HEAD_HEADROOM \ 11262306a36Sopenharmony_ci SKB_WITH_OVERHEAD(SKB_SMALL_HEAD_CACHE_SIZE) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ciint sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS; 11562306a36Sopenharmony_ciEXPORT_SYMBOL(sysctl_max_skb_frags); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#undef FN 11862306a36Sopenharmony_ci#define FN(reason) [SKB_DROP_REASON_##reason] = #reason, 11962306a36Sopenharmony_cistatic const char * const drop_reasons[] = { 12062306a36Sopenharmony_ci [SKB_CONSUMED] = "CONSUMED", 12162306a36Sopenharmony_ci DEFINE_DROP_REASON(FN, FN) 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic const struct drop_reason_list drop_reasons_core = { 12562306a36Sopenharmony_ci .reasons = drop_reasons, 12662306a36Sopenharmony_ci .n_reasons = ARRAY_SIZE(drop_reasons), 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ciconst struct drop_reason_list __rcu * 13062306a36Sopenharmony_cidrop_reasons_by_subsys[SKB_DROP_REASON_SUBSYS_NUM] = { 13162306a36Sopenharmony_ci [SKB_DROP_REASON_SUBSYS_CORE] = RCU_INITIALIZER(&drop_reasons_core), 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ciEXPORT_SYMBOL(drop_reasons_by_subsys); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/** 13662306a36Sopenharmony_ci * drop_reasons_register_subsys - register another drop reason subsystem 13762306a36Sopenharmony_ci * @subsys: the subsystem to register, must not be the core 13862306a36Sopenharmony_ci * @list: the list of drop reasons within the subsystem, must point to 13962306a36Sopenharmony_ci * a statically initialized list 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_civoid drop_reasons_register_subsys(enum skb_drop_reason_subsys subsys, 14262306a36Sopenharmony_ci const struct drop_reason_list *list) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci if (WARN(subsys <= SKB_DROP_REASON_SUBSYS_CORE || 14562306a36Sopenharmony_ci subsys >= ARRAY_SIZE(drop_reasons_by_subsys), 14662306a36Sopenharmony_ci "invalid subsystem %d\n", subsys)) 14762306a36Sopenharmony_ci return; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* must point to statically allocated memory, so INIT is OK */ 15062306a36Sopenharmony_ci RCU_INIT_POINTER(drop_reasons_by_subsys[subsys], list); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(drop_reasons_register_subsys); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci/** 15562306a36Sopenharmony_ci * drop_reasons_unregister_subsys - unregister a drop reason subsystem 15662306a36Sopenharmony_ci * @subsys: the subsystem to remove, must not be the core 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * Note: This will synchronize_rcu() to ensure no users when it returns. 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_civoid drop_reasons_unregister_subsys(enum skb_drop_reason_subsys subsys) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci if (WARN(subsys <= SKB_DROP_REASON_SUBSYS_CORE || 16362306a36Sopenharmony_ci subsys >= ARRAY_SIZE(drop_reasons_by_subsys), 16462306a36Sopenharmony_ci "invalid subsystem %d\n", subsys)) 16562306a36Sopenharmony_ci return; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci RCU_INIT_POINTER(drop_reasons_by_subsys[subsys], NULL); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci synchronize_rcu(); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(drop_reasons_unregister_subsys); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/** 17462306a36Sopenharmony_ci * skb_panic - private function for out-of-line support 17562306a36Sopenharmony_ci * @skb: buffer 17662306a36Sopenharmony_ci * @sz: size 17762306a36Sopenharmony_ci * @addr: address 17862306a36Sopenharmony_ci * @msg: skb_over_panic or skb_under_panic 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * Out-of-line support for skb_put() and skb_push(). 18162306a36Sopenharmony_ci * Called via the wrapper skb_over_panic() or skb_under_panic(). 18262306a36Sopenharmony_ci * Keep out of line to prevent kernel bloat. 18362306a36Sopenharmony_ci * __builtin_return_address is not used because it is not always reliable. 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_cistatic void skb_panic(struct sk_buff *skb, unsigned int sz, void *addr, 18662306a36Sopenharmony_ci const char msg[]) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci pr_emerg("%s: text:%px len:%d put:%d head:%px data:%px tail:%#lx end:%#lx dev:%s\n", 18962306a36Sopenharmony_ci msg, addr, skb->len, sz, skb->head, skb->data, 19062306a36Sopenharmony_ci (unsigned long)skb->tail, (unsigned long)skb->end, 19162306a36Sopenharmony_ci skb->dev ? skb->dev->name : "<NULL>"); 19262306a36Sopenharmony_ci BUG(); 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic void skb_over_panic(struct sk_buff *skb, unsigned int sz, void *addr) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci skb_panic(skb, sz, addr, __func__); 19862306a36Sopenharmony_ci} 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic void skb_under_panic(struct sk_buff *skb, unsigned int sz, void *addr) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci skb_panic(skb, sz, addr, __func__); 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci#define NAPI_SKB_CACHE_SIZE 64 20662306a36Sopenharmony_ci#define NAPI_SKB_CACHE_BULK 16 20762306a36Sopenharmony_ci#define NAPI_SKB_CACHE_HALF (NAPI_SKB_CACHE_SIZE / 2) 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#if PAGE_SIZE == SZ_4K 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define NAPI_HAS_SMALL_PAGE_FRAG 1 21262306a36Sopenharmony_ci#define NAPI_SMALL_PAGE_PFMEMALLOC(nc) ((nc).pfmemalloc) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* specialized page frag allocator using a single order 0 page 21562306a36Sopenharmony_ci * and slicing it into 1K sized fragment. Constrained to systems 21662306a36Sopenharmony_ci * with a very limited amount of 1K fragments fitting a single 21762306a36Sopenharmony_ci * page - to avoid excessive truesize underestimation 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistruct page_frag_1k { 22162306a36Sopenharmony_ci void *va; 22262306a36Sopenharmony_ci u16 offset; 22362306a36Sopenharmony_ci bool pfmemalloc; 22462306a36Sopenharmony_ci}; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cistatic void *page_frag_alloc_1k(struct page_frag_1k *nc, gfp_t gfp) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci struct page *page; 22962306a36Sopenharmony_ci int offset; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci offset = nc->offset - SZ_1K; 23262306a36Sopenharmony_ci if (likely(offset >= 0)) 23362306a36Sopenharmony_ci goto use_frag; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); 23662306a36Sopenharmony_ci if (!page) 23762306a36Sopenharmony_ci return NULL; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci nc->va = page_address(page); 24062306a36Sopenharmony_ci nc->pfmemalloc = page_is_pfmemalloc(page); 24162306a36Sopenharmony_ci offset = PAGE_SIZE - SZ_1K; 24262306a36Sopenharmony_ci page_ref_add(page, offset / SZ_1K); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ciuse_frag: 24562306a36Sopenharmony_ci nc->offset = offset; 24662306a36Sopenharmony_ci return nc->va + offset; 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci#else 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci/* the small page is actually unused in this build; add dummy helpers 25162306a36Sopenharmony_ci * to please the compiler and avoid later preprocessor's conditionals 25262306a36Sopenharmony_ci */ 25362306a36Sopenharmony_ci#define NAPI_HAS_SMALL_PAGE_FRAG 0 25462306a36Sopenharmony_ci#define NAPI_SMALL_PAGE_PFMEMALLOC(nc) false 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cistruct page_frag_1k { 25762306a36Sopenharmony_ci}; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic void *page_frag_alloc_1k(struct page_frag_1k *nc, gfp_t gfp_mask) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci return NULL; 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci#endif 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistruct napi_alloc_cache { 26762306a36Sopenharmony_ci struct page_frag_cache page; 26862306a36Sopenharmony_ci struct page_frag_1k page_small; 26962306a36Sopenharmony_ci unsigned int skb_count; 27062306a36Sopenharmony_ci void *skb_cache[NAPI_SKB_CACHE_SIZE]; 27162306a36Sopenharmony_ci}; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache); 27462306a36Sopenharmony_cistatic DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci/* Double check that napi_get_frags() allocates skbs with 27762306a36Sopenharmony_ci * skb->head being backed by slab, not a page fragment. 27862306a36Sopenharmony_ci * This is to make sure bug fixed in 3226b158e67c 27962306a36Sopenharmony_ci * ("net: avoid 32 x truesize under-estimation for tiny skbs") 28062306a36Sopenharmony_ci * does not accidentally come back. 28162306a36Sopenharmony_ci */ 28262306a36Sopenharmony_civoid napi_get_frags_check(struct napi_struct *napi) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci struct sk_buff *skb; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci local_bh_disable(); 28762306a36Sopenharmony_ci skb = napi_get_frags(napi); 28862306a36Sopenharmony_ci WARN_ON_ONCE(!NAPI_HAS_SMALL_PAGE_FRAG && skb && skb->head_frag); 28962306a36Sopenharmony_ci napi_free_frags(napi); 29062306a36Sopenharmony_ci local_bh_enable(); 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_civoid *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci fragsz = SKB_DATA_ALIGN(fragsz); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci return page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, align_mask); 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ciEXPORT_SYMBOL(__napi_alloc_frag_align); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_civoid *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci void *data; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci fragsz = SKB_DATA_ALIGN(fragsz); 30862306a36Sopenharmony_ci if (in_hardirq() || irqs_disabled()) { 30962306a36Sopenharmony_ci struct page_frag_cache *nc = this_cpu_ptr(&netdev_alloc_cache); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci data = page_frag_alloc_align(nc, fragsz, GFP_ATOMIC, align_mask); 31262306a36Sopenharmony_ci } else { 31362306a36Sopenharmony_ci struct napi_alloc_cache *nc; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci local_bh_disable(); 31662306a36Sopenharmony_ci nc = this_cpu_ptr(&napi_alloc_cache); 31762306a36Sopenharmony_ci data = page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, align_mask); 31862306a36Sopenharmony_ci local_bh_enable(); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci return data; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ciEXPORT_SYMBOL(__netdev_alloc_frag_align); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic struct sk_buff *napi_skb_cache_get(void) 32562306a36Sopenharmony_ci{ 32662306a36Sopenharmony_ci struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); 32762306a36Sopenharmony_ci struct sk_buff *skb; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci if (unlikely(!nc->skb_count)) { 33062306a36Sopenharmony_ci nc->skb_count = kmem_cache_alloc_bulk(skbuff_cache, 33162306a36Sopenharmony_ci GFP_ATOMIC, 33262306a36Sopenharmony_ci NAPI_SKB_CACHE_BULK, 33362306a36Sopenharmony_ci nc->skb_cache); 33462306a36Sopenharmony_ci if (unlikely(!nc->skb_count)) 33562306a36Sopenharmony_ci return NULL; 33662306a36Sopenharmony_ci } 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci skb = nc->skb_cache[--nc->skb_count]; 33962306a36Sopenharmony_ci kasan_unpoison_object_data(skbuff_cache, skb); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci return skb; 34262306a36Sopenharmony_ci} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cistatic inline void __finalize_skb_around(struct sk_buff *skb, void *data, 34562306a36Sopenharmony_ci unsigned int size) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci struct skb_shared_info *shinfo; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci size -= SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* Assumes caller memset cleared SKB */ 35262306a36Sopenharmony_ci skb->truesize = SKB_TRUESIZE(size); 35362306a36Sopenharmony_ci refcount_set(&skb->users, 1); 35462306a36Sopenharmony_ci skb->head = data; 35562306a36Sopenharmony_ci skb->data = data; 35662306a36Sopenharmony_ci skb_reset_tail_pointer(skb); 35762306a36Sopenharmony_ci skb_set_end_offset(skb, size); 35862306a36Sopenharmony_ci skb->mac_header = (typeof(skb->mac_header))~0U; 35962306a36Sopenharmony_ci skb->transport_header = (typeof(skb->transport_header))~0U; 36062306a36Sopenharmony_ci skb->alloc_cpu = raw_smp_processor_id(); 36162306a36Sopenharmony_ci /* make sure we initialize shinfo sequentially */ 36262306a36Sopenharmony_ci shinfo = skb_shinfo(skb); 36362306a36Sopenharmony_ci memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); 36462306a36Sopenharmony_ci atomic_set(&shinfo->dataref, 1); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci skb_set_kcov_handle(skb, kcov_common_handle()); 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistatic inline void *__slab_build_skb(struct sk_buff *skb, void *data, 37062306a36Sopenharmony_ci unsigned int *size) 37162306a36Sopenharmony_ci{ 37262306a36Sopenharmony_ci void *resized; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* Must find the allocation size (and grow it to match). */ 37562306a36Sopenharmony_ci *size = ksize(data); 37662306a36Sopenharmony_ci /* krealloc() will immediately return "data" when 37762306a36Sopenharmony_ci * "ksize(data)" is requested: it is the existing upper 37862306a36Sopenharmony_ci * bounds. As a result, GFP_ATOMIC will be ignored. Note 37962306a36Sopenharmony_ci * that this "new" pointer needs to be passed back to the 38062306a36Sopenharmony_ci * caller for use so the __alloc_size hinting will be 38162306a36Sopenharmony_ci * tracked correctly. 38262306a36Sopenharmony_ci */ 38362306a36Sopenharmony_ci resized = krealloc(data, *size, GFP_ATOMIC); 38462306a36Sopenharmony_ci WARN_ON_ONCE(resized != data); 38562306a36Sopenharmony_ci return resized; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci/* build_skb() variant which can operate on slab buffers. 38962306a36Sopenharmony_ci * Note that this should be used sparingly as slab buffers 39062306a36Sopenharmony_ci * cannot be combined efficiently by GRO! 39162306a36Sopenharmony_ci */ 39262306a36Sopenharmony_cistruct sk_buff *slab_build_skb(void *data) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci struct sk_buff *skb; 39562306a36Sopenharmony_ci unsigned int size; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci skb = kmem_cache_alloc(skbuff_cache, GFP_ATOMIC); 39862306a36Sopenharmony_ci if (unlikely(!skb)) 39962306a36Sopenharmony_ci return NULL; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci memset(skb, 0, offsetof(struct sk_buff, tail)); 40262306a36Sopenharmony_ci data = __slab_build_skb(skb, data, &size); 40362306a36Sopenharmony_ci __finalize_skb_around(skb, data, size); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci return skb; 40662306a36Sopenharmony_ci} 40762306a36Sopenharmony_ciEXPORT_SYMBOL(slab_build_skb); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci/* Caller must provide SKB that is memset cleared */ 41062306a36Sopenharmony_cistatic void __build_skb_around(struct sk_buff *skb, void *data, 41162306a36Sopenharmony_ci unsigned int frag_size) 41262306a36Sopenharmony_ci{ 41362306a36Sopenharmony_ci unsigned int size = frag_size; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci /* frag_size == 0 is considered deprecated now. Callers 41662306a36Sopenharmony_ci * using slab buffer should use slab_build_skb() instead. 41762306a36Sopenharmony_ci */ 41862306a36Sopenharmony_ci if (WARN_ONCE(size == 0, "Use slab_build_skb() instead")) 41962306a36Sopenharmony_ci data = __slab_build_skb(skb, data, &size); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci __finalize_skb_around(skb, data, size); 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci/** 42562306a36Sopenharmony_ci * __build_skb - build a network buffer 42662306a36Sopenharmony_ci * @data: data buffer provided by caller 42762306a36Sopenharmony_ci * @frag_size: size of data (must not be 0) 42862306a36Sopenharmony_ci * 42962306a36Sopenharmony_ci * Allocate a new &sk_buff. Caller provides space holding head and 43062306a36Sopenharmony_ci * skb_shared_info. @data must have been allocated from the page 43162306a36Sopenharmony_ci * allocator or vmalloc(). (A @frag_size of 0 to indicate a kmalloc() 43262306a36Sopenharmony_ci * allocation is deprecated, and callers should use slab_build_skb() 43362306a36Sopenharmony_ci * instead.) 43462306a36Sopenharmony_ci * The return is the new skb buffer. 43562306a36Sopenharmony_ci * On a failure the return is %NULL, and @data is not freed. 43662306a36Sopenharmony_ci * Notes : 43762306a36Sopenharmony_ci * Before IO, driver allocates only data buffer where NIC put incoming frame 43862306a36Sopenharmony_ci * Driver should add room at head (NET_SKB_PAD) and 43962306a36Sopenharmony_ci * MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info)) 44062306a36Sopenharmony_ci * After IO, driver calls build_skb(), to allocate sk_buff and populate it 44162306a36Sopenharmony_ci * before giving packet to stack. 44262306a36Sopenharmony_ci * RX rings only contains data buffers, not full skbs. 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_cistruct sk_buff *__build_skb(void *data, unsigned int frag_size) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci struct sk_buff *skb; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci skb = kmem_cache_alloc(skbuff_cache, GFP_ATOMIC); 44962306a36Sopenharmony_ci if (unlikely(!skb)) 45062306a36Sopenharmony_ci return NULL; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci memset(skb, 0, offsetof(struct sk_buff, tail)); 45362306a36Sopenharmony_ci __build_skb_around(skb, data, frag_size); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci return skb; 45662306a36Sopenharmony_ci} 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci/* build_skb() is wrapper over __build_skb(), that specifically 45962306a36Sopenharmony_ci * takes care of skb->head and skb->pfmemalloc 46062306a36Sopenharmony_ci */ 46162306a36Sopenharmony_cistruct sk_buff *build_skb(void *data, unsigned int frag_size) 46262306a36Sopenharmony_ci{ 46362306a36Sopenharmony_ci struct sk_buff *skb = __build_skb(data, frag_size); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci if (likely(skb && frag_size)) { 46662306a36Sopenharmony_ci skb->head_frag = 1; 46762306a36Sopenharmony_ci skb_propagate_pfmemalloc(virt_to_head_page(data), skb); 46862306a36Sopenharmony_ci } 46962306a36Sopenharmony_ci return skb; 47062306a36Sopenharmony_ci} 47162306a36Sopenharmony_ciEXPORT_SYMBOL(build_skb); 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci/** 47462306a36Sopenharmony_ci * build_skb_around - build a network buffer around provided skb 47562306a36Sopenharmony_ci * @skb: sk_buff provide by caller, must be memset cleared 47662306a36Sopenharmony_ci * @data: data buffer provided by caller 47762306a36Sopenharmony_ci * @frag_size: size of data 47862306a36Sopenharmony_ci */ 47962306a36Sopenharmony_cistruct sk_buff *build_skb_around(struct sk_buff *skb, 48062306a36Sopenharmony_ci void *data, unsigned int frag_size) 48162306a36Sopenharmony_ci{ 48262306a36Sopenharmony_ci if (unlikely(!skb)) 48362306a36Sopenharmony_ci return NULL; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci __build_skb_around(skb, data, frag_size); 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci if (frag_size) { 48862306a36Sopenharmony_ci skb->head_frag = 1; 48962306a36Sopenharmony_ci skb_propagate_pfmemalloc(virt_to_head_page(data), skb); 49062306a36Sopenharmony_ci } 49162306a36Sopenharmony_ci return skb; 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ciEXPORT_SYMBOL(build_skb_around); 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci/** 49662306a36Sopenharmony_ci * __napi_build_skb - build a network buffer 49762306a36Sopenharmony_ci * @data: data buffer provided by caller 49862306a36Sopenharmony_ci * @frag_size: size of data 49962306a36Sopenharmony_ci * 50062306a36Sopenharmony_ci * Version of __build_skb() that uses NAPI percpu caches to obtain 50162306a36Sopenharmony_ci * skbuff_head instead of inplace allocation. 50262306a36Sopenharmony_ci * 50362306a36Sopenharmony_ci * Returns a new &sk_buff on success, %NULL on allocation failure. 50462306a36Sopenharmony_ci */ 50562306a36Sopenharmony_cistatic struct sk_buff *__napi_build_skb(void *data, unsigned int frag_size) 50662306a36Sopenharmony_ci{ 50762306a36Sopenharmony_ci struct sk_buff *skb; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci skb = napi_skb_cache_get(); 51062306a36Sopenharmony_ci if (unlikely(!skb)) 51162306a36Sopenharmony_ci return NULL; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci memset(skb, 0, offsetof(struct sk_buff, tail)); 51462306a36Sopenharmony_ci __build_skb_around(skb, data, frag_size); 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci return skb; 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci/** 52062306a36Sopenharmony_ci * napi_build_skb - build a network buffer 52162306a36Sopenharmony_ci * @data: data buffer provided by caller 52262306a36Sopenharmony_ci * @frag_size: size of data 52362306a36Sopenharmony_ci * 52462306a36Sopenharmony_ci * Version of __napi_build_skb() that takes care of skb->head_frag 52562306a36Sopenharmony_ci * and skb->pfmemalloc when the data is a page or page fragment. 52662306a36Sopenharmony_ci * 52762306a36Sopenharmony_ci * Returns a new &sk_buff on success, %NULL on allocation failure. 52862306a36Sopenharmony_ci */ 52962306a36Sopenharmony_cistruct sk_buff *napi_build_skb(void *data, unsigned int frag_size) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci struct sk_buff *skb = __napi_build_skb(data, frag_size); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (likely(skb) && frag_size) { 53462306a36Sopenharmony_ci skb->head_frag = 1; 53562306a36Sopenharmony_ci skb_propagate_pfmemalloc(virt_to_head_page(data), skb); 53662306a36Sopenharmony_ci } 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return skb; 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ciEXPORT_SYMBOL(napi_build_skb); 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci/* 54362306a36Sopenharmony_ci * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tells 54462306a36Sopenharmony_ci * the caller if emergency pfmemalloc reserves are being used. If it is and 54562306a36Sopenharmony_ci * the socket is later found to be SOCK_MEMALLOC then PFMEMALLOC reserves 54662306a36Sopenharmony_ci * may be used. Otherwise, the packet data may be discarded until enough 54762306a36Sopenharmony_ci * memory is free 54862306a36Sopenharmony_ci */ 54962306a36Sopenharmony_cistatic void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, 55062306a36Sopenharmony_ci bool *pfmemalloc) 55162306a36Sopenharmony_ci{ 55262306a36Sopenharmony_ci bool ret_pfmemalloc = false; 55362306a36Sopenharmony_ci size_t obj_size; 55462306a36Sopenharmony_ci void *obj; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci obj_size = SKB_HEAD_ALIGN(*size); 55762306a36Sopenharmony_ci if (obj_size <= SKB_SMALL_HEAD_CACHE_SIZE && 55862306a36Sopenharmony_ci !(flags & KMALLOC_NOT_NORMAL_BITS)) { 55962306a36Sopenharmony_ci obj = kmem_cache_alloc_node(skb_small_head_cache, 56062306a36Sopenharmony_ci flags | __GFP_NOMEMALLOC | __GFP_NOWARN, 56162306a36Sopenharmony_ci node); 56262306a36Sopenharmony_ci *size = SKB_SMALL_HEAD_CACHE_SIZE; 56362306a36Sopenharmony_ci if (obj || !(gfp_pfmemalloc_allowed(flags))) 56462306a36Sopenharmony_ci goto out; 56562306a36Sopenharmony_ci /* Try again but now we are using pfmemalloc reserves */ 56662306a36Sopenharmony_ci ret_pfmemalloc = true; 56762306a36Sopenharmony_ci obj = kmem_cache_alloc_node(skb_small_head_cache, flags, node); 56862306a36Sopenharmony_ci goto out; 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci obj_size = kmalloc_size_roundup(obj_size); 57262306a36Sopenharmony_ci /* The following cast might truncate high-order bits of obj_size, this 57362306a36Sopenharmony_ci * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. 57462306a36Sopenharmony_ci */ 57562306a36Sopenharmony_ci *size = (unsigned int)obj_size; 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci /* 57862306a36Sopenharmony_ci * Try a regular allocation, when that fails and we're not entitled 57962306a36Sopenharmony_ci * to the reserves, fail. 58062306a36Sopenharmony_ci */ 58162306a36Sopenharmony_ci obj = kmalloc_node_track_caller(obj_size, 58262306a36Sopenharmony_ci flags | __GFP_NOMEMALLOC | __GFP_NOWARN, 58362306a36Sopenharmony_ci node); 58462306a36Sopenharmony_ci if (obj || !(gfp_pfmemalloc_allowed(flags))) 58562306a36Sopenharmony_ci goto out; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci /* Try again but now we are using pfmemalloc reserves */ 58862306a36Sopenharmony_ci ret_pfmemalloc = true; 58962306a36Sopenharmony_ci obj = kmalloc_node_track_caller(obj_size, flags, node); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ciout: 59262306a36Sopenharmony_ci if (pfmemalloc) 59362306a36Sopenharmony_ci *pfmemalloc = ret_pfmemalloc; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci return obj; 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci/* Allocate a new skbuff. We do this ourselves so we can fill in a few 59962306a36Sopenharmony_ci * 'private' fields and also do memory statistics to find all the 60062306a36Sopenharmony_ci * [BEEP] leaks. 60162306a36Sopenharmony_ci * 60262306a36Sopenharmony_ci */ 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci/** 60562306a36Sopenharmony_ci * __alloc_skb - allocate a network buffer 60662306a36Sopenharmony_ci * @size: size to allocate 60762306a36Sopenharmony_ci * @gfp_mask: allocation mask 60862306a36Sopenharmony_ci * @flags: If SKB_ALLOC_FCLONE is set, allocate from fclone cache 60962306a36Sopenharmony_ci * instead of head cache and allocate a cloned (child) skb. 61062306a36Sopenharmony_ci * If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for 61162306a36Sopenharmony_ci * allocations in case the data is required for writeback 61262306a36Sopenharmony_ci * @node: numa node to allocate memory on 61362306a36Sopenharmony_ci * 61462306a36Sopenharmony_ci * Allocate a new &sk_buff. The returned buffer has no headroom and a 61562306a36Sopenharmony_ci * tail room of at least size bytes. The object has a reference count 61662306a36Sopenharmony_ci * of one. The return is the buffer. On a failure the return is %NULL. 61762306a36Sopenharmony_ci * 61862306a36Sopenharmony_ci * Buffers may only be allocated from interrupts using a @gfp_mask of 61962306a36Sopenharmony_ci * %GFP_ATOMIC. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_cistruct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, 62262306a36Sopenharmony_ci int flags, int node) 62362306a36Sopenharmony_ci{ 62462306a36Sopenharmony_ci struct kmem_cache *cache; 62562306a36Sopenharmony_ci struct sk_buff *skb; 62662306a36Sopenharmony_ci bool pfmemalloc; 62762306a36Sopenharmony_ci u8 *data; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci cache = (flags & SKB_ALLOC_FCLONE) 63062306a36Sopenharmony_ci ? skbuff_fclone_cache : skbuff_cache; 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci if (sk_memalloc_socks() && (flags & SKB_ALLOC_RX)) 63362306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci /* Get the HEAD */ 63662306a36Sopenharmony_ci if ((flags & (SKB_ALLOC_FCLONE | SKB_ALLOC_NAPI)) == SKB_ALLOC_NAPI && 63762306a36Sopenharmony_ci likely(node == NUMA_NO_NODE || node == numa_mem_id())) 63862306a36Sopenharmony_ci skb = napi_skb_cache_get(); 63962306a36Sopenharmony_ci else 64062306a36Sopenharmony_ci skb = kmem_cache_alloc_node(cache, gfp_mask & ~GFP_DMA, node); 64162306a36Sopenharmony_ci if (unlikely(!skb)) 64262306a36Sopenharmony_ci return NULL; 64362306a36Sopenharmony_ci prefetchw(skb); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci /* We do our best to align skb_shared_info on a separate cache 64662306a36Sopenharmony_ci * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives 64762306a36Sopenharmony_ci * aligned memory blocks, unless SLUB/SLAB debug is enabled. 64862306a36Sopenharmony_ci * Both skb->head and skb_shared_info are cache line aligned. 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_ci data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); 65162306a36Sopenharmony_ci if (unlikely(!data)) 65262306a36Sopenharmony_ci goto nodata; 65362306a36Sopenharmony_ci /* kmalloc_size_roundup() might give us more room than requested. 65462306a36Sopenharmony_ci * Put skb_shared_info exactly at the end of allocated zone, 65562306a36Sopenharmony_ci * to allow max possible filling before reallocation. 65662306a36Sopenharmony_ci */ 65762306a36Sopenharmony_ci prefetchw(data + SKB_WITH_OVERHEAD(size)); 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci /* 66062306a36Sopenharmony_ci * Only clear those fields we need to clear, not those that we will 66162306a36Sopenharmony_ci * actually initialise below. Hence, don't put any more fields after 66262306a36Sopenharmony_ci * the tail pointer in struct sk_buff! 66362306a36Sopenharmony_ci */ 66462306a36Sopenharmony_ci memset(skb, 0, offsetof(struct sk_buff, tail)); 66562306a36Sopenharmony_ci __build_skb_around(skb, data, size); 66662306a36Sopenharmony_ci skb->pfmemalloc = pfmemalloc; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci if (flags & SKB_ALLOC_FCLONE) { 66962306a36Sopenharmony_ci struct sk_buff_fclones *fclones; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci fclones = container_of(skb, struct sk_buff_fclones, skb1); 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci skb->fclone = SKB_FCLONE_ORIG; 67462306a36Sopenharmony_ci refcount_set(&fclones->fclone_ref, 1); 67562306a36Sopenharmony_ci } 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci return skb; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_cinodata: 68062306a36Sopenharmony_ci kmem_cache_free(cache, skb); 68162306a36Sopenharmony_ci return NULL; 68262306a36Sopenharmony_ci} 68362306a36Sopenharmony_ciEXPORT_SYMBOL(__alloc_skb); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci/** 68662306a36Sopenharmony_ci * __netdev_alloc_skb - allocate an skbuff for rx on a specific device 68762306a36Sopenharmony_ci * @dev: network device to receive on 68862306a36Sopenharmony_ci * @len: length to allocate 68962306a36Sopenharmony_ci * @gfp_mask: get_free_pages mask, passed to alloc_skb 69062306a36Sopenharmony_ci * 69162306a36Sopenharmony_ci * Allocate a new &sk_buff and assign it a usage count of one. The 69262306a36Sopenharmony_ci * buffer has NET_SKB_PAD headroom built in. Users should allocate 69362306a36Sopenharmony_ci * the headroom they think they need without accounting for the 69462306a36Sopenharmony_ci * built in space. The built in space is used for optimisations. 69562306a36Sopenharmony_ci * 69662306a36Sopenharmony_ci * %NULL is returned if there is no free memory. 69762306a36Sopenharmony_ci */ 69862306a36Sopenharmony_cistruct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, 69962306a36Sopenharmony_ci gfp_t gfp_mask) 70062306a36Sopenharmony_ci{ 70162306a36Sopenharmony_ci struct page_frag_cache *nc; 70262306a36Sopenharmony_ci struct sk_buff *skb; 70362306a36Sopenharmony_ci bool pfmemalloc; 70462306a36Sopenharmony_ci void *data; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci len += NET_SKB_PAD; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci /* If requested length is either too small or too big, 70962306a36Sopenharmony_ci * we use kmalloc() for skb->head allocation. 71062306a36Sopenharmony_ci */ 71162306a36Sopenharmony_ci if (len <= SKB_WITH_OVERHEAD(1024) || 71262306a36Sopenharmony_ci len > SKB_WITH_OVERHEAD(PAGE_SIZE) || 71362306a36Sopenharmony_ci (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { 71462306a36Sopenharmony_ci skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE); 71562306a36Sopenharmony_ci if (!skb) 71662306a36Sopenharmony_ci goto skb_fail; 71762306a36Sopenharmony_ci goto skb_success; 71862306a36Sopenharmony_ci } 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci len = SKB_HEAD_ALIGN(len); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci if (sk_memalloc_socks()) 72362306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci if (in_hardirq() || irqs_disabled()) { 72662306a36Sopenharmony_ci nc = this_cpu_ptr(&netdev_alloc_cache); 72762306a36Sopenharmony_ci data = page_frag_alloc(nc, len, gfp_mask); 72862306a36Sopenharmony_ci pfmemalloc = nc->pfmemalloc; 72962306a36Sopenharmony_ci } else { 73062306a36Sopenharmony_ci local_bh_disable(); 73162306a36Sopenharmony_ci nc = this_cpu_ptr(&napi_alloc_cache.page); 73262306a36Sopenharmony_ci data = page_frag_alloc(nc, len, gfp_mask); 73362306a36Sopenharmony_ci pfmemalloc = nc->pfmemalloc; 73462306a36Sopenharmony_ci local_bh_enable(); 73562306a36Sopenharmony_ci } 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci if (unlikely(!data)) 73862306a36Sopenharmony_ci return NULL; 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci skb = __build_skb(data, len); 74162306a36Sopenharmony_ci if (unlikely(!skb)) { 74262306a36Sopenharmony_ci skb_free_frag(data); 74362306a36Sopenharmony_ci return NULL; 74462306a36Sopenharmony_ci } 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci if (pfmemalloc) 74762306a36Sopenharmony_ci skb->pfmemalloc = 1; 74862306a36Sopenharmony_ci skb->head_frag = 1; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ciskb_success: 75162306a36Sopenharmony_ci skb_reserve(skb, NET_SKB_PAD); 75262306a36Sopenharmony_ci skb->dev = dev; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ciskb_fail: 75562306a36Sopenharmony_ci return skb; 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ciEXPORT_SYMBOL(__netdev_alloc_skb); 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci/** 76062306a36Sopenharmony_ci * __napi_alloc_skb - allocate skbuff for rx in a specific NAPI instance 76162306a36Sopenharmony_ci * @napi: napi instance this buffer was allocated for 76262306a36Sopenharmony_ci * @len: length to allocate 76362306a36Sopenharmony_ci * @gfp_mask: get_free_pages mask, passed to alloc_skb and alloc_pages 76462306a36Sopenharmony_ci * 76562306a36Sopenharmony_ci * Allocate a new sk_buff for use in NAPI receive. This buffer will 76662306a36Sopenharmony_ci * attempt to allocate the head from a special reserved region used 76762306a36Sopenharmony_ci * only for NAPI Rx allocation. By doing this we can save several 76862306a36Sopenharmony_ci * CPU cycles by avoiding having to disable and re-enable IRQs. 76962306a36Sopenharmony_ci * 77062306a36Sopenharmony_ci * %NULL is returned if there is no free memory. 77162306a36Sopenharmony_ci */ 77262306a36Sopenharmony_cistruct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, 77362306a36Sopenharmony_ci gfp_t gfp_mask) 77462306a36Sopenharmony_ci{ 77562306a36Sopenharmony_ci struct napi_alloc_cache *nc; 77662306a36Sopenharmony_ci struct sk_buff *skb; 77762306a36Sopenharmony_ci bool pfmemalloc; 77862306a36Sopenharmony_ci void *data; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(!in_softirq()); 78162306a36Sopenharmony_ci len += NET_SKB_PAD + NET_IP_ALIGN; 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci /* If requested length is either too small or too big, 78462306a36Sopenharmony_ci * we use kmalloc() for skb->head allocation. 78562306a36Sopenharmony_ci * When the small frag allocator is available, prefer it over kmalloc 78662306a36Sopenharmony_ci * for small fragments 78762306a36Sopenharmony_ci */ 78862306a36Sopenharmony_ci if ((!NAPI_HAS_SMALL_PAGE_FRAG && len <= SKB_WITH_OVERHEAD(1024)) || 78962306a36Sopenharmony_ci len > SKB_WITH_OVERHEAD(PAGE_SIZE) || 79062306a36Sopenharmony_ci (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) { 79162306a36Sopenharmony_ci skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX | SKB_ALLOC_NAPI, 79262306a36Sopenharmony_ci NUMA_NO_NODE); 79362306a36Sopenharmony_ci if (!skb) 79462306a36Sopenharmony_ci goto skb_fail; 79562306a36Sopenharmony_ci goto skb_success; 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci nc = this_cpu_ptr(&napi_alloc_cache); 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci if (sk_memalloc_socks()) 80162306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci if (NAPI_HAS_SMALL_PAGE_FRAG && len <= SKB_WITH_OVERHEAD(1024)) { 80462306a36Sopenharmony_ci /* we are artificially inflating the allocation size, but 80562306a36Sopenharmony_ci * that is not as bad as it may look like, as: 80662306a36Sopenharmony_ci * - 'len' less than GRO_MAX_HEAD makes little sense 80762306a36Sopenharmony_ci * - On most systems, larger 'len' values lead to fragment 80862306a36Sopenharmony_ci * size above 512 bytes 80962306a36Sopenharmony_ci * - kmalloc would use the kmalloc-1k slab for such values 81062306a36Sopenharmony_ci * - Builds with smaller GRO_MAX_HEAD will very likely do 81162306a36Sopenharmony_ci * little networking, as that implies no WiFi and no 81262306a36Sopenharmony_ci * tunnels support, and 32 bits arches. 81362306a36Sopenharmony_ci */ 81462306a36Sopenharmony_ci len = SZ_1K; 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci data = page_frag_alloc_1k(&nc->page_small, gfp_mask); 81762306a36Sopenharmony_ci pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); 81862306a36Sopenharmony_ci } else { 81962306a36Sopenharmony_ci len = SKB_HEAD_ALIGN(len); 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci data = page_frag_alloc(&nc->page, len, gfp_mask); 82262306a36Sopenharmony_ci pfmemalloc = nc->page.pfmemalloc; 82362306a36Sopenharmony_ci } 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci if (unlikely(!data)) 82662306a36Sopenharmony_ci return NULL; 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci skb = __napi_build_skb(data, len); 82962306a36Sopenharmony_ci if (unlikely(!skb)) { 83062306a36Sopenharmony_ci skb_free_frag(data); 83162306a36Sopenharmony_ci return NULL; 83262306a36Sopenharmony_ci } 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci if (pfmemalloc) 83562306a36Sopenharmony_ci skb->pfmemalloc = 1; 83662306a36Sopenharmony_ci skb->head_frag = 1; 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ciskb_success: 83962306a36Sopenharmony_ci skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); 84062306a36Sopenharmony_ci skb->dev = napi->dev; 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ciskb_fail: 84362306a36Sopenharmony_ci return skb; 84462306a36Sopenharmony_ci} 84562306a36Sopenharmony_ciEXPORT_SYMBOL(__napi_alloc_skb); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_civoid skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, 84862306a36Sopenharmony_ci int size, unsigned int truesize) 84962306a36Sopenharmony_ci{ 85062306a36Sopenharmony_ci skb_fill_page_desc(skb, i, page, off, size); 85162306a36Sopenharmony_ci skb->len += size; 85262306a36Sopenharmony_ci skb->data_len += size; 85362306a36Sopenharmony_ci skb->truesize += truesize; 85462306a36Sopenharmony_ci} 85562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_add_rx_frag); 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_civoid skb_coalesce_rx_frag(struct sk_buff *skb, int i, int size, 85862306a36Sopenharmony_ci unsigned int truesize) 85962306a36Sopenharmony_ci{ 86062306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci skb_frag_size_add(frag, size); 86362306a36Sopenharmony_ci skb->len += size; 86462306a36Sopenharmony_ci skb->data_len += size; 86562306a36Sopenharmony_ci skb->truesize += truesize; 86662306a36Sopenharmony_ci} 86762306a36Sopenharmony_ciEXPORT_SYMBOL(skb_coalesce_rx_frag); 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_cistatic void skb_drop_list(struct sk_buff **listp) 87062306a36Sopenharmony_ci{ 87162306a36Sopenharmony_ci kfree_skb_list(*listp); 87262306a36Sopenharmony_ci *listp = NULL; 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic inline void skb_drop_fraglist(struct sk_buff *skb) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci skb_drop_list(&skb_shinfo(skb)->frag_list); 87862306a36Sopenharmony_ci} 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_cistatic void skb_clone_fraglist(struct sk_buff *skb) 88162306a36Sopenharmony_ci{ 88262306a36Sopenharmony_ci struct sk_buff *list; 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci skb_walk_frags(skb, list) 88562306a36Sopenharmony_ci skb_get(list); 88662306a36Sopenharmony_ci} 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_PAGE_POOL) 88962306a36Sopenharmony_cibool napi_pp_put_page(struct page *page, bool napi_safe) 89062306a36Sopenharmony_ci{ 89162306a36Sopenharmony_ci bool allow_direct = false; 89262306a36Sopenharmony_ci struct page_pool *pp; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci page = compound_head(page); 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci /* page->pp_magic is OR'ed with PP_SIGNATURE after the allocation 89762306a36Sopenharmony_ci * in order to preserve any existing bits, such as bit 0 for the 89862306a36Sopenharmony_ci * head page of compound page and bit 1 for pfmemalloc page, so 89962306a36Sopenharmony_ci * mask those bits for freeing side when doing below checking, 90062306a36Sopenharmony_ci * and page_is_pfmemalloc() is checked in __page_pool_put_page() 90162306a36Sopenharmony_ci * to avoid recycling the pfmemalloc page. 90262306a36Sopenharmony_ci */ 90362306a36Sopenharmony_ci if (unlikely((page->pp_magic & ~0x3UL) != PP_SIGNATURE)) 90462306a36Sopenharmony_ci return false; 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci pp = page->pp; 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci /* Allow direct recycle if we have reasons to believe that we are 90962306a36Sopenharmony_ci * in the same context as the consumer would run, so there's 91062306a36Sopenharmony_ci * no possible race. 91162306a36Sopenharmony_ci * __page_pool_put_page() makes sure we're not in hardirq context 91262306a36Sopenharmony_ci * and interrupts are enabled prior to accessing the cache. 91362306a36Sopenharmony_ci */ 91462306a36Sopenharmony_ci if (napi_safe || in_softirq()) { 91562306a36Sopenharmony_ci const struct napi_struct *napi = READ_ONCE(pp->p.napi); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci allow_direct = napi && 91862306a36Sopenharmony_ci READ_ONCE(napi->list_owner) == smp_processor_id(); 91962306a36Sopenharmony_ci } 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci /* Driver set this to memory recycling info. Reset it on recycle. 92262306a36Sopenharmony_ci * This will *not* work for NIC using a split-page memory model. 92362306a36Sopenharmony_ci * The page will be returned to the pool here regardless of the 92462306a36Sopenharmony_ci * 'flipped' fragment being in use or not. 92562306a36Sopenharmony_ci */ 92662306a36Sopenharmony_ci page_pool_put_full_page(pp, page, allow_direct); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci return true; 92962306a36Sopenharmony_ci} 93062306a36Sopenharmony_ciEXPORT_SYMBOL(napi_pp_put_page); 93162306a36Sopenharmony_ci#endif 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_cistatic bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe) 93462306a36Sopenharmony_ci{ 93562306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle) 93662306a36Sopenharmony_ci return false; 93762306a36Sopenharmony_ci return napi_pp_put_page(virt_to_page(data), napi_safe); 93862306a36Sopenharmony_ci} 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_cistatic void skb_kfree_head(void *head, unsigned int end_offset) 94162306a36Sopenharmony_ci{ 94262306a36Sopenharmony_ci if (end_offset == SKB_SMALL_HEAD_HEADROOM) 94362306a36Sopenharmony_ci kmem_cache_free(skb_small_head_cache, head); 94462306a36Sopenharmony_ci else 94562306a36Sopenharmony_ci kfree(head); 94662306a36Sopenharmony_ci} 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_cistatic void skb_free_head(struct sk_buff *skb, bool napi_safe) 94962306a36Sopenharmony_ci{ 95062306a36Sopenharmony_ci unsigned char *head = skb->head; 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci if (skb->head_frag) { 95362306a36Sopenharmony_ci if (skb_pp_recycle(skb, head, napi_safe)) 95462306a36Sopenharmony_ci return; 95562306a36Sopenharmony_ci skb_free_frag(head); 95662306a36Sopenharmony_ci } else { 95762306a36Sopenharmony_ci skb_kfree_head(head, skb_end_offset(skb)); 95862306a36Sopenharmony_ci } 95962306a36Sopenharmony_ci} 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_cistatic void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason, 96262306a36Sopenharmony_ci bool napi_safe) 96362306a36Sopenharmony_ci{ 96462306a36Sopenharmony_ci struct skb_shared_info *shinfo = skb_shinfo(skb); 96562306a36Sopenharmony_ci int i; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci if (skb->cloned && 96862306a36Sopenharmony_ci atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, 96962306a36Sopenharmony_ci &shinfo->dataref)) 97062306a36Sopenharmony_ci goto exit; 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci if (skb_zcopy(skb)) { 97362306a36Sopenharmony_ci bool skip_unref = shinfo->flags & SKBFL_MANAGED_FRAG_REFS; 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci skb_zcopy_clear(skb, true); 97662306a36Sopenharmony_ci if (skip_unref) 97762306a36Sopenharmony_ci goto free_head; 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci for (i = 0; i < shinfo->nr_frags; i++) 98162306a36Sopenharmony_ci napi_frag_unref(&shinfo->frags[i], skb->pp_recycle, napi_safe); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_cifree_head: 98462306a36Sopenharmony_ci if (shinfo->frag_list) 98562306a36Sopenharmony_ci kfree_skb_list_reason(shinfo->frag_list, reason); 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci skb_free_head(skb, napi_safe); 98862306a36Sopenharmony_ciexit: 98962306a36Sopenharmony_ci /* When we clone an SKB we copy the reycling bit. The pp_recycle 99062306a36Sopenharmony_ci * bit is only set on the head though, so in order to avoid races 99162306a36Sopenharmony_ci * while trying to recycle fragments on __skb_frag_unref() we need 99262306a36Sopenharmony_ci * to make one SKB responsible for triggering the recycle path. 99362306a36Sopenharmony_ci * So disable the recycling bit if an SKB is cloned and we have 99462306a36Sopenharmony_ci * additional references to the fragmented part of the SKB. 99562306a36Sopenharmony_ci * Eventually the last SKB will have the recycling bit set and it's 99662306a36Sopenharmony_ci * dataref set to 0, which will trigger the recycling 99762306a36Sopenharmony_ci */ 99862306a36Sopenharmony_ci skb->pp_recycle = 0; 99962306a36Sopenharmony_ci} 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci/* 100262306a36Sopenharmony_ci * Free an skbuff by memory without cleaning the state. 100362306a36Sopenharmony_ci */ 100462306a36Sopenharmony_cistatic void kfree_skbmem(struct sk_buff *skb) 100562306a36Sopenharmony_ci{ 100662306a36Sopenharmony_ci struct sk_buff_fclones *fclones; 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci switch (skb->fclone) { 100962306a36Sopenharmony_ci case SKB_FCLONE_UNAVAILABLE: 101062306a36Sopenharmony_ci kmem_cache_free(skbuff_cache, skb); 101162306a36Sopenharmony_ci return; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci case SKB_FCLONE_ORIG: 101462306a36Sopenharmony_ci fclones = container_of(skb, struct sk_buff_fclones, skb1); 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci /* We usually free the clone (TX completion) before original skb 101762306a36Sopenharmony_ci * This test would have no chance to be true for the clone, 101862306a36Sopenharmony_ci * while here, branch prediction will be good. 101962306a36Sopenharmony_ci */ 102062306a36Sopenharmony_ci if (refcount_read(&fclones->fclone_ref) == 1) 102162306a36Sopenharmony_ci goto fastpath; 102262306a36Sopenharmony_ci break; 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci default: /* SKB_FCLONE_CLONE */ 102562306a36Sopenharmony_ci fclones = container_of(skb, struct sk_buff_fclones, skb2); 102662306a36Sopenharmony_ci break; 102762306a36Sopenharmony_ci } 102862306a36Sopenharmony_ci if (!refcount_dec_and_test(&fclones->fclone_ref)) 102962306a36Sopenharmony_ci return; 103062306a36Sopenharmony_cifastpath: 103162306a36Sopenharmony_ci kmem_cache_free(skbuff_fclone_cache, fclones); 103262306a36Sopenharmony_ci} 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_civoid skb_release_head_state(struct sk_buff *skb) 103562306a36Sopenharmony_ci{ 103662306a36Sopenharmony_ci skb_dst_drop(skb); 103762306a36Sopenharmony_ci if (skb->destructor) { 103862306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(in_hardirq()); 103962306a36Sopenharmony_ci skb->destructor(skb); 104062306a36Sopenharmony_ci } 104162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK) 104262306a36Sopenharmony_ci nf_conntrack_put(skb_nfct(skb)); 104362306a36Sopenharmony_ci#endif 104462306a36Sopenharmony_ci skb_ext_put(skb); 104562306a36Sopenharmony_ci} 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci/* Free everything but the sk_buff shell. */ 104862306a36Sopenharmony_cistatic void skb_release_all(struct sk_buff *skb, enum skb_drop_reason reason, 104962306a36Sopenharmony_ci bool napi_safe) 105062306a36Sopenharmony_ci{ 105162306a36Sopenharmony_ci skb_release_head_state(skb); 105262306a36Sopenharmony_ci if (likely(skb->head)) 105362306a36Sopenharmony_ci skb_release_data(skb, reason, napi_safe); 105462306a36Sopenharmony_ci} 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci/** 105762306a36Sopenharmony_ci * __kfree_skb - private function 105862306a36Sopenharmony_ci * @skb: buffer 105962306a36Sopenharmony_ci * 106062306a36Sopenharmony_ci * Free an sk_buff. Release anything attached to the buffer. 106162306a36Sopenharmony_ci * Clean the state. This is an internal helper function. Users should 106262306a36Sopenharmony_ci * always call kfree_skb 106362306a36Sopenharmony_ci */ 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_civoid __kfree_skb(struct sk_buff *skb) 106662306a36Sopenharmony_ci{ 106762306a36Sopenharmony_ci skb_release_all(skb, SKB_DROP_REASON_NOT_SPECIFIED, false); 106862306a36Sopenharmony_ci kfree_skbmem(skb); 106962306a36Sopenharmony_ci} 107062306a36Sopenharmony_ciEXPORT_SYMBOL(__kfree_skb); 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_cistatic __always_inline 107362306a36Sopenharmony_cibool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason) 107462306a36Sopenharmony_ci{ 107562306a36Sopenharmony_ci if (unlikely(!skb_unref(skb))) 107662306a36Sopenharmony_ci return false; 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(reason == SKB_NOT_DROPPED_YET || 107962306a36Sopenharmony_ci u32_get_bits(reason, 108062306a36Sopenharmony_ci SKB_DROP_REASON_SUBSYS_MASK) >= 108162306a36Sopenharmony_ci SKB_DROP_REASON_SUBSYS_NUM); 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci if (reason == SKB_CONSUMED) 108462306a36Sopenharmony_ci trace_consume_skb(skb, __builtin_return_address(0)); 108562306a36Sopenharmony_ci else 108662306a36Sopenharmony_ci trace_kfree_skb(skb, __builtin_return_address(0), reason); 108762306a36Sopenharmony_ci return true; 108862306a36Sopenharmony_ci} 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci/** 109162306a36Sopenharmony_ci * kfree_skb_reason - free an sk_buff with special reason 109262306a36Sopenharmony_ci * @skb: buffer to free 109362306a36Sopenharmony_ci * @reason: reason why this skb is dropped 109462306a36Sopenharmony_ci * 109562306a36Sopenharmony_ci * Drop a reference to the buffer and free it if the usage count has 109662306a36Sopenharmony_ci * hit zero. Meanwhile, pass the drop reason to 'kfree_skb' 109762306a36Sopenharmony_ci * tracepoint. 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_civoid __fix_address 110062306a36Sopenharmony_cikfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason) 110162306a36Sopenharmony_ci{ 110262306a36Sopenharmony_ci if (__kfree_skb_reason(skb, reason)) 110362306a36Sopenharmony_ci __kfree_skb(skb); 110462306a36Sopenharmony_ci} 110562306a36Sopenharmony_ciEXPORT_SYMBOL(kfree_skb_reason); 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci#define KFREE_SKB_BULK_SIZE 16 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_cistruct skb_free_array { 111062306a36Sopenharmony_ci unsigned int skb_count; 111162306a36Sopenharmony_ci void *skb_array[KFREE_SKB_BULK_SIZE]; 111262306a36Sopenharmony_ci}; 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_cistatic void kfree_skb_add_bulk(struct sk_buff *skb, 111562306a36Sopenharmony_ci struct skb_free_array *sa, 111662306a36Sopenharmony_ci enum skb_drop_reason reason) 111762306a36Sopenharmony_ci{ 111862306a36Sopenharmony_ci /* if SKB is a clone, don't handle this case */ 111962306a36Sopenharmony_ci if (unlikely(skb->fclone != SKB_FCLONE_UNAVAILABLE)) { 112062306a36Sopenharmony_ci __kfree_skb(skb); 112162306a36Sopenharmony_ci return; 112262306a36Sopenharmony_ci } 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci skb_release_all(skb, reason, false); 112562306a36Sopenharmony_ci sa->skb_array[sa->skb_count++] = skb; 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_ci if (unlikely(sa->skb_count == KFREE_SKB_BULK_SIZE)) { 112862306a36Sopenharmony_ci kmem_cache_free_bulk(skbuff_cache, KFREE_SKB_BULK_SIZE, 112962306a36Sopenharmony_ci sa->skb_array); 113062306a36Sopenharmony_ci sa->skb_count = 0; 113162306a36Sopenharmony_ci } 113262306a36Sopenharmony_ci} 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_civoid __fix_address 113562306a36Sopenharmony_cikfree_skb_list_reason(struct sk_buff *segs, enum skb_drop_reason reason) 113662306a36Sopenharmony_ci{ 113762306a36Sopenharmony_ci struct skb_free_array sa; 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci sa.skb_count = 0; 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci while (segs) { 114262306a36Sopenharmony_ci struct sk_buff *next = segs->next; 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci if (__kfree_skb_reason(segs, reason)) { 114562306a36Sopenharmony_ci skb_poison_list(segs); 114662306a36Sopenharmony_ci kfree_skb_add_bulk(segs, &sa, reason); 114762306a36Sopenharmony_ci } 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci segs = next; 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci if (sa.skb_count) 115362306a36Sopenharmony_ci kmem_cache_free_bulk(skbuff_cache, sa.skb_count, sa.skb_array); 115462306a36Sopenharmony_ci} 115562306a36Sopenharmony_ciEXPORT_SYMBOL(kfree_skb_list_reason); 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci/* Dump skb information and contents. 115862306a36Sopenharmony_ci * 115962306a36Sopenharmony_ci * Must only be called from net_ratelimit()-ed paths. 116062306a36Sopenharmony_ci * 116162306a36Sopenharmony_ci * Dumps whole packets if full_pkt, only headers otherwise. 116262306a36Sopenharmony_ci */ 116362306a36Sopenharmony_civoid skb_dump(const char *level, const struct sk_buff *skb, bool full_pkt) 116462306a36Sopenharmony_ci{ 116562306a36Sopenharmony_ci struct skb_shared_info *sh = skb_shinfo(skb); 116662306a36Sopenharmony_ci struct net_device *dev = skb->dev; 116762306a36Sopenharmony_ci struct sock *sk = skb->sk; 116862306a36Sopenharmony_ci struct sk_buff *list_skb; 116962306a36Sopenharmony_ci bool has_mac, has_trans; 117062306a36Sopenharmony_ci int headroom, tailroom; 117162306a36Sopenharmony_ci int i, len, seg_len; 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci if (full_pkt) 117462306a36Sopenharmony_ci len = skb->len; 117562306a36Sopenharmony_ci else 117662306a36Sopenharmony_ci len = min_t(int, skb->len, MAX_HEADER + 128); 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci headroom = skb_headroom(skb); 117962306a36Sopenharmony_ci tailroom = skb_tailroom(skb); 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_ci has_mac = skb_mac_header_was_set(skb); 118262306a36Sopenharmony_ci has_trans = skb_transport_header_was_set(skb); 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci printk("%sskb len=%u headroom=%u headlen=%u tailroom=%u\n" 118562306a36Sopenharmony_ci "mac=(%d,%d) net=(%d,%d) trans=%d\n" 118662306a36Sopenharmony_ci "shinfo(txflags=%u nr_frags=%u gso(size=%hu type=%u segs=%hu))\n" 118762306a36Sopenharmony_ci "csum(0x%x ip_summed=%u complete_sw=%u valid=%u level=%u)\n" 118862306a36Sopenharmony_ci "hash(0x%x sw=%u l4=%u) proto=0x%04x pkttype=%u iif=%d\n", 118962306a36Sopenharmony_ci level, skb->len, headroom, skb_headlen(skb), tailroom, 119062306a36Sopenharmony_ci has_mac ? skb->mac_header : -1, 119162306a36Sopenharmony_ci has_mac ? skb_mac_header_len(skb) : -1, 119262306a36Sopenharmony_ci skb->network_header, 119362306a36Sopenharmony_ci has_trans ? skb_network_header_len(skb) : -1, 119462306a36Sopenharmony_ci has_trans ? skb->transport_header : -1, 119562306a36Sopenharmony_ci sh->tx_flags, sh->nr_frags, 119662306a36Sopenharmony_ci sh->gso_size, sh->gso_type, sh->gso_segs, 119762306a36Sopenharmony_ci skb->csum, skb->ip_summed, skb->csum_complete_sw, 119862306a36Sopenharmony_ci skb->csum_valid, skb->csum_level, 119962306a36Sopenharmony_ci skb->hash, skb->sw_hash, skb->l4_hash, 120062306a36Sopenharmony_ci ntohs(skb->protocol), skb->pkt_type, skb->skb_iif); 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci if (dev) 120362306a36Sopenharmony_ci printk("%sdev name=%s feat=%pNF\n", 120462306a36Sopenharmony_ci level, dev->name, &dev->features); 120562306a36Sopenharmony_ci if (sk) 120662306a36Sopenharmony_ci printk("%ssk family=%hu type=%u proto=%u\n", 120762306a36Sopenharmony_ci level, sk->sk_family, sk->sk_type, sk->sk_protocol); 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci if (full_pkt && headroom) 121062306a36Sopenharmony_ci print_hex_dump(level, "skb headroom: ", DUMP_PREFIX_OFFSET, 121162306a36Sopenharmony_ci 16, 1, skb->head, headroom, false); 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci seg_len = min_t(int, skb_headlen(skb), len); 121462306a36Sopenharmony_ci if (seg_len) 121562306a36Sopenharmony_ci print_hex_dump(level, "skb linear: ", DUMP_PREFIX_OFFSET, 121662306a36Sopenharmony_ci 16, 1, skb->data, seg_len, false); 121762306a36Sopenharmony_ci len -= seg_len; 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci if (full_pkt && tailroom) 122062306a36Sopenharmony_ci print_hex_dump(level, "skb tailroom: ", DUMP_PREFIX_OFFSET, 122162306a36Sopenharmony_ci 16, 1, skb_tail_pointer(skb), tailroom, false); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci for (i = 0; len && i < skb_shinfo(skb)->nr_frags; i++) { 122462306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 122562306a36Sopenharmony_ci u32 p_off, p_len, copied; 122662306a36Sopenharmony_ci struct page *p; 122762306a36Sopenharmony_ci u8 *vaddr; 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_ci skb_frag_foreach_page(frag, skb_frag_off(frag), 123062306a36Sopenharmony_ci skb_frag_size(frag), p, p_off, p_len, 123162306a36Sopenharmony_ci copied) { 123262306a36Sopenharmony_ci seg_len = min_t(int, p_len, len); 123362306a36Sopenharmony_ci vaddr = kmap_atomic(p); 123462306a36Sopenharmony_ci print_hex_dump(level, "skb frag: ", 123562306a36Sopenharmony_ci DUMP_PREFIX_OFFSET, 123662306a36Sopenharmony_ci 16, 1, vaddr + p_off, seg_len, false); 123762306a36Sopenharmony_ci kunmap_atomic(vaddr); 123862306a36Sopenharmony_ci len -= seg_len; 123962306a36Sopenharmony_ci if (!len) 124062306a36Sopenharmony_ci break; 124162306a36Sopenharmony_ci } 124262306a36Sopenharmony_ci } 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci if (full_pkt && skb_has_frag_list(skb)) { 124562306a36Sopenharmony_ci printk("skb fraglist:\n"); 124662306a36Sopenharmony_ci skb_walk_frags(skb, list_skb) 124762306a36Sopenharmony_ci skb_dump(level, list_skb, true); 124862306a36Sopenharmony_ci } 124962306a36Sopenharmony_ci} 125062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_dump); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci/** 125362306a36Sopenharmony_ci * skb_tx_error - report an sk_buff xmit error 125462306a36Sopenharmony_ci * @skb: buffer that triggered an error 125562306a36Sopenharmony_ci * 125662306a36Sopenharmony_ci * Report xmit error if a device callback is tracking this skb. 125762306a36Sopenharmony_ci * skb must be freed afterwards. 125862306a36Sopenharmony_ci */ 125962306a36Sopenharmony_civoid skb_tx_error(struct sk_buff *skb) 126062306a36Sopenharmony_ci{ 126162306a36Sopenharmony_ci if (skb) { 126262306a36Sopenharmony_ci skb_zcopy_downgrade_managed(skb); 126362306a36Sopenharmony_ci skb_zcopy_clear(skb, true); 126462306a36Sopenharmony_ci } 126562306a36Sopenharmony_ci} 126662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_tx_error); 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci#ifdef CONFIG_TRACEPOINTS 126962306a36Sopenharmony_ci/** 127062306a36Sopenharmony_ci * consume_skb - free an skbuff 127162306a36Sopenharmony_ci * @skb: buffer to free 127262306a36Sopenharmony_ci * 127362306a36Sopenharmony_ci * Drop a ref to the buffer and free it if the usage count has hit zero 127462306a36Sopenharmony_ci * Functions identically to kfree_skb, but kfree_skb assumes that the frame 127562306a36Sopenharmony_ci * is being dropped after a failure and notes that 127662306a36Sopenharmony_ci */ 127762306a36Sopenharmony_civoid consume_skb(struct sk_buff *skb) 127862306a36Sopenharmony_ci{ 127962306a36Sopenharmony_ci if (!skb_unref(skb)) 128062306a36Sopenharmony_ci return; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci trace_consume_skb(skb, __builtin_return_address(0)); 128362306a36Sopenharmony_ci __kfree_skb(skb); 128462306a36Sopenharmony_ci} 128562306a36Sopenharmony_ciEXPORT_SYMBOL(consume_skb); 128662306a36Sopenharmony_ci#endif 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci/** 128962306a36Sopenharmony_ci * __consume_stateless_skb - free an skbuff, assuming it is stateless 129062306a36Sopenharmony_ci * @skb: buffer to free 129162306a36Sopenharmony_ci * 129262306a36Sopenharmony_ci * Alike consume_skb(), but this variant assumes that this is the last 129362306a36Sopenharmony_ci * skb reference and all the head states have been already dropped 129462306a36Sopenharmony_ci */ 129562306a36Sopenharmony_civoid __consume_stateless_skb(struct sk_buff *skb) 129662306a36Sopenharmony_ci{ 129762306a36Sopenharmony_ci trace_consume_skb(skb, __builtin_return_address(0)); 129862306a36Sopenharmony_ci skb_release_data(skb, SKB_CONSUMED, false); 129962306a36Sopenharmony_ci kfree_skbmem(skb); 130062306a36Sopenharmony_ci} 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_cistatic void napi_skb_cache_put(struct sk_buff *skb) 130362306a36Sopenharmony_ci{ 130462306a36Sopenharmony_ci struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); 130562306a36Sopenharmony_ci u32 i; 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_ci kasan_poison_object_data(skbuff_cache, skb); 130862306a36Sopenharmony_ci nc->skb_cache[nc->skb_count++] = skb; 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci if (unlikely(nc->skb_count == NAPI_SKB_CACHE_SIZE)) { 131162306a36Sopenharmony_ci for (i = NAPI_SKB_CACHE_HALF; i < NAPI_SKB_CACHE_SIZE; i++) 131262306a36Sopenharmony_ci kasan_unpoison_object_data(skbuff_cache, 131362306a36Sopenharmony_ci nc->skb_cache[i]); 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci kmem_cache_free_bulk(skbuff_cache, NAPI_SKB_CACHE_HALF, 131662306a36Sopenharmony_ci nc->skb_cache + NAPI_SKB_CACHE_HALF); 131762306a36Sopenharmony_ci nc->skb_count = NAPI_SKB_CACHE_HALF; 131862306a36Sopenharmony_ci } 131962306a36Sopenharmony_ci} 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_civoid __napi_kfree_skb(struct sk_buff *skb, enum skb_drop_reason reason) 132262306a36Sopenharmony_ci{ 132362306a36Sopenharmony_ci skb_release_all(skb, reason, true); 132462306a36Sopenharmony_ci napi_skb_cache_put(skb); 132562306a36Sopenharmony_ci} 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_civoid napi_skb_free_stolen_head(struct sk_buff *skb) 132862306a36Sopenharmony_ci{ 132962306a36Sopenharmony_ci if (unlikely(skb->slow_gro)) { 133062306a36Sopenharmony_ci nf_reset_ct(skb); 133162306a36Sopenharmony_ci skb_dst_drop(skb); 133262306a36Sopenharmony_ci skb_ext_put(skb); 133362306a36Sopenharmony_ci skb_orphan(skb); 133462306a36Sopenharmony_ci skb->slow_gro = 0; 133562306a36Sopenharmony_ci } 133662306a36Sopenharmony_ci napi_skb_cache_put(skb); 133762306a36Sopenharmony_ci} 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_civoid napi_consume_skb(struct sk_buff *skb, int budget) 134062306a36Sopenharmony_ci{ 134162306a36Sopenharmony_ci /* Zero budget indicate non-NAPI context called us, like netpoll */ 134262306a36Sopenharmony_ci if (unlikely(!budget)) { 134362306a36Sopenharmony_ci dev_consume_skb_any(skb); 134462306a36Sopenharmony_ci return; 134562306a36Sopenharmony_ci } 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(!in_softirq()); 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci if (!skb_unref(skb)) 135062306a36Sopenharmony_ci return; 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci /* if reaching here SKB is ready to free */ 135362306a36Sopenharmony_ci trace_consume_skb(skb, __builtin_return_address(0)); 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci /* if SKB is a clone, don't handle this case */ 135662306a36Sopenharmony_ci if (skb->fclone != SKB_FCLONE_UNAVAILABLE) { 135762306a36Sopenharmony_ci __kfree_skb(skb); 135862306a36Sopenharmony_ci return; 135962306a36Sopenharmony_ci } 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci skb_release_all(skb, SKB_CONSUMED, !!budget); 136262306a36Sopenharmony_ci napi_skb_cache_put(skb); 136362306a36Sopenharmony_ci} 136462306a36Sopenharmony_ciEXPORT_SYMBOL(napi_consume_skb); 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci/* Make sure a field is contained by headers group */ 136762306a36Sopenharmony_ci#define CHECK_SKB_FIELD(field) \ 136862306a36Sopenharmony_ci BUILD_BUG_ON(offsetof(struct sk_buff, field) != \ 136962306a36Sopenharmony_ci offsetof(struct sk_buff, headers.field)); \ 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_cistatic void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) 137262306a36Sopenharmony_ci{ 137362306a36Sopenharmony_ci new->tstamp = old->tstamp; 137462306a36Sopenharmony_ci /* We do not copy old->sk */ 137562306a36Sopenharmony_ci new->dev = old->dev; 137662306a36Sopenharmony_ci memcpy(new->cb, old->cb, sizeof(old->cb)); 137762306a36Sopenharmony_ci skb_dst_copy(new, old); 137862306a36Sopenharmony_ci __skb_ext_copy(new, old); 137962306a36Sopenharmony_ci __nf_copy(new, old, false); 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_ci /* Note : this field could be in the headers group. 138262306a36Sopenharmony_ci * It is not yet because we do not want to have a 16 bit hole 138362306a36Sopenharmony_ci */ 138462306a36Sopenharmony_ci new->queue_mapping = old->queue_mapping; 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci memcpy(&new->headers, &old->headers, sizeof(new->headers)); 138762306a36Sopenharmony_ci CHECK_SKB_FIELD(protocol); 138862306a36Sopenharmony_ci CHECK_SKB_FIELD(csum); 138962306a36Sopenharmony_ci CHECK_SKB_FIELD(hash); 139062306a36Sopenharmony_ci CHECK_SKB_FIELD(priority); 139162306a36Sopenharmony_ci CHECK_SKB_FIELD(skb_iif); 139262306a36Sopenharmony_ci CHECK_SKB_FIELD(vlan_proto); 139362306a36Sopenharmony_ci CHECK_SKB_FIELD(vlan_tci); 139462306a36Sopenharmony_ci CHECK_SKB_FIELD(transport_header); 139562306a36Sopenharmony_ci CHECK_SKB_FIELD(network_header); 139662306a36Sopenharmony_ci CHECK_SKB_FIELD(mac_header); 139762306a36Sopenharmony_ci CHECK_SKB_FIELD(inner_protocol); 139862306a36Sopenharmony_ci CHECK_SKB_FIELD(inner_transport_header); 139962306a36Sopenharmony_ci CHECK_SKB_FIELD(inner_network_header); 140062306a36Sopenharmony_ci CHECK_SKB_FIELD(inner_mac_header); 140162306a36Sopenharmony_ci CHECK_SKB_FIELD(mark); 140262306a36Sopenharmony_ci#ifdef CONFIG_NETWORK_SECMARK 140362306a36Sopenharmony_ci CHECK_SKB_FIELD(secmark); 140462306a36Sopenharmony_ci#endif 140562306a36Sopenharmony_ci#ifdef CONFIG_NET_RX_BUSY_POLL 140662306a36Sopenharmony_ci CHECK_SKB_FIELD(napi_id); 140762306a36Sopenharmony_ci#endif 140862306a36Sopenharmony_ci CHECK_SKB_FIELD(alloc_cpu); 140962306a36Sopenharmony_ci#ifdef CONFIG_XPS 141062306a36Sopenharmony_ci CHECK_SKB_FIELD(sender_cpu); 141162306a36Sopenharmony_ci#endif 141262306a36Sopenharmony_ci#ifdef CONFIG_NET_SCHED 141362306a36Sopenharmony_ci CHECK_SKB_FIELD(tc_index); 141462306a36Sopenharmony_ci#endif 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci} 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci/* 141962306a36Sopenharmony_ci * You should not add any new code to this function. Add it to 142062306a36Sopenharmony_ci * __copy_skb_header above instead. 142162306a36Sopenharmony_ci */ 142262306a36Sopenharmony_cistatic struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) 142362306a36Sopenharmony_ci{ 142462306a36Sopenharmony_ci#define C(x) n->x = skb->x 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci n->next = n->prev = NULL; 142762306a36Sopenharmony_ci n->sk = NULL; 142862306a36Sopenharmony_ci __copy_skb_header(n, skb); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci C(len); 143162306a36Sopenharmony_ci C(data_len); 143262306a36Sopenharmony_ci C(mac_len); 143362306a36Sopenharmony_ci n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; 143462306a36Sopenharmony_ci n->cloned = 1; 143562306a36Sopenharmony_ci n->nohdr = 0; 143662306a36Sopenharmony_ci n->peeked = 0; 143762306a36Sopenharmony_ci C(pfmemalloc); 143862306a36Sopenharmony_ci C(pp_recycle); 143962306a36Sopenharmony_ci n->destructor = NULL; 144062306a36Sopenharmony_ci C(tail); 144162306a36Sopenharmony_ci C(end); 144262306a36Sopenharmony_ci C(head); 144362306a36Sopenharmony_ci C(head_frag); 144462306a36Sopenharmony_ci C(data); 144562306a36Sopenharmony_ci C(truesize); 144662306a36Sopenharmony_ci refcount_set(&n->users, 1); 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci atomic_inc(&(skb_shinfo(skb)->dataref)); 144962306a36Sopenharmony_ci skb->cloned = 1; 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci return n; 145262306a36Sopenharmony_ci#undef C 145362306a36Sopenharmony_ci} 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci/** 145662306a36Sopenharmony_ci * alloc_skb_for_msg() - allocate sk_buff to wrap frag list forming a msg 145762306a36Sopenharmony_ci * @first: first sk_buff of the msg 145862306a36Sopenharmony_ci */ 145962306a36Sopenharmony_cistruct sk_buff *alloc_skb_for_msg(struct sk_buff *first) 146062306a36Sopenharmony_ci{ 146162306a36Sopenharmony_ci struct sk_buff *n; 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci n = alloc_skb(0, GFP_ATOMIC); 146462306a36Sopenharmony_ci if (!n) 146562306a36Sopenharmony_ci return NULL; 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci n->len = first->len; 146862306a36Sopenharmony_ci n->data_len = first->len; 146962306a36Sopenharmony_ci n->truesize = first->truesize; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci skb_shinfo(n)->frag_list = first; 147262306a36Sopenharmony_ci 147362306a36Sopenharmony_ci __copy_skb_header(n, first); 147462306a36Sopenharmony_ci n->destructor = NULL; 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci return n; 147762306a36Sopenharmony_ci} 147862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(alloc_skb_for_msg); 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_ci/** 148162306a36Sopenharmony_ci * skb_morph - morph one skb into another 148262306a36Sopenharmony_ci * @dst: the skb to receive the contents 148362306a36Sopenharmony_ci * @src: the skb to supply the contents 148462306a36Sopenharmony_ci * 148562306a36Sopenharmony_ci * This is identical to skb_clone except that the target skb is 148662306a36Sopenharmony_ci * supplied by the user. 148762306a36Sopenharmony_ci * 148862306a36Sopenharmony_ci * The target skb is returned upon exit. 148962306a36Sopenharmony_ci */ 149062306a36Sopenharmony_cistruct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src) 149162306a36Sopenharmony_ci{ 149262306a36Sopenharmony_ci skb_release_all(dst, SKB_CONSUMED, false); 149362306a36Sopenharmony_ci return __skb_clone(dst, src); 149462306a36Sopenharmony_ci} 149562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_morph); 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ciint mm_account_pinned_pages(struct mmpin *mmp, size_t size) 149862306a36Sopenharmony_ci{ 149962306a36Sopenharmony_ci unsigned long max_pg, num_pg, new_pg, old_pg, rlim; 150062306a36Sopenharmony_ci struct user_struct *user; 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci if (capable(CAP_IPC_LOCK) || !size) 150362306a36Sopenharmony_ci return 0; 150462306a36Sopenharmony_ci 150562306a36Sopenharmony_ci rlim = rlimit(RLIMIT_MEMLOCK); 150662306a36Sopenharmony_ci if (rlim == RLIM_INFINITY) 150762306a36Sopenharmony_ci return 0; 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci num_pg = (size >> PAGE_SHIFT) + 2; /* worst case */ 151062306a36Sopenharmony_ci max_pg = rlim >> PAGE_SHIFT; 151162306a36Sopenharmony_ci user = mmp->user ? : current_user(); 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci old_pg = atomic_long_read(&user->locked_vm); 151462306a36Sopenharmony_ci do { 151562306a36Sopenharmony_ci new_pg = old_pg + num_pg; 151662306a36Sopenharmony_ci if (new_pg > max_pg) 151762306a36Sopenharmony_ci return -ENOBUFS; 151862306a36Sopenharmony_ci } while (!atomic_long_try_cmpxchg(&user->locked_vm, &old_pg, new_pg)); 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_ci if (!mmp->user) { 152162306a36Sopenharmony_ci mmp->user = get_uid(user); 152262306a36Sopenharmony_ci mmp->num_pg = num_pg; 152362306a36Sopenharmony_ci } else { 152462306a36Sopenharmony_ci mmp->num_pg += num_pg; 152562306a36Sopenharmony_ci } 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci return 0; 152862306a36Sopenharmony_ci} 152962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mm_account_pinned_pages); 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_civoid mm_unaccount_pinned_pages(struct mmpin *mmp) 153262306a36Sopenharmony_ci{ 153362306a36Sopenharmony_ci if (mmp->user) { 153462306a36Sopenharmony_ci atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm); 153562306a36Sopenharmony_ci free_uid(mmp->user); 153662306a36Sopenharmony_ci } 153762306a36Sopenharmony_ci} 153862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mm_unaccount_pinned_pages); 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_cistatic struct ubuf_info *msg_zerocopy_alloc(struct sock *sk, size_t size) 154162306a36Sopenharmony_ci{ 154262306a36Sopenharmony_ci struct ubuf_info_msgzc *uarg; 154362306a36Sopenharmony_ci struct sk_buff *skb; 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci WARN_ON_ONCE(!in_task()); 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci skb = sock_omalloc(sk, 0, GFP_KERNEL); 154862306a36Sopenharmony_ci if (!skb) 154962306a36Sopenharmony_ci return NULL; 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(*uarg) > sizeof(skb->cb)); 155262306a36Sopenharmony_ci uarg = (void *)skb->cb; 155362306a36Sopenharmony_ci uarg->mmp.user = NULL; 155462306a36Sopenharmony_ci 155562306a36Sopenharmony_ci if (mm_account_pinned_pages(&uarg->mmp, size)) { 155662306a36Sopenharmony_ci kfree_skb(skb); 155762306a36Sopenharmony_ci return NULL; 155862306a36Sopenharmony_ci } 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci uarg->ubuf.callback = msg_zerocopy_callback; 156162306a36Sopenharmony_ci uarg->id = ((u32)atomic_inc_return(&sk->sk_zckey)) - 1; 156262306a36Sopenharmony_ci uarg->len = 1; 156362306a36Sopenharmony_ci uarg->bytelen = size; 156462306a36Sopenharmony_ci uarg->zerocopy = 1; 156562306a36Sopenharmony_ci uarg->ubuf.flags = SKBFL_ZEROCOPY_FRAG | SKBFL_DONT_ORPHAN; 156662306a36Sopenharmony_ci refcount_set(&uarg->ubuf.refcnt, 1); 156762306a36Sopenharmony_ci sock_hold(sk); 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_ci return &uarg->ubuf; 157062306a36Sopenharmony_ci} 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_cistatic inline struct sk_buff *skb_from_uarg(struct ubuf_info_msgzc *uarg) 157362306a36Sopenharmony_ci{ 157462306a36Sopenharmony_ci return container_of((void *)uarg, struct sk_buff, cb); 157562306a36Sopenharmony_ci} 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_cistruct ubuf_info *msg_zerocopy_realloc(struct sock *sk, size_t size, 157862306a36Sopenharmony_ci struct ubuf_info *uarg) 157962306a36Sopenharmony_ci{ 158062306a36Sopenharmony_ci if (uarg) { 158162306a36Sopenharmony_ci struct ubuf_info_msgzc *uarg_zc; 158262306a36Sopenharmony_ci const u32 byte_limit = 1 << 19; /* limit to a few TSO */ 158362306a36Sopenharmony_ci u32 bytelen, next; 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci /* there might be non MSG_ZEROCOPY users */ 158662306a36Sopenharmony_ci if (uarg->callback != msg_zerocopy_callback) 158762306a36Sopenharmony_ci return NULL; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci /* realloc only when socket is locked (TCP, UDP cork), 159062306a36Sopenharmony_ci * so uarg->len and sk_zckey access is serialized 159162306a36Sopenharmony_ci */ 159262306a36Sopenharmony_ci if (!sock_owned_by_user(sk)) { 159362306a36Sopenharmony_ci WARN_ON_ONCE(1); 159462306a36Sopenharmony_ci return NULL; 159562306a36Sopenharmony_ci } 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci uarg_zc = uarg_to_msgzc(uarg); 159862306a36Sopenharmony_ci bytelen = uarg_zc->bytelen + size; 159962306a36Sopenharmony_ci if (uarg_zc->len == USHRT_MAX - 1 || bytelen > byte_limit) { 160062306a36Sopenharmony_ci /* TCP can create new skb to attach new uarg */ 160162306a36Sopenharmony_ci if (sk->sk_type == SOCK_STREAM) 160262306a36Sopenharmony_ci goto new_alloc; 160362306a36Sopenharmony_ci return NULL; 160462306a36Sopenharmony_ci } 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci next = (u32)atomic_read(&sk->sk_zckey); 160762306a36Sopenharmony_ci if ((u32)(uarg_zc->id + uarg_zc->len) == next) { 160862306a36Sopenharmony_ci if (mm_account_pinned_pages(&uarg_zc->mmp, size)) 160962306a36Sopenharmony_ci return NULL; 161062306a36Sopenharmony_ci uarg_zc->len++; 161162306a36Sopenharmony_ci uarg_zc->bytelen = bytelen; 161262306a36Sopenharmony_ci atomic_set(&sk->sk_zckey, ++next); 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci /* no extra ref when appending to datagram (MSG_MORE) */ 161562306a36Sopenharmony_ci if (sk->sk_type == SOCK_STREAM) 161662306a36Sopenharmony_ci net_zcopy_get(uarg); 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci return uarg; 161962306a36Sopenharmony_ci } 162062306a36Sopenharmony_ci } 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_cinew_alloc: 162362306a36Sopenharmony_ci return msg_zerocopy_alloc(sk, size); 162462306a36Sopenharmony_ci} 162562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(msg_zerocopy_realloc); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_cistatic bool skb_zerocopy_notify_extend(struct sk_buff *skb, u32 lo, u16 len) 162862306a36Sopenharmony_ci{ 162962306a36Sopenharmony_ci struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); 163062306a36Sopenharmony_ci u32 old_lo, old_hi; 163162306a36Sopenharmony_ci u64 sum_len; 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci old_lo = serr->ee.ee_info; 163462306a36Sopenharmony_ci old_hi = serr->ee.ee_data; 163562306a36Sopenharmony_ci sum_len = old_hi - old_lo + 1ULL + len; 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci if (sum_len >= (1ULL << 32)) 163862306a36Sopenharmony_ci return false; 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ci if (lo != old_hi + 1) 164162306a36Sopenharmony_ci return false; 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci serr->ee.ee_data += len; 164462306a36Sopenharmony_ci return true; 164562306a36Sopenharmony_ci} 164662306a36Sopenharmony_ci 164762306a36Sopenharmony_cistatic void __msg_zerocopy_callback(struct ubuf_info_msgzc *uarg) 164862306a36Sopenharmony_ci{ 164962306a36Sopenharmony_ci struct sk_buff *tail, *skb = skb_from_uarg(uarg); 165062306a36Sopenharmony_ci struct sock_exterr_skb *serr; 165162306a36Sopenharmony_ci struct sock *sk = skb->sk; 165262306a36Sopenharmony_ci struct sk_buff_head *q; 165362306a36Sopenharmony_ci unsigned long flags; 165462306a36Sopenharmony_ci bool is_zerocopy; 165562306a36Sopenharmony_ci u32 lo, hi; 165662306a36Sopenharmony_ci u16 len; 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci mm_unaccount_pinned_pages(&uarg->mmp); 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci /* if !len, there was only 1 call, and it was aborted 166162306a36Sopenharmony_ci * so do not queue a completion notification 166262306a36Sopenharmony_ci */ 166362306a36Sopenharmony_ci if (!uarg->len || sock_flag(sk, SOCK_DEAD)) 166462306a36Sopenharmony_ci goto release; 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci len = uarg->len; 166762306a36Sopenharmony_ci lo = uarg->id; 166862306a36Sopenharmony_ci hi = uarg->id + len - 1; 166962306a36Sopenharmony_ci is_zerocopy = uarg->zerocopy; 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci serr = SKB_EXT_ERR(skb); 167262306a36Sopenharmony_ci memset(serr, 0, sizeof(*serr)); 167362306a36Sopenharmony_ci serr->ee.ee_errno = 0; 167462306a36Sopenharmony_ci serr->ee.ee_origin = SO_EE_ORIGIN_ZEROCOPY; 167562306a36Sopenharmony_ci serr->ee.ee_data = hi; 167662306a36Sopenharmony_ci serr->ee.ee_info = lo; 167762306a36Sopenharmony_ci if (!is_zerocopy) 167862306a36Sopenharmony_ci serr->ee.ee_code |= SO_EE_CODE_ZEROCOPY_COPIED; 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci q = &sk->sk_error_queue; 168162306a36Sopenharmony_ci spin_lock_irqsave(&q->lock, flags); 168262306a36Sopenharmony_ci tail = skb_peek_tail(q); 168362306a36Sopenharmony_ci if (!tail || SKB_EXT_ERR(tail)->ee.ee_origin != SO_EE_ORIGIN_ZEROCOPY || 168462306a36Sopenharmony_ci !skb_zerocopy_notify_extend(tail, lo, len)) { 168562306a36Sopenharmony_ci __skb_queue_tail(q, skb); 168662306a36Sopenharmony_ci skb = NULL; 168762306a36Sopenharmony_ci } 168862306a36Sopenharmony_ci spin_unlock_irqrestore(&q->lock, flags); 168962306a36Sopenharmony_ci 169062306a36Sopenharmony_ci sk_error_report(sk); 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_cirelease: 169362306a36Sopenharmony_ci consume_skb(skb); 169462306a36Sopenharmony_ci sock_put(sk); 169562306a36Sopenharmony_ci} 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_civoid msg_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *uarg, 169862306a36Sopenharmony_ci bool success) 169962306a36Sopenharmony_ci{ 170062306a36Sopenharmony_ci struct ubuf_info_msgzc *uarg_zc = uarg_to_msgzc(uarg); 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci uarg_zc->zerocopy = uarg_zc->zerocopy & success; 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci if (refcount_dec_and_test(&uarg->refcnt)) 170562306a36Sopenharmony_ci __msg_zerocopy_callback(uarg_zc); 170662306a36Sopenharmony_ci} 170762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(msg_zerocopy_callback); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_civoid msg_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref) 171062306a36Sopenharmony_ci{ 171162306a36Sopenharmony_ci struct sock *sk = skb_from_uarg(uarg_to_msgzc(uarg))->sk; 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_ci atomic_dec(&sk->sk_zckey); 171462306a36Sopenharmony_ci uarg_to_msgzc(uarg)->len--; 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_ci if (have_uref) 171762306a36Sopenharmony_ci msg_zerocopy_callback(NULL, uarg, true); 171862306a36Sopenharmony_ci} 171962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(msg_zerocopy_put_abort); 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ciint skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, 172262306a36Sopenharmony_ci struct msghdr *msg, int len, 172362306a36Sopenharmony_ci struct ubuf_info *uarg) 172462306a36Sopenharmony_ci{ 172562306a36Sopenharmony_ci struct ubuf_info *orig_uarg = skb_zcopy(skb); 172662306a36Sopenharmony_ci int err, orig_len = skb->len; 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci /* An skb can only point to one uarg. This edge case happens when 172962306a36Sopenharmony_ci * TCP appends to an skb, but zerocopy_realloc triggered a new alloc. 173062306a36Sopenharmony_ci */ 173162306a36Sopenharmony_ci if (orig_uarg && uarg != orig_uarg) 173262306a36Sopenharmony_ci return -EEXIST; 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci err = __zerocopy_sg_from_iter(msg, sk, skb, &msg->msg_iter, len); 173562306a36Sopenharmony_ci if (err == -EFAULT || (err == -EMSGSIZE && skb->len == orig_len)) { 173662306a36Sopenharmony_ci struct sock *save_sk = skb->sk; 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci /* Streams do not free skb on error. Reset to prev state. */ 173962306a36Sopenharmony_ci iov_iter_revert(&msg->msg_iter, skb->len - orig_len); 174062306a36Sopenharmony_ci skb->sk = sk; 174162306a36Sopenharmony_ci ___pskb_trim(skb, orig_len); 174262306a36Sopenharmony_ci skb->sk = save_sk; 174362306a36Sopenharmony_ci return err; 174462306a36Sopenharmony_ci } 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci skb_zcopy_set(skb, uarg, NULL); 174762306a36Sopenharmony_ci return skb->len - orig_len; 174862306a36Sopenharmony_ci} 174962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_zerocopy_iter_stream); 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_civoid __skb_zcopy_downgrade_managed(struct sk_buff *skb) 175262306a36Sopenharmony_ci{ 175362306a36Sopenharmony_ci int i; 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci skb_shinfo(skb)->flags &= ~SKBFL_MANAGED_FRAG_REFS; 175662306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 175762306a36Sopenharmony_ci skb_frag_ref(skb, i); 175862306a36Sopenharmony_ci} 175962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__skb_zcopy_downgrade_managed); 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_cistatic int skb_zerocopy_clone(struct sk_buff *nskb, struct sk_buff *orig, 176262306a36Sopenharmony_ci gfp_t gfp_mask) 176362306a36Sopenharmony_ci{ 176462306a36Sopenharmony_ci if (skb_zcopy(orig)) { 176562306a36Sopenharmony_ci if (skb_zcopy(nskb)) { 176662306a36Sopenharmony_ci /* !gfp_mask callers are verified to !skb_zcopy(nskb) */ 176762306a36Sopenharmony_ci if (!gfp_mask) { 176862306a36Sopenharmony_ci WARN_ON_ONCE(1); 176962306a36Sopenharmony_ci return -ENOMEM; 177062306a36Sopenharmony_ci } 177162306a36Sopenharmony_ci if (skb_uarg(nskb) == skb_uarg(orig)) 177262306a36Sopenharmony_ci return 0; 177362306a36Sopenharmony_ci if (skb_copy_ubufs(nskb, GFP_ATOMIC)) 177462306a36Sopenharmony_ci return -EIO; 177562306a36Sopenharmony_ci } 177662306a36Sopenharmony_ci skb_zcopy_set(nskb, skb_uarg(orig), NULL); 177762306a36Sopenharmony_ci } 177862306a36Sopenharmony_ci return 0; 177962306a36Sopenharmony_ci} 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci/** 178262306a36Sopenharmony_ci * skb_copy_ubufs - copy userspace skb frags buffers to kernel 178362306a36Sopenharmony_ci * @skb: the skb to modify 178462306a36Sopenharmony_ci * @gfp_mask: allocation priority 178562306a36Sopenharmony_ci * 178662306a36Sopenharmony_ci * This must be called on skb with SKBFL_ZEROCOPY_ENABLE. 178762306a36Sopenharmony_ci * It will copy all frags into kernel and drop the reference 178862306a36Sopenharmony_ci * to userspace pages. 178962306a36Sopenharmony_ci * 179062306a36Sopenharmony_ci * If this function is called from an interrupt gfp_mask() must be 179162306a36Sopenharmony_ci * %GFP_ATOMIC. 179262306a36Sopenharmony_ci * 179362306a36Sopenharmony_ci * Returns 0 on success or a negative error code on failure 179462306a36Sopenharmony_ci * to allocate kernel memory to copy to. 179562306a36Sopenharmony_ci */ 179662306a36Sopenharmony_ciint skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) 179762306a36Sopenharmony_ci{ 179862306a36Sopenharmony_ci int num_frags = skb_shinfo(skb)->nr_frags; 179962306a36Sopenharmony_ci struct page *page, *head = NULL; 180062306a36Sopenharmony_ci int i, order, psize, new_frags; 180162306a36Sopenharmony_ci u32 d_off; 180262306a36Sopenharmony_ci 180362306a36Sopenharmony_ci if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) 180462306a36Sopenharmony_ci return -EINVAL; 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci if (!num_frags) 180762306a36Sopenharmony_ci goto release; 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_ci /* We might have to allocate high order pages, so compute what minimum 181062306a36Sopenharmony_ci * page order is needed. 181162306a36Sopenharmony_ci */ 181262306a36Sopenharmony_ci order = 0; 181362306a36Sopenharmony_ci while ((PAGE_SIZE << order) * MAX_SKB_FRAGS < __skb_pagelen(skb)) 181462306a36Sopenharmony_ci order++; 181562306a36Sopenharmony_ci psize = (PAGE_SIZE << order); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci new_frags = (__skb_pagelen(skb) + psize - 1) >> (PAGE_SHIFT + order); 181862306a36Sopenharmony_ci for (i = 0; i < new_frags; i++) { 181962306a36Sopenharmony_ci page = alloc_pages(gfp_mask | __GFP_COMP, order); 182062306a36Sopenharmony_ci if (!page) { 182162306a36Sopenharmony_ci while (head) { 182262306a36Sopenharmony_ci struct page *next = (struct page *)page_private(head); 182362306a36Sopenharmony_ci put_page(head); 182462306a36Sopenharmony_ci head = next; 182562306a36Sopenharmony_ci } 182662306a36Sopenharmony_ci return -ENOMEM; 182762306a36Sopenharmony_ci } 182862306a36Sopenharmony_ci set_page_private(page, (unsigned long)head); 182962306a36Sopenharmony_ci head = page; 183062306a36Sopenharmony_ci } 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_ci page = head; 183362306a36Sopenharmony_ci d_off = 0; 183462306a36Sopenharmony_ci for (i = 0; i < num_frags; i++) { 183562306a36Sopenharmony_ci skb_frag_t *f = &skb_shinfo(skb)->frags[i]; 183662306a36Sopenharmony_ci u32 p_off, p_len, copied; 183762306a36Sopenharmony_ci struct page *p; 183862306a36Sopenharmony_ci u8 *vaddr; 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci skb_frag_foreach_page(f, skb_frag_off(f), skb_frag_size(f), 184162306a36Sopenharmony_ci p, p_off, p_len, copied) { 184262306a36Sopenharmony_ci u32 copy, done = 0; 184362306a36Sopenharmony_ci vaddr = kmap_atomic(p); 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci while (done < p_len) { 184662306a36Sopenharmony_ci if (d_off == psize) { 184762306a36Sopenharmony_ci d_off = 0; 184862306a36Sopenharmony_ci page = (struct page *)page_private(page); 184962306a36Sopenharmony_ci } 185062306a36Sopenharmony_ci copy = min_t(u32, psize - d_off, p_len - done); 185162306a36Sopenharmony_ci memcpy(page_address(page) + d_off, 185262306a36Sopenharmony_ci vaddr + p_off + done, copy); 185362306a36Sopenharmony_ci done += copy; 185462306a36Sopenharmony_ci d_off += copy; 185562306a36Sopenharmony_ci } 185662306a36Sopenharmony_ci kunmap_atomic(vaddr); 185762306a36Sopenharmony_ci } 185862306a36Sopenharmony_ci } 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_ci /* skb frags release userspace buffers */ 186162306a36Sopenharmony_ci for (i = 0; i < num_frags; i++) 186262306a36Sopenharmony_ci skb_frag_unref(skb, i); 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_ci /* skb frags point to kernel buffers */ 186562306a36Sopenharmony_ci for (i = 0; i < new_frags - 1; i++) { 186662306a36Sopenharmony_ci __skb_fill_page_desc(skb, i, head, 0, psize); 186762306a36Sopenharmony_ci head = (struct page *)page_private(head); 186862306a36Sopenharmony_ci } 186962306a36Sopenharmony_ci __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); 187062306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = new_frags; 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_cirelease: 187362306a36Sopenharmony_ci skb_zcopy_clear(skb, false); 187462306a36Sopenharmony_ci return 0; 187562306a36Sopenharmony_ci} 187662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_copy_ubufs); 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci/** 187962306a36Sopenharmony_ci * skb_clone - duplicate an sk_buff 188062306a36Sopenharmony_ci * @skb: buffer to clone 188162306a36Sopenharmony_ci * @gfp_mask: allocation priority 188262306a36Sopenharmony_ci * 188362306a36Sopenharmony_ci * Duplicate an &sk_buff. The new one is not owned by a socket. Both 188462306a36Sopenharmony_ci * copies share the same packet data but not structure. The new 188562306a36Sopenharmony_ci * buffer has a reference count of 1. If the allocation fails the 188662306a36Sopenharmony_ci * function returns %NULL otherwise the new buffer is returned. 188762306a36Sopenharmony_ci * 188862306a36Sopenharmony_ci * If this function is called from an interrupt gfp_mask() must be 188962306a36Sopenharmony_ci * %GFP_ATOMIC. 189062306a36Sopenharmony_ci */ 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_cistruct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) 189362306a36Sopenharmony_ci{ 189462306a36Sopenharmony_ci struct sk_buff_fclones *fclones = container_of(skb, 189562306a36Sopenharmony_ci struct sk_buff_fclones, 189662306a36Sopenharmony_ci skb1); 189762306a36Sopenharmony_ci struct sk_buff *n; 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci if (skb_orphan_frags(skb, gfp_mask)) 190062306a36Sopenharmony_ci return NULL; 190162306a36Sopenharmony_ci 190262306a36Sopenharmony_ci if (skb->fclone == SKB_FCLONE_ORIG && 190362306a36Sopenharmony_ci refcount_read(&fclones->fclone_ref) == 1) { 190462306a36Sopenharmony_ci n = &fclones->skb2; 190562306a36Sopenharmony_ci refcount_set(&fclones->fclone_ref, 2); 190662306a36Sopenharmony_ci n->fclone = SKB_FCLONE_CLONE; 190762306a36Sopenharmony_ci } else { 190862306a36Sopenharmony_ci if (skb_pfmemalloc(skb)) 190962306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_ci n = kmem_cache_alloc(skbuff_cache, gfp_mask); 191262306a36Sopenharmony_ci if (!n) 191362306a36Sopenharmony_ci return NULL; 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci n->fclone = SKB_FCLONE_UNAVAILABLE; 191662306a36Sopenharmony_ci } 191762306a36Sopenharmony_ci 191862306a36Sopenharmony_ci return __skb_clone(n, skb); 191962306a36Sopenharmony_ci} 192062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_clone); 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_civoid skb_headers_offset_update(struct sk_buff *skb, int off) 192362306a36Sopenharmony_ci{ 192462306a36Sopenharmony_ci /* Only adjust this if it actually is csum_start rather than csum */ 192562306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_PARTIAL) 192662306a36Sopenharmony_ci skb->csum_start += off; 192762306a36Sopenharmony_ci /* {transport,network,mac}_header and tail are relative to skb->head */ 192862306a36Sopenharmony_ci skb->transport_header += off; 192962306a36Sopenharmony_ci skb->network_header += off; 193062306a36Sopenharmony_ci if (skb_mac_header_was_set(skb)) 193162306a36Sopenharmony_ci skb->mac_header += off; 193262306a36Sopenharmony_ci skb->inner_transport_header += off; 193362306a36Sopenharmony_ci skb->inner_network_header += off; 193462306a36Sopenharmony_ci skb->inner_mac_header += off; 193562306a36Sopenharmony_ci} 193662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_headers_offset_update); 193762306a36Sopenharmony_ci 193862306a36Sopenharmony_civoid skb_copy_header(struct sk_buff *new, const struct sk_buff *old) 193962306a36Sopenharmony_ci{ 194062306a36Sopenharmony_ci __copy_skb_header(new, old); 194162306a36Sopenharmony_ci 194262306a36Sopenharmony_ci skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; 194362306a36Sopenharmony_ci skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; 194462306a36Sopenharmony_ci skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; 194562306a36Sopenharmony_ci} 194662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy_header); 194762306a36Sopenharmony_ci 194862306a36Sopenharmony_cistatic inline int skb_alloc_rx_flag(const struct sk_buff *skb) 194962306a36Sopenharmony_ci{ 195062306a36Sopenharmony_ci if (skb_pfmemalloc(skb)) 195162306a36Sopenharmony_ci return SKB_ALLOC_RX; 195262306a36Sopenharmony_ci return 0; 195362306a36Sopenharmony_ci} 195462306a36Sopenharmony_ci 195562306a36Sopenharmony_ci/** 195662306a36Sopenharmony_ci * skb_copy - create private copy of an sk_buff 195762306a36Sopenharmony_ci * @skb: buffer to copy 195862306a36Sopenharmony_ci * @gfp_mask: allocation priority 195962306a36Sopenharmony_ci * 196062306a36Sopenharmony_ci * Make a copy of both an &sk_buff and its data. This is used when the 196162306a36Sopenharmony_ci * caller wishes to modify the data and needs a private copy of the 196262306a36Sopenharmony_ci * data to alter. Returns %NULL on failure or the pointer to the buffer 196362306a36Sopenharmony_ci * on success. The returned buffer has a reference count of 1. 196462306a36Sopenharmony_ci * 196562306a36Sopenharmony_ci * As by-product this function converts non-linear &sk_buff to linear 196662306a36Sopenharmony_ci * one, so that &sk_buff becomes completely private and caller is allowed 196762306a36Sopenharmony_ci * to modify all the data of returned buffer. This means that this 196862306a36Sopenharmony_ci * function is not recommended for use in circumstances when only 196962306a36Sopenharmony_ci * header is going to be modified. Use pskb_copy() instead. 197062306a36Sopenharmony_ci */ 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_cistruct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) 197362306a36Sopenharmony_ci{ 197462306a36Sopenharmony_ci int headerlen = skb_headroom(skb); 197562306a36Sopenharmony_ci unsigned int size = skb_end_offset(skb) + skb->data_len; 197662306a36Sopenharmony_ci struct sk_buff *n = __alloc_skb(size, gfp_mask, 197762306a36Sopenharmony_ci skb_alloc_rx_flag(skb), NUMA_NO_NODE); 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_ci if (!n) 198062306a36Sopenharmony_ci return NULL; 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_ci /* Set the data pointer */ 198362306a36Sopenharmony_ci skb_reserve(n, headerlen); 198462306a36Sopenharmony_ci /* Set the tail pointer and length */ 198562306a36Sopenharmony_ci skb_put(n, skb->len); 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len)); 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci skb_copy_header(n, skb); 199062306a36Sopenharmony_ci return n; 199162306a36Sopenharmony_ci} 199262306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy); 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci/** 199562306a36Sopenharmony_ci * __pskb_copy_fclone - create copy of an sk_buff with private head. 199662306a36Sopenharmony_ci * @skb: buffer to copy 199762306a36Sopenharmony_ci * @headroom: headroom of new skb 199862306a36Sopenharmony_ci * @gfp_mask: allocation priority 199962306a36Sopenharmony_ci * @fclone: if true allocate the copy of the skb from the fclone 200062306a36Sopenharmony_ci * cache instead of the head cache; it is recommended to set this 200162306a36Sopenharmony_ci * to true for the cases where the copy will likely be cloned 200262306a36Sopenharmony_ci * 200362306a36Sopenharmony_ci * Make a copy of both an &sk_buff and part of its data, located 200462306a36Sopenharmony_ci * in header. Fragmented data remain shared. This is used when 200562306a36Sopenharmony_ci * the caller wishes to modify only header of &sk_buff and needs 200662306a36Sopenharmony_ci * private copy of the header to alter. Returns %NULL on failure 200762306a36Sopenharmony_ci * or the pointer to the buffer on success. 200862306a36Sopenharmony_ci * The returned buffer has a reference count of 1. 200962306a36Sopenharmony_ci */ 201062306a36Sopenharmony_ci 201162306a36Sopenharmony_cistruct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom, 201262306a36Sopenharmony_ci gfp_t gfp_mask, bool fclone) 201362306a36Sopenharmony_ci{ 201462306a36Sopenharmony_ci unsigned int size = skb_headlen(skb) + headroom; 201562306a36Sopenharmony_ci int flags = skb_alloc_rx_flag(skb) | (fclone ? SKB_ALLOC_FCLONE : 0); 201662306a36Sopenharmony_ci struct sk_buff *n = __alloc_skb(size, gfp_mask, flags, NUMA_NO_NODE); 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_ci if (!n) 201962306a36Sopenharmony_ci goto out; 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_ci /* Set the data pointer */ 202262306a36Sopenharmony_ci skb_reserve(n, headroom); 202362306a36Sopenharmony_ci /* Set the tail pointer and length */ 202462306a36Sopenharmony_ci skb_put(n, skb_headlen(skb)); 202562306a36Sopenharmony_ci /* Copy the bytes */ 202662306a36Sopenharmony_ci skb_copy_from_linear_data(skb, n->data, n->len); 202762306a36Sopenharmony_ci 202862306a36Sopenharmony_ci n->truesize += skb->data_len; 202962306a36Sopenharmony_ci n->data_len = skb->data_len; 203062306a36Sopenharmony_ci n->len = skb->len; 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_ci if (skb_shinfo(skb)->nr_frags) { 203362306a36Sopenharmony_ci int i; 203462306a36Sopenharmony_ci 203562306a36Sopenharmony_ci if (skb_orphan_frags(skb, gfp_mask) || 203662306a36Sopenharmony_ci skb_zerocopy_clone(n, skb, gfp_mask)) { 203762306a36Sopenharmony_ci kfree_skb(n); 203862306a36Sopenharmony_ci n = NULL; 203962306a36Sopenharmony_ci goto out; 204062306a36Sopenharmony_ci } 204162306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 204262306a36Sopenharmony_ci skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; 204362306a36Sopenharmony_ci skb_frag_ref(skb, i); 204462306a36Sopenharmony_ci } 204562306a36Sopenharmony_ci skb_shinfo(n)->nr_frags = i; 204662306a36Sopenharmony_ci } 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_ci if (skb_has_frag_list(skb)) { 204962306a36Sopenharmony_ci skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; 205062306a36Sopenharmony_ci skb_clone_fraglist(n); 205162306a36Sopenharmony_ci } 205262306a36Sopenharmony_ci 205362306a36Sopenharmony_ci skb_copy_header(n, skb); 205462306a36Sopenharmony_ciout: 205562306a36Sopenharmony_ci return n; 205662306a36Sopenharmony_ci} 205762306a36Sopenharmony_ciEXPORT_SYMBOL(__pskb_copy_fclone); 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci/** 206062306a36Sopenharmony_ci * pskb_expand_head - reallocate header of &sk_buff 206162306a36Sopenharmony_ci * @skb: buffer to reallocate 206262306a36Sopenharmony_ci * @nhead: room to add at head 206362306a36Sopenharmony_ci * @ntail: room to add at tail 206462306a36Sopenharmony_ci * @gfp_mask: allocation priority 206562306a36Sopenharmony_ci * 206662306a36Sopenharmony_ci * Expands (or creates identical copy, if @nhead and @ntail are zero) 206762306a36Sopenharmony_ci * header of @skb. &sk_buff itself is not changed. &sk_buff MUST have 206862306a36Sopenharmony_ci * reference count of 1. Returns zero in the case of success or error, 206962306a36Sopenharmony_ci * if expansion failed. In the last case, &sk_buff is not changed. 207062306a36Sopenharmony_ci * 207162306a36Sopenharmony_ci * All the pointers pointing into skb header may change and must be 207262306a36Sopenharmony_ci * reloaded after call to this function. 207362306a36Sopenharmony_ci */ 207462306a36Sopenharmony_ci 207562306a36Sopenharmony_ciint pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, 207662306a36Sopenharmony_ci gfp_t gfp_mask) 207762306a36Sopenharmony_ci{ 207862306a36Sopenharmony_ci unsigned int osize = skb_end_offset(skb); 207962306a36Sopenharmony_ci unsigned int size = osize + nhead + ntail; 208062306a36Sopenharmony_ci long off; 208162306a36Sopenharmony_ci u8 *data; 208262306a36Sopenharmony_ci int i; 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci BUG_ON(nhead < 0); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci BUG_ON(skb_shared(skb)); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci skb_zcopy_downgrade_managed(skb); 208962306a36Sopenharmony_ci 209062306a36Sopenharmony_ci if (skb_pfmemalloc(skb)) 209162306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); 209462306a36Sopenharmony_ci if (!data) 209562306a36Sopenharmony_ci goto nodata; 209662306a36Sopenharmony_ci size = SKB_WITH_OVERHEAD(size); 209762306a36Sopenharmony_ci 209862306a36Sopenharmony_ci /* Copy only real data... and, alas, header. This should be 209962306a36Sopenharmony_ci * optimized for the cases when header is void. 210062306a36Sopenharmony_ci */ 210162306a36Sopenharmony_ci memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head); 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci memcpy((struct skb_shared_info *)(data + size), 210462306a36Sopenharmony_ci skb_shinfo(skb), 210562306a36Sopenharmony_ci offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); 210662306a36Sopenharmony_ci 210762306a36Sopenharmony_ci /* 210862306a36Sopenharmony_ci * if shinfo is shared we must drop the old head gracefully, but if it 210962306a36Sopenharmony_ci * is not we can just drop the old head and let the existing refcount 211062306a36Sopenharmony_ci * be since all we did is relocate the values 211162306a36Sopenharmony_ci */ 211262306a36Sopenharmony_ci if (skb_cloned(skb)) { 211362306a36Sopenharmony_ci if (skb_orphan_frags(skb, gfp_mask)) 211462306a36Sopenharmony_ci goto nofrags; 211562306a36Sopenharmony_ci if (skb_zcopy(skb)) 211662306a36Sopenharmony_ci refcount_inc(&skb_uarg(skb)->refcnt); 211762306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 211862306a36Sopenharmony_ci skb_frag_ref(skb, i); 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_ci if (skb_has_frag_list(skb)) 212162306a36Sopenharmony_ci skb_clone_fraglist(skb); 212262306a36Sopenharmony_ci 212362306a36Sopenharmony_ci skb_release_data(skb, SKB_CONSUMED, false); 212462306a36Sopenharmony_ci } else { 212562306a36Sopenharmony_ci skb_free_head(skb, false); 212662306a36Sopenharmony_ci } 212762306a36Sopenharmony_ci off = (data + nhead) - skb->head; 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_ci skb->head = data; 213062306a36Sopenharmony_ci skb->head_frag = 0; 213162306a36Sopenharmony_ci skb->data += off; 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_ci skb_set_end_offset(skb, size); 213462306a36Sopenharmony_ci#ifdef NET_SKBUFF_DATA_USES_OFFSET 213562306a36Sopenharmony_ci off = nhead; 213662306a36Sopenharmony_ci#endif 213762306a36Sopenharmony_ci skb->tail += off; 213862306a36Sopenharmony_ci skb_headers_offset_update(skb, nhead); 213962306a36Sopenharmony_ci skb->cloned = 0; 214062306a36Sopenharmony_ci skb->hdr_len = 0; 214162306a36Sopenharmony_ci skb->nohdr = 0; 214262306a36Sopenharmony_ci atomic_set(&skb_shinfo(skb)->dataref, 1); 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci skb_metadata_clear(skb); 214562306a36Sopenharmony_ci 214662306a36Sopenharmony_ci /* It is not generally safe to change skb->truesize. 214762306a36Sopenharmony_ci * For the moment, we really care of rx path, or 214862306a36Sopenharmony_ci * when skb is orphaned (not attached to a socket). 214962306a36Sopenharmony_ci */ 215062306a36Sopenharmony_ci if (!skb->sk || skb->destructor == sock_edemux) 215162306a36Sopenharmony_ci skb->truesize += size - osize; 215262306a36Sopenharmony_ci 215362306a36Sopenharmony_ci return 0; 215462306a36Sopenharmony_ci 215562306a36Sopenharmony_cinofrags: 215662306a36Sopenharmony_ci skb_kfree_head(data, size); 215762306a36Sopenharmony_cinodata: 215862306a36Sopenharmony_ci return -ENOMEM; 215962306a36Sopenharmony_ci} 216062306a36Sopenharmony_ciEXPORT_SYMBOL(pskb_expand_head); 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci/* Make private copy of skb with writable head and some headroom */ 216362306a36Sopenharmony_ci 216462306a36Sopenharmony_cistruct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) 216562306a36Sopenharmony_ci{ 216662306a36Sopenharmony_ci struct sk_buff *skb2; 216762306a36Sopenharmony_ci int delta = headroom - skb_headroom(skb); 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_ci if (delta <= 0) 217062306a36Sopenharmony_ci skb2 = pskb_copy(skb, GFP_ATOMIC); 217162306a36Sopenharmony_ci else { 217262306a36Sopenharmony_ci skb2 = skb_clone(skb, GFP_ATOMIC); 217362306a36Sopenharmony_ci if (skb2 && pskb_expand_head(skb2, SKB_DATA_ALIGN(delta), 0, 217462306a36Sopenharmony_ci GFP_ATOMIC)) { 217562306a36Sopenharmony_ci kfree_skb(skb2); 217662306a36Sopenharmony_ci skb2 = NULL; 217762306a36Sopenharmony_ci } 217862306a36Sopenharmony_ci } 217962306a36Sopenharmony_ci return skb2; 218062306a36Sopenharmony_ci} 218162306a36Sopenharmony_ciEXPORT_SYMBOL(skb_realloc_headroom); 218262306a36Sopenharmony_ci 218362306a36Sopenharmony_ci/* Note: We plan to rework this in linux-6.4 */ 218462306a36Sopenharmony_ciint __skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri) 218562306a36Sopenharmony_ci{ 218662306a36Sopenharmony_ci unsigned int saved_end_offset, saved_truesize; 218762306a36Sopenharmony_ci struct skb_shared_info *shinfo; 218862306a36Sopenharmony_ci int res; 218962306a36Sopenharmony_ci 219062306a36Sopenharmony_ci saved_end_offset = skb_end_offset(skb); 219162306a36Sopenharmony_ci saved_truesize = skb->truesize; 219262306a36Sopenharmony_ci 219362306a36Sopenharmony_ci res = pskb_expand_head(skb, 0, 0, pri); 219462306a36Sopenharmony_ci if (res) 219562306a36Sopenharmony_ci return res; 219662306a36Sopenharmony_ci 219762306a36Sopenharmony_ci skb->truesize = saved_truesize; 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ci if (likely(skb_end_offset(skb) == saved_end_offset)) 220062306a36Sopenharmony_ci return 0; 220162306a36Sopenharmony_ci 220262306a36Sopenharmony_ci /* We can not change skb->end if the original or new value 220362306a36Sopenharmony_ci * is SKB_SMALL_HEAD_HEADROOM, as it might break skb_kfree_head(). 220462306a36Sopenharmony_ci */ 220562306a36Sopenharmony_ci if (saved_end_offset == SKB_SMALL_HEAD_HEADROOM || 220662306a36Sopenharmony_ci skb_end_offset(skb) == SKB_SMALL_HEAD_HEADROOM) { 220762306a36Sopenharmony_ci /* We think this path should not be taken. 220862306a36Sopenharmony_ci * Add a temporary trace to warn us just in case. 220962306a36Sopenharmony_ci */ 221062306a36Sopenharmony_ci pr_err_once("__skb_unclone_keeptruesize() skb_end_offset() %u -> %u\n", 221162306a36Sopenharmony_ci saved_end_offset, skb_end_offset(skb)); 221262306a36Sopenharmony_ci WARN_ON_ONCE(1); 221362306a36Sopenharmony_ci return 0; 221462306a36Sopenharmony_ci } 221562306a36Sopenharmony_ci 221662306a36Sopenharmony_ci shinfo = skb_shinfo(skb); 221762306a36Sopenharmony_ci 221862306a36Sopenharmony_ci /* We are about to change back skb->end, 221962306a36Sopenharmony_ci * we need to move skb_shinfo() to its new location. 222062306a36Sopenharmony_ci */ 222162306a36Sopenharmony_ci memmove(skb->head + saved_end_offset, 222262306a36Sopenharmony_ci shinfo, 222362306a36Sopenharmony_ci offsetof(struct skb_shared_info, frags[shinfo->nr_frags])); 222462306a36Sopenharmony_ci 222562306a36Sopenharmony_ci skb_set_end_offset(skb, saved_end_offset); 222662306a36Sopenharmony_ci 222762306a36Sopenharmony_ci return 0; 222862306a36Sopenharmony_ci} 222962306a36Sopenharmony_ci 223062306a36Sopenharmony_ci/** 223162306a36Sopenharmony_ci * skb_expand_head - reallocate header of &sk_buff 223262306a36Sopenharmony_ci * @skb: buffer to reallocate 223362306a36Sopenharmony_ci * @headroom: needed headroom 223462306a36Sopenharmony_ci * 223562306a36Sopenharmony_ci * Unlike skb_realloc_headroom, this one does not allocate a new skb 223662306a36Sopenharmony_ci * if possible; copies skb->sk to new skb as needed 223762306a36Sopenharmony_ci * and frees original skb in case of failures. 223862306a36Sopenharmony_ci * 223962306a36Sopenharmony_ci * It expect increased headroom and generates warning otherwise. 224062306a36Sopenharmony_ci */ 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_cistruct sk_buff *skb_expand_head(struct sk_buff *skb, unsigned int headroom) 224362306a36Sopenharmony_ci{ 224462306a36Sopenharmony_ci int delta = headroom - skb_headroom(skb); 224562306a36Sopenharmony_ci int osize = skb_end_offset(skb); 224662306a36Sopenharmony_ci struct sock *sk = skb->sk; 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci if (WARN_ONCE(delta <= 0, 224962306a36Sopenharmony_ci "%s is expecting an increase in the headroom", __func__)) 225062306a36Sopenharmony_ci return skb; 225162306a36Sopenharmony_ci 225262306a36Sopenharmony_ci delta = SKB_DATA_ALIGN(delta); 225362306a36Sopenharmony_ci /* pskb_expand_head() might crash, if skb is shared. */ 225462306a36Sopenharmony_ci if (skb_shared(skb) || !is_skb_wmem(skb)) { 225562306a36Sopenharmony_ci struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci if (unlikely(!nskb)) 225862306a36Sopenharmony_ci goto fail; 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_ci if (sk) 226162306a36Sopenharmony_ci skb_set_owner_w(nskb, sk); 226262306a36Sopenharmony_ci consume_skb(skb); 226362306a36Sopenharmony_ci skb = nskb; 226462306a36Sopenharmony_ci } 226562306a36Sopenharmony_ci if (pskb_expand_head(skb, delta, 0, GFP_ATOMIC)) 226662306a36Sopenharmony_ci goto fail; 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci if (sk && is_skb_wmem(skb)) { 226962306a36Sopenharmony_ci delta = skb_end_offset(skb) - osize; 227062306a36Sopenharmony_ci refcount_add(delta, &sk->sk_wmem_alloc); 227162306a36Sopenharmony_ci skb->truesize += delta; 227262306a36Sopenharmony_ci } 227362306a36Sopenharmony_ci return skb; 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_cifail: 227662306a36Sopenharmony_ci kfree_skb(skb); 227762306a36Sopenharmony_ci return NULL; 227862306a36Sopenharmony_ci} 227962306a36Sopenharmony_ciEXPORT_SYMBOL(skb_expand_head); 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_ci/** 228262306a36Sopenharmony_ci * skb_copy_expand - copy and expand sk_buff 228362306a36Sopenharmony_ci * @skb: buffer to copy 228462306a36Sopenharmony_ci * @newheadroom: new free bytes at head 228562306a36Sopenharmony_ci * @newtailroom: new free bytes at tail 228662306a36Sopenharmony_ci * @gfp_mask: allocation priority 228762306a36Sopenharmony_ci * 228862306a36Sopenharmony_ci * Make a copy of both an &sk_buff and its data and while doing so 228962306a36Sopenharmony_ci * allocate additional space. 229062306a36Sopenharmony_ci * 229162306a36Sopenharmony_ci * This is used when the caller wishes to modify the data and needs a 229262306a36Sopenharmony_ci * private copy of the data to alter as well as more space for new fields. 229362306a36Sopenharmony_ci * Returns %NULL on failure or the pointer to the buffer 229462306a36Sopenharmony_ci * on success. The returned buffer has a reference count of 1. 229562306a36Sopenharmony_ci * 229662306a36Sopenharmony_ci * You must pass %GFP_ATOMIC as the allocation priority if this function 229762306a36Sopenharmony_ci * is called from an interrupt. 229862306a36Sopenharmony_ci */ 229962306a36Sopenharmony_cistruct sk_buff *skb_copy_expand(const struct sk_buff *skb, 230062306a36Sopenharmony_ci int newheadroom, int newtailroom, 230162306a36Sopenharmony_ci gfp_t gfp_mask) 230262306a36Sopenharmony_ci{ 230362306a36Sopenharmony_ci /* 230462306a36Sopenharmony_ci * Allocate the copy buffer 230562306a36Sopenharmony_ci */ 230662306a36Sopenharmony_ci struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, 230762306a36Sopenharmony_ci gfp_mask, skb_alloc_rx_flag(skb), 230862306a36Sopenharmony_ci NUMA_NO_NODE); 230962306a36Sopenharmony_ci int oldheadroom = skb_headroom(skb); 231062306a36Sopenharmony_ci int head_copy_len, head_copy_off; 231162306a36Sopenharmony_ci 231262306a36Sopenharmony_ci if (!n) 231362306a36Sopenharmony_ci return NULL; 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci skb_reserve(n, newheadroom); 231662306a36Sopenharmony_ci 231762306a36Sopenharmony_ci /* Set the tail pointer and length */ 231862306a36Sopenharmony_ci skb_put(n, skb->len); 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci head_copy_len = oldheadroom; 232162306a36Sopenharmony_ci head_copy_off = 0; 232262306a36Sopenharmony_ci if (newheadroom <= head_copy_len) 232362306a36Sopenharmony_ci head_copy_len = newheadroom; 232462306a36Sopenharmony_ci else 232562306a36Sopenharmony_ci head_copy_off = newheadroom - head_copy_len; 232662306a36Sopenharmony_ci 232762306a36Sopenharmony_ci /* Copy the linear header and data. */ 232862306a36Sopenharmony_ci BUG_ON(skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off, 232962306a36Sopenharmony_ci skb->len + head_copy_len)); 233062306a36Sopenharmony_ci 233162306a36Sopenharmony_ci skb_copy_header(n, skb); 233262306a36Sopenharmony_ci 233362306a36Sopenharmony_ci skb_headers_offset_update(n, newheadroom - oldheadroom); 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci return n; 233662306a36Sopenharmony_ci} 233762306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy_expand); 233862306a36Sopenharmony_ci 233962306a36Sopenharmony_ci/** 234062306a36Sopenharmony_ci * __skb_pad - zero pad the tail of an skb 234162306a36Sopenharmony_ci * @skb: buffer to pad 234262306a36Sopenharmony_ci * @pad: space to pad 234362306a36Sopenharmony_ci * @free_on_error: free buffer on error 234462306a36Sopenharmony_ci * 234562306a36Sopenharmony_ci * Ensure that a buffer is followed by a padding area that is zero 234662306a36Sopenharmony_ci * filled. Used by network drivers which may DMA or transfer data 234762306a36Sopenharmony_ci * beyond the buffer end onto the wire. 234862306a36Sopenharmony_ci * 234962306a36Sopenharmony_ci * May return error in out of memory cases. The skb is freed on error 235062306a36Sopenharmony_ci * if @free_on_error is true. 235162306a36Sopenharmony_ci */ 235262306a36Sopenharmony_ci 235362306a36Sopenharmony_ciint __skb_pad(struct sk_buff *skb, int pad, bool free_on_error) 235462306a36Sopenharmony_ci{ 235562306a36Sopenharmony_ci int err; 235662306a36Sopenharmony_ci int ntail; 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci /* If the skbuff is non linear tailroom is always zero.. */ 235962306a36Sopenharmony_ci if (!skb_cloned(skb) && skb_tailroom(skb) >= pad) { 236062306a36Sopenharmony_ci memset(skb->data+skb->len, 0, pad); 236162306a36Sopenharmony_ci return 0; 236262306a36Sopenharmony_ci } 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci ntail = skb->data_len + pad - (skb->end - skb->tail); 236562306a36Sopenharmony_ci if (likely(skb_cloned(skb) || ntail > 0)) { 236662306a36Sopenharmony_ci err = pskb_expand_head(skb, 0, ntail, GFP_ATOMIC); 236762306a36Sopenharmony_ci if (unlikely(err)) 236862306a36Sopenharmony_ci goto free_skb; 236962306a36Sopenharmony_ci } 237062306a36Sopenharmony_ci 237162306a36Sopenharmony_ci /* FIXME: The use of this function with non-linear skb's really needs 237262306a36Sopenharmony_ci * to be audited. 237362306a36Sopenharmony_ci */ 237462306a36Sopenharmony_ci err = skb_linearize(skb); 237562306a36Sopenharmony_ci if (unlikely(err)) 237662306a36Sopenharmony_ci goto free_skb; 237762306a36Sopenharmony_ci 237862306a36Sopenharmony_ci memset(skb->data + skb->len, 0, pad); 237962306a36Sopenharmony_ci return 0; 238062306a36Sopenharmony_ci 238162306a36Sopenharmony_cifree_skb: 238262306a36Sopenharmony_ci if (free_on_error) 238362306a36Sopenharmony_ci kfree_skb(skb); 238462306a36Sopenharmony_ci return err; 238562306a36Sopenharmony_ci} 238662306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_pad); 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ci/** 238962306a36Sopenharmony_ci * pskb_put - add data to the tail of a potentially fragmented buffer 239062306a36Sopenharmony_ci * @skb: start of the buffer to use 239162306a36Sopenharmony_ci * @tail: tail fragment of the buffer to use 239262306a36Sopenharmony_ci * @len: amount of data to add 239362306a36Sopenharmony_ci * 239462306a36Sopenharmony_ci * This function extends the used data area of the potentially 239562306a36Sopenharmony_ci * fragmented buffer. @tail must be the last fragment of @skb -- or 239662306a36Sopenharmony_ci * @skb itself. If this would exceed the total buffer size the kernel 239762306a36Sopenharmony_ci * will panic. A pointer to the first byte of the extra data is 239862306a36Sopenharmony_ci * returned. 239962306a36Sopenharmony_ci */ 240062306a36Sopenharmony_ci 240162306a36Sopenharmony_civoid *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len) 240262306a36Sopenharmony_ci{ 240362306a36Sopenharmony_ci if (tail != skb) { 240462306a36Sopenharmony_ci skb->data_len += len; 240562306a36Sopenharmony_ci skb->len += len; 240662306a36Sopenharmony_ci } 240762306a36Sopenharmony_ci return skb_put(tail, len); 240862306a36Sopenharmony_ci} 240962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pskb_put); 241062306a36Sopenharmony_ci 241162306a36Sopenharmony_ci/** 241262306a36Sopenharmony_ci * skb_put - add data to a buffer 241362306a36Sopenharmony_ci * @skb: buffer to use 241462306a36Sopenharmony_ci * @len: amount of data to add 241562306a36Sopenharmony_ci * 241662306a36Sopenharmony_ci * This function extends the used data area of the buffer. If this would 241762306a36Sopenharmony_ci * exceed the total buffer size the kernel will panic. A pointer to the 241862306a36Sopenharmony_ci * first byte of the extra data is returned. 241962306a36Sopenharmony_ci */ 242062306a36Sopenharmony_civoid *skb_put(struct sk_buff *skb, unsigned int len) 242162306a36Sopenharmony_ci{ 242262306a36Sopenharmony_ci void *tmp = skb_tail_pointer(skb); 242362306a36Sopenharmony_ci SKB_LINEAR_ASSERT(skb); 242462306a36Sopenharmony_ci skb->tail += len; 242562306a36Sopenharmony_ci skb->len += len; 242662306a36Sopenharmony_ci if (unlikely(skb->tail > skb->end)) 242762306a36Sopenharmony_ci skb_over_panic(skb, len, __builtin_return_address(0)); 242862306a36Sopenharmony_ci return tmp; 242962306a36Sopenharmony_ci} 243062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_put); 243162306a36Sopenharmony_ci 243262306a36Sopenharmony_ci/** 243362306a36Sopenharmony_ci * skb_push - add data to the start of a buffer 243462306a36Sopenharmony_ci * @skb: buffer to use 243562306a36Sopenharmony_ci * @len: amount of data to add 243662306a36Sopenharmony_ci * 243762306a36Sopenharmony_ci * This function extends the used data area of the buffer at the buffer 243862306a36Sopenharmony_ci * start. If this would exceed the total buffer headroom the kernel will 243962306a36Sopenharmony_ci * panic. A pointer to the first byte of the extra data is returned. 244062306a36Sopenharmony_ci */ 244162306a36Sopenharmony_civoid *skb_push(struct sk_buff *skb, unsigned int len) 244262306a36Sopenharmony_ci{ 244362306a36Sopenharmony_ci skb->data -= len; 244462306a36Sopenharmony_ci skb->len += len; 244562306a36Sopenharmony_ci if (unlikely(skb->data < skb->head)) 244662306a36Sopenharmony_ci skb_under_panic(skb, len, __builtin_return_address(0)); 244762306a36Sopenharmony_ci return skb->data; 244862306a36Sopenharmony_ci} 244962306a36Sopenharmony_ciEXPORT_SYMBOL(skb_push); 245062306a36Sopenharmony_ci 245162306a36Sopenharmony_ci/** 245262306a36Sopenharmony_ci * skb_pull - remove data from the start of a buffer 245362306a36Sopenharmony_ci * @skb: buffer to use 245462306a36Sopenharmony_ci * @len: amount of data to remove 245562306a36Sopenharmony_ci * 245662306a36Sopenharmony_ci * This function removes data from the start of a buffer, returning 245762306a36Sopenharmony_ci * the memory to the headroom. A pointer to the next data in the buffer 245862306a36Sopenharmony_ci * is returned. Once the data has been pulled future pushes will overwrite 245962306a36Sopenharmony_ci * the old data. 246062306a36Sopenharmony_ci */ 246162306a36Sopenharmony_civoid *skb_pull(struct sk_buff *skb, unsigned int len) 246262306a36Sopenharmony_ci{ 246362306a36Sopenharmony_ci return skb_pull_inline(skb, len); 246462306a36Sopenharmony_ci} 246562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_pull); 246662306a36Sopenharmony_ci 246762306a36Sopenharmony_ci/** 246862306a36Sopenharmony_ci * skb_pull_data - remove data from the start of a buffer returning its 246962306a36Sopenharmony_ci * original position. 247062306a36Sopenharmony_ci * @skb: buffer to use 247162306a36Sopenharmony_ci * @len: amount of data to remove 247262306a36Sopenharmony_ci * 247362306a36Sopenharmony_ci * This function removes data from the start of a buffer, returning 247462306a36Sopenharmony_ci * the memory to the headroom. A pointer to the original data in the buffer 247562306a36Sopenharmony_ci * is returned after checking if there is enough data to pull. Once the 247662306a36Sopenharmony_ci * data has been pulled future pushes will overwrite the old data. 247762306a36Sopenharmony_ci */ 247862306a36Sopenharmony_civoid *skb_pull_data(struct sk_buff *skb, size_t len) 247962306a36Sopenharmony_ci{ 248062306a36Sopenharmony_ci void *data = skb->data; 248162306a36Sopenharmony_ci 248262306a36Sopenharmony_ci if (skb->len < len) 248362306a36Sopenharmony_ci return NULL; 248462306a36Sopenharmony_ci 248562306a36Sopenharmony_ci skb_pull(skb, len); 248662306a36Sopenharmony_ci 248762306a36Sopenharmony_ci return data; 248862306a36Sopenharmony_ci} 248962306a36Sopenharmony_ciEXPORT_SYMBOL(skb_pull_data); 249062306a36Sopenharmony_ci 249162306a36Sopenharmony_ci/** 249262306a36Sopenharmony_ci * skb_trim - remove end from a buffer 249362306a36Sopenharmony_ci * @skb: buffer to alter 249462306a36Sopenharmony_ci * @len: new length 249562306a36Sopenharmony_ci * 249662306a36Sopenharmony_ci * Cut the length of a buffer down by removing data from the tail. If 249762306a36Sopenharmony_ci * the buffer is already under the length specified it is not modified. 249862306a36Sopenharmony_ci * The skb must be linear. 249962306a36Sopenharmony_ci */ 250062306a36Sopenharmony_civoid skb_trim(struct sk_buff *skb, unsigned int len) 250162306a36Sopenharmony_ci{ 250262306a36Sopenharmony_ci if (skb->len > len) 250362306a36Sopenharmony_ci __skb_trim(skb, len); 250462306a36Sopenharmony_ci} 250562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_trim); 250662306a36Sopenharmony_ci 250762306a36Sopenharmony_ci/* Trims skb to length len. It can change skb pointers. 250862306a36Sopenharmony_ci */ 250962306a36Sopenharmony_ci 251062306a36Sopenharmony_ciint ___pskb_trim(struct sk_buff *skb, unsigned int len) 251162306a36Sopenharmony_ci{ 251262306a36Sopenharmony_ci struct sk_buff **fragp; 251362306a36Sopenharmony_ci struct sk_buff *frag; 251462306a36Sopenharmony_ci int offset = skb_headlen(skb); 251562306a36Sopenharmony_ci int nfrags = skb_shinfo(skb)->nr_frags; 251662306a36Sopenharmony_ci int i; 251762306a36Sopenharmony_ci int err; 251862306a36Sopenharmony_ci 251962306a36Sopenharmony_ci if (skb_cloned(skb) && 252062306a36Sopenharmony_ci unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) 252162306a36Sopenharmony_ci return err; 252262306a36Sopenharmony_ci 252362306a36Sopenharmony_ci i = 0; 252462306a36Sopenharmony_ci if (offset >= len) 252562306a36Sopenharmony_ci goto drop_pages; 252662306a36Sopenharmony_ci 252762306a36Sopenharmony_ci for (; i < nfrags; i++) { 252862306a36Sopenharmony_ci int end = offset + skb_frag_size(&skb_shinfo(skb)->frags[i]); 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci if (end < len) { 253162306a36Sopenharmony_ci offset = end; 253262306a36Sopenharmony_ci continue; 253362306a36Sopenharmony_ci } 253462306a36Sopenharmony_ci 253562306a36Sopenharmony_ci skb_frag_size_set(&skb_shinfo(skb)->frags[i++], len - offset); 253662306a36Sopenharmony_ci 253762306a36Sopenharmony_cidrop_pages: 253862306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = i; 253962306a36Sopenharmony_ci 254062306a36Sopenharmony_ci for (; i < nfrags; i++) 254162306a36Sopenharmony_ci skb_frag_unref(skb, i); 254262306a36Sopenharmony_ci 254362306a36Sopenharmony_ci if (skb_has_frag_list(skb)) 254462306a36Sopenharmony_ci skb_drop_fraglist(skb); 254562306a36Sopenharmony_ci goto done; 254662306a36Sopenharmony_ci } 254762306a36Sopenharmony_ci 254862306a36Sopenharmony_ci for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); 254962306a36Sopenharmony_ci fragp = &frag->next) { 255062306a36Sopenharmony_ci int end = offset + frag->len; 255162306a36Sopenharmony_ci 255262306a36Sopenharmony_ci if (skb_shared(frag)) { 255362306a36Sopenharmony_ci struct sk_buff *nfrag; 255462306a36Sopenharmony_ci 255562306a36Sopenharmony_ci nfrag = skb_clone(frag, GFP_ATOMIC); 255662306a36Sopenharmony_ci if (unlikely(!nfrag)) 255762306a36Sopenharmony_ci return -ENOMEM; 255862306a36Sopenharmony_ci 255962306a36Sopenharmony_ci nfrag->next = frag->next; 256062306a36Sopenharmony_ci consume_skb(frag); 256162306a36Sopenharmony_ci frag = nfrag; 256262306a36Sopenharmony_ci *fragp = frag; 256362306a36Sopenharmony_ci } 256462306a36Sopenharmony_ci 256562306a36Sopenharmony_ci if (end < len) { 256662306a36Sopenharmony_ci offset = end; 256762306a36Sopenharmony_ci continue; 256862306a36Sopenharmony_ci } 256962306a36Sopenharmony_ci 257062306a36Sopenharmony_ci if (end > len && 257162306a36Sopenharmony_ci unlikely((err = pskb_trim(frag, len - offset)))) 257262306a36Sopenharmony_ci return err; 257362306a36Sopenharmony_ci 257462306a36Sopenharmony_ci if (frag->next) 257562306a36Sopenharmony_ci skb_drop_list(&frag->next); 257662306a36Sopenharmony_ci break; 257762306a36Sopenharmony_ci } 257862306a36Sopenharmony_ci 257962306a36Sopenharmony_cidone: 258062306a36Sopenharmony_ci if (len > skb_headlen(skb)) { 258162306a36Sopenharmony_ci skb->data_len -= skb->len - len; 258262306a36Sopenharmony_ci skb->len = len; 258362306a36Sopenharmony_ci } else { 258462306a36Sopenharmony_ci skb->len = len; 258562306a36Sopenharmony_ci skb->data_len = 0; 258662306a36Sopenharmony_ci skb_set_tail_pointer(skb, len); 258762306a36Sopenharmony_ci } 258862306a36Sopenharmony_ci 258962306a36Sopenharmony_ci if (!skb->sk || skb->destructor == sock_edemux) 259062306a36Sopenharmony_ci skb_condense(skb); 259162306a36Sopenharmony_ci return 0; 259262306a36Sopenharmony_ci} 259362306a36Sopenharmony_ciEXPORT_SYMBOL(___pskb_trim); 259462306a36Sopenharmony_ci 259562306a36Sopenharmony_ci/* Note : use pskb_trim_rcsum() instead of calling this directly 259662306a36Sopenharmony_ci */ 259762306a36Sopenharmony_ciint pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len) 259862306a36Sopenharmony_ci{ 259962306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_COMPLETE) { 260062306a36Sopenharmony_ci int delta = skb->len - len; 260162306a36Sopenharmony_ci 260262306a36Sopenharmony_ci skb->csum = csum_block_sub(skb->csum, 260362306a36Sopenharmony_ci skb_checksum(skb, len, delta, 0), 260462306a36Sopenharmony_ci len); 260562306a36Sopenharmony_ci } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 260662306a36Sopenharmony_ci int hdlen = (len > skb_headlen(skb)) ? skb_headlen(skb) : len; 260762306a36Sopenharmony_ci int offset = skb_checksum_start_offset(skb) + skb->csum_offset; 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci if (offset + sizeof(__sum16) > hdlen) 261062306a36Sopenharmony_ci return -EINVAL; 261162306a36Sopenharmony_ci } 261262306a36Sopenharmony_ci return __pskb_trim(skb, len); 261362306a36Sopenharmony_ci} 261462306a36Sopenharmony_ciEXPORT_SYMBOL(pskb_trim_rcsum_slow); 261562306a36Sopenharmony_ci 261662306a36Sopenharmony_ci/** 261762306a36Sopenharmony_ci * __pskb_pull_tail - advance tail of skb header 261862306a36Sopenharmony_ci * @skb: buffer to reallocate 261962306a36Sopenharmony_ci * @delta: number of bytes to advance tail 262062306a36Sopenharmony_ci * 262162306a36Sopenharmony_ci * The function makes a sense only on a fragmented &sk_buff, 262262306a36Sopenharmony_ci * it expands header moving its tail forward and copying necessary 262362306a36Sopenharmony_ci * data from fragmented part. 262462306a36Sopenharmony_ci * 262562306a36Sopenharmony_ci * &sk_buff MUST have reference count of 1. 262662306a36Sopenharmony_ci * 262762306a36Sopenharmony_ci * Returns %NULL (and &sk_buff does not change) if pull failed 262862306a36Sopenharmony_ci * or value of new tail of skb in the case of success. 262962306a36Sopenharmony_ci * 263062306a36Sopenharmony_ci * All the pointers pointing into skb header may change and must be 263162306a36Sopenharmony_ci * reloaded after call to this function. 263262306a36Sopenharmony_ci */ 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci/* Moves tail of skb head forward, copying data from fragmented part, 263562306a36Sopenharmony_ci * when it is necessary. 263662306a36Sopenharmony_ci * 1. It may fail due to malloc failure. 263762306a36Sopenharmony_ci * 2. It may change skb pointers. 263862306a36Sopenharmony_ci * 263962306a36Sopenharmony_ci * It is pretty complicated. Luckily, it is called only in exceptional cases. 264062306a36Sopenharmony_ci */ 264162306a36Sopenharmony_civoid *__pskb_pull_tail(struct sk_buff *skb, int delta) 264262306a36Sopenharmony_ci{ 264362306a36Sopenharmony_ci /* If skb has not enough free space at tail, get new one 264462306a36Sopenharmony_ci * plus 128 bytes for future expansions. If we have enough 264562306a36Sopenharmony_ci * room at tail, reallocate without expansion only if skb is cloned. 264662306a36Sopenharmony_ci */ 264762306a36Sopenharmony_ci int i, k, eat = (skb->tail + delta) - skb->end; 264862306a36Sopenharmony_ci 264962306a36Sopenharmony_ci if (eat > 0 || skb_cloned(skb)) { 265062306a36Sopenharmony_ci if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0, 265162306a36Sopenharmony_ci GFP_ATOMIC)) 265262306a36Sopenharmony_ci return NULL; 265362306a36Sopenharmony_ci } 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_ci BUG_ON(skb_copy_bits(skb, skb_headlen(skb), 265662306a36Sopenharmony_ci skb_tail_pointer(skb), delta)); 265762306a36Sopenharmony_ci 265862306a36Sopenharmony_ci /* Optimization: no fragments, no reasons to preestimate 265962306a36Sopenharmony_ci * size of pulled pages. Superb. 266062306a36Sopenharmony_ci */ 266162306a36Sopenharmony_ci if (!skb_has_frag_list(skb)) 266262306a36Sopenharmony_ci goto pull_pages; 266362306a36Sopenharmony_ci 266462306a36Sopenharmony_ci /* Estimate size of pulled pages. */ 266562306a36Sopenharmony_ci eat = delta; 266662306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 266762306a36Sopenharmony_ci int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_ci if (size >= eat) 267062306a36Sopenharmony_ci goto pull_pages; 267162306a36Sopenharmony_ci eat -= size; 267262306a36Sopenharmony_ci } 267362306a36Sopenharmony_ci 267462306a36Sopenharmony_ci /* If we need update frag list, we are in troubles. 267562306a36Sopenharmony_ci * Certainly, it is possible to add an offset to skb data, 267662306a36Sopenharmony_ci * but taking into account that pulling is expected to 267762306a36Sopenharmony_ci * be very rare operation, it is worth to fight against 267862306a36Sopenharmony_ci * further bloating skb head and crucify ourselves here instead. 267962306a36Sopenharmony_ci * Pure masohism, indeed. 8)8) 268062306a36Sopenharmony_ci */ 268162306a36Sopenharmony_ci if (eat) { 268262306a36Sopenharmony_ci struct sk_buff *list = skb_shinfo(skb)->frag_list; 268362306a36Sopenharmony_ci struct sk_buff *clone = NULL; 268462306a36Sopenharmony_ci struct sk_buff *insp = NULL; 268562306a36Sopenharmony_ci 268662306a36Sopenharmony_ci do { 268762306a36Sopenharmony_ci if (list->len <= eat) { 268862306a36Sopenharmony_ci /* Eaten as whole. */ 268962306a36Sopenharmony_ci eat -= list->len; 269062306a36Sopenharmony_ci list = list->next; 269162306a36Sopenharmony_ci insp = list; 269262306a36Sopenharmony_ci } else { 269362306a36Sopenharmony_ci /* Eaten partially. */ 269462306a36Sopenharmony_ci if (skb_is_gso(skb) && !list->head_frag && 269562306a36Sopenharmony_ci skb_headlen(list)) 269662306a36Sopenharmony_ci skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; 269762306a36Sopenharmony_ci 269862306a36Sopenharmony_ci if (skb_shared(list)) { 269962306a36Sopenharmony_ci /* Sucks! We need to fork list. :-( */ 270062306a36Sopenharmony_ci clone = skb_clone(list, GFP_ATOMIC); 270162306a36Sopenharmony_ci if (!clone) 270262306a36Sopenharmony_ci return NULL; 270362306a36Sopenharmony_ci insp = list->next; 270462306a36Sopenharmony_ci list = clone; 270562306a36Sopenharmony_ci } else { 270662306a36Sopenharmony_ci /* This may be pulled without 270762306a36Sopenharmony_ci * problems. */ 270862306a36Sopenharmony_ci insp = list; 270962306a36Sopenharmony_ci } 271062306a36Sopenharmony_ci if (!pskb_pull(list, eat)) { 271162306a36Sopenharmony_ci kfree_skb(clone); 271262306a36Sopenharmony_ci return NULL; 271362306a36Sopenharmony_ci } 271462306a36Sopenharmony_ci break; 271562306a36Sopenharmony_ci } 271662306a36Sopenharmony_ci } while (eat); 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ci /* Free pulled out fragments. */ 271962306a36Sopenharmony_ci while ((list = skb_shinfo(skb)->frag_list) != insp) { 272062306a36Sopenharmony_ci skb_shinfo(skb)->frag_list = list->next; 272162306a36Sopenharmony_ci consume_skb(list); 272262306a36Sopenharmony_ci } 272362306a36Sopenharmony_ci /* And insert new clone at head. */ 272462306a36Sopenharmony_ci if (clone) { 272562306a36Sopenharmony_ci clone->next = list; 272662306a36Sopenharmony_ci skb_shinfo(skb)->frag_list = clone; 272762306a36Sopenharmony_ci } 272862306a36Sopenharmony_ci } 272962306a36Sopenharmony_ci /* Success! Now we may commit changes to skb data. */ 273062306a36Sopenharmony_ci 273162306a36Sopenharmony_cipull_pages: 273262306a36Sopenharmony_ci eat = delta; 273362306a36Sopenharmony_ci k = 0; 273462306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 273562306a36Sopenharmony_ci int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); 273662306a36Sopenharmony_ci 273762306a36Sopenharmony_ci if (size <= eat) { 273862306a36Sopenharmony_ci skb_frag_unref(skb, i); 273962306a36Sopenharmony_ci eat -= size; 274062306a36Sopenharmony_ci } else { 274162306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[k]; 274262306a36Sopenharmony_ci 274362306a36Sopenharmony_ci *frag = skb_shinfo(skb)->frags[i]; 274462306a36Sopenharmony_ci if (eat) { 274562306a36Sopenharmony_ci skb_frag_off_add(frag, eat); 274662306a36Sopenharmony_ci skb_frag_size_sub(frag, eat); 274762306a36Sopenharmony_ci if (!i) 274862306a36Sopenharmony_ci goto end; 274962306a36Sopenharmony_ci eat = 0; 275062306a36Sopenharmony_ci } 275162306a36Sopenharmony_ci k++; 275262306a36Sopenharmony_ci } 275362306a36Sopenharmony_ci } 275462306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = k; 275562306a36Sopenharmony_ci 275662306a36Sopenharmony_ciend: 275762306a36Sopenharmony_ci skb->tail += delta; 275862306a36Sopenharmony_ci skb->data_len -= delta; 275962306a36Sopenharmony_ci 276062306a36Sopenharmony_ci if (!skb->data_len) 276162306a36Sopenharmony_ci skb_zcopy_clear(skb, false); 276262306a36Sopenharmony_ci 276362306a36Sopenharmony_ci return skb_tail_pointer(skb); 276462306a36Sopenharmony_ci} 276562306a36Sopenharmony_ciEXPORT_SYMBOL(__pskb_pull_tail); 276662306a36Sopenharmony_ci 276762306a36Sopenharmony_ci/** 276862306a36Sopenharmony_ci * skb_copy_bits - copy bits from skb to kernel buffer 276962306a36Sopenharmony_ci * @skb: source skb 277062306a36Sopenharmony_ci * @offset: offset in source 277162306a36Sopenharmony_ci * @to: destination buffer 277262306a36Sopenharmony_ci * @len: number of bytes to copy 277362306a36Sopenharmony_ci * 277462306a36Sopenharmony_ci * Copy the specified number of bytes from the source skb to the 277562306a36Sopenharmony_ci * destination buffer. 277662306a36Sopenharmony_ci * 277762306a36Sopenharmony_ci * CAUTION ! : 277862306a36Sopenharmony_ci * If its prototype is ever changed, 277962306a36Sopenharmony_ci * check arch/{*}/net/{*}.S files, 278062306a36Sopenharmony_ci * since it is called from BPF assembly code. 278162306a36Sopenharmony_ci */ 278262306a36Sopenharmony_ciint skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) 278362306a36Sopenharmony_ci{ 278462306a36Sopenharmony_ci int start = skb_headlen(skb); 278562306a36Sopenharmony_ci struct sk_buff *frag_iter; 278662306a36Sopenharmony_ci int i, copy; 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_ci if (offset > (int)skb->len - len) 278962306a36Sopenharmony_ci goto fault; 279062306a36Sopenharmony_ci 279162306a36Sopenharmony_ci /* Copy header. */ 279262306a36Sopenharmony_ci if ((copy = start - offset) > 0) { 279362306a36Sopenharmony_ci if (copy > len) 279462306a36Sopenharmony_ci copy = len; 279562306a36Sopenharmony_ci skb_copy_from_linear_data_offset(skb, offset, to, copy); 279662306a36Sopenharmony_ci if ((len -= copy) == 0) 279762306a36Sopenharmony_ci return 0; 279862306a36Sopenharmony_ci offset += copy; 279962306a36Sopenharmony_ci to += copy; 280062306a36Sopenharmony_ci } 280162306a36Sopenharmony_ci 280262306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 280362306a36Sopenharmony_ci int end; 280462306a36Sopenharmony_ci skb_frag_t *f = &skb_shinfo(skb)->frags[i]; 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci WARN_ON(start > offset + len); 280762306a36Sopenharmony_ci 280862306a36Sopenharmony_ci end = start + skb_frag_size(f); 280962306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 281062306a36Sopenharmony_ci u32 p_off, p_len, copied; 281162306a36Sopenharmony_ci struct page *p; 281262306a36Sopenharmony_ci u8 *vaddr; 281362306a36Sopenharmony_ci 281462306a36Sopenharmony_ci if (copy > len) 281562306a36Sopenharmony_ci copy = len; 281662306a36Sopenharmony_ci 281762306a36Sopenharmony_ci skb_frag_foreach_page(f, 281862306a36Sopenharmony_ci skb_frag_off(f) + offset - start, 281962306a36Sopenharmony_ci copy, p, p_off, p_len, copied) { 282062306a36Sopenharmony_ci vaddr = kmap_atomic(p); 282162306a36Sopenharmony_ci memcpy(to + copied, vaddr + p_off, p_len); 282262306a36Sopenharmony_ci kunmap_atomic(vaddr); 282362306a36Sopenharmony_ci } 282462306a36Sopenharmony_ci 282562306a36Sopenharmony_ci if ((len -= copy) == 0) 282662306a36Sopenharmony_ci return 0; 282762306a36Sopenharmony_ci offset += copy; 282862306a36Sopenharmony_ci to += copy; 282962306a36Sopenharmony_ci } 283062306a36Sopenharmony_ci start = end; 283162306a36Sopenharmony_ci } 283262306a36Sopenharmony_ci 283362306a36Sopenharmony_ci skb_walk_frags(skb, frag_iter) { 283462306a36Sopenharmony_ci int end; 283562306a36Sopenharmony_ci 283662306a36Sopenharmony_ci WARN_ON(start > offset + len); 283762306a36Sopenharmony_ci 283862306a36Sopenharmony_ci end = start + frag_iter->len; 283962306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 284062306a36Sopenharmony_ci if (copy > len) 284162306a36Sopenharmony_ci copy = len; 284262306a36Sopenharmony_ci if (skb_copy_bits(frag_iter, offset - start, to, copy)) 284362306a36Sopenharmony_ci goto fault; 284462306a36Sopenharmony_ci if ((len -= copy) == 0) 284562306a36Sopenharmony_ci return 0; 284662306a36Sopenharmony_ci offset += copy; 284762306a36Sopenharmony_ci to += copy; 284862306a36Sopenharmony_ci } 284962306a36Sopenharmony_ci start = end; 285062306a36Sopenharmony_ci } 285162306a36Sopenharmony_ci 285262306a36Sopenharmony_ci if (!len) 285362306a36Sopenharmony_ci return 0; 285462306a36Sopenharmony_ci 285562306a36Sopenharmony_cifault: 285662306a36Sopenharmony_ci return -EFAULT; 285762306a36Sopenharmony_ci} 285862306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy_bits); 285962306a36Sopenharmony_ci 286062306a36Sopenharmony_ci/* 286162306a36Sopenharmony_ci * Callback from splice_to_pipe(), if we need to release some pages 286262306a36Sopenharmony_ci * at the end of the spd in case we error'ed out in filling the pipe. 286362306a36Sopenharmony_ci */ 286462306a36Sopenharmony_cistatic void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) 286562306a36Sopenharmony_ci{ 286662306a36Sopenharmony_ci put_page(spd->pages[i]); 286762306a36Sopenharmony_ci} 286862306a36Sopenharmony_ci 286962306a36Sopenharmony_cistatic struct page *linear_to_page(struct page *page, unsigned int *len, 287062306a36Sopenharmony_ci unsigned int *offset, 287162306a36Sopenharmony_ci struct sock *sk) 287262306a36Sopenharmony_ci{ 287362306a36Sopenharmony_ci struct page_frag *pfrag = sk_page_frag(sk); 287462306a36Sopenharmony_ci 287562306a36Sopenharmony_ci if (!sk_page_frag_refill(sk, pfrag)) 287662306a36Sopenharmony_ci return NULL; 287762306a36Sopenharmony_ci 287862306a36Sopenharmony_ci *len = min_t(unsigned int, *len, pfrag->size - pfrag->offset); 287962306a36Sopenharmony_ci 288062306a36Sopenharmony_ci memcpy(page_address(pfrag->page) + pfrag->offset, 288162306a36Sopenharmony_ci page_address(page) + *offset, *len); 288262306a36Sopenharmony_ci *offset = pfrag->offset; 288362306a36Sopenharmony_ci pfrag->offset += *len; 288462306a36Sopenharmony_ci 288562306a36Sopenharmony_ci return pfrag->page; 288662306a36Sopenharmony_ci} 288762306a36Sopenharmony_ci 288862306a36Sopenharmony_cistatic bool spd_can_coalesce(const struct splice_pipe_desc *spd, 288962306a36Sopenharmony_ci struct page *page, 289062306a36Sopenharmony_ci unsigned int offset) 289162306a36Sopenharmony_ci{ 289262306a36Sopenharmony_ci return spd->nr_pages && 289362306a36Sopenharmony_ci spd->pages[spd->nr_pages - 1] == page && 289462306a36Sopenharmony_ci (spd->partial[spd->nr_pages - 1].offset + 289562306a36Sopenharmony_ci spd->partial[spd->nr_pages - 1].len == offset); 289662306a36Sopenharmony_ci} 289762306a36Sopenharmony_ci 289862306a36Sopenharmony_ci/* 289962306a36Sopenharmony_ci * Fill page/offset/length into spd, if it can hold more pages. 290062306a36Sopenharmony_ci */ 290162306a36Sopenharmony_cistatic bool spd_fill_page(struct splice_pipe_desc *spd, 290262306a36Sopenharmony_ci struct pipe_inode_info *pipe, struct page *page, 290362306a36Sopenharmony_ci unsigned int *len, unsigned int offset, 290462306a36Sopenharmony_ci bool linear, 290562306a36Sopenharmony_ci struct sock *sk) 290662306a36Sopenharmony_ci{ 290762306a36Sopenharmony_ci if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) 290862306a36Sopenharmony_ci return true; 290962306a36Sopenharmony_ci 291062306a36Sopenharmony_ci if (linear) { 291162306a36Sopenharmony_ci page = linear_to_page(page, len, &offset, sk); 291262306a36Sopenharmony_ci if (!page) 291362306a36Sopenharmony_ci return true; 291462306a36Sopenharmony_ci } 291562306a36Sopenharmony_ci if (spd_can_coalesce(spd, page, offset)) { 291662306a36Sopenharmony_ci spd->partial[spd->nr_pages - 1].len += *len; 291762306a36Sopenharmony_ci return false; 291862306a36Sopenharmony_ci } 291962306a36Sopenharmony_ci get_page(page); 292062306a36Sopenharmony_ci spd->pages[spd->nr_pages] = page; 292162306a36Sopenharmony_ci spd->partial[spd->nr_pages].len = *len; 292262306a36Sopenharmony_ci spd->partial[spd->nr_pages].offset = offset; 292362306a36Sopenharmony_ci spd->nr_pages++; 292462306a36Sopenharmony_ci 292562306a36Sopenharmony_ci return false; 292662306a36Sopenharmony_ci} 292762306a36Sopenharmony_ci 292862306a36Sopenharmony_cistatic bool __splice_segment(struct page *page, unsigned int poff, 292962306a36Sopenharmony_ci unsigned int plen, unsigned int *off, 293062306a36Sopenharmony_ci unsigned int *len, 293162306a36Sopenharmony_ci struct splice_pipe_desc *spd, bool linear, 293262306a36Sopenharmony_ci struct sock *sk, 293362306a36Sopenharmony_ci struct pipe_inode_info *pipe) 293462306a36Sopenharmony_ci{ 293562306a36Sopenharmony_ci if (!*len) 293662306a36Sopenharmony_ci return true; 293762306a36Sopenharmony_ci 293862306a36Sopenharmony_ci /* skip this segment if already processed */ 293962306a36Sopenharmony_ci if (*off >= plen) { 294062306a36Sopenharmony_ci *off -= plen; 294162306a36Sopenharmony_ci return false; 294262306a36Sopenharmony_ci } 294362306a36Sopenharmony_ci 294462306a36Sopenharmony_ci /* ignore any bits we already processed */ 294562306a36Sopenharmony_ci poff += *off; 294662306a36Sopenharmony_ci plen -= *off; 294762306a36Sopenharmony_ci *off = 0; 294862306a36Sopenharmony_ci 294962306a36Sopenharmony_ci do { 295062306a36Sopenharmony_ci unsigned int flen = min(*len, plen); 295162306a36Sopenharmony_ci 295262306a36Sopenharmony_ci if (spd_fill_page(spd, pipe, page, &flen, poff, 295362306a36Sopenharmony_ci linear, sk)) 295462306a36Sopenharmony_ci return true; 295562306a36Sopenharmony_ci poff += flen; 295662306a36Sopenharmony_ci plen -= flen; 295762306a36Sopenharmony_ci *len -= flen; 295862306a36Sopenharmony_ci } while (*len && plen); 295962306a36Sopenharmony_ci 296062306a36Sopenharmony_ci return false; 296162306a36Sopenharmony_ci} 296262306a36Sopenharmony_ci 296362306a36Sopenharmony_ci/* 296462306a36Sopenharmony_ci * Map linear and fragment data from the skb to spd. It reports true if the 296562306a36Sopenharmony_ci * pipe is full or if we already spliced the requested length. 296662306a36Sopenharmony_ci */ 296762306a36Sopenharmony_cistatic bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, 296862306a36Sopenharmony_ci unsigned int *offset, unsigned int *len, 296962306a36Sopenharmony_ci struct splice_pipe_desc *spd, struct sock *sk) 297062306a36Sopenharmony_ci{ 297162306a36Sopenharmony_ci int seg; 297262306a36Sopenharmony_ci struct sk_buff *iter; 297362306a36Sopenharmony_ci 297462306a36Sopenharmony_ci /* map the linear part : 297562306a36Sopenharmony_ci * If skb->head_frag is set, this 'linear' part is backed by a 297662306a36Sopenharmony_ci * fragment, and if the head is not shared with any clones then 297762306a36Sopenharmony_ci * we can avoid a copy since we own the head portion of this page. 297862306a36Sopenharmony_ci */ 297962306a36Sopenharmony_ci if (__splice_segment(virt_to_page(skb->data), 298062306a36Sopenharmony_ci (unsigned long) skb->data & (PAGE_SIZE - 1), 298162306a36Sopenharmony_ci skb_headlen(skb), 298262306a36Sopenharmony_ci offset, len, spd, 298362306a36Sopenharmony_ci skb_head_is_locked(skb), 298462306a36Sopenharmony_ci sk, pipe)) 298562306a36Sopenharmony_ci return true; 298662306a36Sopenharmony_ci 298762306a36Sopenharmony_ci /* 298862306a36Sopenharmony_ci * then map the fragments 298962306a36Sopenharmony_ci */ 299062306a36Sopenharmony_ci for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) { 299162306a36Sopenharmony_ci const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; 299262306a36Sopenharmony_ci 299362306a36Sopenharmony_ci if (__splice_segment(skb_frag_page(f), 299462306a36Sopenharmony_ci skb_frag_off(f), skb_frag_size(f), 299562306a36Sopenharmony_ci offset, len, spd, false, sk, pipe)) 299662306a36Sopenharmony_ci return true; 299762306a36Sopenharmony_ci } 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_ci skb_walk_frags(skb, iter) { 300062306a36Sopenharmony_ci if (*offset >= iter->len) { 300162306a36Sopenharmony_ci *offset -= iter->len; 300262306a36Sopenharmony_ci continue; 300362306a36Sopenharmony_ci } 300462306a36Sopenharmony_ci /* __skb_splice_bits() only fails if the output has no room 300562306a36Sopenharmony_ci * left, so no point in going over the frag_list for the error 300662306a36Sopenharmony_ci * case. 300762306a36Sopenharmony_ci */ 300862306a36Sopenharmony_ci if (__skb_splice_bits(iter, pipe, offset, len, spd, sk)) 300962306a36Sopenharmony_ci return true; 301062306a36Sopenharmony_ci } 301162306a36Sopenharmony_ci 301262306a36Sopenharmony_ci return false; 301362306a36Sopenharmony_ci} 301462306a36Sopenharmony_ci 301562306a36Sopenharmony_ci/* 301662306a36Sopenharmony_ci * Map data from the skb to a pipe. Should handle both the linear part, 301762306a36Sopenharmony_ci * the fragments, and the frag list. 301862306a36Sopenharmony_ci */ 301962306a36Sopenharmony_ciint skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset, 302062306a36Sopenharmony_ci struct pipe_inode_info *pipe, unsigned int tlen, 302162306a36Sopenharmony_ci unsigned int flags) 302262306a36Sopenharmony_ci{ 302362306a36Sopenharmony_ci struct partial_page partial[MAX_SKB_FRAGS]; 302462306a36Sopenharmony_ci struct page *pages[MAX_SKB_FRAGS]; 302562306a36Sopenharmony_ci struct splice_pipe_desc spd = { 302662306a36Sopenharmony_ci .pages = pages, 302762306a36Sopenharmony_ci .partial = partial, 302862306a36Sopenharmony_ci .nr_pages_max = MAX_SKB_FRAGS, 302962306a36Sopenharmony_ci .ops = &nosteal_pipe_buf_ops, 303062306a36Sopenharmony_ci .spd_release = sock_spd_release, 303162306a36Sopenharmony_ci }; 303262306a36Sopenharmony_ci int ret = 0; 303362306a36Sopenharmony_ci 303462306a36Sopenharmony_ci __skb_splice_bits(skb, pipe, &offset, &tlen, &spd, sk); 303562306a36Sopenharmony_ci 303662306a36Sopenharmony_ci if (spd.nr_pages) 303762306a36Sopenharmony_ci ret = splice_to_pipe(pipe, &spd); 303862306a36Sopenharmony_ci 303962306a36Sopenharmony_ci return ret; 304062306a36Sopenharmony_ci} 304162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_splice_bits); 304262306a36Sopenharmony_ci 304362306a36Sopenharmony_cistatic int sendmsg_locked(struct sock *sk, struct msghdr *msg) 304462306a36Sopenharmony_ci{ 304562306a36Sopenharmony_ci struct socket *sock = sk->sk_socket; 304662306a36Sopenharmony_ci size_t size = msg_data_left(msg); 304762306a36Sopenharmony_ci 304862306a36Sopenharmony_ci if (!sock) 304962306a36Sopenharmony_ci return -EINVAL; 305062306a36Sopenharmony_ci 305162306a36Sopenharmony_ci if (!sock->ops->sendmsg_locked) 305262306a36Sopenharmony_ci return sock_no_sendmsg_locked(sk, msg, size); 305362306a36Sopenharmony_ci 305462306a36Sopenharmony_ci return sock->ops->sendmsg_locked(sk, msg, size); 305562306a36Sopenharmony_ci} 305662306a36Sopenharmony_ci 305762306a36Sopenharmony_cistatic int sendmsg_unlocked(struct sock *sk, struct msghdr *msg) 305862306a36Sopenharmony_ci{ 305962306a36Sopenharmony_ci struct socket *sock = sk->sk_socket; 306062306a36Sopenharmony_ci 306162306a36Sopenharmony_ci if (!sock) 306262306a36Sopenharmony_ci return -EINVAL; 306362306a36Sopenharmony_ci return sock_sendmsg(sock, msg); 306462306a36Sopenharmony_ci} 306562306a36Sopenharmony_ci 306662306a36Sopenharmony_citypedef int (*sendmsg_func)(struct sock *sk, struct msghdr *msg); 306762306a36Sopenharmony_cistatic int __skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, 306862306a36Sopenharmony_ci int len, sendmsg_func sendmsg) 306962306a36Sopenharmony_ci{ 307062306a36Sopenharmony_ci unsigned int orig_len = len; 307162306a36Sopenharmony_ci struct sk_buff *head = skb; 307262306a36Sopenharmony_ci unsigned short fragidx; 307362306a36Sopenharmony_ci int slen, ret; 307462306a36Sopenharmony_ci 307562306a36Sopenharmony_cido_frag_list: 307662306a36Sopenharmony_ci 307762306a36Sopenharmony_ci /* Deal with head data */ 307862306a36Sopenharmony_ci while (offset < skb_headlen(skb) && len) { 307962306a36Sopenharmony_ci struct kvec kv; 308062306a36Sopenharmony_ci struct msghdr msg; 308162306a36Sopenharmony_ci 308262306a36Sopenharmony_ci slen = min_t(int, len, skb_headlen(skb) - offset); 308362306a36Sopenharmony_ci kv.iov_base = skb->data + offset; 308462306a36Sopenharmony_ci kv.iov_len = slen; 308562306a36Sopenharmony_ci memset(&msg, 0, sizeof(msg)); 308662306a36Sopenharmony_ci msg.msg_flags = MSG_DONTWAIT; 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_ci iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &kv, 1, slen); 308962306a36Sopenharmony_ci ret = INDIRECT_CALL_2(sendmsg, sendmsg_locked, 309062306a36Sopenharmony_ci sendmsg_unlocked, sk, &msg); 309162306a36Sopenharmony_ci if (ret <= 0) 309262306a36Sopenharmony_ci goto error; 309362306a36Sopenharmony_ci 309462306a36Sopenharmony_ci offset += ret; 309562306a36Sopenharmony_ci len -= ret; 309662306a36Sopenharmony_ci } 309762306a36Sopenharmony_ci 309862306a36Sopenharmony_ci /* All the data was skb head? */ 309962306a36Sopenharmony_ci if (!len) 310062306a36Sopenharmony_ci goto out; 310162306a36Sopenharmony_ci 310262306a36Sopenharmony_ci /* Make offset relative to start of frags */ 310362306a36Sopenharmony_ci offset -= skb_headlen(skb); 310462306a36Sopenharmony_ci 310562306a36Sopenharmony_ci /* Find where we are in frag list */ 310662306a36Sopenharmony_ci for (fragidx = 0; fragidx < skb_shinfo(skb)->nr_frags; fragidx++) { 310762306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[fragidx]; 310862306a36Sopenharmony_ci 310962306a36Sopenharmony_ci if (offset < skb_frag_size(frag)) 311062306a36Sopenharmony_ci break; 311162306a36Sopenharmony_ci 311262306a36Sopenharmony_ci offset -= skb_frag_size(frag); 311362306a36Sopenharmony_ci } 311462306a36Sopenharmony_ci 311562306a36Sopenharmony_ci for (; len && fragidx < skb_shinfo(skb)->nr_frags; fragidx++) { 311662306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[fragidx]; 311762306a36Sopenharmony_ci 311862306a36Sopenharmony_ci slen = min_t(size_t, len, skb_frag_size(frag) - offset); 311962306a36Sopenharmony_ci 312062306a36Sopenharmony_ci while (slen) { 312162306a36Sopenharmony_ci struct bio_vec bvec; 312262306a36Sopenharmony_ci struct msghdr msg = { 312362306a36Sopenharmony_ci .msg_flags = MSG_SPLICE_PAGES | MSG_DONTWAIT, 312462306a36Sopenharmony_ci }; 312562306a36Sopenharmony_ci 312662306a36Sopenharmony_ci bvec_set_page(&bvec, skb_frag_page(frag), slen, 312762306a36Sopenharmony_ci skb_frag_off(frag) + offset); 312862306a36Sopenharmony_ci iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, 312962306a36Sopenharmony_ci slen); 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci ret = INDIRECT_CALL_2(sendmsg, sendmsg_locked, 313262306a36Sopenharmony_ci sendmsg_unlocked, sk, &msg); 313362306a36Sopenharmony_ci if (ret <= 0) 313462306a36Sopenharmony_ci goto error; 313562306a36Sopenharmony_ci 313662306a36Sopenharmony_ci len -= ret; 313762306a36Sopenharmony_ci offset += ret; 313862306a36Sopenharmony_ci slen -= ret; 313962306a36Sopenharmony_ci } 314062306a36Sopenharmony_ci 314162306a36Sopenharmony_ci offset = 0; 314262306a36Sopenharmony_ci } 314362306a36Sopenharmony_ci 314462306a36Sopenharmony_ci if (len) { 314562306a36Sopenharmony_ci /* Process any frag lists */ 314662306a36Sopenharmony_ci 314762306a36Sopenharmony_ci if (skb == head) { 314862306a36Sopenharmony_ci if (skb_has_frag_list(skb)) { 314962306a36Sopenharmony_ci skb = skb_shinfo(skb)->frag_list; 315062306a36Sopenharmony_ci goto do_frag_list; 315162306a36Sopenharmony_ci } 315262306a36Sopenharmony_ci } else if (skb->next) { 315362306a36Sopenharmony_ci skb = skb->next; 315462306a36Sopenharmony_ci goto do_frag_list; 315562306a36Sopenharmony_ci } 315662306a36Sopenharmony_ci } 315762306a36Sopenharmony_ci 315862306a36Sopenharmony_ciout: 315962306a36Sopenharmony_ci return orig_len - len; 316062306a36Sopenharmony_ci 316162306a36Sopenharmony_cierror: 316262306a36Sopenharmony_ci return orig_len == len ? ret : orig_len - len; 316362306a36Sopenharmony_ci} 316462306a36Sopenharmony_ci 316562306a36Sopenharmony_ci/* Send skb data on a socket. Socket must be locked. */ 316662306a36Sopenharmony_ciint skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset, 316762306a36Sopenharmony_ci int len) 316862306a36Sopenharmony_ci{ 316962306a36Sopenharmony_ci return __skb_send_sock(sk, skb, offset, len, sendmsg_locked); 317062306a36Sopenharmony_ci} 317162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_send_sock_locked); 317262306a36Sopenharmony_ci 317362306a36Sopenharmony_ci/* Send skb data on a socket. Socket must be unlocked. */ 317462306a36Sopenharmony_ciint skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, int len) 317562306a36Sopenharmony_ci{ 317662306a36Sopenharmony_ci return __skb_send_sock(sk, skb, offset, len, sendmsg_unlocked); 317762306a36Sopenharmony_ci} 317862306a36Sopenharmony_ci 317962306a36Sopenharmony_ci/** 318062306a36Sopenharmony_ci * skb_store_bits - store bits from kernel buffer to skb 318162306a36Sopenharmony_ci * @skb: destination buffer 318262306a36Sopenharmony_ci * @offset: offset in destination 318362306a36Sopenharmony_ci * @from: source buffer 318462306a36Sopenharmony_ci * @len: number of bytes to copy 318562306a36Sopenharmony_ci * 318662306a36Sopenharmony_ci * Copy the specified number of bytes from the source buffer to the 318762306a36Sopenharmony_ci * destination skb. This function handles all the messy bits of 318862306a36Sopenharmony_ci * traversing fragment lists and such. 318962306a36Sopenharmony_ci */ 319062306a36Sopenharmony_ci 319162306a36Sopenharmony_ciint skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) 319262306a36Sopenharmony_ci{ 319362306a36Sopenharmony_ci int start = skb_headlen(skb); 319462306a36Sopenharmony_ci struct sk_buff *frag_iter; 319562306a36Sopenharmony_ci int i, copy; 319662306a36Sopenharmony_ci 319762306a36Sopenharmony_ci if (offset > (int)skb->len - len) 319862306a36Sopenharmony_ci goto fault; 319962306a36Sopenharmony_ci 320062306a36Sopenharmony_ci if ((copy = start - offset) > 0) { 320162306a36Sopenharmony_ci if (copy > len) 320262306a36Sopenharmony_ci copy = len; 320362306a36Sopenharmony_ci skb_copy_to_linear_data_offset(skb, offset, from, copy); 320462306a36Sopenharmony_ci if ((len -= copy) == 0) 320562306a36Sopenharmony_ci return 0; 320662306a36Sopenharmony_ci offset += copy; 320762306a36Sopenharmony_ci from += copy; 320862306a36Sopenharmony_ci } 320962306a36Sopenharmony_ci 321062306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 321162306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 321262306a36Sopenharmony_ci int end; 321362306a36Sopenharmony_ci 321462306a36Sopenharmony_ci WARN_ON(start > offset + len); 321562306a36Sopenharmony_ci 321662306a36Sopenharmony_ci end = start + skb_frag_size(frag); 321762306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 321862306a36Sopenharmony_ci u32 p_off, p_len, copied; 321962306a36Sopenharmony_ci struct page *p; 322062306a36Sopenharmony_ci u8 *vaddr; 322162306a36Sopenharmony_ci 322262306a36Sopenharmony_ci if (copy > len) 322362306a36Sopenharmony_ci copy = len; 322462306a36Sopenharmony_ci 322562306a36Sopenharmony_ci skb_frag_foreach_page(frag, 322662306a36Sopenharmony_ci skb_frag_off(frag) + offset - start, 322762306a36Sopenharmony_ci copy, p, p_off, p_len, copied) { 322862306a36Sopenharmony_ci vaddr = kmap_atomic(p); 322962306a36Sopenharmony_ci memcpy(vaddr + p_off, from + copied, p_len); 323062306a36Sopenharmony_ci kunmap_atomic(vaddr); 323162306a36Sopenharmony_ci } 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_ci if ((len -= copy) == 0) 323462306a36Sopenharmony_ci return 0; 323562306a36Sopenharmony_ci offset += copy; 323662306a36Sopenharmony_ci from += copy; 323762306a36Sopenharmony_ci } 323862306a36Sopenharmony_ci start = end; 323962306a36Sopenharmony_ci } 324062306a36Sopenharmony_ci 324162306a36Sopenharmony_ci skb_walk_frags(skb, frag_iter) { 324262306a36Sopenharmony_ci int end; 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_ci WARN_ON(start > offset + len); 324562306a36Sopenharmony_ci 324662306a36Sopenharmony_ci end = start + frag_iter->len; 324762306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 324862306a36Sopenharmony_ci if (copy > len) 324962306a36Sopenharmony_ci copy = len; 325062306a36Sopenharmony_ci if (skb_store_bits(frag_iter, offset - start, 325162306a36Sopenharmony_ci from, copy)) 325262306a36Sopenharmony_ci goto fault; 325362306a36Sopenharmony_ci if ((len -= copy) == 0) 325462306a36Sopenharmony_ci return 0; 325562306a36Sopenharmony_ci offset += copy; 325662306a36Sopenharmony_ci from += copy; 325762306a36Sopenharmony_ci } 325862306a36Sopenharmony_ci start = end; 325962306a36Sopenharmony_ci } 326062306a36Sopenharmony_ci if (!len) 326162306a36Sopenharmony_ci return 0; 326262306a36Sopenharmony_ci 326362306a36Sopenharmony_cifault: 326462306a36Sopenharmony_ci return -EFAULT; 326562306a36Sopenharmony_ci} 326662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_store_bits); 326762306a36Sopenharmony_ci 326862306a36Sopenharmony_ci/* Checksum skb data. */ 326962306a36Sopenharmony_ci__wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, 327062306a36Sopenharmony_ci __wsum csum, const struct skb_checksum_ops *ops) 327162306a36Sopenharmony_ci{ 327262306a36Sopenharmony_ci int start = skb_headlen(skb); 327362306a36Sopenharmony_ci int i, copy = start - offset; 327462306a36Sopenharmony_ci struct sk_buff *frag_iter; 327562306a36Sopenharmony_ci int pos = 0; 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci /* Checksum header. */ 327862306a36Sopenharmony_ci if (copy > 0) { 327962306a36Sopenharmony_ci if (copy > len) 328062306a36Sopenharmony_ci copy = len; 328162306a36Sopenharmony_ci csum = INDIRECT_CALL_1(ops->update, csum_partial_ext, 328262306a36Sopenharmony_ci skb->data + offset, copy, csum); 328362306a36Sopenharmony_ci if ((len -= copy) == 0) 328462306a36Sopenharmony_ci return csum; 328562306a36Sopenharmony_ci offset += copy; 328662306a36Sopenharmony_ci pos = copy; 328762306a36Sopenharmony_ci } 328862306a36Sopenharmony_ci 328962306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 329062306a36Sopenharmony_ci int end; 329162306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 329262306a36Sopenharmony_ci 329362306a36Sopenharmony_ci WARN_ON(start > offset + len); 329462306a36Sopenharmony_ci 329562306a36Sopenharmony_ci end = start + skb_frag_size(frag); 329662306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 329762306a36Sopenharmony_ci u32 p_off, p_len, copied; 329862306a36Sopenharmony_ci struct page *p; 329962306a36Sopenharmony_ci __wsum csum2; 330062306a36Sopenharmony_ci u8 *vaddr; 330162306a36Sopenharmony_ci 330262306a36Sopenharmony_ci if (copy > len) 330362306a36Sopenharmony_ci copy = len; 330462306a36Sopenharmony_ci 330562306a36Sopenharmony_ci skb_frag_foreach_page(frag, 330662306a36Sopenharmony_ci skb_frag_off(frag) + offset - start, 330762306a36Sopenharmony_ci copy, p, p_off, p_len, copied) { 330862306a36Sopenharmony_ci vaddr = kmap_atomic(p); 330962306a36Sopenharmony_ci csum2 = INDIRECT_CALL_1(ops->update, 331062306a36Sopenharmony_ci csum_partial_ext, 331162306a36Sopenharmony_ci vaddr + p_off, p_len, 0); 331262306a36Sopenharmony_ci kunmap_atomic(vaddr); 331362306a36Sopenharmony_ci csum = INDIRECT_CALL_1(ops->combine, 331462306a36Sopenharmony_ci csum_block_add_ext, csum, 331562306a36Sopenharmony_ci csum2, pos, p_len); 331662306a36Sopenharmony_ci pos += p_len; 331762306a36Sopenharmony_ci } 331862306a36Sopenharmony_ci 331962306a36Sopenharmony_ci if (!(len -= copy)) 332062306a36Sopenharmony_ci return csum; 332162306a36Sopenharmony_ci offset += copy; 332262306a36Sopenharmony_ci } 332362306a36Sopenharmony_ci start = end; 332462306a36Sopenharmony_ci } 332562306a36Sopenharmony_ci 332662306a36Sopenharmony_ci skb_walk_frags(skb, frag_iter) { 332762306a36Sopenharmony_ci int end; 332862306a36Sopenharmony_ci 332962306a36Sopenharmony_ci WARN_ON(start > offset + len); 333062306a36Sopenharmony_ci 333162306a36Sopenharmony_ci end = start + frag_iter->len; 333262306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 333362306a36Sopenharmony_ci __wsum csum2; 333462306a36Sopenharmony_ci if (copy > len) 333562306a36Sopenharmony_ci copy = len; 333662306a36Sopenharmony_ci csum2 = __skb_checksum(frag_iter, offset - start, 333762306a36Sopenharmony_ci copy, 0, ops); 333862306a36Sopenharmony_ci csum = INDIRECT_CALL_1(ops->combine, csum_block_add_ext, 333962306a36Sopenharmony_ci csum, csum2, pos, copy); 334062306a36Sopenharmony_ci if ((len -= copy) == 0) 334162306a36Sopenharmony_ci return csum; 334262306a36Sopenharmony_ci offset += copy; 334362306a36Sopenharmony_ci pos += copy; 334462306a36Sopenharmony_ci } 334562306a36Sopenharmony_ci start = end; 334662306a36Sopenharmony_ci } 334762306a36Sopenharmony_ci BUG_ON(len); 334862306a36Sopenharmony_ci 334962306a36Sopenharmony_ci return csum; 335062306a36Sopenharmony_ci} 335162306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_checksum); 335262306a36Sopenharmony_ci 335362306a36Sopenharmony_ci__wsum skb_checksum(const struct sk_buff *skb, int offset, 335462306a36Sopenharmony_ci int len, __wsum csum) 335562306a36Sopenharmony_ci{ 335662306a36Sopenharmony_ci const struct skb_checksum_ops ops = { 335762306a36Sopenharmony_ci .update = csum_partial_ext, 335862306a36Sopenharmony_ci .combine = csum_block_add_ext, 335962306a36Sopenharmony_ci }; 336062306a36Sopenharmony_ci 336162306a36Sopenharmony_ci return __skb_checksum(skb, offset, len, csum, &ops); 336262306a36Sopenharmony_ci} 336362306a36Sopenharmony_ciEXPORT_SYMBOL(skb_checksum); 336462306a36Sopenharmony_ci 336562306a36Sopenharmony_ci/* Both of above in one bottle. */ 336662306a36Sopenharmony_ci 336762306a36Sopenharmony_ci__wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, 336862306a36Sopenharmony_ci u8 *to, int len) 336962306a36Sopenharmony_ci{ 337062306a36Sopenharmony_ci int start = skb_headlen(skb); 337162306a36Sopenharmony_ci int i, copy = start - offset; 337262306a36Sopenharmony_ci struct sk_buff *frag_iter; 337362306a36Sopenharmony_ci int pos = 0; 337462306a36Sopenharmony_ci __wsum csum = 0; 337562306a36Sopenharmony_ci 337662306a36Sopenharmony_ci /* Copy header. */ 337762306a36Sopenharmony_ci if (copy > 0) { 337862306a36Sopenharmony_ci if (copy > len) 337962306a36Sopenharmony_ci copy = len; 338062306a36Sopenharmony_ci csum = csum_partial_copy_nocheck(skb->data + offset, to, 338162306a36Sopenharmony_ci copy); 338262306a36Sopenharmony_ci if ((len -= copy) == 0) 338362306a36Sopenharmony_ci return csum; 338462306a36Sopenharmony_ci offset += copy; 338562306a36Sopenharmony_ci to += copy; 338662306a36Sopenharmony_ci pos = copy; 338762306a36Sopenharmony_ci } 338862306a36Sopenharmony_ci 338962306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 339062306a36Sopenharmony_ci int end; 339162306a36Sopenharmony_ci 339262306a36Sopenharmony_ci WARN_ON(start > offset + len); 339362306a36Sopenharmony_ci 339462306a36Sopenharmony_ci end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); 339562306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 339662306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 339762306a36Sopenharmony_ci u32 p_off, p_len, copied; 339862306a36Sopenharmony_ci struct page *p; 339962306a36Sopenharmony_ci __wsum csum2; 340062306a36Sopenharmony_ci u8 *vaddr; 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci if (copy > len) 340362306a36Sopenharmony_ci copy = len; 340462306a36Sopenharmony_ci 340562306a36Sopenharmony_ci skb_frag_foreach_page(frag, 340662306a36Sopenharmony_ci skb_frag_off(frag) + offset - start, 340762306a36Sopenharmony_ci copy, p, p_off, p_len, copied) { 340862306a36Sopenharmony_ci vaddr = kmap_atomic(p); 340962306a36Sopenharmony_ci csum2 = csum_partial_copy_nocheck(vaddr + p_off, 341062306a36Sopenharmony_ci to + copied, 341162306a36Sopenharmony_ci p_len); 341262306a36Sopenharmony_ci kunmap_atomic(vaddr); 341362306a36Sopenharmony_ci csum = csum_block_add(csum, csum2, pos); 341462306a36Sopenharmony_ci pos += p_len; 341562306a36Sopenharmony_ci } 341662306a36Sopenharmony_ci 341762306a36Sopenharmony_ci if (!(len -= copy)) 341862306a36Sopenharmony_ci return csum; 341962306a36Sopenharmony_ci offset += copy; 342062306a36Sopenharmony_ci to += copy; 342162306a36Sopenharmony_ci } 342262306a36Sopenharmony_ci start = end; 342362306a36Sopenharmony_ci } 342462306a36Sopenharmony_ci 342562306a36Sopenharmony_ci skb_walk_frags(skb, frag_iter) { 342662306a36Sopenharmony_ci __wsum csum2; 342762306a36Sopenharmony_ci int end; 342862306a36Sopenharmony_ci 342962306a36Sopenharmony_ci WARN_ON(start > offset + len); 343062306a36Sopenharmony_ci 343162306a36Sopenharmony_ci end = start + frag_iter->len; 343262306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 343362306a36Sopenharmony_ci if (copy > len) 343462306a36Sopenharmony_ci copy = len; 343562306a36Sopenharmony_ci csum2 = skb_copy_and_csum_bits(frag_iter, 343662306a36Sopenharmony_ci offset - start, 343762306a36Sopenharmony_ci to, copy); 343862306a36Sopenharmony_ci csum = csum_block_add(csum, csum2, pos); 343962306a36Sopenharmony_ci if ((len -= copy) == 0) 344062306a36Sopenharmony_ci return csum; 344162306a36Sopenharmony_ci offset += copy; 344262306a36Sopenharmony_ci to += copy; 344362306a36Sopenharmony_ci pos += copy; 344462306a36Sopenharmony_ci } 344562306a36Sopenharmony_ci start = end; 344662306a36Sopenharmony_ci } 344762306a36Sopenharmony_ci BUG_ON(len); 344862306a36Sopenharmony_ci return csum; 344962306a36Sopenharmony_ci} 345062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy_and_csum_bits); 345162306a36Sopenharmony_ci 345262306a36Sopenharmony_ci__sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len) 345362306a36Sopenharmony_ci{ 345462306a36Sopenharmony_ci __sum16 sum; 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci sum = csum_fold(skb_checksum(skb, 0, len, skb->csum)); 345762306a36Sopenharmony_ci /* See comments in __skb_checksum_complete(). */ 345862306a36Sopenharmony_ci if (likely(!sum)) { 345962306a36Sopenharmony_ci if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && 346062306a36Sopenharmony_ci !skb->csum_complete_sw) 346162306a36Sopenharmony_ci netdev_rx_csum_fault(skb->dev, skb); 346262306a36Sopenharmony_ci } 346362306a36Sopenharmony_ci if (!skb_shared(skb)) 346462306a36Sopenharmony_ci skb->csum_valid = !sum; 346562306a36Sopenharmony_ci return sum; 346662306a36Sopenharmony_ci} 346762306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_checksum_complete_head); 346862306a36Sopenharmony_ci 346962306a36Sopenharmony_ci/* This function assumes skb->csum already holds pseudo header's checksum, 347062306a36Sopenharmony_ci * which has been changed from the hardware checksum, for example, by 347162306a36Sopenharmony_ci * __skb_checksum_validate_complete(). And, the original skb->csum must 347262306a36Sopenharmony_ci * have been validated unsuccessfully for CHECKSUM_COMPLETE case. 347362306a36Sopenharmony_ci * 347462306a36Sopenharmony_ci * It returns non-zero if the recomputed checksum is still invalid, otherwise 347562306a36Sopenharmony_ci * zero. The new checksum is stored back into skb->csum unless the skb is 347662306a36Sopenharmony_ci * shared. 347762306a36Sopenharmony_ci */ 347862306a36Sopenharmony_ci__sum16 __skb_checksum_complete(struct sk_buff *skb) 347962306a36Sopenharmony_ci{ 348062306a36Sopenharmony_ci __wsum csum; 348162306a36Sopenharmony_ci __sum16 sum; 348262306a36Sopenharmony_ci 348362306a36Sopenharmony_ci csum = skb_checksum(skb, 0, skb->len, 0); 348462306a36Sopenharmony_ci 348562306a36Sopenharmony_ci sum = csum_fold(csum_add(skb->csum, csum)); 348662306a36Sopenharmony_ci /* This check is inverted, because we already knew the hardware 348762306a36Sopenharmony_ci * checksum is invalid before calling this function. So, if the 348862306a36Sopenharmony_ci * re-computed checksum is valid instead, then we have a mismatch 348962306a36Sopenharmony_ci * between the original skb->csum and skb_checksum(). This means either 349062306a36Sopenharmony_ci * the original hardware checksum is incorrect or we screw up skb->csum 349162306a36Sopenharmony_ci * when moving skb->data around. 349262306a36Sopenharmony_ci */ 349362306a36Sopenharmony_ci if (likely(!sum)) { 349462306a36Sopenharmony_ci if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && 349562306a36Sopenharmony_ci !skb->csum_complete_sw) 349662306a36Sopenharmony_ci netdev_rx_csum_fault(skb->dev, skb); 349762306a36Sopenharmony_ci } 349862306a36Sopenharmony_ci 349962306a36Sopenharmony_ci if (!skb_shared(skb)) { 350062306a36Sopenharmony_ci /* Save full packet checksum */ 350162306a36Sopenharmony_ci skb->csum = csum; 350262306a36Sopenharmony_ci skb->ip_summed = CHECKSUM_COMPLETE; 350362306a36Sopenharmony_ci skb->csum_complete_sw = 1; 350462306a36Sopenharmony_ci skb->csum_valid = !sum; 350562306a36Sopenharmony_ci } 350662306a36Sopenharmony_ci 350762306a36Sopenharmony_ci return sum; 350862306a36Sopenharmony_ci} 350962306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_checksum_complete); 351062306a36Sopenharmony_ci 351162306a36Sopenharmony_cistatic __wsum warn_crc32c_csum_update(const void *buff, int len, __wsum sum) 351262306a36Sopenharmony_ci{ 351362306a36Sopenharmony_ci net_warn_ratelimited( 351462306a36Sopenharmony_ci "%s: attempt to compute crc32c without libcrc32c.ko\n", 351562306a36Sopenharmony_ci __func__); 351662306a36Sopenharmony_ci return 0; 351762306a36Sopenharmony_ci} 351862306a36Sopenharmony_ci 351962306a36Sopenharmony_cistatic __wsum warn_crc32c_csum_combine(__wsum csum, __wsum csum2, 352062306a36Sopenharmony_ci int offset, int len) 352162306a36Sopenharmony_ci{ 352262306a36Sopenharmony_ci net_warn_ratelimited( 352362306a36Sopenharmony_ci "%s: attempt to compute crc32c without libcrc32c.ko\n", 352462306a36Sopenharmony_ci __func__); 352562306a36Sopenharmony_ci return 0; 352662306a36Sopenharmony_ci} 352762306a36Sopenharmony_ci 352862306a36Sopenharmony_cistatic const struct skb_checksum_ops default_crc32c_ops = { 352962306a36Sopenharmony_ci .update = warn_crc32c_csum_update, 353062306a36Sopenharmony_ci .combine = warn_crc32c_csum_combine, 353162306a36Sopenharmony_ci}; 353262306a36Sopenharmony_ci 353362306a36Sopenharmony_ciconst struct skb_checksum_ops *crc32c_csum_stub __read_mostly = 353462306a36Sopenharmony_ci &default_crc32c_ops; 353562306a36Sopenharmony_ciEXPORT_SYMBOL(crc32c_csum_stub); 353662306a36Sopenharmony_ci 353762306a36Sopenharmony_ci /** 353862306a36Sopenharmony_ci * skb_zerocopy_headlen - Calculate headroom needed for skb_zerocopy() 353962306a36Sopenharmony_ci * @from: source buffer 354062306a36Sopenharmony_ci * 354162306a36Sopenharmony_ci * Calculates the amount of linear headroom needed in the 'to' skb passed 354262306a36Sopenharmony_ci * into skb_zerocopy(). 354362306a36Sopenharmony_ci */ 354462306a36Sopenharmony_ciunsigned int 354562306a36Sopenharmony_ciskb_zerocopy_headlen(const struct sk_buff *from) 354662306a36Sopenharmony_ci{ 354762306a36Sopenharmony_ci unsigned int hlen = 0; 354862306a36Sopenharmony_ci 354962306a36Sopenharmony_ci if (!from->head_frag || 355062306a36Sopenharmony_ci skb_headlen(from) < L1_CACHE_BYTES || 355162306a36Sopenharmony_ci skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) { 355262306a36Sopenharmony_ci hlen = skb_headlen(from); 355362306a36Sopenharmony_ci if (!hlen) 355462306a36Sopenharmony_ci hlen = from->len; 355562306a36Sopenharmony_ci } 355662306a36Sopenharmony_ci 355762306a36Sopenharmony_ci if (skb_has_frag_list(from)) 355862306a36Sopenharmony_ci hlen = from->len; 355962306a36Sopenharmony_ci 356062306a36Sopenharmony_ci return hlen; 356162306a36Sopenharmony_ci} 356262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_zerocopy_headlen); 356362306a36Sopenharmony_ci 356462306a36Sopenharmony_ci/** 356562306a36Sopenharmony_ci * skb_zerocopy - Zero copy skb to skb 356662306a36Sopenharmony_ci * @to: destination buffer 356762306a36Sopenharmony_ci * @from: source buffer 356862306a36Sopenharmony_ci * @len: number of bytes to copy from source buffer 356962306a36Sopenharmony_ci * @hlen: size of linear headroom in destination buffer 357062306a36Sopenharmony_ci * 357162306a36Sopenharmony_ci * Copies up to `len` bytes from `from` to `to` by creating references 357262306a36Sopenharmony_ci * to the frags in the source buffer. 357362306a36Sopenharmony_ci * 357462306a36Sopenharmony_ci * The `hlen` as calculated by skb_zerocopy_headlen() specifies the 357562306a36Sopenharmony_ci * headroom in the `to` buffer. 357662306a36Sopenharmony_ci * 357762306a36Sopenharmony_ci * Return value: 357862306a36Sopenharmony_ci * 0: everything is OK 357962306a36Sopenharmony_ci * -ENOMEM: couldn't orphan frags of @from due to lack of memory 358062306a36Sopenharmony_ci * -EFAULT: skb_copy_bits() found some problem with skb geometry 358162306a36Sopenharmony_ci */ 358262306a36Sopenharmony_ciint 358362306a36Sopenharmony_ciskb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) 358462306a36Sopenharmony_ci{ 358562306a36Sopenharmony_ci int i, j = 0; 358662306a36Sopenharmony_ci int plen = 0; /* length of skb->head fragment */ 358762306a36Sopenharmony_ci int ret; 358862306a36Sopenharmony_ci struct page *page; 358962306a36Sopenharmony_ci unsigned int offset; 359062306a36Sopenharmony_ci 359162306a36Sopenharmony_ci BUG_ON(!from->head_frag && !hlen); 359262306a36Sopenharmony_ci 359362306a36Sopenharmony_ci /* dont bother with small payloads */ 359462306a36Sopenharmony_ci if (len <= skb_tailroom(to)) 359562306a36Sopenharmony_ci return skb_copy_bits(from, 0, skb_put(to, len), len); 359662306a36Sopenharmony_ci 359762306a36Sopenharmony_ci if (hlen) { 359862306a36Sopenharmony_ci ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen); 359962306a36Sopenharmony_ci if (unlikely(ret)) 360062306a36Sopenharmony_ci return ret; 360162306a36Sopenharmony_ci len -= hlen; 360262306a36Sopenharmony_ci } else { 360362306a36Sopenharmony_ci plen = min_t(int, skb_headlen(from), len); 360462306a36Sopenharmony_ci if (plen) { 360562306a36Sopenharmony_ci page = virt_to_head_page(from->head); 360662306a36Sopenharmony_ci offset = from->data - (unsigned char *)page_address(page); 360762306a36Sopenharmony_ci __skb_fill_page_desc(to, 0, page, offset, plen); 360862306a36Sopenharmony_ci get_page(page); 360962306a36Sopenharmony_ci j = 1; 361062306a36Sopenharmony_ci len -= plen; 361162306a36Sopenharmony_ci } 361262306a36Sopenharmony_ci } 361362306a36Sopenharmony_ci 361462306a36Sopenharmony_ci skb_len_add(to, len + plen); 361562306a36Sopenharmony_ci 361662306a36Sopenharmony_ci if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) { 361762306a36Sopenharmony_ci skb_tx_error(from); 361862306a36Sopenharmony_ci return -ENOMEM; 361962306a36Sopenharmony_ci } 362062306a36Sopenharmony_ci skb_zerocopy_clone(to, from, GFP_ATOMIC); 362162306a36Sopenharmony_ci 362262306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { 362362306a36Sopenharmony_ci int size; 362462306a36Sopenharmony_ci 362562306a36Sopenharmony_ci if (!len) 362662306a36Sopenharmony_ci break; 362762306a36Sopenharmony_ci skb_shinfo(to)->frags[j] = skb_shinfo(from)->frags[i]; 362862306a36Sopenharmony_ci size = min_t(int, skb_frag_size(&skb_shinfo(to)->frags[j]), 362962306a36Sopenharmony_ci len); 363062306a36Sopenharmony_ci skb_frag_size_set(&skb_shinfo(to)->frags[j], size); 363162306a36Sopenharmony_ci len -= size; 363262306a36Sopenharmony_ci skb_frag_ref(to, j); 363362306a36Sopenharmony_ci j++; 363462306a36Sopenharmony_ci } 363562306a36Sopenharmony_ci skb_shinfo(to)->nr_frags = j; 363662306a36Sopenharmony_ci 363762306a36Sopenharmony_ci return 0; 363862306a36Sopenharmony_ci} 363962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_zerocopy); 364062306a36Sopenharmony_ci 364162306a36Sopenharmony_civoid skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) 364262306a36Sopenharmony_ci{ 364362306a36Sopenharmony_ci __wsum csum; 364462306a36Sopenharmony_ci long csstart; 364562306a36Sopenharmony_ci 364662306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_PARTIAL) 364762306a36Sopenharmony_ci csstart = skb_checksum_start_offset(skb); 364862306a36Sopenharmony_ci else 364962306a36Sopenharmony_ci csstart = skb_headlen(skb); 365062306a36Sopenharmony_ci 365162306a36Sopenharmony_ci BUG_ON(csstart > skb_headlen(skb)); 365262306a36Sopenharmony_ci 365362306a36Sopenharmony_ci skb_copy_from_linear_data(skb, to, csstart); 365462306a36Sopenharmony_ci 365562306a36Sopenharmony_ci csum = 0; 365662306a36Sopenharmony_ci if (csstart != skb->len) 365762306a36Sopenharmony_ci csum = skb_copy_and_csum_bits(skb, csstart, to + csstart, 365862306a36Sopenharmony_ci skb->len - csstart); 365962306a36Sopenharmony_ci 366062306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_PARTIAL) { 366162306a36Sopenharmony_ci long csstuff = csstart + skb->csum_offset; 366262306a36Sopenharmony_ci 366362306a36Sopenharmony_ci *((__sum16 *)(to + csstuff)) = csum_fold(csum); 366462306a36Sopenharmony_ci } 366562306a36Sopenharmony_ci} 366662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_copy_and_csum_dev); 366762306a36Sopenharmony_ci 366862306a36Sopenharmony_ci/** 366962306a36Sopenharmony_ci * skb_dequeue - remove from the head of the queue 367062306a36Sopenharmony_ci * @list: list to dequeue from 367162306a36Sopenharmony_ci * 367262306a36Sopenharmony_ci * Remove the head of the list. The list lock is taken so the function 367362306a36Sopenharmony_ci * may be used safely with other locking list functions. The head item is 367462306a36Sopenharmony_ci * returned or %NULL if the list is empty. 367562306a36Sopenharmony_ci */ 367662306a36Sopenharmony_ci 367762306a36Sopenharmony_cistruct sk_buff *skb_dequeue(struct sk_buff_head *list) 367862306a36Sopenharmony_ci{ 367962306a36Sopenharmony_ci unsigned long flags; 368062306a36Sopenharmony_ci struct sk_buff *result; 368162306a36Sopenharmony_ci 368262306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 368362306a36Sopenharmony_ci result = __skb_dequeue(list); 368462306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 368562306a36Sopenharmony_ci return result; 368662306a36Sopenharmony_ci} 368762306a36Sopenharmony_ciEXPORT_SYMBOL(skb_dequeue); 368862306a36Sopenharmony_ci 368962306a36Sopenharmony_ci/** 369062306a36Sopenharmony_ci * skb_dequeue_tail - remove from the tail of the queue 369162306a36Sopenharmony_ci * @list: list to dequeue from 369262306a36Sopenharmony_ci * 369362306a36Sopenharmony_ci * Remove the tail of the list. The list lock is taken so the function 369462306a36Sopenharmony_ci * may be used safely with other locking list functions. The tail item is 369562306a36Sopenharmony_ci * returned or %NULL if the list is empty. 369662306a36Sopenharmony_ci */ 369762306a36Sopenharmony_cistruct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) 369862306a36Sopenharmony_ci{ 369962306a36Sopenharmony_ci unsigned long flags; 370062306a36Sopenharmony_ci struct sk_buff *result; 370162306a36Sopenharmony_ci 370262306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 370362306a36Sopenharmony_ci result = __skb_dequeue_tail(list); 370462306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 370562306a36Sopenharmony_ci return result; 370662306a36Sopenharmony_ci} 370762306a36Sopenharmony_ciEXPORT_SYMBOL(skb_dequeue_tail); 370862306a36Sopenharmony_ci 370962306a36Sopenharmony_ci/** 371062306a36Sopenharmony_ci * skb_queue_purge_reason - empty a list 371162306a36Sopenharmony_ci * @list: list to empty 371262306a36Sopenharmony_ci * @reason: drop reason 371362306a36Sopenharmony_ci * 371462306a36Sopenharmony_ci * Delete all buffers on an &sk_buff list. Each buffer is removed from 371562306a36Sopenharmony_ci * the list and one reference dropped. This function takes the list 371662306a36Sopenharmony_ci * lock and is atomic with respect to other list locking functions. 371762306a36Sopenharmony_ci */ 371862306a36Sopenharmony_civoid skb_queue_purge_reason(struct sk_buff_head *list, 371962306a36Sopenharmony_ci enum skb_drop_reason reason) 372062306a36Sopenharmony_ci{ 372162306a36Sopenharmony_ci struct sk_buff *skb; 372262306a36Sopenharmony_ci 372362306a36Sopenharmony_ci while ((skb = skb_dequeue(list)) != NULL) 372462306a36Sopenharmony_ci kfree_skb_reason(skb, reason); 372562306a36Sopenharmony_ci} 372662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_queue_purge_reason); 372762306a36Sopenharmony_ci 372862306a36Sopenharmony_ci/** 372962306a36Sopenharmony_ci * skb_rbtree_purge - empty a skb rbtree 373062306a36Sopenharmony_ci * @root: root of the rbtree to empty 373162306a36Sopenharmony_ci * Return value: the sum of truesizes of all purged skbs. 373262306a36Sopenharmony_ci * 373362306a36Sopenharmony_ci * Delete all buffers on an &sk_buff rbtree. Each buffer is removed from 373462306a36Sopenharmony_ci * the list and one reference dropped. This function does not take 373562306a36Sopenharmony_ci * any lock. Synchronization should be handled by the caller (e.g., TCP 373662306a36Sopenharmony_ci * out-of-order queue is protected by the socket lock). 373762306a36Sopenharmony_ci */ 373862306a36Sopenharmony_ciunsigned int skb_rbtree_purge(struct rb_root *root) 373962306a36Sopenharmony_ci{ 374062306a36Sopenharmony_ci struct rb_node *p = rb_first(root); 374162306a36Sopenharmony_ci unsigned int sum = 0; 374262306a36Sopenharmony_ci 374362306a36Sopenharmony_ci while (p) { 374462306a36Sopenharmony_ci struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode); 374562306a36Sopenharmony_ci 374662306a36Sopenharmony_ci p = rb_next(p); 374762306a36Sopenharmony_ci rb_erase(&skb->rbnode, root); 374862306a36Sopenharmony_ci sum += skb->truesize; 374962306a36Sopenharmony_ci kfree_skb(skb); 375062306a36Sopenharmony_ci } 375162306a36Sopenharmony_ci return sum; 375262306a36Sopenharmony_ci} 375362306a36Sopenharmony_ci 375462306a36Sopenharmony_civoid skb_errqueue_purge(struct sk_buff_head *list) 375562306a36Sopenharmony_ci{ 375662306a36Sopenharmony_ci struct sk_buff *skb, *next; 375762306a36Sopenharmony_ci struct sk_buff_head kill; 375862306a36Sopenharmony_ci unsigned long flags; 375962306a36Sopenharmony_ci 376062306a36Sopenharmony_ci __skb_queue_head_init(&kill); 376162306a36Sopenharmony_ci 376262306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 376362306a36Sopenharmony_ci skb_queue_walk_safe(list, skb, next) { 376462306a36Sopenharmony_ci if (SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_ZEROCOPY || 376562306a36Sopenharmony_ci SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) 376662306a36Sopenharmony_ci continue; 376762306a36Sopenharmony_ci __skb_unlink(skb, list); 376862306a36Sopenharmony_ci __skb_queue_tail(&kill, skb); 376962306a36Sopenharmony_ci } 377062306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 377162306a36Sopenharmony_ci __skb_queue_purge(&kill); 377262306a36Sopenharmony_ci} 377362306a36Sopenharmony_ciEXPORT_SYMBOL(skb_errqueue_purge); 377462306a36Sopenharmony_ci 377562306a36Sopenharmony_ci/** 377662306a36Sopenharmony_ci * skb_queue_head - queue a buffer at the list head 377762306a36Sopenharmony_ci * @list: list to use 377862306a36Sopenharmony_ci * @newsk: buffer to queue 377962306a36Sopenharmony_ci * 378062306a36Sopenharmony_ci * Queue a buffer at the start of the list. This function takes the 378162306a36Sopenharmony_ci * list lock and can be used safely with other locking &sk_buff functions 378262306a36Sopenharmony_ci * safely. 378362306a36Sopenharmony_ci * 378462306a36Sopenharmony_ci * A buffer cannot be placed on two lists at the same time. 378562306a36Sopenharmony_ci */ 378662306a36Sopenharmony_civoid skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) 378762306a36Sopenharmony_ci{ 378862306a36Sopenharmony_ci unsigned long flags; 378962306a36Sopenharmony_ci 379062306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 379162306a36Sopenharmony_ci __skb_queue_head(list, newsk); 379262306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 379362306a36Sopenharmony_ci} 379462306a36Sopenharmony_ciEXPORT_SYMBOL(skb_queue_head); 379562306a36Sopenharmony_ci 379662306a36Sopenharmony_ci/** 379762306a36Sopenharmony_ci * skb_queue_tail - queue a buffer at the list tail 379862306a36Sopenharmony_ci * @list: list to use 379962306a36Sopenharmony_ci * @newsk: buffer to queue 380062306a36Sopenharmony_ci * 380162306a36Sopenharmony_ci * Queue a buffer at the tail of the list. This function takes the 380262306a36Sopenharmony_ci * list lock and can be used safely with other locking &sk_buff functions 380362306a36Sopenharmony_ci * safely. 380462306a36Sopenharmony_ci * 380562306a36Sopenharmony_ci * A buffer cannot be placed on two lists at the same time. 380662306a36Sopenharmony_ci */ 380762306a36Sopenharmony_civoid skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) 380862306a36Sopenharmony_ci{ 380962306a36Sopenharmony_ci unsigned long flags; 381062306a36Sopenharmony_ci 381162306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 381262306a36Sopenharmony_ci __skb_queue_tail(list, newsk); 381362306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 381462306a36Sopenharmony_ci} 381562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_queue_tail); 381662306a36Sopenharmony_ci 381762306a36Sopenharmony_ci/** 381862306a36Sopenharmony_ci * skb_unlink - remove a buffer from a list 381962306a36Sopenharmony_ci * @skb: buffer to remove 382062306a36Sopenharmony_ci * @list: list to use 382162306a36Sopenharmony_ci * 382262306a36Sopenharmony_ci * Remove a packet from a list. The list locks are taken and this 382362306a36Sopenharmony_ci * function is atomic with respect to other list locked calls 382462306a36Sopenharmony_ci * 382562306a36Sopenharmony_ci * You must know what list the SKB is on. 382662306a36Sopenharmony_ci */ 382762306a36Sopenharmony_civoid skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) 382862306a36Sopenharmony_ci{ 382962306a36Sopenharmony_ci unsigned long flags; 383062306a36Sopenharmony_ci 383162306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 383262306a36Sopenharmony_ci __skb_unlink(skb, list); 383362306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 383462306a36Sopenharmony_ci} 383562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_unlink); 383662306a36Sopenharmony_ci 383762306a36Sopenharmony_ci/** 383862306a36Sopenharmony_ci * skb_append - append a buffer 383962306a36Sopenharmony_ci * @old: buffer to insert after 384062306a36Sopenharmony_ci * @newsk: buffer to insert 384162306a36Sopenharmony_ci * @list: list to use 384262306a36Sopenharmony_ci * 384362306a36Sopenharmony_ci * Place a packet after a given packet in a list. The list locks are taken 384462306a36Sopenharmony_ci * and this function is atomic with respect to other list locked calls. 384562306a36Sopenharmony_ci * A buffer cannot be placed on two lists at the same time. 384662306a36Sopenharmony_ci */ 384762306a36Sopenharmony_civoid skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list) 384862306a36Sopenharmony_ci{ 384962306a36Sopenharmony_ci unsigned long flags; 385062306a36Sopenharmony_ci 385162306a36Sopenharmony_ci spin_lock_irqsave(&list->lock, flags); 385262306a36Sopenharmony_ci __skb_queue_after(list, old, newsk); 385362306a36Sopenharmony_ci spin_unlock_irqrestore(&list->lock, flags); 385462306a36Sopenharmony_ci} 385562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_append); 385662306a36Sopenharmony_ci 385762306a36Sopenharmony_cistatic inline void skb_split_inside_header(struct sk_buff *skb, 385862306a36Sopenharmony_ci struct sk_buff* skb1, 385962306a36Sopenharmony_ci const u32 len, const int pos) 386062306a36Sopenharmony_ci{ 386162306a36Sopenharmony_ci int i; 386262306a36Sopenharmony_ci 386362306a36Sopenharmony_ci skb_copy_from_linear_data_offset(skb, len, skb_put(skb1, pos - len), 386462306a36Sopenharmony_ci pos - len); 386562306a36Sopenharmony_ci /* And move data appendix as is. */ 386662306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 386762306a36Sopenharmony_ci skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i]; 386862306a36Sopenharmony_ci 386962306a36Sopenharmony_ci skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags; 387062306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = 0; 387162306a36Sopenharmony_ci skb1->data_len = skb->data_len; 387262306a36Sopenharmony_ci skb1->len += skb1->data_len; 387362306a36Sopenharmony_ci skb->data_len = 0; 387462306a36Sopenharmony_ci skb->len = len; 387562306a36Sopenharmony_ci skb_set_tail_pointer(skb, len); 387662306a36Sopenharmony_ci} 387762306a36Sopenharmony_ci 387862306a36Sopenharmony_cistatic inline void skb_split_no_header(struct sk_buff *skb, 387962306a36Sopenharmony_ci struct sk_buff* skb1, 388062306a36Sopenharmony_ci const u32 len, int pos) 388162306a36Sopenharmony_ci{ 388262306a36Sopenharmony_ci int i, k = 0; 388362306a36Sopenharmony_ci const int nfrags = skb_shinfo(skb)->nr_frags; 388462306a36Sopenharmony_ci 388562306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = 0; 388662306a36Sopenharmony_ci skb1->len = skb1->data_len = skb->len - len; 388762306a36Sopenharmony_ci skb->len = len; 388862306a36Sopenharmony_ci skb->data_len = len - pos; 388962306a36Sopenharmony_ci 389062306a36Sopenharmony_ci for (i = 0; i < nfrags; i++) { 389162306a36Sopenharmony_ci int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); 389262306a36Sopenharmony_ci 389362306a36Sopenharmony_ci if (pos + size > len) { 389462306a36Sopenharmony_ci skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i]; 389562306a36Sopenharmony_ci 389662306a36Sopenharmony_ci if (pos < len) { 389762306a36Sopenharmony_ci /* Split frag. 389862306a36Sopenharmony_ci * We have two variants in this case: 389962306a36Sopenharmony_ci * 1. Move all the frag to the second 390062306a36Sopenharmony_ci * part, if it is possible. F.e. 390162306a36Sopenharmony_ci * this approach is mandatory for TUX, 390262306a36Sopenharmony_ci * where splitting is expensive. 390362306a36Sopenharmony_ci * 2. Split is accurately. We make this. 390462306a36Sopenharmony_ci */ 390562306a36Sopenharmony_ci skb_frag_ref(skb, i); 390662306a36Sopenharmony_ci skb_frag_off_add(&skb_shinfo(skb1)->frags[0], len - pos); 390762306a36Sopenharmony_ci skb_frag_size_sub(&skb_shinfo(skb1)->frags[0], len - pos); 390862306a36Sopenharmony_ci skb_frag_size_set(&skb_shinfo(skb)->frags[i], len - pos); 390962306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags++; 391062306a36Sopenharmony_ci } 391162306a36Sopenharmony_ci k++; 391262306a36Sopenharmony_ci } else 391362306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags++; 391462306a36Sopenharmony_ci pos += size; 391562306a36Sopenharmony_ci } 391662306a36Sopenharmony_ci skb_shinfo(skb1)->nr_frags = k; 391762306a36Sopenharmony_ci} 391862306a36Sopenharmony_ci 391962306a36Sopenharmony_ci/** 392062306a36Sopenharmony_ci * skb_split - Split fragmented skb to two parts at length len. 392162306a36Sopenharmony_ci * @skb: the buffer to split 392262306a36Sopenharmony_ci * @skb1: the buffer to receive the second part 392362306a36Sopenharmony_ci * @len: new length for skb 392462306a36Sopenharmony_ci */ 392562306a36Sopenharmony_civoid skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) 392662306a36Sopenharmony_ci{ 392762306a36Sopenharmony_ci int pos = skb_headlen(skb); 392862306a36Sopenharmony_ci const int zc_flags = SKBFL_SHARED_FRAG | SKBFL_PURE_ZEROCOPY; 392962306a36Sopenharmony_ci 393062306a36Sopenharmony_ci skb_zcopy_downgrade_managed(skb); 393162306a36Sopenharmony_ci 393262306a36Sopenharmony_ci skb_shinfo(skb1)->flags |= skb_shinfo(skb)->flags & zc_flags; 393362306a36Sopenharmony_ci skb_zerocopy_clone(skb1, skb, 0); 393462306a36Sopenharmony_ci if (len < pos) /* Split line is inside header. */ 393562306a36Sopenharmony_ci skb_split_inside_header(skb, skb1, len, pos); 393662306a36Sopenharmony_ci else /* Second chunk has no header, nothing to copy. */ 393762306a36Sopenharmony_ci skb_split_no_header(skb, skb1, len, pos); 393862306a36Sopenharmony_ci} 393962306a36Sopenharmony_ciEXPORT_SYMBOL(skb_split); 394062306a36Sopenharmony_ci 394162306a36Sopenharmony_ci/* Shifting from/to a cloned skb is a no-go. 394262306a36Sopenharmony_ci * 394362306a36Sopenharmony_ci * Caller cannot keep skb_shinfo related pointers past calling here! 394462306a36Sopenharmony_ci */ 394562306a36Sopenharmony_cistatic int skb_prepare_for_shift(struct sk_buff *skb) 394662306a36Sopenharmony_ci{ 394762306a36Sopenharmony_ci return skb_unclone_keeptruesize(skb, GFP_ATOMIC); 394862306a36Sopenharmony_ci} 394962306a36Sopenharmony_ci 395062306a36Sopenharmony_ci/** 395162306a36Sopenharmony_ci * skb_shift - Shifts paged data partially from skb to another 395262306a36Sopenharmony_ci * @tgt: buffer into which tail data gets added 395362306a36Sopenharmony_ci * @skb: buffer from which the paged data comes from 395462306a36Sopenharmony_ci * @shiftlen: shift up to this many bytes 395562306a36Sopenharmony_ci * 395662306a36Sopenharmony_ci * Attempts to shift up to shiftlen worth of bytes, which may be less than 395762306a36Sopenharmony_ci * the length of the skb, from skb to tgt. Returns number bytes shifted. 395862306a36Sopenharmony_ci * It's up to caller to free skb if everything was shifted. 395962306a36Sopenharmony_ci * 396062306a36Sopenharmony_ci * If @tgt runs out of frags, the whole operation is aborted. 396162306a36Sopenharmony_ci * 396262306a36Sopenharmony_ci * Skb cannot include anything else but paged data while tgt is allowed 396362306a36Sopenharmony_ci * to have non-paged data as well. 396462306a36Sopenharmony_ci * 396562306a36Sopenharmony_ci * TODO: full sized shift could be optimized but that would need 396662306a36Sopenharmony_ci * specialized skb free'er to handle frags without up-to-date nr_frags. 396762306a36Sopenharmony_ci */ 396862306a36Sopenharmony_ciint skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) 396962306a36Sopenharmony_ci{ 397062306a36Sopenharmony_ci int from, to, merge, todo; 397162306a36Sopenharmony_ci skb_frag_t *fragfrom, *fragto; 397262306a36Sopenharmony_ci 397362306a36Sopenharmony_ci BUG_ON(shiftlen > skb->len); 397462306a36Sopenharmony_ci 397562306a36Sopenharmony_ci if (skb_headlen(skb)) 397662306a36Sopenharmony_ci return 0; 397762306a36Sopenharmony_ci if (skb_zcopy(tgt) || skb_zcopy(skb)) 397862306a36Sopenharmony_ci return 0; 397962306a36Sopenharmony_ci 398062306a36Sopenharmony_ci todo = shiftlen; 398162306a36Sopenharmony_ci from = 0; 398262306a36Sopenharmony_ci to = skb_shinfo(tgt)->nr_frags; 398362306a36Sopenharmony_ci fragfrom = &skb_shinfo(skb)->frags[from]; 398462306a36Sopenharmony_ci 398562306a36Sopenharmony_ci /* Actual merge is delayed until the point when we know we can 398662306a36Sopenharmony_ci * commit all, so that we don't have to undo partial changes 398762306a36Sopenharmony_ci */ 398862306a36Sopenharmony_ci if (!to || 398962306a36Sopenharmony_ci !skb_can_coalesce(tgt, to, skb_frag_page(fragfrom), 399062306a36Sopenharmony_ci skb_frag_off(fragfrom))) { 399162306a36Sopenharmony_ci merge = -1; 399262306a36Sopenharmony_ci } else { 399362306a36Sopenharmony_ci merge = to - 1; 399462306a36Sopenharmony_ci 399562306a36Sopenharmony_ci todo -= skb_frag_size(fragfrom); 399662306a36Sopenharmony_ci if (todo < 0) { 399762306a36Sopenharmony_ci if (skb_prepare_for_shift(skb) || 399862306a36Sopenharmony_ci skb_prepare_for_shift(tgt)) 399962306a36Sopenharmony_ci return 0; 400062306a36Sopenharmony_ci 400162306a36Sopenharmony_ci /* All previous frag pointers might be stale! */ 400262306a36Sopenharmony_ci fragfrom = &skb_shinfo(skb)->frags[from]; 400362306a36Sopenharmony_ci fragto = &skb_shinfo(tgt)->frags[merge]; 400462306a36Sopenharmony_ci 400562306a36Sopenharmony_ci skb_frag_size_add(fragto, shiftlen); 400662306a36Sopenharmony_ci skb_frag_size_sub(fragfrom, shiftlen); 400762306a36Sopenharmony_ci skb_frag_off_add(fragfrom, shiftlen); 400862306a36Sopenharmony_ci 400962306a36Sopenharmony_ci goto onlymerged; 401062306a36Sopenharmony_ci } 401162306a36Sopenharmony_ci 401262306a36Sopenharmony_ci from++; 401362306a36Sopenharmony_ci } 401462306a36Sopenharmony_ci 401562306a36Sopenharmony_ci /* Skip full, not-fitting skb to avoid expensive operations */ 401662306a36Sopenharmony_ci if ((shiftlen == skb->len) && 401762306a36Sopenharmony_ci (skb_shinfo(skb)->nr_frags - from) > (MAX_SKB_FRAGS - to)) 401862306a36Sopenharmony_ci return 0; 401962306a36Sopenharmony_ci 402062306a36Sopenharmony_ci if (skb_prepare_for_shift(skb) || skb_prepare_for_shift(tgt)) 402162306a36Sopenharmony_ci return 0; 402262306a36Sopenharmony_ci 402362306a36Sopenharmony_ci while ((todo > 0) && (from < skb_shinfo(skb)->nr_frags)) { 402462306a36Sopenharmony_ci if (to == MAX_SKB_FRAGS) 402562306a36Sopenharmony_ci return 0; 402662306a36Sopenharmony_ci 402762306a36Sopenharmony_ci fragfrom = &skb_shinfo(skb)->frags[from]; 402862306a36Sopenharmony_ci fragto = &skb_shinfo(tgt)->frags[to]; 402962306a36Sopenharmony_ci 403062306a36Sopenharmony_ci if (todo >= skb_frag_size(fragfrom)) { 403162306a36Sopenharmony_ci *fragto = *fragfrom; 403262306a36Sopenharmony_ci todo -= skb_frag_size(fragfrom); 403362306a36Sopenharmony_ci from++; 403462306a36Sopenharmony_ci to++; 403562306a36Sopenharmony_ci 403662306a36Sopenharmony_ci } else { 403762306a36Sopenharmony_ci __skb_frag_ref(fragfrom); 403862306a36Sopenharmony_ci skb_frag_page_copy(fragto, fragfrom); 403962306a36Sopenharmony_ci skb_frag_off_copy(fragto, fragfrom); 404062306a36Sopenharmony_ci skb_frag_size_set(fragto, todo); 404162306a36Sopenharmony_ci 404262306a36Sopenharmony_ci skb_frag_off_add(fragfrom, todo); 404362306a36Sopenharmony_ci skb_frag_size_sub(fragfrom, todo); 404462306a36Sopenharmony_ci todo = 0; 404562306a36Sopenharmony_ci 404662306a36Sopenharmony_ci to++; 404762306a36Sopenharmony_ci break; 404862306a36Sopenharmony_ci } 404962306a36Sopenharmony_ci } 405062306a36Sopenharmony_ci 405162306a36Sopenharmony_ci /* Ready to "commit" this state change to tgt */ 405262306a36Sopenharmony_ci skb_shinfo(tgt)->nr_frags = to; 405362306a36Sopenharmony_ci 405462306a36Sopenharmony_ci if (merge >= 0) { 405562306a36Sopenharmony_ci fragfrom = &skb_shinfo(skb)->frags[0]; 405662306a36Sopenharmony_ci fragto = &skb_shinfo(tgt)->frags[merge]; 405762306a36Sopenharmony_ci 405862306a36Sopenharmony_ci skb_frag_size_add(fragto, skb_frag_size(fragfrom)); 405962306a36Sopenharmony_ci __skb_frag_unref(fragfrom, skb->pp_recycle); 406062306a36Sopenharmony_ci } 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_ci /* Reposition in the original skb */ 406362306a36Sopenharmony_ci to = 0; 406462306a36Sopenharmony_ci while (from < skb_shinfo(skb)->nr_frags) 406562306a36Sopenharmony_ci skb_shinfo(skb)->frags[to++] = skb_shinfo(skb)->frags[from++]; 406662306a36Sopenharmony_ci skb_shinfo(skb)->nr_frags = to; 406762306a36Sopenharmony_ci 406862306a36Sopenharmony_ci BUG_ON(todo > 0 && !skb_shinfo(skb)->nr_frags); 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_cionlymerged: 407162306a36Sopenharmony_ci /* Most likely the tgt won't ever need its checksum anymore, skb on 407262306a36Sopenharmony_ci * the other hand might need it if it needs to be resent 407362306a36Sopenharmony_ci */ 407462306a36Sopenharmony_ci tgt->ip_summed = CHECKSUM_PARTIAL; 407562306a36Sopenharmony_ci skb->ip_summed = CHECKSUM_PARTIAL; 407662306a36Sopenharmony_ci 407762306a36Sopenharmony_ci skb_len_add(skb, -shiftlen); 407862306a36Sopenharmony_ci skb_len_add(tgt, shiftlen); 407962306a36Sopenharmony_ci 408062306a36Sopenharmony_ci return shiftlen; 408162306a36Sopenharmony_ci} 408262306a36Sopenharmony_ci 408362306a36Sopenharmony_ci/** 408462306a36Sopenharmony_ci * skb_prepare_seq_read - Prepare a sequential read of skb data 408562306a36Sopenharmony_ci * @skb: the buffer to read 408662306a36Sopenharmony_ci * @from: lower offset of data to be read 408762306a36Sopenharmony_ci * @to: upper offset of data to be read 408862306a36Sopenharmony_ci * @st: state variable 408962306a36Sopenharmony_ci * 409062306a36Sopenharmony_ci * Initializes the specified state variable. Must be called before 409162306a36Sopenharmony_ci * invoking skb_seq_read() for the first time. 409262306a36Sopenharmony_ci */ 409362306a36Sopenharmony_civoid skb_prepare_seq_read(struct sk_buff *skb, unsigned int from, 409462306a36Sopenharmony_ci unsigned int to, struct skb_seq_state *st) 409562306a36Sopenharmony_ci{ 409662306a36Sopenharmony_ci st->lower_offset = from; 409762306a36Sopenharmony_ci st->upper_offset = to; 409862306a36Sopenharmony_ci st->root_skb = st->cur_skb = skb; 409962306a36Sopenharmony_ci st->frag_idx = st->stepped_offset = 0; 410062306a36Sopenharmony_ci st->frag_data = NULL; 410162306a36Sopenharmony_ci st->frag_off = 0; 410262306a36Sopenharmony_ci} 410362306a36Sopenharmony_ciEXPORT_SYMBOL(skb_prepare_seq_read); 410462306a36Sopenharmony_ci 410562306a36Sopenharmony_ci/** 410662306a36Sopenharmony_ci * skb_seq_read - Sequentially read skb data 410762306a36Sopenharmony_ci * @consumed: number of bytes consumed by the caller so far 410862306a36Sopenharmony_ci * @data: destination pointer for data to be returned 410962306a36Sopenharmony_ci * @st: state variable 411062306a36Sopenharmony_ci * 411162306a36Sopenharmony_ci * Reads a block of skb data at @consumed relative to the 411262306a36Sopenharmony_ci * lower offset specified to skb_prepare_seq_read(). Assigns 411362306a36Sopenharmony_ci * the head of the data block to @data and returns the length 411462306a36Sopenharmony_ci * of the block or 0 if the end of the skb data or the upper 411562306a36Sopenharmony_ci * offset has been reached. 411662306a36Sopenharmony_ci * 411762306a36Sopenharmony_ci * The caller is not required to consume all of the data 411862306a36Sopenharmony_ci * returned, i.e. @consumed is typically set to the number 411962306a36Sopenharmony_ci * of bytes already consumed and the next call to 412062306a36Sopenharmony_ci * skb_seq_read() will return the remaining part of the block. 412162306a36Sopenharmony_ci * 412262306a36Sopenharmony_ci * Note 1: The size of each block of data returned can be arbitrary, 412362306a36Sopenharmony_ci * this limitation is the cost for zerocopy sequential 412462306a36Sopenharmony_ci * reads of potentially non linear data. 412562306a36Sopenharmony_ci * 412662306a36Sopenharmony_ci * Note 2: Fragment lists within fragments are not implemented 412762306a36Sopenharmony_ci * at the moment, state->root_skb could be replaced with 412862306a36Sopenharmony_ci * a stack for this purpose. 412962306a36Sopenharmony_ci */ 413062306a36Sopenharmony_ciunsigned int skb_seq_read(unsigned int consumed, const u8 **data, 413162306a36Sopenharmony_ci struct skb_seq_state *st) 413262306a36Sopenharmony_ci{ 413362306a36Sopenharmony_ci unsigned int block_limit, abs_offset = consumed + st->lower_offset; 413462306a36Sopenharmony_ci skb_frag_t *frag; 413562306a36Sopenharmony_ci 413662306a36Sopenharmony_ci if (unlikely(abs_offset >= st->upper_offset)) { 413762306a36Sopenharmony_ci if (st->frag_data) { 413862306a36Sopenharmony_ci kunmap_atomic(st->frag_data); 413962306a36Sopenharmony_ci st->frag_data = NULL; 414062306a36Sopenharmony_ci } 414162306a36Sopenharmony_ci return 0; 414262306a36Sopenharmony_ci } 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_cinext_skb: 414562306a36Sopenharmony_ci block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; 414662306a36Sopenharmony_ci 414762306a36Sopenharmony_ci if (abs_offset < block_limit && !st->frag_data) { 414862306a36Sopenharmony_ci *data = st->cur_skb->data + (abs_offset - st->stepped_offset); 414962306a36Sopenharmony_ci return block_limit - abs_offset; 415062306a36Sopenharmony_ci } 415162306a36Sopenharmony_ci 415262306a36Sopenharmony_ci if (st->frag_idx == 0 && !st->frag_data) 415362306a36Sopenharmony_ci st->stepped_offset += skb_headlen(st->cur_skb); 415462306a36Sopenharmony_ci 415562306a36Sopenharmony_ci while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) { 415662306a36Sopenharmony_ci unsigned int pg_idx, pg_off, pg_sz; 415762306a36Sopenharmony_ci 415862306a36Sopenharmony_ci frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx]; 415962306a36Sopenharmony_ci 416062306a36Sopenharmony_ci pg_idx = 0; 416162306a36Sopenharmony_ci pg_off = skb_frag_off(frag); 416262306a36Sopenharmony_ci pg_sz = skb_frag_size(frag); 416362306a36Sopenharmony_ci 416462306a36Sopenharmony_ci if (skb_frag_must_loop(skb_frag_page(frag))) { 416562306a36Sopenharmony_ci pg_idx = (pg_off + st->frag_off) >> PAGE_SHIFT; 416662306a36Sopenharmony_ci pg_off = offset_in_page(pg_off + st->frag_off); 416762306a36Sopenharmony_ci pg_sz = min_t(unsigned int, pg_sz - st->frag_off, 416862306a36Sopenharmony_ci PAGE_SIZE - pg_off); 416962306a36Sopenharmony_ci } 417062306a36Sopenharmony_ci 417162306a36Sopenharmony_ci block_limit = pg_sz + st->stepped_offset; 417262306a36Sopenharmony_ci if (abs_offset < block_limit) { 417362306a36Sopenharmony_ci if (!st->frag_data) 417462306a36Sopenharmony_ci st->frag_data = kmap_atomic(skb_frag_page(frag) + pg_idx); 417562306a36Sopenharmony_ci 417662306a36Sopenharmony_ci *data = (u8 *)st->frag_data + pg_off + 417762306a36Sopenharmony_ci (abs_offset - st->stepped_offset); 417862306a36Sopenharmony_ci 417962306a36Sopenharmony_ci return block_limit - abs_offset; 418062306a36Sopenharmony_ci } 418162306a36Sopenharmony_ci 418262306a36Sopenharmony_ci if (st->frag_data) { 418362306a36Sopenharmony_ci kunmap_atomic(st->frag_data); 418462306a36Sopenharmony_ci st->frag_data = NULL; 418562306a36Sopenharmony_ci } 418662306a36Sopenharmony_ci 418762306a36Sopenharmony_ci st->stepped_offset += pg_sz; 418862306a36Sopenharmony_ci st->frag_off += pg_sz; 418962306a36Sopenharmony_ci if (st->frag_off == skb_frag_size(frag)) { 419062306a36Sopenharmony_ci st->frag_off = 0; 419162306a36Sopenharmony_ci st->frag_idx++; 419262306a36Sopenharmony_ci } 419362306a36Sopenharmony_ci } 419462306a36Sopenharmony_ci 419562306a36Sopenharmony_ci if (st->frag_data) { 419662306a36Sopenharmony_ci kunmap_atomic(st->frag_data); 419762306a36Sopenharmony_ci st->frag_data = NULL; 419862306a36Sopenharmony_ci } 419962306a36Sopenharmony_ci 420062306a36Sopenharmony_ci if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) { 420162306a36Sopenharmony_ci st->cur_skb = skb_shinfo(st->root_skb)->frag_list; 420262306a36Sopenharmony_ci st->frag_idx = 0; 420362306a36Sopenharmony_ci goto next_skb; 420462306a36Sopenharmony_ci } else if (st->cur_skb->next) { 420562306a36Sopenharmony_ci st->cur_skb = st->cur_skb->next; 420662306a36Sopenharmony_ci st->frag_idx = 0; 420762306a36Sopenharmony_ci goto next_skb; 420862306a36Sopenharmony_ci } 420962306a36Sopenharmony_ci 421062306a36Sopenharmony_ci return 0; 421162306a36Sopenharmony_ci} 421262306a36Sopenharmony_ciEXPORT_SYMBOL(skb_seq_read); 421362306a36Sopenharmony_ci 421462306a36Sopenharmony_ci/** 421562306a36Sopenharmony_ci * skb_abort_seq_read - Abort a sequential read of skb data 421662306a36Sopenharmony_ci * @st: state variable 421762306a36Sopenharmony_ci * 421862306a36Sopenharmony_ci * Must be called if skb_seq_read() was not called until it 421962306a36Sopenharmony_ci * returned 0. 422062306a36Sopenharmony_ci */ 422162306a36Sopenharmony_civoid skb_abort_seq_read(struct skb_seq_state *st) 422262306a36Sopenharmony_ci{ 422362306a36Sopenharmony_ci if (st->frag_data) 422462306a36Sopenharmony_ci kunmap_atomic(st->frag_data); 422562306a36Sopenharmony_ci} 422662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_abort_seq_read); 422762306a36Sopenharmony_ci 422862306a36Sopenharmony_ci#define TS_SKB_CB(state) ((struct skb_seq_state *) &((state)->cb)) 422962306a36Sopenharmony_ci 423062306a36Sopenharmony_cistatic unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text, 423162306a36Sopenharmony_ci struct ts_config *conf, 423262306a36Sopenharmony_ci struct ts_state *state) 423362306a36Sopenharmony_ci{ 423462306a36Sopenharmony_ci return skb_seq_read(offset, text, TS_SKB_CB(state)); 423562306a36Sopenharmony_ci} 423662306a36Sopenharmony_ci 423762306a36Sopenharmony_cistatic void skb_ts_finish(struct ts_config *conf, struct ts_state *state) 423862306a36Sopenharmony_ci{ 423962306a36Sopenharmony_ci skb_abort_seq_read(TS_SKB_CB(state)); 424062306a36Sopenharmony_ci} 424162306a36Sopenharmony_ci 424262306a36Sopenharmony_ci/** 424362306a36Sopenharmony_ci * skb_find_text - Find a text pattern in skb data 424462306a36Sopenharmony_ci * @skb: the buffer to look in 424562306a36Sopenharmony_ci * @from: search offset 424662306a36Sopenharmony_ci * @to: search limit 424762306a36Sopenharmony_ci * @config: textsearch configuration 424862306a36Sopenharmony_ci * 424962306a36Sopenharmony_ci * Finds a pattern in the skb data according to the specified 425062306a36Sopenharmony_ci * textsearch configuration. Use textsearch_next() to retrieve 425162306a36Sopenharmony_ci * subsequent occurrences of the pattern. Returns the offset 425262306a36Sopenharmony_ci * to the first occurrence or UINT_MAX if no match was found. 425362306a36Sopenharmony_ci */ 425462306a36Sopenharmony_ciunsigned int skb_find_text(struct sk_buff *skb, unsigned int from, 425562306a36Sopenharmony_ci unsigned int to, struct ts_config *config) 425662306a36Sopenharmony_ci{ 425762306a36Sopenharmony_ci unsigned int patlen = config->ops->get_pattern_len(config); 425862306a36Sopenharmony_ci struct ts_state state; 425962306a36Sopenharmony_ci unsigned int ret; 426062306a36Sopenharmony_ci 426162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct skb_seq_state) > sizeof(state.cb)); 426262306a36Sopenharmony_ci 426362306a36Sopenharmony_ci config->get_next_block = skb_ts_get_next_block; 426462306a36Sopenharmony_ci config->finish = skb_ts_finish; 426562306a36Sopenharmony_ci 426662306a36Sopenharmony_ci skb_prepare_seq_read(skb, from, to, TS_SKB_CB(&state)); 426762306a36Sopenharmony_ci 426862306a36Sopenharmony_ci ret = textsearch_find(config, &state); 426962306a36Sopenharmony_ci return (ret + patlen <= to - from ? ret : UINT_MAX); 427062306a36Sopenharmony_ci} 427162306a36Sopenharmony_ciEXPORT_SYMBOL(skb_find_text); 427262306a36Sopenharmony_ci 427362306a36Sopenharmony_ciint skb_append_pagefrags(struct sk_buff *skb, struct page *page, 427462306a36Sopenharmony_ci int offset, size_t size, size_t max_frags) 427562306a36Sopenharmony_ci{ 427662306a36Sopenharmony_ci int i = skb_shinfo(skb)->nr_frags; 427762306a36Sopenharmony_ci 427862306a36Sopenharmony_ci if (skb_can_coalesce(skb, i, page, offset)) { 427962306a36Sopenharmony_ci skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], size); 428062306a36Sopenharmony_ci } else if (i < max_frags) { 428162306a36Sopenharmony_ci skb_zcopy_downgrade_managed(skb); 428262306a36Sopenharmony_ci get_page(page); 428362306a36Sopenharmony_ci skb_fill_page_desc_noacc(skb, i, page, offset, size); 428462306a36Sopenharmony_ci } else { 428562306a36Sopenharmony_ci return -EMSGSIZE; 428662306a36Sopenharmony_ci } 428762306a36Sopenharmony_ci 428862306a36Sopenharmony_ci return 0; 428962306a36Sopenharmony_ci} 429062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_append_pagefrags); 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_ci/** 429362306a36Sopenharmony_ci * skb_pull_rcsum - pull skb and update receive checksum 429462306a36Sopenharmony_ci * @skb: buffer to update 429562306a36Sopenharmony_ci * @len: length of data pulled 429662306a36Sopenharmony_ci * 429762306a36Sopenharmony_ci * This function performs an skb_pull on the packet and updates 429862306a36Sopenharmony_ci * the CHECKSUM_COMPLETE checksum. It should be used on 429962306a36Sopenharmony_ci * receive path processing instead of skb_pull unless you know 430062306a36Sopenharmony_ci * that the checksum difference is zero (e.g., a valid IP header) 430162306a36Sopenharmony_ci * or you are setting ip_summed to CHECKSUM_NONE. 430262306a36Sopenharmony_ci */ 430362306a36Sopenharmony_civoid *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) 430462306a36Sopenharmony_ci{ 430562306a36Sopenharmony_ci unsigned char *data = skb->data; 430662306a36Sopenharmony_ci 430762306a36Sopenharmony_ci BUG_ON(len > skb->len); 430862306a36Sopenharmony_ci __skb_pull(skb, len); 430962306a36Sopenharmony_ci skb_postpull_rcsum(skb, data, len); 431062306a36Sopenharmony_ci return skb->data; 431162306a36Sopenharmony_ci} 431262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_pull_rcsum); 431362306a36Sopenharmony_ci 431462306a36Sopenharmony_cistatic inline skb_frag_t skb_head_frag_to_page_desc(struct sk_buff *frag_skb) 431562306a36Sopenharmony_ci{ 431662306a36Sopenharmony_ci skb_frag_t head_frag; 431762306a36Sopenharmony_ci struct page *page; 431862306a36Sopenharmony_ci 431962306a36Sopenharmony_ci page = virt_to_head_page(frag_skb->head); 432062306a36Sopenharmony_ci skb_frag_fill_page_desc(&head_frag, page, frag_skb->data - 432162306a36Sopenharmony_ci (unsigned char *)page_address(page), 432262306a36Sopenharmony_ci skb_headlen(frag_skb)); 432362306a36Sopenharmony_ci return head_frag; 432462306a36Sopenharmony_ci} 432562306a36Sopenharmony_ci 432662306a36Sopenharmony_cistruct sk_buff *skb_segment_list(struct sk_buff *skb, 432762306a36Sopenharmony_ci netdev_features_t features, 432862306a36Sopenharmony_ci unsigned int offset) 432962306a36Sopenharmony_ci{ 433062306a36Sopenharmony_ci struct sk_buff *list_skb = skb_shinfo(skb)->frag_list; 433162306a36Sopenharmony_ci unsigned int tnl_hlen = skb_tnl_header_len(skb); 433262306a36Sopenharmony_ci unsigned int delta_truesize = 0; 433362306a36Sopenharmony_ci unsigned int delta_len = 0; 433462306a36Sopenharmony_ci struct sk_buff *tail = NULL; 433562306a36Sopenharmony_ci struct sk_buff *nskb, *tmp; 433662306a36Sopenharmony_ci int len_diff, err; 433762306a36Sopenharmony_ci 433862306a36Sopenharmony_ci skb_push(skb, -skb_network_offset(skb) + offset); 433962306a36Sopenharmony_ci 434062306a36Sopenharmony_ci /* Ensure the head is writeable before touching the shared info */ 434162306a36Sopenharmony_ci err = skb_unclone(skb, GFP_ATOMIC); 434262306a36Sopenharmony_ci if (err) 434362306a36Sopenharmony_ci goto err_linearize; 434462306a36Sopenharmony_ci 434562306a36Sopenharmony_ci skb_shinfo(skb)->frag_list = NULL; 434662306a36Sopenharmony_ci 434762306a36Sopenharmony_ci while (list_skb) { 434862306a36Sopenharmony_ci nskb = list_skb; 434962306a36Sopenharmony_ci list_skb = list_skb->next; 435062306a36Sopenharmony_ci 435162306a36Sopenharmony_ci err = 0; 435262306a36Sopenharmony_ci delta_truesize += nskb->truesize; 435362306a36Sopenharmony_ci if (skb_shared(nskb)) { 435462306a36Sopenharmony_ci tmp = skb_clone(nskb, GFP_ATOMIC); 435562306a36Sopenharmony_ci if (tmp) { 435662306a36Sopenharmony_ci consume_skb(nskb); 435762306a36Sopenharmony_ci nskb = tmp; 435862306a36Sopenharmony_ci err = skb_unclone(nskb, GFP_ATOMIC); 435962306a36Sopenharmony_ci } else { 436062306a36Sopenharmony_ci err = -ENOMEM; 436162306a36Sopenharmony_ci } 436262306a36Sopenharmony_ci } 436362306a36Sopenharmony_ci 436462306a36Sopenharmony_ci if (!tail) 436562306a36Sopenharmony_ci skb->next = nskb; 436662306a36Sopenharmony_ci else 436762306a36Sopenharmony_ci tail->next = nskb; 436862306a36Sopenharmony_ci 436962306a36Sopenharmony_ci if (unlikely(err)) { 437062306a36Sopenharmony_ci nskb->next = list_skb; 437162306a36Sopenharmony_ci goto err_linearize; 437262306a36Sopenharmony_ci } 437362306a36Sopenharmony_ci 437462306a36Sopenharmony_ci tail = nskb; 437562306a36Sopenharmony_ci 437662306a36Sopenharmony_ci delta_len += nskb->len; 437762306a36Sopenharmony_ci 437862306a36Sopenharmony_ci skb_push(nskb, -skb_network_offset(nskb) + offset); 437962306a36Sopenharmony_ci 438062306a36Sopenharmony_ci skb_release_head_state(nskb); 438162306a36Sopenharmony_ci len_diff = skb_network_header_len(nskb) - skb_network_header_len(skb); 438262306a36Sopenharmony_ci __copy_skb_header(nskb, skb); 438362306a36Sopenharmony_ci 438462306a36Sopenharmony_ci skb_headers_offset_update(nskb, skb_headroom(nskb) - skb_headroom(skb)); 438562306a36Sopenharmony_ci nskb->transport_header += len_diff; 438662306a36Sopenharmony_ci skb_copy_from_linear_data_offset(skb, -tnl_hlen, 438762306a36Sopenharmony_ci nskb->data - tnl_hlen, 438862306a36Sopenharmony_ci offset + tnl_hlen); 438962306a36Sopenharmony_ci 439062306a36Sopenharmony_ci if (skb_needs_linearize(nskb, features) && 439162306a36Sopenharmony_ci __skb_linearize(nskb)) 439262306a36Sopenharmony_ci goto err_linearize; 439362306a36Sopenharmony_ci } 439462306a36Sopenharmony_ci 439562306a36Sopenharmony_ci skb->truesize = skb->truesize - delta_truesize; 439662306a36Sopenharmony_ci skb->data_len = skb->data_len - delta_len; 439762306a36Sopenharmony_ci skb->len = skb->len - delta_len; 439862306a36Sopenharmony_ci 439962306a36Sopenharmony_ci skb_gso_reset(skb); 440062306a36Sopenharmony_ci 440162306a36Sopenharmony_ci skb->prev = tail; 440262306a36Sopenharmony_ci 440362306a36Sopenharmony_ci if (skb_needs_linearize(skb, features) && 440462306a36Sopenharmony_ci __skb_linearize(skb)) 440562306a36Sopenharmony_ci goto err_linearize; 440662306a36Sopenharmony_ci 440762306a36Sopenharmony_ci skb_get(skb); 440862306a36Sopenharmony_ci 440962306a36Sopenharmony_ci return skb; 441062306a36Sopenharmony_ci 441162306a36Sopenharmony_cierr_linearize: 441262306a36Sopenharmony_ci kfree_skb_list(skb->next); 441362306a36Sopenharmony_ci skb->next = NULL; 441462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 441562306a36Sopenharmony_ci} 441662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_segment_list); 441762306a36Sopenharmony_ci 441862306a36Sopenharmony_ci/** 441962306a36Sopenharmony_ci * skb_segment - Perform protocol segmentation on skb. 442062306a36Sopenharmony_ci * @head_skb: buffer to segment 442162306a36Sopenharmony_ci * @features: features for the output path (see dev->features) 442262306a36Sopenharmony_ci * 442362306a36Sopenharmony_ci * This function performs segmentation on the given skb. It returns 442462306a36Sopenharmony_ci * a pointer to the first in a list of new skbs for the segments. 442562306a36Sopenharmony_ci * In case of error it returns ERR_PTR(err). 442662306a36Sopenharmony_ci */ 442762306a36Sopenharmony_cistruct sk_buff *skb_segment(struct sk_buff *head_skb, 442862306a36Sopenharmony_ci netdev_features_t features) 442962306a36Sopenharmony_ci{ 443062306a36Sopenharmony_ci struct sk_buff *segs = NULL; 443162306a36Sopenharmony_ci struct sk_buff *tail = NULL; 443262306a36Sopenharmony_ci struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; 443362306a36Sopenharmony_ci unsigned int mss = skb_shinfo(head_skb)->gso_size; 443462306a36Sopenharmony_ci unsigned int doffset = head_skb->data - skb_mac_header(head_skb); 443562306a36Sopenharmony_ci unsigned int offset = doffset; 443662306a36Sopenharmony_ci unsigned int tnl_hlen = skb_tnl_header_len(head_skb); 443762306a36Sopenharmony_ci unsigned int partial_segs = 0; 443862306a36Sopenharmony_ci unsigned int headroom; 443962306a36Sopenharmony_ci unsigned int len = head_skb->len; 444062306a36Sopenharmony_ci struct sk_buff *frag_skb; 444162306a36Sopenharmony_ci skb_frag_t *frag; 444262306a36Sopenharmony_ci __be16 proto; 444362306a36Sopenharmony_ci bool csum, sg; 444462306a36Sopenharmony_ci int err = -ENOMEM; 444562306a36Sopenharmony_ci int i = 0; 444662306a36Sopenharmony_ci int nfrags, pos; 444762306a36Sopenharmony_ci 444862306a36Sopenharmony_ci if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && 444962306a36Sopenharmony_ci mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { 445062306a36Sopenharmony_ci struct sk_buff *check_skb; 445162306a36Sopenharmony_ci 445262306a36Sopenharmony_ci for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { 445362306a36Sopenharmony_ci if (skb_headlen(check_skb) && !check_skb->head_frag) { 445462306a36Sopenharmony_ci /* gso_size is untrusted, and we have a frag_list with 445562306a36Sopenharmony_ci * a linear non head_frag item. 445662306a36Sopenharmony_ci * 445762306a36Sopenharmony_ci * If head_skb's headlen does not fit requested gso_size, 445862306a36Sopenharmony_ci * it means that the frag_list members do NOT terminate 445962306a36Sopenharmony_ci * on exact gso_size boundaries. Hence we cannot perform 446062306a36Sopenharmony_ci * skb_frag_t page sharing. Therefore we must fallback to 446162306a36Sopenharmony_ci * copying the frag_list skbs; we do so by disabling SG. 446262306a36Sopenharmony_ci */ 446362306a36Sopenharmony_ci features &= ~NETIF_F_SG; 446462306a36Sopenharmony_ci break; 446562306a36Sopenharmony_ci } 446662306a36Sopenharmony_ci } 446762306a36Sopenharmony_ci } 446862306a36Sopenharmony_ci 446962306a36Sopenharmony_ci __skb_push(head_skb, doffset); 447062306a36Sopenharmony_ci proto = skb_network_protocol(head_skb, NULL); 447162306a36Sopenharmony_ci if (unlikely(!proto)) 447262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 447362306a36Sopenharmony_ci 447462306a36Sopenharmony_ci sg = !!(features & NETIF_F_SG); 447562306a36Sopenharmony_ci csum = !!can_checksum_protocol(features, proto); 447662306a36Sopenharmony_ci 447762306a36Sopenharmony_ci if (sg && csum && (mss != GSO_BY_FRAGS)) { 447862306a36Sopenharmony_ci if (!(features & NETIF_F_GSO_PARTIAL)) { 447962306a36Sopenharmony_ci struct sk_buff *iter; 448062306a36Sopenharmony_ci unsigned int frag_len; 448162306a36Sopenharmony_ci 448262306a36Sopenharmony_ci if (!list_skb || 448362306a36Sopenharmony_ci !net_gso_ok(features, skb_shinfo(head_skb)->gso_type)) 448462306a36Sopenharmony_ci goto normal; 448562306a36Sopenharmony_ci 448662306a36Sopenharmony_ci /* If we get here then all the required 448762306a36Sopenharmony_ci * GSO features except frag_list are supported. 448862306a36Sopenharmony_ci * Try to split the SKB to multiple GSO SKBs 448962306a36Sopenharmony_ci * with no frag_list. 449062306a36Sopenharmony_ci * Currently we can do that only when the buffers don't 449162306a36Sopenharmony_ci * have a linear part and all the buffers except 449262306a36Sopenharmony_ci * the last are of the same length. 449362306a36Sopenharmony_ci */ 449462306a36Sopenharmony_ci frag_len = list_skb->len; 449562306a36Sopenharmony_ci skb_walk_frags(head_skb, iter) { 449662306a36Sopenharmony_ci if (frag_len != iter->len && iter->next) 449762306a36Sopenharmony_ci goto normal; 449862306a36Sopenharmony_ci if (skb_headlen(iter) && !iter->head_frag) 449962306a36Sopenharmony_ci goto normal; 450062306a36Sopenharmony_ci 450162306a36Sopenharmony_ci len -= iter->len; 450262306a36Sopenharmony_ci } 450362306a36Sopenharmony_ci 450462306a36Sopenharmony_ci if (len != frag_len) 450562306a36Sopenharmony_ci goto normal; 450662306a36Sopenharmony_ci } 450762306a36Sopenharmony_ci 450862306a36Sopenharmony_ci /* GSO partial only requires that we trim off any excess that 450962306a36Sopenharmony_ci * doesn't fit into an MSS sized block, so take care of that 451062306a36Sopenharmony_ci * now. 451162306a36Sopenharmony_ci * Cap len to not accidentally hit GSO_BY_FRAGS. 451262306a36Sopenharmony_ci */ 451362306a36Sopenharmony_ci partial_segs = min(len, GSO_BY_FRAGS - 1U) / mss; 451462306a36Sopenharmony_ci if (partial_segs > 1) 451562306a36Sopenharmony_ci mss *= partial_segs; 451662306a36Sopenharmony_ci else 451762306a36Sopenharmony_ci partial_segs = 0; 451862306a36Sopenharmony_ci } 451962306a36Sopenharmony_ci 452062306a36Sopenharmony_cinormal: 452162306a36Sopenharmony_ci headroom = skb_headroom(head_skb); 452262306a36Sopenharmony_ci pos = skb_headlen(head_skb); 452362306a36Sopenharmony_ci 452462306a36Sopenharmony_ci if (skb_orphan_frags(head_skb, GFP_ATOMIC)) 452562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 452662306a36Sopenharmony_ci 452762306a36Sopenharmony_ci nfrags = skb_shinfo(head_skb)->nr_frags; 452862306a36Sopenharmony_ci frag = skb_shinfo(head_skb)->frags; 452962306a36Sopenharmony_ci frag_skb = head_skb; 453062306a36Sopenharmony_ci 453162306a36Sopenharmony_ci do { 453262306a36Sopenharmony_ci struct sk_buff *nskb; 453362306a36Sopenharmony_ci skb_frag_t *nskb_frag; 453462306a36Sopenharmony_ci int hsize; 453562306a36Sopenharmony_ci int size; 453662306a36Sopenharmony_ci 453762306a36Sopenharmony_ci if (unlikely(mss == GSO_BY_FRAGS)) { 453862306a36Sopenharmony_ci len = list_skb->len; 453962306a36Sopenharmony_ci } else { 454062306a36Sopenharmony_ci len = head_skb->len - offset; 454162306a36Sopenharmony_ci if (len > mss) 454262306a36Sopenharmony_ci len = mss; 454362306a36Sopenharmony_ci } 454462306a36Sopenharmony_ci 454562306a36Sopenharmony_ci hsize = skb_headlen(head_skb) - offset; 454662306a36Sopenharmony_ci 454762306a36Sopenharmony_ci if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && 454862306a36Sopenharmony_ci (skb_headlen(list_skb) == len || sg)) { 454962306a36Sopenharmony_ci BUG_ON(skb_headlen(list_skb) > len); 455062306a36Sopenharmony_ci 455162306a36Sopenharmony_ci nskb = skb_clone(list_skb, GFP_ATOMIC); 455262306a36Sopenharmony_ci if (unlikely(!nskb)) 455362306a36Sopenharmony_ci goto err; 455462306a36Sopenharmony_ci 455562306a36Sopenharmony_ci i = 0; 455662306a36Sopenharmony_ci nfrags = skb_shinfo(list_skb)->nr_frags; 455762306a36Sopenharmony_ci frag = skb_shinfo(list_skb)->frags; 455862306a36Sopenharmony_ci frag_skb = list_skb; 455962306a36Sopenharmony_ci pos += skb_headlen(list_skb); 456062306a36Sopenharmony_ci 456162306a36Sopenharmony_ci while (pos < offset + len) { 456262306a36Sopenharmony_ci BUG_ON(i >= nfrags); 456362306a36Sopenharmony_ci 456462306a36Sopenharmony_ci size = skb_frag_size(frag); 456562306a36Sopenharmony_ci if (pos + size > offset + len) 456662306a36Sopenharmony_ci break; 456762306a36Sopenharmony_ci 456862306a36Sopenharmony_ci i++; 456962306a36Sopenharmony_ci pos += size; 457062306a36Sopenharmony_ci frag++; 457162306a36Sopenharmony_ci } 457262306a36Sopenharmony_ci 457362306a36Sopenharmony_ci list_skb = list_skb->next; 457462306a36Sopenharmony_ci 457562306a36Sopenharmony_ci if (unlikely(pskb_trim(nskb, len))) { 457662306a36Sopenharmony_ci kfree_skb(nskb); 457762306a36Sopenharmony_ci goto err; 457862306a36Sopenharmony_ci } 457962306a36Sopenharmony_ci 458062306a36Sopenharmony_ci hsize = skb_end_offset(nskb); 458162306a36Sopenharmony_ci if (skb_cow_head(nskb, doffset + headroom)) { 458262306a36Sopenharmony_ci kfree_skb(nskb); 458362306a36Sopenharmony_ci goto err; 458462306a36Sopenharmony_ci } 458562306a36Sopenharmony_ci 458662306a36Sopenharmony_ci nskb->truesize += skb_end_offset(nskb) - hsize; 458762306a36Sopenharmony_ci skb_release_head_state(nskb); 458862306a36Sopenharmony_ci __skb_push(nskb, doffset); 458962306a36Sopenharmony_ci } else { 459062306a36Sopenharmony_ci if (hsize < 0) 459162306a36Sopenharmony_ci hsize = 0; 459262306a36Sopenharmony_ci if (hsize > len || !sg) 459362306a36Sopenharmony_ci hsize = len; 459462306a36Sopenharmony_ci 459562306a36Sopenharmony_ci nskb = __alloc_skb(hsize + doffset + headroom, 459662306a36Sopenharmony_ci GFP_ATOMIC, skb_alloc_rx_flag(head_skb), 459762306a36Sopenharmony_ci NUMA_NO_NODE); 459862306a36Sopenharmony_ci 459962306a36Sopenharmony_ci if (unlikely(!nskb)) 460062306a36Sopenharmony_ci goto err; 460162306a36Sopenharmony_ci 460262306a36Sopenharmony_ci skb_reserve(nskb, headroom); 460362306a36Sopenharmony_ci __skb_put(nskb, doffset); 460462306a36Sopenharmony_ci } 460562306a36Sopenharmony_ci 460662306a36Sopenharmony_ci if (segs) 460762306a36Sopenharmony_ci tail->next = nskb; 460862306a36Sopenharmony_ci else 460962306a36Sopenharmony_ci segs = nskb; 461062306a36Sopenharmony_ci tail = nskb; 461162306a36Sopenharmony_ci 461262306a36Sopenharmony_ci __copy_skb_header(nskb, head_skb); 461362306a36Sopenharmony_ci 461462306a36Sopenharmony_ci skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); 461562306a36Sopenharmony_ci skb_reset_mac_len(nskb); 461662306a36Sopenharmony_ci 461762306a36Sopenharmony_ci skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, 461862306a36Sopenharmony_ci nskb->data - tnl_hlen, 461962306a36Sopenharmony_ci doffset + tnl_hlen); 462062306a36Sopenharmony_ci 462162306a36Sopenharmony_ci if (nskb->len == len + doffset) 462262306a36Sopenharmony_ci goto perform_csum_check; 462362306a36Sopenharmony_ci 462462306a36Sopenharmony_ci if (!sg) { 462562306a36Sopenharmony_ci if (!csum) { 462662306a36Sopenharmony_ci if (!nskb->remcsum_offload) 462762306a36Sopenharmony_ci nskb->ip_summed = CHECKSUM_NONE; 462862306a36Sopenharmony_ci SKB_GSO_CB(nskb)->csum = 462962306a36Sopenharmony_ci skb_copy_and_csum_bits(head_skb, offset, 463062306a36Sopenharmony_ci skb_put(nskb, 463162306a36Sopenharmony_ci len), 463262306a36Sopenharmony_ci len); 463362306a36Sopenharmony_ci SKB_GSO_CB(nskb)->csum_start = 463462306a36Sopenharmony_ci skb_headroom(nskb) + doffset; 463562306a36Sopenharmony_ci } else { 463662306a36Sopenharmony_ci if (skb_copy_bits(head_skb, offset, skb_put(nskb, len), len)) 463762306a36Sopenharmony_ci goto err; 463862306a36Sopenharmony_ci } 463962306a36Sopenharmony_ci continue; 464062306a36Sopenharmony_ci } 464162306a36Sopenharmony_ci 464262306a36Sopenharmony_ci nskb_frag = skb_shinfo(nskb)->frags; 464362306a36Sopenharmony_ci 464462306a36Sopenharmony_ci skb_copy_from_linear_data_offset(head_skb, offset, 464562306a36Sopenharmony_ci skb_put(nskb, hsize), hsize); 464662306a36Sopenharmony_ci 464762306a36Sopenharmony_ci skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags & 464862306a36Sopenharmony_ci SKBFL_SHARED_FRAG; 464962306a36Sopenharmony_ci 465062306a36Sopenharmony_ci if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) 465162306a36Sopenharmony_ci goto err; 465262306a36Sopenharmony_ci 465362306a36Sopenharmony_ci while (pos < offset + len) { 465462306a36Sopenharmony_ci if (i >= nfrags) { 465562306a36Sopenharmony_ci if (skb_orphan_frags(list_skb, GFP_ATOMIC) || 465662306a36Sopenharmony_ci skb_zerocopy_clone(nskb, list_skb, 465762306a36Sopenharmony_ci GFP_ATOMIC)) 465862306a36Sopenharmony_ci goto err; 465962306a36Sopenharmony_ci 466062306a36Sopenharmony_ci i = 0; 466162306a36Sopenharmony_ci nfrags = skb_shinfo(list_skb)->nr_frags; 466262306a36Sopenharmony_ci frag = skb_shinfo(list_skb)->frags; 466362306a36Sopenharmony_ci frag_skb = list_skb; 466462306a36Sopenharmony_ci if (!skb_headlen(list_skb)) { 466562306a36Sopenharmony_ci BUG_ON(!nfrags); 466662306a36Sopenharmony_ci } else { 466762306a36Sopenharmony_ci BUG_ON(!list_skb->head_frag); 466862306a36Sopenharmony_ci 466962306a36Sopenharmony_ci /* to make room for head_frag. */ 467062306a36Sopenharmony_ci i--; 467162306a36Sopenharmony_ci frag--; 467262306a36Sopenharmony_ci } 467362306a36Sopenharmony_ci 467462306a36Sopenharmony_ci list_skb = list_skb->next; 467562306a36Sopenharmony_ci } 467662306a36Sopenharmony_ci 467762306a36Sopenharmony_ci if (unlikely(skb_shinfo(nskb)->nr_frags >= 467862306a36Sopenharmony_ci MAX_SKB_FRAGS)) { 467962306a36Sopenharmony_ci net_warn_ratelimited( 468062306a36Sopenharmony_ci "skb_segment: too many frags: %u %u\n", 468162306a36Sopenharmony_ci pos, mss); 468262306a36Sopenharmony_ci err = -EINVAL; 468362306a36Sopenharmony_ci goto err; 468462306a36Sopenharmony_ci } 468562306a36Sopenharmony_ci 468662306a36Sopenharmony_ci *nskb_frag = (i < 0) ? skb_head_frag_to_page_desc(frag_skb) : *frag; 468762306a36Sopenharmony_ci __skb_frag_ref(nskb_frag); 468862306a36Sopenharmony_ci size = skb_frag_size(nskb_frag); 468962306a36Sopenharmony_ci 469062306a36Sopenharmony_ci if (pos < offset) { 469162306a36Sopenharmony_ci skb_frag_off_add(nskb_frag, offset - pos); 469262306a36Sopenharmony_ci skb_frag_size_sub(nskb_frag, offset - pos); 469362306a36Sopenharmony_ci } 469462306a36Sopenharmony_ci 469562306a36Sopenharmony_ci skb_shinfo(nskb)->nr_frags++; 469662306a36Sopenharmony_ci 469762306a36Sopenharmony_ci if (pos + size <= offset + len) { 469862306a36Sopenharmony_ci i++; 469962306a36Sopenharmony_ci frag++; 470062306a36Sopenharmony_ci pos += size; 470162306a36Sopenharmony_ci } else { 470262306a36Sopenharmony_ci skb_frag_size_sub(nskb_frag, pos + size - (offset + len)); 470362306a36Sopenharmony_ci goto skip_fraglist; 470462306a36Sopenharmony_ci } 470562306a36Sopenharmony_ci 470662306a36Sopenharmony_ci nskb_frag++; 470762306a36Sopenharmony_ci } 470862306a36Sopenharmony_ci 470962306a36Sopenharmony_ciskip_fraglist: 471062306a36Sopenharmony_ci nskb->data_len = len - hsize; 471162306a36Sopenharmony_ci nskb->len += nskb->data_len; 471262306a36Sopenharmony_ci nskb->truesize += nskb->data_len; 471362306a36Sopenharmony_ci 471462306a36Sopenharmony_ciperform_csum_check: 471562306a36Sopenharmony_ci if (!csum) { 471662306a36Sopenharmony_ci if (skb_has_shared_frag(nskb) && 471762306a36Sopenharmony_ci __skb_linearize(nskb)) 471862306a36Sopenharmony_ci goto err; 471962306a36Sopenharmony_ci 472062306a36Sopenharmony_ci if (!nskb->remcsum_offload) 472162306a36Sopenharmony_ci nskb->ip_summed = CHECKSUM_NONE; 472262306a36Sopenharmony_ci SKB_GSO_CB(nskb)->csum = 472362306a36Sopenharmony_ci skb_checksum(nskb, doffset, 472462306a36Sopenharmony_ci nskb->len - doffset, 0); 472562306a36Sopenharmony_ci SKB_GSO_CB(nskb)->csum_start = 472662306a36Sopenharmony_ci skb_headroom(nskb) + doffset; 472762306a36Sopenharmony_ci } 472862306a36Sopenharmony_ci } while ((offset += len) < head_skb->len); 472962306a36Sopenharmony_ci 473062306a36Sopenharmony_ci /* Some callers want to get the end of the list. 473162306a36Sopenharmony_ci * Put it in segs->prev to avoid walking the list. 473262306a36Sopenharmony_ci * (see validate_xmit_skb_list() for example) 473362306a36Sopenharmony_ci */ 473462306a36Sopenharmony_ci segs->prev = tail; 473562306a36Sopenharmony_ci 473662306a36Sopenharmony_ci if (partial_segs) { 473762306a36Sopenharmony_ci struct sk_buff *iter; 473862306a36Sopenharmony_ci int type = skb_shinfo(head_skb)->gso_type; 473962306a36Sopenharmony_ci unsigned short gso_size = skb_shinfo(head_skb)->gso_size; 474062306a36Sopenharmony_ci 474162306a36Sopenharmony_ci /* Update type to add partial and then remove dodgy if set */ 474262306a36Sopenharmony_ci type |= (features & NETIF_F_GSO_PARTIAL) / NETIF_F_GSO_PARTIAL * SKB_GSO_PARTIAL; 474362306a36Sopenharmony_ci type &= ~SKB_GSO_DODGY; 474462306a36Sopenharmony_ci 474562306a36Sopenharmony_ci /* Update GSO info and prepare to start updating headers on 474662306a36Sopenharmony_ci * our way back down the stack of protocols. 474762306a36Sopenharmony_ci */ 474862306a36Sopenharmony_ci for (iter = segs; iter; iter = iter->next) { 474962306a36Sopenharmony_ci skb_shinfo(iter)->gso_size = gso_size; 475062306a36Sopenharmony_ci skb_shinfo(iter)->gso_segs = partial_segs; 475162306a36Sopenharmony_ci skb_shinfo(iter)->gso_type = type; 475262306a36Sopenharmony_ci SKB_GSO_CB(iter)->data_offset = skb_headroom(iter) + doffset; 475362306a36Sopenharmony_ci } 475462306a36Sopenharmony_ci 475562306a36Sopenharmony_ci if (tail->len - doffset <= gso_size) 475662306a36Sopenharmony_ci skb_shinfo(tail)->gso_size = 0; 475762306a36Sopenharmony_ci else if (tail != segs) 475862306a36Sopenharmony_ci skb_shinfo(tail)->gso_segs = DIV_ROUND_UP(tail->len - doffset, gso_size); 475962306a36Sopenharmony_ci } 476062306a36Sopenharmony_ci 476162306a36Sopenharmony_ci /* Following permits correct backpressure, for protocols 476262306a36Sopenharmony_ci * using skb_set_owner_w(). 476362306a36Sopenharmony_ci * Idea is to tranfert ownership from head_skb to last segment. 476462306a36Sopenharmony_ci */ 476562306a36Sopenharmony_ci if (head_skb->destructor == sock_wfree) { 476662306a36Sopenharmony_ci swap(tail->truesize, head_skb->truesize); 476762306a36Sopenharmony_ci swap(tail->destructor, head_skb->destructor); 476862306a36Sopenharmony_ci swap(tail->sk, head_skb->sk); 476962306a36Sopenharmony_ci } 477062306a36Sopenharmony_ci return segs; 477162306a36Sopenharmony_ci 477262306a36Sopenharmony_cierr: 477362306a36Sopenharmony_ci kfree_skb_list(segs); 477462306a36Sopenharmony_ci return ERR_PTR(err); 477562306a36Sopenharmony_ci} 477662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_segment); 477762306a36Sopenharmony_ci 477862306a36Sopenharmony_ci#ifdef CONFIG_SKB_EXTENSIONS 477962306a36Sopenharmony_ci#define SKB_EXT_ALIGN_VALUE 8 478062306a36Sopenharmony_ci#define SKB_EXT_CHUNKSIZEOF(x) (ALIGN((sizeof(x)), SKB_EXT_ALIGN_VALUE) / SKB_EXT_ALIGN_VALUE) 478162306a36Sopenharmony_ci 478262306a36Sopenharmony_cistatic const u8 skb_ext_type_len[] = { 478362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 478462306a36Sopenharmony_ci [SKB_EXT_BRIDGE_NF] = SKB_EXT_CHUNKSIZEOF(struct nf_bridge_info), 478562306a36Sopenharmony_ci#endif 478662306a36Sopenharmony_ci#ifdef CONFIG_XFRM 478762306a36Sopenharmony_ci [SKB_EXT_SEC_PATH] = SKB_EXT_CHUNKSIZEOF(struct sec_path), 478862306a36Sopenharmony_ci#endif 478962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) 479062306a36Sopenharmony_ci [TC_SKB_EXT] = SKB_EXT_CHUNKSIZEOF(struct tc_skb_ext), 479162306a36Sopenharmony_ci#endif 479262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MPTCP) 479362306a36Sopenharmony_ci [SKB_EXT_MPTCP] = SKB_EXT_CHUNKSIZEOF(struct mptcp_ext), 479462306a36Sopenharmony_ci#endif 479562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MCTP_FLOWS) 479662306a36Sopenharmony_ci [SKB_EXT_MCTP] = SKB_EXT_CHUNKSIZEOF(struct mctp_flow), 479762306a36Sopenharmony_ci#endif 479862306a36Sopenharmony_ci}; 479962306a36Sopenharmony_ci 480062306a36Sopenharmony_cistatic __always_inline unsigned int skb_ext_total_length(void) 480162306a36Sopenharmony_ci{ 480262306a36Sopenharmony_ci unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); 480362306a36Sopenharmony_ci int i; 480462306a36Sopenharmony_ci 480562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(skb_ext_type_len); i++) 480662306a36Sopenharmony_ci l += skb_ext_type_len[i]; 480762306a36Sopenharmony_ci 480862306a36Sopenharmony_ci return l; 480962306a36Sopenharmony_ci} 481062306a36Sopenharmony_ci 481162306a36Sopenharmony_cistatic void skb_extensions_init(void) 481262306a36Sopenharmony_ci{ 481362306a36Sopenharmony_ci BUILD_BUG_ON(SKB_EXT_NUM >= 8); 481462306a36Sopenharmony_ci#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) 481562306a36Sopenharmony_ci BUILD_BUG_ON(skb_ext_total_length() > 255); 481662306a36Sopenharmony_ci#endif 481762306a36Sopenharmony_ci 481862306a36Sopenharmony_ci skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", 481962306a36Sopenharmony_ci SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), 482062306a36Sopenharmony_ci 0, 482162306a36Sopenharmony_ci SLAB_HWCACHE_ALIGN|SLAB_PANIC, 482262306a36Sopenharmony_ci NULL); 482362306a36Sopenharmony_ci} 482462306a36Sopenharmony_ci#else 482562306a36Sopenharmony_cistatic void skb_extensions_init(void) {} 482662306a36Sopenharmony_ci#endif 482762306a36Sopenharmony_ci 482862306a36Sopenharmony_ci/* The SKB kmem_cache slab is critical for network performance. Never 482962306a36Sopenharmony_ci * merge/alias the slab with similar sized objects. This avoids fragmentation 483062306a36Sopenharmony_ci * that hurts performance of kmem_cache_{alloc,free}_bulk APIs. 483162306a36Sopenharmony_ci */ 483262306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY 483362306a36Sopenharmony_ci#define FLAG_SKB_NO_MERGE SLAB_NO_MERGE 483462306a36Sopenharmony_ci#else /* CONFIG_SLUB_TINY - simple loop in kmem_cache_alloc_bulk */ 483562306a36Sopenharmony_ci#define FLAG_SKB_NO_MERGE 0 483662306a36Sopenharmony_ci#endif 483762306a36Sopenharmony_ci 483862306a36Sopenharmony_civoid __init skb_init(void) 483962306a36Sopenharmony_ci{ 484062306a36Sopenharmony_ci skbuff_cache = kmem_cache_create_usercopy("skbuff_head_cache", 484162306a36Sopenharmony_ci sizeof(struct sk_buff), 484262306a36Sopenharmony_ci 0, 484362306a36Sopenharmony_ci SLAB_HWCACHE_ALIGN|SLAB_PANIC| 484462306a36Sopenharmony_ci FLAG_SKB_NO_MERGE, 484562306a36Sopenharmony_ci offsetof(struct sk_buff, cb), 484662306a36Sopenharmony_ci sizeof_field(struct sk_buff, cb), 484762306a36Sopenharmony_ci NULL); 484862306a36Sopenharmony_ci skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache", 484962306a36Sopenharmony_ci sizeof(struct sk_buff_fclones), 485062306a36Sopenharmony_ci 0, 485162306a36Sopenharmony_ci SLAB_HWCACHE_ALIGN|SLAB_PANIC, 485262306a36Sopenharmony_ci NULL); 485362306a36Sopenharmony_ci /* usercopy should only access first SKB_SMALL_HEAD_HEADROOM bytes. 485462306a36Sopenharmony_ci * struct skb_shared_info is located at the end of skb->head, 485562306a36Sopenharmony_ci * and should not be copied to/from user. 485662306a36Sopenharmony_ci */ 485762306a36Sopenharmony_ci skb_small_head_cache = kmem_cache_create_usercopy("skbuff_small_head", 485862306a36Sopenharmony_ci SKB_SMALL_HEAD_CACHE_SIZE, 485962306a36Sopenharmony_ci 0, 486062306a36Sopenharmony_ci SLAB_HWCACHE_ALIGN | SLAB_PANIC, 486162306a36Sopenharmony_ci 0, 486262306a36Sopenharmony_ci SKB_SMALL_HEAD_HEADROOM, 486362306a36Sopenharmony_ci NULL); 486462306a36Sopenharmony_ci skb_extensions_init(); 486562306a36Sopenharmony_ci} 486662306a36Sopenharmony_ci 486762306a36Sopenharmony_cistatic int 486862306a36Sopenharmony_ci__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len, 486962306a36Sopenharmony_ci unsigned int recursion_level) 487062306a36Sopenharmony_ci{ 487162306a36Sopenharmony_ci int start = skb_headlen(skb); 487262306a36Sopenharmony_ci int i, copy = start - offset; 487362306a36Sopenharmony_ci struct sk_buff *frag_iter; 487462306a36Sopenharmony_ci int elt = 0; 487562306a36Sopenharmony_ci 487662306a36Sopenharmony_ci if (unlikely(recursion_level >= 24)) 487762306a36Sopenharmony_ci return -EMSGSIZE; 487862306a36Sopenharmony_ci 487962306a36Sopenharmony_ci if (copy > 0) { 488062306a36Sopenharmony_ci if (copy > len) 488162306a36Sopenharmony_ci copy = len; 488262306a36Sopenharmony_ci sg_set_buf(sg, skb->data + offset, copy); 488362306a36Sopenharmony_ci elt++; 488462306a36Sopenharmony_ci if ((len -= copy) == 0) 488562306a36Sopenharmony_ci return elt; 488662306a36Sopenharmony_ci offset += copy; 488762306a36Sopenharmony_ci } 488862306a36Sopenharmony_ci 488962306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 489062306a36Sopenharmony_ci int end; 489162306a36Sopenharmony_ci 489262306a36Sopenharmony_ci WARN_ON(start > offset + len); 489362306a36Sopenharmony_ci 489462306a36Sopenharmony_ci end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); 489562306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 489662306a36Sopenharmony_ci skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 489762306a36Sopenharmony_ci if (unlikely(elt && sg_is_last(&sg[elt - 1]))) 489862306a36Sopenharmony_ci return -EMSGSIZE; 489962306a36Sopenharmony_ci 490062306a36Sopenharmony_ci if (copy > len) 490162306a36Sopenharmony_ci copy = len; 490262306a36Sopenharmony_ci sg_set_page(&sg[elt], skb_frag_page(frag), copy, 490362306a36Sopenharmony_ci skb_frag_off(frag) + offset - start); 490462306a36Sopenharmony_ci elt++; 490562306a36Sopenharmony_ci if (!(len -= copy)) 490662306a36Sopenharmony_ci return elt; 490762306a36Sopenharmony_ci offset += copy; 490862306a36Sopenharmony_ci } 490962306a36Sopenharmony_ci start = end; 491062306a36Sopenharmony_ci } 491162306a36Sopenharmony_ci 491262306a36Sopenharmony_ci skb_walk_frags(skb, frag_iter) { 491362306a36Sopenharmony_ci int end, ret; 491462306a36Sopenharmony_ci 491562306a36Sopenharmony_ci WARN_ON(start > offset + len); 491662306a36Sopenharmony_ci 491762306a36Sopenharmony_ci end = start + frag_iter->len; 491862306a36Sopenharmony_ci if ((copy = end - offset) > 0) { 491962306a36Sopenharmony_ci if (unlikely(elt && sg_is_last(&sg[elt - 1]))) 492062306a36Sopenharmony_ci return -EMSGSIZE; 492162306a36Sopenharmony_ci 492262306a36Sopenharmony_ci if (copy > len) 492362306a36Sopenharmony_ci copy = len; 492462306a36Sopenharmony_ci ret = __skb_to_sgvec(frag_iter, sg+elt, offset - start, 492562306a36Sopenharmony_ci copy, recursion_level + 1); 492662306a36Sopenharmony_ci if (unlikely(ret < 0)) 492762306a36Sopenharmony_ci return ret; 492862306a36Sopenharmony_ci elt += ret; 492962306a36Sopenharmony_ci if ((len -= copy) == 0) 493062306a36Sopenharmony_ci return elt; 493162306a36Sopenharmony_ci offset += copy; 493262306a36Sopenharmony_ci } 493362306a36Sopenharmony_ci start = end; 493462306a36Sopenharmony_ci } 493562306a36Sopenharmony_ci BUG_ON(len); 493662306a36Sopenharmony_ci return elt; 493762306a36Sopenharmony_ci} 493862306a36Sopenharmony_ci 493962306a36Sopenharmony_ci/** 494062306a36Sopenharmony_ci * skb_to_sgvec - Fill a scatter-gather list from a socket buffer 494162306a36Sopenharmony_ci * @skb: Socket buffer containing the buffers to be mapped 494262306a36Sopenharmony_ci * @sg: The scatter-gather list to map into 494362306a36Sopenharmony_ci * @offset: The offset into the buffer's contents to start mapping 494462306a36Sopenharmony_ci * @len: Length of buffer space to be mapped 494562306a36Sopenharmony_ci * 494662306a36Sopenharmony_ci * Fill the specified scatter-gather list with mappings/pointers into a 494762306a36Sopenharmony_ci * region of the buffer space attached to a socket buffer. Returns either 494862306a36Sopenharmony_ci * the number of scatterlist items used, or -EMSGSIZE if the contents 494962306a36Sopenharmony_ci * could not fit. 495062306a36Sopenharmony_ci */ 495162306a36Sopenharmony_ciint skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) 495262306a36Sopenharmony_ci{ 495362306a36Sopenharmony_ci int nsg = __skb_to_sgvec(skb, sg, offset, len, 0); 495462306a36Sopenharmony_ci 495562306a36Sopenharmony_ci if (nsg <= 0) 495662306a36Sopenharmony_ci return nsg; 495762306a36Sopenharmony_ci 495862306a36Sopenharmony_ci sg_mark_end(&sg[nsg - 1]); 495962306a36Sopenharmony_ci 496062306a36Sopenharmony_ci return nsg; 496162306a36Sopenharmony_ci} 496262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_to_sgvec); 496362306a36Sopenharmony_ci 496462306a36Sopenharmony_ci/* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to given 496562306a36Sopenharmony_ci * sglist without mark the sg which contain last skb data as the end. 496662306a36Sopenharmony_ci * So the caller can mannipulate sg list as will when padding new data after 496762306a36Sopenharmony_ci * the first call without calling sg_unmark_end to expend sg list. 496862306a36Sopenharmony_ci * 496962306a36Sopenharmony_ci * Scenario to use skb_to_sgvec_nomark: 497062306a36Sopenharmony_ci * 1. sg_init_table 497162306a36Sopenharmony_ci * 2. skb_to_sgvec_nomark(payload1) 497262306a36Sopenharmony_ci * 3. skb_to_sgvec_nomark(payload2) 497362306a36Sopenharmony_ci * 497462306a36Sopenharmony_ci * This is equivalent to: 497562306a36Sopenharmony_ci * 1. sg_init_table 497662306a36Sopenharmony_ci * 2. skb_to_sgvec(payload1) 497762306a36Sopenharmony_ci * 3. sg_unmark_end 497862306a36Sopenharmony_ci * 4. skb_to_sgvec(payload2) 497962306a36Sopenharmony_ci * 498062306a36Sopenharmony_ci * When mapping mutilple payload conditionally, skb_to_sgvec_nomark 498162306a36Sopenharmony_ci * is more preferable. 498262306a36Sopenharmony_ci */ 498362306a36Sopenharmony_ciint skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, 498462306a36Sopenharmony_ci int offset, int len) 498562306a36Sopenharmony_ci{ 498662306a36Sopenharmony_ci return __skb_to_sgvec(skb, sg, offset, len, 0); 498762306a36Sopenharmony_ci} 498862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_to_sgvec_nomark); 498962306a36Sopenharmony_ci 499062306a36Sopenharmony_ci 499162306a36Sopenharmony_ci 499262306a36Sopenharmony_ci/** 499362306a36Sopenharmony_ci * skb_cow_data - Check that a socket buffer's data buffers are writable 499462306a36Sopenharmony_ci * @skb: The socket buffer to check. 499562306a36Sopenharmony_ci * @tailbits: Amount of trailing space to be added 499662306a36Sopenharmony_ci * @trailer: Returned pointer to the skb where the @tailbits space begins 499762306a36Sopenharmony_ci * 499862306a36Sopenharmony_ci * Make sure that the data buffers attached to a socket buffer are 499962306a36Sopenharmony_ci * writable. If they are not, private copies are made of the data buffers 500062306a36Sopenharmony_ci * and the socket buffer is set to use these instead. 500162306a36Sopenharmony_ci * 500262306a36Sopenharmony_ci * If @tailbits is given, make sure that there is space to write @tailbits 500362306a36Sopenharmony_ci * bytes of data beyond current end of socket buffer. @trailer will be 500462306a36Sopenharmony_ci * set to point to the skb in which this space begins. 500562306a36Sopenharmony_ci * 500662306a36Sopenharmony_ci * The number of scatterlist elements required to completely map the 500762306a36Sopenharmony_ci * COW'd and extended socket buffer will be returned. 500862306a36Sopenharmony_ci */ 500962306a36Sopenharmony_ciint skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) 501062306a36Sopenharmony_ci{ 501162306a36Sopenharmony_ci int copyflag; 501262306a36Sopenharmony_ci int elt; 501362306a36Sopenharmony_ci struct sk_buff *skb1, **skb_p; 501462306a36Sopenharmony_ci 501562306a36Sopenharmony_ci /* If skb is cloned or its head is paged, reallocate 501662306a36Sopenharmony_ci * head pulling out all the pages (pages are considered not writable 501762306a36Sopenharmony_ci * at the moment even if they are anonymous). 501862306a36Sopenharmony_ci */ 501962306a36Sopenharmony_ci if ((skb_cloned(skb) || skb_shinfo(skb)->nr_frags) && 502062306a36Sopenharmony_ci !__pskb_pull_tail(skb, __skb_pagelen(skb))) 502162306a36Sopenharmony_ci return -ENOMEM; 502262306a36Sopenharmony_ci 502362306a36Sopenharmony_ci /* Easy case. Most of packets will go this way. */ 502462306a36Sopenharmony_ci if (!skb_has_frag_list(skb)) { 502562306a36Sopenharmony_ci /* A little of trouble, not enough of space for trailer. 502662306a36Sopenharmony_ci * This should not happen, when stack is tuned to generate 502762306a36Sopenharmony_ci * good frames. OK, on miss we reallocate and reserve even more 502862306a36Sopenharmony_ci * space, 128 bytes is fair. */ 502962306a36Sopenharmony_ci 503062306a36Sopenharmony_ci if (skb_tailroom(skb) < tailbits && 503162306a36Sopenharmony_ci pskb_expand_head(skb, 0, tailbits-skb_tailroom(skb)+128, GFP_ATOMIC)) 503262306a36Sopenharmony_ci return -ENOMEM; 503362306a36Sopenharmony_ci 503462306a36Sopenharmony_ci /* Voila! */ 503562306a36Sopenharmony_ci *trailer = skb; 503662306a36Sopenharmony_ci return 1; 503762306a36Sopenharmony_ci } 503862306a36Sopenharmony_ci 503962306a36Sopenharmony_ci /* Misery. We are in troubles, going to mincer fragments... */ 504062306a36Sopenharmony_ci 504162306a36Sopenharmony_ci elt = 1; 504262306a36Sopenharmony_ci skb_p = &skb_shinfo(skb)->frag_list; 504362306a36Sopenharmony_ci copyflag = 0; 504462306a36Sopenharmony_ci 504562306a36Sopenharmony_ci while ((skb1 = *skb_p) != NULL) { 504662306a36Sopenharmony_ci int ntail = 0; 504762306a36Sopenharmony_ci 504862306a36Sopenharmony_ci /* The fragment is partially pulled by someone, 504962306a36Sopenharmony_ci * this can happen on input. Copy it and everything 505062306a36Sopenharmony_ci * after it. */ 505162306a36Sopenharmony_ci 505262306a36Sopenharmony_ci if (skb_shared(skb1)) 505362306a36Sopenharmony_ci copyflag = 1; 505462306a36Sopenharmony_ci 505562306a36Sopenharmony_ci /* If the skb is the last, worry about trailer. */ 505662306a36Sopenharmony_ci 505762306a36Sopenharmony_ci if (skb1->next == NULL && tailbits) { 505862306a36Sopenharmony_ci if (skb_shinfo(skb1)->nr_frags || 505962306a36Sopenharmony_ci skb_has_frag_list(skb1) || 506062306a36Sopenharmony_ci skb_tailroom(skb1) < tailbits) 506162306a36Sopenharmony_ci ntail = tailbits + 128; 506262306a36Sopenharmony_ci } 506362306a36Sopenharmony_ci 506462306a36Sopenharmony_ci if (copyflag || 506562306a36Sopenharmony_ci skb_cloned(skb1) || 506662306a36Sopenharmony_ci ntail || 506762306a36Sopenharmony_ci skb_shinfo(skb1)->nr_frags || 506862306a36Sopenharmony_ci skb_has_frag_list(skb1)) { 506962306a36Sopenharmony_ci struct sk_buff *skb2; 507062306a36Sopenharmony_ci 507162306a36Sopenharmony_ci /* Fuck, we are miserable poor guys... */ 507262306a36Sopenharmony_ci if (ntail == 0) 507362306a36Sopenharmony_ci skb2 = skb_copy(skb1, GFP_ATOMIC); 507462306a36Sopenharmony_ci else 507562306a36Sopenharmony_ci skb2 = skb_copy_expand(skb1, 507662306a36Sopenharmony_ci skb_headroom(skb1), 507762306a36Sopenharmony_ci ntail, 507862306a36Sopenharmony_ci GFP_ATOMIC); 507962306a36Sopenharmony_ci if (unlikely(skb2 == NULL)) 508062306a36Sopenharmony_ci return -ENOMEM; 508162306a36Sopenharmony_ci 508262306a36Sopenharmony_ci if (skb1->sk) 508362306a36Sopenharmony_ci skb_set_owner_w(skb2, skb1->sk); 508462306a36Sopenharmony_ci 508562306a36Sopenharmony_ci /* Looking around. Are we still alive? 508662306a36Sopenharmony_ci * OK, link new skb, drop old one */ 508762306a36Sopenharmony_ci 508862306a36Sopenharmony_ci skb2->next = skb1->next; 508962306a36Sopenharmony_ci *skb_p = skb2; 509062306a36Sopenharmony_ci kfree_skb(skb1); 509162306a36Sopenharmony_ci skb1 = skb2; 509262306a36Sopenharmony_ci } 509362306a36Sopenharmony_ci elt++; 509462306a36Sopenharmony_ci *trailer = skb1; 509562306a36Sopenharmony_ci skb_p = &skb1->next; 509662306a36Sopenharmony_ci } 509762306a36Sopenharmony_ci 509862306a36Sopenharmony_ci return elt; 509962306a36Sopenharmony_ci} 510062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_cow_data); 510162306a36Sopenharmony_ci 510262306a36Sopenharmony_cistatic void sock_rmem_free(struct sk_buff *skb) 510362306a36Sopenharmony_ci{ 510462306a36Sopenharmony_ci struct sock *sk = skb->sk; 510562306a36Sopenharmony_ci 510662306a36Sopenharmony_ci atomic_sub(skb->truesize, &sk->sk_rmem_alloc); 510762306a36Sopenharmony_ci} 510862306a36Sopenharmony_ci 510962306a36Sopenharmony_cistatic void skb_set_err_queue(struct sk_buff *skb) 511062306a36Sopenharmony_ci{ 511162306a36Sopenharmony_ci /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING. 511262306a36Sopenharmony_ci * So, it is safe to (mis)use it to mark skbs on the error queue. 511362306a36Sopenharmony_ci */ 511462306a36Sopenharmony_ci skb->pkt_type = PACKET_OUTGOING; 511562306a36Sopenharmony_ci BUILD_BUG_ON(PACKET_OUTGOING == 0); 511662306a36Sopenharmony_ci} 511762306a36Sopenharmony_ci 511862306a36Sopenharmony_ci/* 511962306a36Sopenharmony_ci * Note: We dont mem charge error packets (no sk_forward_alloc changes) 512062306a36Sopenharmony_ci */ 512162306a36Sopenharmony_ciint sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) 512262306a36Sopenharmony_ci{ 512362306a36Sopenharmony_ci if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= 512462306a36Sopenharmony_ci (unsigned int)READ_ONCE(sk->sk_rcvbuf)) 512562306a36Sopenharmony_ci return -ENOMEM; 512662306a36Sopenharmony_ci 512762306a36Sopenharmony_ci skb_orphan(skb); 512862306a36Sopenharmony_ci skb->sk = sk; 512962306a36Sopenharmony_ci skb->destructor = sock_rmem_free; 513062306a36Sopenharmony_ci atomic_add(skb->truesize, &sk->sk_rmem_alloc); 513162306a36Sopenharmony_ci skb_set_err_queue(skb); 513262306a36Sopenharmony_ci 513362306a36Sopenharmony_ci /* before exiting rcu section, make sure dst is refcounted */ 513462306a36Sopenharmony_ci skb_dst_force(skb); 513562306a36Sopenharmony_ci 513662306a36Sopenharmony_ci skb_queue_tail(&sk->sk_error_queue, skb); 513762306a36Sopenharmony_ci if (!sock_flag(sk, SOCK_DEAD)) 513862306a36Sopenharmony_ci sk_error_report(sk); 513962306a36Sopenharmony_ci return 0; 514062306a36Sopenharmony_ci} 514162306a36Sopenharmony_ciEXPORT_SYMBOL(sock_queue_err_skb); 514262306a36Sopenharmony_ci 514362306a36Sopenharmony_cistatic bool is_icmp_err_skb(const struct sk_buff *skb) 514462306a36Sopenharmony_ci{ 514562306a36Sopenharmony_ci return skb && (SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_ICMP || 514662306a36Sopenharmony_ci SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_ICMP6); 514762306a36Sopenharmony_ci} 514862306a36Sopenharmony_ci 514962306a36Sopenharmony_cistruct sk_buff *sock_dequeue_err_skb(struct sock *sk) 515062306a36Sopenharmony_ci{ 515162306a36Sopenharmony_ci struct sk_buff_head *q = &sk->sk_error_queue; 515262306a36Sopenharmony_ci struct sk_buff *skb, *skb_next = NULL; 515362306a36Sopenharmony_ci bool icmp_next = false; 515462306a36Sopenharmony_ci unsigned long flags; 515562306a36Sopenharmony_ci 515662306a36Sopenharmony_ci spin_lock_irqsave(&q->lock, flags); 515762306a36Sopenharmony_ci skb = __skb_dequeue(q); 515862306a36Sopenharmony_ci if (skb && (skb_next = skb_peek(q))) { 515962306a36Sopenharmony_ci icmp_next = is_icmp_err_skb(skb_next); 516062306a36Sopenharmony_ci if (icmp_next) 516162306a36Sopenharmony_ci sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_errno; 516262306a36Sopenharmony_ci } 516362306a36Sopenharmony_ci spin_unlock_irqrestore(&q->lock, flags); 516462306a36Sopenharmony_ci 516562306a36Sopenharmony_ci if (is_icmp_err_skb(skb) && !icmp_next) 516662306a36Sopenharmony_ci sk->sk_err = 0; 516762306a36Sopenharmony_ci 516862306a36Sopenharmony_ci if (skb_next) 516962306a36Sopenharmony_ci sk_error_report(sk); 517062306a36Sopenharmony_ci 517162306a36Sopenharmony_ci return skb; 517262306a36Sopenharmony_ci} 517362306a36Sopenharmony_ciEXPORT_SYMBOL(sock_dequeue_err_skb); 517462306a36Sopenharmony_ci 517562306a36Sopenharmony_ci/** 517662306a36Sopenharmony_ci * skb_clone_sk - create clone of skb, and take reference to socket 517762306a36Sopenharmony_ci * @skb: the skb to clone 517862306a36Sopenharmony_ci * 517962306a36Sopenharmony_ci * This function creates a clone of a buffer that holds a reference on 518062306a36Sopenharmony_ci * sk_refcnt. Buffers created via this function are meant to be 518162306a36Sopenharmony_ci * returned using sock_queue_err_skb, or free via kfree_skb. 518262306a36Sopenharmony_ci * 518362306a36Sopenharmony_ci * When passing buffers allocated with this function to sock_queue_err_skb 518462306a36Sopenharmony_ci * it is necessary to wrap the call with sock_hold/sock_put in order to 518562306a36Sopenharmony_ci * prevent the socket from being released prior to being enqueued on 518662306a36Sopenharmony_ci * the sk_error_queue. 518762306a36Sopenharmony_ci */ 518862306a36Sopenharmony_cistruct sk_buff *skb_clone_sk(struct sk_buff *skb) 518962306a36Sopenharmony_ci{ 519062306a36Sopenharmony_ci struct sock *sk = skb->sk; 519162306a36Sopenharmony_ci struct sk_buff *clone; 519262306a36Sopenharmony_ci 519362306a36Sopenharmony_ci if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt)) 519462306a36Sopenharmony_ci return NULL; 519562306a36Sopenharmony_ci 519662306a36Sopenharmony_ci clone = skb_clone(skb, GFP_ATOMIC); 519762306a36Sopenharmony_ci if (!clone) { 519862306a36Sopenharmony_ci sock_put(sk); 519962306a36Sopenharmony_ci return NULL; 520062306a36Sopenharmony_ci } 520162306a36Sopenharmony_ci 520262306a36Sopenharmony_ci clone->sk = sk; 520362306a36Sopenharmony_ci clone->destructor = sock_efree; 520462306a36Sopenharmony_ci 520562306a36Sopenharmony_ci return clone; 520662306a36Sopenharmony_ci} 520762306a36Sopenharmony_ciEXPORT_SYMBOL(skb_clone_sk); 520862306a36Sopenharmony_ci 520962306a36Sopenharmony_cistatic void __skb_complete_tx_timestamp(struct sk_buff *skb, 521062306a36Sopenharmony_ci struct sock *sk, 521162306a36Sopenharmony_ci int tstype, 521262306a36Sopenharmony_ci bool opt_stats) 521362306a36Sopenharmony_ci{ 521462306a36Sopenharmony_ci struct sock_exterr_skb *serr; 521562306a36Sopenharmony_ci int err; 521662306a36Sopenharmony_ci 521762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct sock_exterr_skb) > sizeof(skb->cb)); 521862306a36Sopenharmony_ci 521962306a36Sopenharmony_ci serr = SKB_EXT_ERR(skb); 522062306a36Sopenharmony_ci memset(serr, 0, sizeof(*serr)); 522162306a36Sopenharmony_ci serr->ee.ee_errno = ENOMSG; 522262306a36Sopenharmony_ci serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; 522362306a36Sopenharmony_ci serr->ee.ee_info = tstype; 522462306a36Sopenharmony_ci serr->opt_stats = opt_stats; 522562306a36Sopenharmony_ci serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; 522662306a36Sopenharmony_ci if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) { 522762306a36Sopenharmony_ci serr->ee.ee_data = skb_shinfo(skb)->tskey; 522862306a36Sopenharmony_ci if (sk_is_tcp(sk)) 522962306a36Sopenharmony_ci serr->ee.ee_data -= atomic_read(&sk->sk_tskey); 523062306a36Sopenharmony_ci } 523162306a36Sopenharmony_ci 523262306a36Sopenharmony_ci err = sock_queue_err_skb(sk, skb); 523362306a36Sopenharmony_ci 523462306a36Sopenharmony_ci if (err) 523562306a36Sopenharmony_ci kfree_skb(skb); 523662306a36Sopenharmony_ci} 523762306a36Sopenharmony_ci 523862306a36Sopenharmony_cistatic bool skb_may_tx_timestamp(struct sock *sk, bool tsonly) 523962306a36Sopenharmony_ci{ 524062306a36Sopenharmony_ci bool ret; 524162306a36Sopenharmony_ci 524262306a36Sopenharmony_ci if (likely(READ_ONCE(sysctl_tstamp_allow_data) || tsonly)) 524362306a36Sopenharmony_ci return true; 524462306a36Sopenharmony_ci 524562306a36Sopenharmony_ci read_lock_bh(&sk->sk_callback_lock); 524662306a36Sopenharmony_ci ret = sk->sk_socket && sk->sk_socket->file && 524762306a36Sopenharmony_ci file_ns_capable(sk->sk_socket->file, &init_user_ns, CAP_NET_RAW); 524862306a36Sopenharmony_ci read_unlock_bh(&sk->sk_callback_lock); 524962306a36Sopenharmony_ci return ret; 525062306a36Sopenharmony_ci} 525162306a36Sopenharmony_ci 525262306a36Sopenharmony_civoid skb_complete_tx_timestamp(struct sk_buff *skb, 525362306a36Sopenharmony_ci struct skb_shared_hwtstamps *hwtstamps) 525462306a36Sopenharmony_ci{ 525562306a36Sopenharmony_ci struct sock *sk = skb->sk; 525662306a36Sopenharmony_ci 525762306a36Sopenharmony_ci if (!skb_may_tx_timestamp(sk, false)) 525862306a36Sopenharmony_ci goto err; 525962306a36Sopenharmony_ci 526062306a36Sopenharmony_ci /* Take a reference to prevent skb_orphan() from freeing the socket, 526162306a36Sopenharmony_ci * but only if the socket refcount is not zero. 526262306a36Sopenharmony_ci */ 526362306a36Sopenharmony_ci if (likely(refcount_inc_not_zero(&sk->sk_refcnt))) { 526462306a36Sopenharmony_ci *skb_hwtstamps(skb) = *hwtstamps; 526562306a36Sopenharmony_ci __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); 526662306a36Sopenharmony_ci sock_put(sk); 526762306a36Sopenharmony_ci return; 526862306a36Sopenharmony_ci } 526962306a36Sopenharmony_ci 527062306a36Sopenharmony_cierr: 527162306a36Sopenharmony_ci kfree_skb(skb); 527262306a36Sopenharmony_ci} 527362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); 527462306a36Sopenharmony_ci 527562306a36Sopenharmony_civoid __skb_tstamp_tx(struct sk_buff *orig_skb, 527662306a36Sopenharmony_ci const struct sk_buff *ack_skb, 527762306a36Sopenharmony_ci struct skb_shared_hwtstamps *hwtstamps, 527862306a36Sopenharmony_ci struct sock *sk, int tstype) 527962306a36Sopenharmony_ci{ 528062306a36Sopenharmony_ci struct sk_buff *skb; 528162306a36Sopenharmony_ci bool tsonly, opt_stats = false; 528262306a36Sopenharmony_ci u32 tsflags; 528362306a36Sopenharmony_ci 528462306a36Sopenharmony_ci if (!sk) 528562306a36Sopenharmony_ci return; 528662306a36Sopenharmony_ci 528762306a36Sopenharmony_ci tsflags = READ_ONCE(sk->sk_tsflags); 528862306a36Sopenharmony_ci if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && 528962306a36Sopenharmony_ci skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS) 529062306a36Sopenharmony_ci return; 529162306a36Sopenharmony_ci 529262306a36Sopenharmony_ci tsonly = tsflags & SOF_TIMESTAMPING_OPT_TSONLY; 529362306a36Sopenharmony_ci if (!skb_may_tx_timestamp(sk, tsonly)) 529462306a36Sopenharmony_ci return; 529562306a36Sopenharmony_ci 529662306a36Sopenharmony_ci if (tsonly) { 529762306a36Sopenharmony_ci#ifdef CONFIG_INET 529862306a36Sopenharmony_ci if ((tsflags & SOF_TIMESTAMPING_OPT_STATS) && 529962306a36Sopenharmony_ci sk_is_tcp(sk)) { 530062306a36Sopenharmony_ci skb = tcp_get_timestamping_opt_stats(sk, orig_skb, 530162306a36Sopenharmony_ci ack_skb); 530262306a36Sopenharmony_ci opt_stats = true; 530362306a36Sopenharmony_ci } else 530462306a36Sopenharmony_ci#endif 530562306a36Sopenharmony_ci skb = alloc_skb(0, GFP_ATOMIC); 530662306a36Sopenharmony_ci } else { 530762306a36Sopenharmony_ci skb = skb_clone(orig_skb, GFP_ATOMIC); 530862306a36Sopenharmony_ci 530962306a36Sopenharmony_ci if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) { 531062306a36Sopenharmony_ci kfree_skb(skb); 531162306a36Sopenharmony_ci return; 531262306a36Sopenharmony_ci } 531362306a36Sopenharmony_ci } 531462306a36Sopenharmony_ci if (!skb) 531562306a36Sopenharmony_ci return; 531662306a36Sopenharmony_ci 531762306a36Sopenharmony_ci if (tsonly) { 531862306a36Sopenharmony_ci skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags & 531962306a36Sopenharmony_ci SKBTX_ANY_TSTAMP; 532062306a36Sopenharmony_ci skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; 532162306a36Sopenharmony_ci } 532262306a36Sopenharmony_ci 532362306a36Sopenharmony_ci if (hwtstamps) 532462306a36Sopenharmony_ci *skb_hwtstamps(skb) = *hwtstamps; 532562306a36Sopenharmony_ci else 532662306a36Sopenharmony_ci __net_timestamp(skb); 532762306a36Sopenharmony_ci 532862306a36Sopenharmony_ci __skb_complete_tx_timestamp(skb, sk, tstype, opt_stats); 532962306a36Sopenharmony_ci} 533062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__skb_tstamp_tx); 533162306a36Sopenharmony_ci 533262306a36Sopenharmony_civoid skb_tstamp_tx(struct sk_buff *orig_skb, 533362306a36Sopenharmony_ci struct skb_shared_hwtstamps *hwtstamps) 533462306a36Sopenharmony_ci{ 533562306a36Sopenharmony_ci return __skb_tstamp_tx(orig_skb, NULL, hwtstamps, orig_skb->sk, 533662306a36Sopenharmony_ci SCM_TSTAMP_SND); 533762306a36Sopenharmony_ci} 533862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_tstamp_tx); 533962306a36Sopenharmony_ci 534062306a36Sopenharmony_ci#ifdef CONFIG_WIRELESS 534162306a36Sopenharmony_civoid skb_complete_wifi_ack(struct sk_buff *skb, bool acked) 534262306a36Sopenharmony_ci{ 534362306a36Sopenharmony_ci struct sock *sk = skb->sk; 534462306a36Sopenharmony_ci struct sock_exterr_skb *serr; 534562306a36Sopenharmony_ci int err = 1; 534662306a36Sopenharmony_ci 534762306a36Sopenharmony_ci skb->wifi_acked_valid = 1; 534862306a36Sopenharmony_ci skb->wifi_acked = acked; 534962306a36Sopenharmony_ci 535062306a36Sopenharmony_ci serr = SKB_EXT_ERR(skb); 535162306a36Sopenharmony_ci memset(serr, 0, sizeof(*serr)); 535262306a36Sopenharmony_ci serr->ee.ee_errno = ENOMSG; 535362306a36Sopenharmony_ci serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; 535462306a36Sopenharmony_ci 535562306a36Sopenharmony_ci /* Take a reference to prevent skb_orphan() from freeing the socket, 535662306a36Sopenharmony_ci * but only if the socket refcount is not zero. 535762306a36Sopenharmony_ci */ 535862306a36Sopenharmony_ci if (likely(refcount_inc_not_zero(&sk->sk_refcnt))) { 535962306a36Sopenharmony_ci err = sock_queue_err_skb(sk, skb); 536062306a36Sopenharmony_ci sock_put(sk); 536162306a36Sopenharmony_ci } 536262306a36Sopenharmony_ci if (err) 536362306a36Sopenharmony_ci kfree_skb(skb); 536462306a36Sopenharmony_ci} 536562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_complete_wifi_ack); 536662306a36Sopenharmony_ci#endif /* CONFIG_WIRELESS */ 536762306a36Sopenharmony_ci 536862306a36Sopenharmony_ci/** 536962306a36Sopenharmony_ci * skb_partial_csum_set - set up and verify partial csum values for packet 537062306a36Sopenharmony_ci * @skb: the skb to set 537162306a36Sopenharmony_ci * @start: the number of bytes after skb->data to start checksumming. 537262306a36Sopenharmony_ci * @off: the offset from start to place the checksum. 537362306a36Sopenharmony_ci * 537462306a36Sopenharmony_ci * For untrusted partially-checksummed packets, we need to make sure the values 537562306a36Sopenharmony_ci * for skb->csum_start and skb->csum_offset are valid so we don't oops. 537662306a36Sopenharmony_ci * 537762306a36Sopenharmony_ci * This function checks and sets those values and skb->ip_summed: if this 537862306a36Sopenharmony_ci * returns false you should drop the packet. 537962306a36Sopenharmony_ci */ 538062306a36Sopenharmony_cibool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) 538162306a36Sopenharmony_ci{ 538262306a36Sopenharmony_ci u32 csum_end = (u32)start + (u32)off + sizeof(__sum16); 538362306a36Sopenharmony_ci u32 csum_start = skb_headroom(skb) + (u32)start; 538462306a36Sopenharmony_ci 538562306a36Sopenharmony_ci if (unlikely(csum_start >= U16_MAX || csum_end > skb_headlen(skb))) { 538662306a36Sopenharmony_ci net_warn_ratelimited("bad partial csum: csum=%u/%u headroom=%u headlen=%u\n", 538762306a36Sopenharmony_ci start, off, skb_headroom(skb), skb_headlen(skb)); 538862306a36Sopenharmony_ci return false; 538962306a36Sopenharmony_ci } 539062306a36Sopenharmony_ci skb->ip_summed = CHECKSUM_PARTIAL; 539162306a36Sopenharmony_ci skb->csum_start = csum_start; 539262306a36Sopenharmony_ci skb->csum_offset = off; 539362306a36Sopenharmony_ci skb->transport_header = csum_start; 539462306a36Sopenharmony_ci return true; 539562306a36Sopenharmony_ci} 539662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_partial_csum_set); 539762306a36Sopenharmony_ci 539862306a36Sopenharmony_cistatic int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len, 539962306a36Sopenharmony_ci unsigned int max) 540062306a36Sopenharmony_ci{ 540162306a36Sopenharmony_ci if (skb_headlen(skb) >= len) 540262306a36Sopenharmony_ci return 0; 540362306a36Sopenharmony_ci 540462306a36Sopenharmony_ci /* If we need to pullup then pullup to the max, so we 540562306a36Sopenharmony_ci * won't need to do it again. 540662306a36Sopenharmony_ci */ 540762306a36Sopenharmony_ci if (max > skb->len) 540862306a36Sopenharmony_ci max = skb->len; 540962306a36Sopenharmony_ci 541062306a36Sopenharmony_ci if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL) 541162306a36Sopenharmony_ci return -ENOMEM; 541262306a36Sopenharmony_ci 541362306a36Sopenharmony_ci if (skb_headlen(skb) < len) 541462306a36Sopenharmony_ci return -EPROTO; 541562306a36Sopenharmony_ci 541662306a36Sopenharmony_ci return 0; 541762306a36Sopenharmony_ci} 541862306a36Sopenharmony_ci 541962306a36Sopenharmony_ci#define MAX_TCP_HDR_LEN (15 * 4) 542062306a36Sopenharmony_ci 542162306a36Sopenharmony_cistatic __sum16 *skb_checksum_setup_ip(struct sk_buff *skb, 542262306a36Sopenharmony_ci typeof(IPPROTO_IP) proto, 542362306a36Sopenharmony_ci unsigned int off) 542462306a36Sopenharmony_ci{ 542562306a36Sopenharmony_ci int err; 542662306a36Sopenharmony_ci 542762306a36Sopenharmony_ci switch (proto) { 542862306a36Sopenharmony_ci case IPPROTO_TCP: 542962306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, off + sizeof(struct tcphdr), 543062306a36Sopenharmony_ci off + MAX_TCP_HDR_LEN); 543162306a36Sopenharmony_ci if (!err && !skb_partial_csum_set(skb, off, 543262306a36Sopenharmony_ci offsetof(struct tcphdr, 543362306a36Sopenharmony_ci check))) 543462306a36Sopenharmony_ci err = -EPROTO; 543562306a36Sopenharmony_ci return err ? ERR_PTR(err) : &tcp_hdr(skb)->check; 543662306a36Sopenharmony_ci 543762306a36Sopenharmony_ci case IPPROTO_UDP: 543862306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, off + sizeof(struct udphdr), 543962306a36Sopenharmony_ci off + sizeof(struct udphdr)); 544062306a36Sopenharmony_ci if (!err && !skb_partial_csum_set(skb, off, 544162306a36Sopenharmony_ci offsetof(struct udphdr, 544262306a36Sopenharmony_ci check))) 544362306a36Sopenharmony_ci err = -EPROTO; 544462306a36Sopenharmony_ci return err ? ERR_PTR(err) : &udp_hdr(skb)->check; 544562306a36Sopenharmony_ci } 544662306a36Sopenharmony_ci 544762306a36Sopenharmony_ci return ERR_PTR(-EPROTO); 544862306a36Sopenharmony_ci} 544962306a36Sopenharmony_ci 545062306a36Sopenharmony_ci/* This value should be large enough to cover a tagged ethernet header plus 545162306a36Sopenharmony_ci * maximally sized IP and TCP or UDP headers. 545262306a36Sopenharmony_ci */ 545362306a36Sopenharmony_ci#define MAX_IP_HDR_LEN 128 545462306a36Sopenharmony_ci 545562306a36Sopenharmony_cistatic int skb_checksum_setup_ipv4(struct sk_buff *skb, bool recalculate) 545662306a36Sopenharmony_ci{ 545762306a36Sopenharmony_ci unsigned int off; 545862306a36Sopenharmony_ci bool fragment; 545962306a36Sopenharmony_ci __sum16 *csum; 546062306a36Sopenharmony_ci int err; 546162306a36Sopenharmony_ci 546262306a36Sopenharmony_ci fragment = false; 546362306a36Sopenharmony_ci 546462306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, 546562306a36Sopenharmony_ci sizeof(struct iphdr), 546662306a36Sopenharmony_ci MAX_IP_HDR_LEN); 546762306a36Sopenharmony_ci if (err < 0) 546862306a36Sopenharmony_ci goto out; 546962306a36Sopenharmony_ci 547062306a36Sopenharmony_ci if (ip_is_fragment(ip_hdr(skb))) 547162306a36Sopenharmony_ci fragment = true; 547262306a36Sopenharmony_ci 547362306a36Sopenharmony_ci off = ip_hdrlen(skb); 547462306a36Sopenharmony_ci 547562306a36Sopenharmony_ci err = -EPROTO; 547662306a36Sopenharmony_ci 547762306a36Sopenharmony_ci if (fragment) 547862306a36Sopenharmony_ci goto out; 547962306a36Sopenharmony_ci 548062306a36Sopenharmony_ci csum = skb_checksum_setup_ip(skb, ip_hdr(skb)->protocol, off); 548162306a36Sopenharmony_ci if (IS_ERR(csum)) 548262306a36Sopenharmony_ci return PTR_ERR(csum); 548362306a36Sopenharmony_ci 548462306a36Sopenharmony_ci if (recalculate) 548562306a36Sopenharmony_ci *csum = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, 548662306a36Sopenharmony_ci ip_hdr(skb)->daddr, 548762306a36Sopenharmony_ci skb->len - off, 548862306a36Sopenharmony_ci ip_hdr(skb)->protocol, 0); 548962306a36Sopenharmony_ci err = 0; 549062306a36Sopenharmony_ci 549162306a36Sopenharmony_ciout: 549262306a36Sopenharmony_ci return err; 549362306a36Sopenharmony_ci} 549462306a36Sopenharmony_ci 549562306a36Sopenharmony_ci/* This value should be large enough to cover a tagged ethernet header plus 549662306a36Sopenharmony_ci * an IPv6 header, all options, and a maximal TCP or UDP header. 549762306a36Sopenharmony_ci */ 549862306a36Sopenharmony_ci#define MAX_IPV6_HDR_LEN 256 549962306a36Sopenharmony_ci 550062306a36Sopenharmony_ci#define OPT_HDR(type, skb, off) \ 550162306a36Sopenharmony_ci (type *)(skb_network_header(skb) + (off)) 550262306a36Sopenharmony_ci 550362306a36Sopenharmony_cistatic int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate) 550462306a36Sopenharmony_ci{ 550562306a36Sopenharmony_ci int err; 550662306a36Sopenharmony_ci u8 nexthdr; 550762306a36Sopenharmony_ci unsigned int off; 550862306a36Sopenharmony_ci unsigned int len; 550962306a36Sopenharmony_ci bool fragment; 551062306a36Sopenharmony_ci bool done; 551162306a36Sopenharmony_ci __sum16 *csum; 551262306a36Sopenharmony_ci 551362306a36Sopenharmony_ci fragment = false; 551462306a36Sopenharmony_ci done = false; 551562306a36Sopenharmony_ci 551662306a36Sopenharmony_ci off = sizeof(struct ipv6hdr); 551762306a36Sopenharmony_ci 551862306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN); 551962306a36Sopenharmony_ci if (err < 0) 552062306a36Sopenharmony_ci goto out; 552162306a36Sopenharmony_ci 552262306a36Sopenharmony_ci nexthdr = ipv6_hdr(skb)->nexthdr; 552362306a36Sopenharmony_ci 552462306a36Sopenharmony_ci len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len); 552562306a36Sopenharmony_ci while (off <= len && !done) { 552662306a36Sopenharmony_ci switch (nexthdr) { 552762306a36Sopenharmony_ci case IPPROTO_DSTOPTS: 552862306a36Sopenharmony_ci case IPPROTO_HOPOPTS: 552962306a36Sopenharmony_ci case IPPROTO_ROUTING: { 553062306a36Sopenharmony_ci struct ipv6_opt_hdr *hp; 553162306a36Sopenharmony_ci 553262306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, 553362306a36Sopenharmony_ci off + 553462306a36Sopenharmony_ci sizeof(struct ipv6_opt_hdr), 553562306a36Sopenharmony_ci MAX_IPV6_HDR_LEN); 553662306a36Sopenharmony_ci if (err < 0) 553762306a36Sopenharmony_ci goto out; 553862306a36Sopenharmony_ci 553962306a36Sopenharmony_ci hp = OPT_HDR(struct ipv6_opt_hdr, skb, off); 554062306a36Sopenharmony_ci nexthdr = hp->nexthdr; 554162306a36Sopenharmony_ci off += ipv6_optlen(hp); 554262306a36Sopenharmony_ci break; 554362306a36Sopenharmony_ci } 554462306a36Sopenharmony_ci case IPPROTO_AH: { 554562306a36Sopenharmony_ci struct ip_auth_hdr *hp; 554662306a36Sopenharmony_ci 554762306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, 554862306a36Sopenharmony_ci off + 554962306a36Sopenharmony_ci sizeof(struct ip_auth_hdr), 555062306a36Sopenharmony_ci MAX_IPV6_HDR_LEN); 555162306a36Sopenharmony_ci if (err < 0) 555262306a36Sopenharmony_ci goto out; 555362306a36Sopenharmony_ci 555462306a36Sopenharmony_ci hp = OPT_HDR(struct ip_auth_hdr, skb, off); 555562306a36Sopenharmony_ci nexthdr = hp->nexthdr; 555662306a36Sopenharmony_ci off += ipv6_authlen(hp); 555762306a36Sopenharmony_ci break; 555862306a36Sopenharmony_ci } 555962306a36Sopenharmony_ci case IPPROTO_FRAGMENT: { 556062306a36Sopenharmony_ci struct frag_hdr *hp; 556162306a36Sopenharmony_ci 556262306a36Sopenharmony_ci err = skb_maybe_pull_tail(skb, 556362306a36Sopenharmony_ci off + 556462306a36Sopenharmony_ci sizeof(struct frag_hdr), 556562306a36Sopenharmony_ci MAX_IPV6_HDR_LEN); 556662306a36Sopenharmony_ci if (err < 0) 556762306a36Sopenharmony_ci goto out; 556862306a36Sopenharmony_ci 556962306a36Sopenharmony_ci hp = OPT_HDR(struct frag_hdr, skb, off); 557062306a36Sopenharmony_ci 557162306a36Sopenharmony_ci if (hp->frag_off & htons(IP6_OFFSET | IP6_MF)) 557262306a36Sopenharmony_ci fragment = true; 557362306a36Sopenharmony_ci 557462306a36Sopenharmony_ci nexthdr = hp->nexthdr; 557562306a36Sopenharmony_ci off += sizeof(struct frag_hdr); 557662306a36Sopenharmony_ci break; 557762306a36Sopenharmony_ci } 557862306a36Sopenharmony_ci default: 557962306a36Sopenharmony_ci done = true; 558062306a36Sopenharmony_ci break; 558162306a36Sopenharmony_ci } 558262306a36Sopenharmony_ci } 558362306a36Sopenharmony_ci 558462306a36Sopenharmony_ci err = -EPROTO; 558562306a36Sopenharmony_ci 558662306a36Sopenharmony_ci if (!done || fragment) 558762306a36Sopenharmony_ci goto out; 558862306a36Sopenharmony_ci 558962306a36Sopenharmony_ci csum = skb_checksum_setup_ip(skb, nexthdr, off); 559062306a36Sopenharmony_ci if (IS_ERR(csum)) 559162306a36Sopenharmony_ci return PTR_ERR(csum); 559262306a36Sopenharmony_ci 559362306a36Sopenharmony_ci if (recalculate) 559462306a36Sopenharmony_ci *csum = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, 559562306a36Sopenharmony_ci &ipv6_hdr(skb)->daddr, 559662306a36Sopenharmony_ci skb->len - off, nexthdr, 0); 559762306a36Sopenharmony_ci err = 0; 559862306a36Sopenharmony_ci 559962306a36Sopenharmony_ciout: 560062306a36Sopenharmony_ci return err; 560162306a36Sopenharmony_ci} 560262306a36Sopenharmony_ci 560362306a36Sopenharmony_ci/** 560462306a36Sopenharmony_ci * skb_checksum_setup - set up partial checksum offset 560562306a36Sopenharmony_ci * @skb: the skb to set up 560662306a36Sopenharmony_ci * @recalculate: if true the pseudo-header checksum will be recalculated 560762306a36Sopenharmony_ci */ 560862306a36Sopenharmony_ciint skb_checksum_setup(struct sk_buff *skb, bool recalculate) 560962306a36Sopenharmony_ci{ 561062306a36Sopenharmony_ci int err; 561162306a36Sopenharmony_ci 561262306a36Sopenharmony_ci switch (skb->protocol) { 561362306a36Sopenharmony_ci case htons(ETH_P_IP): 561462306a36Sopenharmony_ci err = skb_checksum_setup_ipv4(skb, recalculate); 561562306a36Sopenharmony_ci break; 561662306a36Sopenharmony_ci 561762306a36Sopenharmony_ci case htons(ETH_P_IPV6): 561862306a36Sopenharmony_ci err = skb_checksum_setup_ipv6(skb, recalculate); 561962306a36Sopenharmony_ci break; 562062306a36Sopenharmony_ci 562162306a36Sopenharmony_ci default: 562262306a36Sopenharmony_ci err = -EPROTO; 562362306a36Sopenharmony_ci break; 562462306a36Sopenharmony_ci } 562562306a36Sopenharmony_ci 562662306a36Sopenharmony_ci return err; 562762306a36Sopenharmony_ci} 562862306a36Sopenharmony_ciEXPORT_SYMBOL(skb_checksum_setup); 562962306a36Sopenharmony_ci 563062306a36Sopenharmony_ci/** 563162306a36Sopenharmony_ci * skb_checksum_maybe_trim - maybe trims the given skb 563262306a36Sopenharmony_ci * @skb: the skb to check 563362306a36Sopenharmony_ci * @transport_len: the data length beyond the network header 563462306a36Sopenharmony_ci * 563562306a36Sopenharmony_ci * Checks whether the given skb has data beyond the given transport length. 563662306a36Sopenharmony_ci * If so, returns a cloned skb trimmed to this transport length. 563762306a36Sopenharmony_ci * Otherwise returns the provided skb. Returns NULL in error cases 563862306a36Sopenharmony_ci * (e.g. transport_len exceeds skb length or out-of-memory). 563962306a36Sopenharmony_ci * 564062306a36Sopenharmony_ci * Caller needs to set the skb transport header and free any returned skb if it 564162306a36Sopenharmony_ci * differs from the provided skb. 564262306a36Sopenharmony_ci */ 564362306a36Sopenharmony_cistatic struct sk_buff *skb_checksum_maybe_trim(struct sk_buff *skb, 564462306a36Sopenharmony_ci unsigned int transport_len) 564562306a36Sopenharmony_ci{ 564662306a36Sopenharmony_ci struct sk_buff *skb_chk; 564762306a36Sopenharmony_ci unsigned int len = skb_transport_offset(skb) + transport_len; 564862306a36Sopenharmony_ci int ret; 564962306a36Sopenharmony_ci 565062306a36Sopenharmony_ci if (skb->len < len) 565162306a36Sopenharmony_ci return NULL; 565262306a36Sopenharmony_ci else if (skb->len == len) 565362306a36Sopenharmony_ci return skb; 565462306a36Sopenharmony_ci 565562306a36Sopenharmony_ci skb_chk = skb_clone(skb, GFP_ATOMIC); 565662306a36Sopenharmony_ci if (!skb_chk) 565762306a36Sopenharmony_ci return NULL; 565862306a36Sopenharmony_ci 565962306a36Sopenharmony_ci ret = pskb_trim_rcsum(skb_chk, len); 566062306a36Sopenharmony_ci if (ret) { 566162306a36Sopenharmony_ci kfree_skb(skb_chk); 566262306a36Sopenharmony_ci return NULL; 566362306a36Sopenharmony_ci } 566462306a36Sopenharmony_ci 566562306a36Sopenharmony_ci return skb_chk; 566662306a36Sopenharmony_ci} 566762306a36Sopenharmony_ci 566862306a36Sopenharmony_ci/** 566962306a36Sopenharmony_ci * skb_checksum_trimmed - validate checksum of an skb 567062306a36Sopenharmony_ci * @skb: the skb to check 567162306a36Sopenharmony_ci * @transport_len: the data length beyond the network header 567262306a36Sopenharmony_ci * @skb_chkf: checksum function to use 567362306a36Sopenharmony_ci * 567462306a36Sopenharmony_ci * Applies the given checksum function skb_chkf to the provided skb. 567562306a36Sopenharmony_ci * Returns a checked and maybe trimmed skb. Returns NULL on error. 567662306a36Sopenharmony_ci * 567762306a36Sopenharmony_ci * If the skb has data beyond the given transport length, then a 567862306a36Sopenharmony_ci * trimmed & cloned skb is checked and returned. 567962306a36Sopenharmony_ci * 568062306a36Sopenharmony_ci * Caller needs to set the skb transport header and free any returned skb if it 568162306a36Sopenharmony_ci * differs from the provided skb. 568262306a36Sopenharmony_ci */ 568362306a36Sopenharmony_cistruct sk_buff *skb_checksum_trimmed(struct sk_buff *skb, 568462306a36Sopenharmony_ci unsigned int transport_len, 568562306a36Sopenharmony_ci __sum16(*skb_chkf)(struct sk_buff *skb)) 568662306a36Sopenharmony_ci{ 568762306a36Sopenharmony_ci struct sk_buff *skb_chk; 568862306a36Sopenharmony_ci unsigned int offset = skb_transport_offset(skb); 568962306a36Sopenharmony_ci __sum16 ret; 569062306a36Sopenharmony_ci 569162306a36Sopenharmony_ci skb_chk = skb_checksum_maybe_trim(skb, transport_len); 569262306a36Sopenharmony_ci if (!skb_chk) 569362306a36Sopenharmony_ci goto err; 569462306a36Sopenharmony_ci 569562306a36Sopenharmony_ci if (!pskb_may_pull(skb_chk, offset)) 569662306a36Sopenharmony_ci goto err; 569762306a36Sopenharmony_ci 569862306a36Sopenharmony_ci skb_pull_rcsum(skb_chk, offset); 569962306a36Sopenharmony_ci ret = skb_chkf(skb_chk); 570062306a36Sopenharmony_ci skb_push_rcsum(skb_chk, offset); 570162306a36Sopenharmony_ci 570262306a36Sopenharmony_ci if (ret) 570362306a36Sopenharmony_ci goto err; 570462306a36Sopenharmony_ci 570562306a36Sopenharmony_ci return skb_chk; 570662306a36Sopenharmony_ci 570762306a36Sopenharmony_cierr: 570862306a36Sopenharmony_ci if (skb_chk && skb_chk != skb) 570962306a36Sopenharmony_ci kfree_skb(skb_chk); 571062306a36Sopenharmony_ci 571162306a36Sopenharmony_ci return NULL; 571262306a36Sopenharmony_ci 571362306a36Sopenharmony_ci} 571462306a36Sopenharmony_ciEXPORT_SYMBOL(skb_checksum_trimmed); 571562306a36Sopenharmony_ci 571662306a36Sopenharmony_civoid __skb_warn_lro_forwarding(const struct sk_buff *skb) 571762306a36Sopenharmony_ci{ 571862306a36Sopenharmony_ci net_warn_ratelimited("%s: received packets cannot be forwarded while LRO is enabled\n", 571962306a36Sopenharmony_ci skb->dev->name); 572062306a36Sopenharmony_ci} 572162306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_warn_lro_forwarding); 572262306a36Sopenharmony_ci 572362306a36Sopenharmony_civoid kfree_skb_partial(struct sk_buff *skb, bool head_stolen) 572462306a36Sopenharmony_ci{ 572562306a36Sopenharmony_ci if (head_stolen) { 572662306a36Sopenharmony_ci skb_release_head_state(skb); 572762306a36Sopenharmony_ci kmem_cache_free(skbuff_cache, skb); 572862306a36Sopenharmony_ci } else { 572962306a36Sopenharmony_ci __kfree_skb(skb); 573062306a36Sopenharmony_ci } 573162306a36Sopenharmony_ci} 573262306a36Sopenharmony_ciEXPORT_SYMBOL(kfree_skb_partial); 573362306a36Sopenharmony_ci 573462306a36Sopenharmony_ci/** 573562306a36Sopenharmony_ci * skb_try_coalesce - try to merge skb to prior one 573662306a36Sopenharmony_ci * @to: prior buffer 573762306a36Sopenharmony_ci * @from: buffer to add 573862306a36Sopenharmony_ci * @fragstolen: pointer to boolean 573962306a36Sopenharmony_ci * @delta_truesize: how much more was allocated than was requested 574062306a36Sopenharmony_ci */ 574162306a36Sopenharmony_cibool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, 574262306a36Sopenharmony_ci bool *fragstolen, int *delta_truesize) 574362306a36Sopenharmony_ci{ 574462306a36Sopenharmony_ci struct skb_shared_info *to_shinfo, *from_shinfo; 574562306a36Sopenharmony_ci int i, delta, len = from->len; 574662306a36Sopenharmony_ci 574762306a36Sopenharmony_ci *fragstolen = false; 574862306a36Sopenharmony_ci 574962306a36Sopenharmony_ci if (skb_cloned(to)) 575062306a36Sopenharmony_ci return false; 575162306a36Sopenharmony_ci 575262306a36Sopenharmony_ci /* In general, avoid mixing page_pool and non-page_pool allocated 575362306a36Sopenharmony_ci * pages within the same SKB. Additionally avoid dealing with clones 575462306a36Sopenharmony_ci * with page_pool pages, in case the SKB is using page_pool fragment 575562306a36Sopenharmony_ci * references (PP_FLAG_PAGE_FRAG). Since we only take full page 575662306a36Sopenharmony_ci * references for cloned SKBs at the moment that would result in 575762306a36Sopenharmony_ci * inconsistent reference counts. 575862306a36Sopenharmony_ci * In theory we could take full references if @from is cloned and 575962306a36Sopenharmony_ci * !@to->pp_recycle but its tricky (due to potential race with 576062306a36Sopenharmony_ci * the clone disappearing) and rare, so not worth dealing with. 576162306a36Sopenharmony_ci */ 576262306a36Sopenharmony_ci if (to->pp_recycle != from->pp_recycle || 576362306a36Sopenharmony_ci (from->pp_recycle && skb_cloned(from))) 576462306a36Sopenharmony_ci return false; 576562306a36Sopenharmony_ci 576662306a36Sopenharmony_ci if (len <= skb_tailroom(to)) { 576762306a36Sopenharmony_ci if (len) 576862306a36Sopenharmony_ci BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); 576962306a36Sopenharmony_ci *delta_truesize = 0; 577062306a36Sopenharmony_ci return true; 577162306a36Sopenharmony_ci } 577262306a36Sopenharmony_ci 577362306a36Sopenharmony_ci to_shinfo = skb_shinfo(to); 577462306a36Sopenharmony_ci from_shinfo = skb_shinfo(from); 577562306a36Sopenharmony_ci if (to_shinfo->frag_list || from_shinfo->frag_list) 577662306a36Sopenharmony_ci return false; 577762306a36Sopenharmony_ci if (skb_zcopy(to) || skb_zcopy(from)) 577862306a36Sopenharmony_ci return false; 577962306a36Sopenharmony_ci 578062306a36Sopenharmony_ci if (skb_headlen(from) != 0) { 578162306a36Sopenharmony_ci struct page *page; 578262306a36Sopenharmony_ci unsigned int offset; 578362306a36Sopenharmony_ci 578462306a36Sopenharmony_ci if (to_shinfo->nr_frags + 578562306a36Sopenharmony_ci from_shinfo->nr_frags >= MAX_SKB_FRAGS) 578662306a36Sopenharmony_ci return false; 578762306a36Sopenharmony_ci 578862306a36Sopenharmony_ci if (skb_head_is_locked(from)) 578962306a36Sopenharmony_ci return false; 579062306a36Sopenharmony_ci 579162306a36Sopenharmony_ci delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); 579262306a36Sopenharmony_ci 579362306a36Sopenharmony_ci page = virt_to_head_page(from->head); 579462306a36Sopenharmony_ci offset = from->data - (unsigned char *)page_address(page); 579562306a36Sopenharmony_ci 579662306a36Sopenharmony_ci skb_fill_page_desc(to, to_shinfo->nr_frags, 579762306a36Sopenharmony_ci page, offset, skb_headlen(from)); 579862306a36Sopenharmony_ci *fragstolen = true; 579962306a36Sopenharmony_ci } else { 580062306a36Sopenharmony_ci if (to_shinfo->nr_frags + 580162306a36Sopenharmony_ci from_shinfo->nr_frags > MAX_SKB_FRAGS) 580262306a36Sopenharmony_ci return false; 580362306a36Sopenharmony_ci 580462306a36Sopenharmony_ci delta = from->truesize - SKB_TRUESIZE(skb_end_offset(from)); 580562306a36Sopenharmony_ci } 580662306a36Sopenharmony_ci 580762306a36Sopenharmony_ci WARN_ON_ONCE(delta < len); 580862306a36Sopenharmony_ci 580962306a36Sopenharmony_ci memcpy(to_shinfo->frags + to_shinfo->nr_frags, 581062306a36Sopenharmony_ci from_shinfo->frags, 581162306a36Sopenharmony_ci from_shinfo->nr_frags * sizeof(skb_frag_t)); 581262306a36Sopenharmony_ci to_shinfo->nr_frags += from_shinfo->nr_frags; 581362306a36Sopenharmony_ci 581462306a36Sopenharmony_ci if (!skb_cloned(from)) 581562306a36Sopenharmony_ci from_shinfo->nr_frags = 0; 581662306a36Sopenharmony_ci 581762306a36Sopenharmony_ci /* if the skb is not cloned this does nothing 581862306a36Sopenharmony_ci * since we set nr_frags to 0. 581962306a36Sopenharmony_ci */ 582062306a36Sopenharmony_ci for (i = 0; i < from_shinfo->nr_frags; i++) 582162306a36Sopenharmony_ci __skb_frag_ref(&from_shinfo->frags[i]); 582262306a36Sopenharmony_ci 582362306a36Sopenharmony_ci to->truesize += delta; 582462306a36Sopenharmony_ci to->len += len; 582562306a36Sopenharmony_ci to->data_len += len; 582662306a36Sopenharmony_ci 582762306a36Sopenharmony_ci *delta_truesize = delta; 582862306a36Sopenharmony_ci return true; 582962306a36Sopenharmony_ci} 583062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_try_coalesce); 583162306a36Sopenharmony_ci 583262306a36Sopenharmony_ci/** 583362306a36Sopenharmony_ci * skb_scrub_packet - scrub an skb 583462306a36Sopenharmony_ci * 583562306a36Sopenharmony_ci * @skb: buffer to clean 583662306a36Sopenharmony_ci * @xnet: packet is crossing netns 583762306a36Sopenharmony_ci * 583862306a36Sopenharmony_ci * skb_scrub_packet can be used after encapsulating or decapsulting a packet 583962306a36Sopenharmony_ci * into/from a tunnel. Some information have to be cleared during these 584062306a36Sopenharmony_ci * operations. 584162306a36Sopenharmony_ci * skb_scrub_packet can also be used to clean a skb before injecting it in 584262306a36Sopenharmony_ci * another namespace (@xnet == true). We have to clear all information in the 584362306a36Sopenharmony_ci * skb that could impact namespace isolation. 584462306a36Sopenharmony_ci */ 584562306a36Sopenharmony_civoid skb_scrub_packet(struct sk_buff *skb, bool xnet) 584662306a36Sopenharmony_ci{ 584762306a36Sopenharmony_ci skb->pkt_type = PACKET_HOST; 584862306a36Sopenharmony_ci skb->skb_iif = 0; 584962306a36Sopenharmony_ci skb->ignore_df = 0; 585062306a36Sopenharmony_ci skb_dst_drop(skb); 585162306a36Sopenharmony_ci skb_ext_reset(skb); 585262306a36Sopenharmony_ci nf_reset_ct(skb); 585362306a36Sopenharmony_ci nf_reset_trace(skb); 585462306a36Sopenharmony_ci 585562306a36Sopenharmony_ci#ifdef CONFIG_NET_SWITCHDEV 585662306a36Sopenharmony_ci skb->offload_fwd_mark = 0; 585762306a36Sopenharmony_ci skb->offload_l3_fwd_mark = 0; 585862306a36Sopenharmony_ci#endif 585962306a36Sopenharmony_ci 586062306a36Sopenharmony_ci if (!xnet) 586162306a36Sopenharmony_ci return; 586262306a36Sopenharmony_ci 586362306a36Sopenharmony_ci ipvs_reset(skb); 586462306a36Sopenharmony_ci skb->mark = 0; 586562306a36Sopenharmony_ci skb_clear_tstamp(skb); 586662306a36Sopenharmony_ci} 586762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_scrub_packet); 586862306a36Sopenharmony_ci 586962306a36Sopenharmony_cistatic struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) 587062306a36Sopenharmony_ci{ 587162306a36Sopenharmony_ci int mac_len, meta_len; 587262306a36Sopenharmony_ci void *meta; 587362306a36Sopenharmony_ci 587462306a36Sopenharmony_ci if (skb_cow(skb, skb_headroom(skb)) < 0) { 587562306a36Sopenharmony_ci kfree_skb(skb); 587662306a36Sopenharmony_ci return NULL; 587762306a36Sopenharmony_ci } 587862306a36Sopenharmony_ci 587962306a36Sopenharmony_ci mac_len = skb->data - skb_mac_header(skb); 588062306a36Sopenharmony_ci if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) { 588162306a36Sopenharmony_ci memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb), 588262306a36Sopenharmony_ci mac_len - VLAN_HLEN - ETH_TLEN); 588362306a36Sopenharmony_ci } 588462306a36Sopenharmony_ci 588562306a36Sopenharmony_ci meta_len = skb_metadata_len(skb); 588662306a36Sopenharmony_ci if (meta_len) { 588762306a36Sopenharmony_ci meta = skb_metadata_end(skb) - meta_len; 588862306a36Sopenharmony_ci memmove(meta + VLAN_HLEN, meta, meta_len); 588962306a36Sopenharmony_ci } 589062306a36Sopenharmony_ci 589162306a36Sopenharmony_ci skb->mac_header += VLAN_HLEN; 589262306a36Sopenharmony_ci return skb; 589362306a36Sopenharmony_ci} 589462306a36Sopenharmony_ci 589562306a36Sopenharmony_cistruct sk_buff *skb_vlan_untag(struct sk_buff *skb) 589662306a36Sopenharmony_ci{ 589762306a36Sopenharmony_ci struct vlan_hdr *vhdr; 589862306a36Sopenharmony_ci u16 vlan_tci; 589962306a36Sopenharmony_ci 590062306a36Sopenharmony_ci if (unlikely(skb_vlan_tag_present(skb))) { 590162306a36Sopenharmony_ci /* vlan_tci is already set-up so leave this for another time */ 590262306a36Sopenharmony_ci return skb; 590362306a36Sopenharmony_ci } 590462306a36Sopenharmony_ci 590562306a36Sopenharmony_ci skb = skb_share_check(skb, GFP_ATOMIC); 590662306a36Sopenharmony_ci if (unlikely(!skb)) 590762306a36Sopenharmony_ci goto err_free; 590862306a36Sopenharmony_ci /* We may access the two bytes after vlan_hdr in vlan_set_encap_proto(). */ 590962306a36Sopenharmony_ci if (unlikely(!pskb_may_pull(skb, VLAN_HLEN + sizeof(unsigned short)))) 591062306a36Sopenharmony_ci goto err_free; 591162306a36Sopenharmony_ci 591262306a36Sopenharmony_ci vhdr = (struct vlan_hdr *)skb->data; 591362306a36Sopenharmony_ci vlan_tci = ntohs(vhdr->h_vlan_TCI); 591462306a36Sopenharmony_ci __vlan_hwaccel_put_tag(skb, skb->protocol, vlan_tci); 591562306a36Sopenharmony_ci 591662306a36Sopenharmony_ci skb_pull_rcsum(skb, VLAN_HLEN); 591762306a36Sopenharmony_ci vlan_set_encap_proto(skb, vhdr); 591862306a36Sopenharmony_ci 591962306a36Sopenharmony_ci skb = skb_reorder_vlan_header(skb); 592062306a36Sopenharmony_ci if (unlikely(!skb)) 592162306a36Sopenharmony_ci goto err_free; 592262306a36Sopenharmony_ci 592362306a36Sopenharmony_ci skb_reset_network_header(skb); 592462306a36Sopenharmony_ci if (!skb_transport_header_was_set(skb)) 592562306a36Sopenharmony_ci skb_reset_transport_header(skb); 592662306a36Sopenharmony_ci skb_reset_mac_len(skb); 592762306a36Sopenharmony_ci 592862306a36Sopenharmony_ci return skb; 592962306a36Sopenharmony_ci 593062306a36Sopenharmony_cierr_free: 593162306a36Sopenharmony_ci kfree_skb(skb); 593262306a36Sopenharmony_ci return NULL; 593362306a36Sopenharmony_ci} 593462306a36Sopenharmony_ciEXPORT_SYMBOL(skb_vlan_untag); 593562306a36Sopenharmony_ci 593662306a36Sopenharmony_ciint skb_ensure_writable(struct sk_buff *skb, unsigned int write_len) 593762306a36Sopenharmony_ci{ 593862306a36Sopenharmony_ci if (!pskb_may_pull(skb, write_len)) 593962306a36Sopenharmony_ci return -ENOMEM; 594062306a36Sopenharmony_ci 594162306a36Sopenharmony_ci if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) 594262306a36Sopenharmony_ci return 0; 594362306a36Sopenharmony_ci 594462306a36Sopenharmony_ci return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); 594562306a36Sopenharmony_ci} 594662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_ensure_writable); 594762306a36Sopenharmony_ci 594862306a36Sopenharmony_ci/* remove VLAN header from packet and update csum accordingly. 594962306a36Sopenharmony_ci * expects a non skb_vlan_tag_present skb with a vlan tag payload 595062306a36Sopenharmony_ci */ 595162306a36Sopenharmony_ciint __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci) 595262306a36Sopenharmony_ci{ 595362306a36Sopenharmony_ci int offset = skb->data - skb_mac_header(skb); 595462306a36Sopenharmony_ci int err; 595562306a36Sopenharmony_ci 595662306a36Sopenharmony_ci if (WARN_ONCE(offset, 595762306a36Sopenharmony_ci "__skb_vlan_pop got skb with skb->data not at mac header (offset %d)\n", 595862306a36Sopenharmony_ci offset)) { 595962306a36Sopenharmony_ci return -EINVAL; 596062306a36Sopenharmony_ci } 596162306a36Sopenharmony_ci 596262306a36Sopenharmony_ci err = skb_ensure_writable(skb, VLAN_ETH_HLEN); 596362306a36Sopenharmony_ci if (unlikely(err)) 596462306a36Sopenharmony_ci return err; 596562306a36Sopenharmony_ci 596662306a36Sopenharmony_ci skb_postpull_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); 596762306a36Sopenharmony_ci 596862306a36Sopenharmony_ci vlan_remove_tag(skb, vlan_tci); 596962306a36Sopenharmony_ci 597062306a36Sopenharmony_ci skb->mac_header += VLAN_HLEN; 597162306a36Sopenharmony_ci 597262306a36Sopenharmony_ci if (skb_network_offset(skb) < ETH_HLEN) 597362306a36Sopenharmony_ci skb_set_network_header(skb, ETH_HLEN); 597462306a36Sopenharmony_ci 597562306a36Sopenharmony_ci skb_reset_mac_len(skb); 597662306a36Sopenharmony_ci 597762306a36Sopenharmony_ci return err; 597862306a36Sopenharmony_ci} 597962306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_vlan_pop); 598062306a36Sopenharmony_ci 598162306a36Sopenharmony_ci/* Pop a vlan tag either from hwaccel or from payload. 598262306a36Sopenharmony_ci * Expects skb->data at mac header. 598362306a36Sopenharmony_ci */ 598462306a36Sopenharmony_ciint skb_vlan_pop(struct sk_buff *skb) 598562306a36Sopenharmony_ci{ 598662306a36Sopenharmony_ci u16 vlan_tci; 598762306a36Sopenharmony_ci __be16 vlan_proto; 598862306a36Sopenharmony_ci int err; 598962306a36Sopenharmony_ci 599062306a36Sopenharmony_ci if (likely(skb_vlan_tag_present(skb))) { 599162306a36Sopenharmony_ci __vlan_hwaccel_clear_tag(skb); 599262306a36Sopenharmony_ci } else { 599362306a36Sopenharmony_ci if (unlikely(!eth_type_vlan(skb->protocol))) 599462306a36Sopenharmony_ci return 0; 599562306a36Sopenharmony_ci 599662306a36Sopenharmony_ci err = __skb_vlan_pop(skb, &vlan_tci); 599762306a36Sopenharmony_ci if (err) 599862306a36Sopenharmony_ci return err; 599962306a36Sopenharmony_ci } 600062306a36Sopenharmony_ci /* move next vlan tag to hw accel tag */ 600162306a36Sopenharmony_ci if (likely(!eth_type_vlan(skb->protocol))) 600262306a36Sopenharmony_ci return 0; 600362306a36Sopenharmony_ci 600462306a36Sopenharmony_ci vlan_proto = skb->protocol; 600562306a36Sopenharmony_ci err = __skb_vlan_pop(skb, &vlan_tci); 600662306a36Sopenharmony_ci if (unlikely(err)) 600762306a36Sopenharmony_ci return err; 600862306a36Sopenharmony_ci 600962306a36Sopenharmony_ci __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); 601062306a36Sopenharmony_ci return 0; 601162306a36Sopenharmony_ci} 601262306a36Sopenharmony_ciEXPORT_SYMBOL(skb_vlan_pop); 601362306a36Sopenharmony_ci 601462306a36Sopenharmony_ci/* Push a vlan tag either into hwaccel or into payload (if hwaccel tag present). 601562306a36Sopenharmony_ci * Expects skb->data at mac header. 601662306a36Sopenharmony_ci */ 601762306a36Sopenharmony_ciint skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) 601862306a36Sopenharmony_ci{ 601962306a36Sopenharmony_ci if (skb_vlan_tag_present(skb)) { 602062306a36Sopenharmony_ci int offset = skb->data - skb_mac_header(skb); 602162306a36Sopenharmony_ci int err; 602262306a36Sopenharmony_ci 602362306a36Sopenharmony_ci if (WARN_ONCE(offset, 602462306a36Sopenharmony_ci "skb_vlan_push got skb with skb->data not at mac header (offset %d)\n", 602562306a36Sopenharmony_ci offset)) { 602662306a36Sopenharmony_ci return -EINVAL; 602762306a36Sopenharmony_ci } 602862306a36Sopenharmony_ci 602962306a36Sopenharmony_ci err = __vlan_insert_tag(skb, skb->vlan_proto, 603062306a36Sopenharmony_ci skb_vlan_tag_get(skb)); 603162306a36Sopenharmony_ci if (err) 603262306a36Sopenharmony_ci return err; 603362306a36Sopenharmony_ci 603462306a36Sopenharmony_ci skb->protocol = skb->vlan_proto; 603562306a36Sopenharmony_ci skb->mac_len += VLAN_HLEN; 603662306a36Sopenharmony_ci 603762306a36Sopenharmony_ci skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); 603862306a36Sopenharmony_ci } 603962306a36Sopenharmony_ci __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); 604062306a36Sopenharmony_ci return 0; 604162306a36Sopenharmony_ci} 604262306a36Sopenharmony_ciEXPORT_SYMBOL(skb_vlan_push); 604362306a36Sopenharmony_ci 604462306a36Sopenharmony_ci/** 604562306a36Sopenharmony_ci * skb_eth_pop() - Drop the Ethernet header at the head of a packet 604662306a36Sopenharmony_ci * 604762306a36Sopenharmony_ci * @skb: Socket buffer to modify 604862306a36Sopenharmony_ci * 604962306a36Sopenharmony_ci * Drop the Ethernet header of @skb. 605062306a36Sopenharmony_ci * 605162306a36Sopenharmony_ci * Expects that skb->data points to the mac header and that no VLAN tags are 605262306a36Sopenharmony_ci * present. 605362306a36Sopenharmony_ci * 605462306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 605562306a36Sopenharmony_ci */ 605662306a36Sopenharmony_ciint skb_eth_pop(struct sk_buff *skb) 605762306a36Sopenharmony_ci{ 605862306a36Sopenharmony_ci if (!pskb_may_pull(skb, ETH_HLEN) || skb_vlan_tagged(skb) || 605962306a36Sopenharmony_ci skb_network_offset(skb) < ETH_HLEN) 606062306a36Sopenharmony_ci return -EPROTO; 606162306a36Sopenharmony_ci 606262306a36Sopenharmony_ci skb_pull_rcsum(skb, ETH_HLEN); 606362306a36Sopenharmony_ci skb_reset_mac_header(skb); 606462306a36Sopenharmony_ci skb_reset_mac_len(skb); 606562306a36Sopenharmony_ci 606662306a36Sopenharmony_ci return 0; 606762306a36Sopenharmony_ci} 606862306a36Sopenharmony_ciEXPORT_SYMBOL(skb_eth_pop); 606962306a36Sopenharmony_ci 607062306a36Sopenharmony_ci/** 607162306a36Sopenharmony_ci * skb_eth_push() - Add a new Ethernet header at the head of a packet 607262306a36Sopenharmony_ci * 607362306a36Sopenharmony_ci * @skb: Socket buffer to modify 607462306a36Sopenharmony_ci * @dst: Destination MAC address of the new header 607562306a36Sopenharmony_ci * @src: Source MAC address of the new header 607662306a36Sopenharmony_ci * 607762306a36Sopenharmony_ci * Prepend @skb with a new Ethernet header. 607862306a36Sopenharmony_ci * 607962306a36Sopenharmony_ci * Expects that skb->data points to the mac header, which must be empty. 608062306a36Sopenharmony_ci * 608162306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 608262306a36Sopenharmony_ci */ 608362306a36Sopenharmony_ciint skb_eth_push(struct sk_buff *skb, const unsigned char *dst, 608462306a36Sopenharmony_ci const unsigned char *src) 608562306a36Sopenharmony_ci{ 608662306a36Sopenharmony_ci struct ethhdr *eth; 608762306a36Sopenharmony_ci int err; 608862306a36Sopenharmony_ci 608962306a36Sopenharmony_ci if (skb_network_offset(skb) || skb_vlan_tag_present(skb)) 609062306a36Sopenharmony_ci return -EPROTO; 609162306a36Sopenharmony_ci 609262306a36Sopenharmony_ci err = skb_cow_head(skb, sizeof(*eth)); 609362306a36Sopenharmony_ci if (err < 0) 609462306a36Sopenharmony_ci return err; 609562306a36Sopenharmony_ci 609662306a36Sopenharmony_ci skb_push(skb, sizeof(*eth)); 609762306a36Sopenharmony_ci skb_reset_mac_header(skb); 609862306a36Sopenharmony_ci skb_reset_mac_len(skb); 609962306a36Sopenharmony_ci 610062306a36Sopenharmony_ci eth = eth_hdr(skb); 610162306a36Sopenharmony_ci ether_addr_copy(eth->h_dest, dst); 610262306a36Sopenharmony_ci ether_addr_copy(eth->h_source, src); 610362306a36Sopenharmony_ci eth->h_proto = skb->protocol; 610462306a36Sopenharmony_ci 610562306a36Sopenharmony_ci skb_postpush_rcsum(skb, eth, sizeof(*eth)); 610662306a36Sopenharmony_ci 610762306a36Sopenharmony_ci return 0; 610862306a36Sopenharmony_ci} 610962306a36Sopenharmony_ciEXPORT_SYMBOL(skb_eth_push); 611062306a36Sopenharmony_ci 611162306a36Sopenharmony_ci/* Update the ethertype of hdr and the skb csum value if required. */ 611262306a36Sopenharmony_cistatic void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr, 611362306a36Sopenharmony_ci __be16 ethertype) 611462306a36Sopenharmony_ci{ 611562306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_COMPLETE) { 611662306a36Sopenharmony_ci __be16 diff[] = { ~hdr->h_proto, ethertype }; 611762306a36Sopenharmony_ci 611862306a36Sopenharmony_ci skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum); 611962306a36Sopenharmony_ci } 612062306a36Sopenharmony_ci 612162306a36Sopenharmony_ci hdr->h_proto = ethertype; 612262306a36Sopenharmony_ci} 612362306a36Sopenharmony_ci 612462306a36Sopenharmony_ci/** 612562306a36Sopenharmony_ci * skb_mpls_push() - push a new MPLS header after mac_len bytes from start of 612662306a36Sopenharmony_ci * the packet 612762306a36Sopenharmony_ci * 612862306a36Sopenharmony_ci * @skb: buffer 612962306a36Sopenharmony_ci * @mpls_lse: MPLS label stack entry to push 613062306a36Sopenharmony_ci * @mpls_proto: ethertype of the new MPLS header (expects 0x8847 or 0x8848) 613162306a36Sopenharmony_ci * @mac_len: length of the MAC header 613262306a36Sopenharmony_ci * @ethernet: flag to indicate if the resulting packet after skb_mpls_push is 613362306a36Sopenharmony_ci * ethernet 613462306a36Sopenharmony_ci * 613562306a36Sopenharmony_ci * Expects skb->data at mac header. 613662306a36Sopenharmony_ci * 613762306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 613862306a36Sopenharmony_ci */ 613962306a36Sopenharmony_ciint skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, 614062306a36Sopenharmony_ci int mac_len, bool ethernet) 614162306a36Sopenharmony_ci{ 614262306a36Sopenharmony_ci struct mpls_shim_hdr *lse; 614362306a36Sopenharmony_ci int err; 614462306a36Sopenharmony_ci 614562306a36Sopenharmony_ci if (unlikely(!eth_p_mpls(mpls_proto))) 614662306a36Sopenharmony_ci return -EINVAL; 614762306a36Sopenharmony_ci 614862306a36Sopenharmony_ci /* Networking stack does not allow simultaneous Tunnel and MPLS GSO. */ 614962306a36Sopenharmony_ci if (skb->encapsulation) 615062306a36Sopenharmony_ci return -EINVAL; 615162306a36Sopenharmony_ci 615262306a36Sopenharmony_ci err = skb_cow_head(skb, MPLS_HLEN); 615362306a36Sopenharmony_ci if (unlikely(err)) 615462306a36Sopenharmony_ci return err; 615562306a36Sopenharmony_ci 615662306a36Sopenharmony_ci if (!skb->inner_protocol) { 615762306a36Sopenharmony_ci skb_set_inner_network_header(skb, skb_network_offset(skb)); 615862306a36Sopenharmony_ci skb_set_inner_protocol(skb, skb->protocol); 615962306a36Sopenharmony_ci } 616062306a36Sopenharmony_ci 616162306a36Sopenharmony_ci skb_push(skb, MPLS_HLEN); 616262306a36Sopenharmony_ci memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb), 616362306a36Sopenharmony_ci mac_len); 616462306a36Sopenharmony_ci skb_reset_mac_header(skb); 616562306a36Sopenharmony_ci skb_set_network_header(skb, mac_len); 616662306a36Sopenharmony_ci skb_reset_mac_len(skb); 616762306a36Sopenharmony_ci 616862306a36Sopenharmony_ci lse = mpls_hdr(skb); 616962306a36Sopenharmony_ci lse->label_stack_entry = mpls_lse; 617062306a36Sopenharmony_ci skb_postpush_rcsum(skb, lse, MPLS_HLEN); 617162306a36Sopenharmony_ci 617262306a36Sopenharmony_ci if (ethernet && mac_len >= ETH_HLEN) 617362306a36Sopenharmony_ci skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto); 617462306a36Sopenharmony_ci skb->protocol = mpls_proto; 617562306a36Sopenharmony_ci 617662306a36Sopenharmony_ci return 0; 617762306a36Sopenharmony_ci} 617862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_mpls_push); 617962306a36Sopenharmony_ci 618062306a36Sopenharmony_ci/** 618162306a36Sopenharmony_ci * skb_mpls_pop() - pop the outermost MPLS header 618262306a36Sopenharmony_ci * 618362306a36Sopenharmony_ci * @skb: buffer 618462306a36Sopenharmony_ci * @next_proto: ethertype of header after popped MPLS header 618562306a36Sopenharmony_ci * @mac_len: length of the MAC header 618662306a36Sopenharmony_ci * @ethernet: flag to indicate if the packet is ethernet 618762306a36Sopenharmony_ci * 618862306a36Sopenharmony_ci * Expects skb->data at mac header. 618962306a36Sopenharmony_ci * 619062306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 619162306a36Sopenharmony_ci */ 619262306a36Sopenharmony_ciint skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, 619362306a36Sopenharmony_ci bool ethernet) 619462306a36Sopenharmony_ci{ 619562306a36Sopenharmony_ci int err; 619662306a36Sopenharmony_ci 619762306a36Sopenharmony_ci if (unlikely(!eth_p_mpls(skb->protocol))) 619862306a36Sopenharmony_ci return 0; 619962306a36Sopenharmony_ci 620062306a36Sopenharmony_ci err = skb_ensure_writable(skb, mac_len + MPLS_HLEN); 620162306a36Sopenharmony_ci if (unlikely(err)) 620262306a36Sopenharmony_ci return err; 620362306a36Sopenharmony_ci 620462306a36Sopenharmony_ci skb_postpull_rcsum(skb, mpls_hdr(skb), MPLS_HLEN); 620562306a36Sopenharmony_ci memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb), 620662306a36Sopenharmony_ci mac_len); 620762306a36Sopenharmony_ci 620862306a36Sopenharmony_ci __skb_pull(skb, MPLS_HLEN); 620962306a36Sopenharmony_ci skb_reset_mac_header(skb); 621062306a36Sopenharmony_ci skb_set_network_header(skb, mac_len); 621162306a36Sopenharmony_ci 621262306a36Sopenharmony_ci if (ethernet && mac_len >= ETH_HLEN) { 621362306a36Sopenharmony_ci struct ethhdr *hdr; 621462306a36Sopenharmony_ci 621562306a36Sopenharmony_ci /* use mpls_hdr() to get ethertype to account for VLANs. */ 621662306a36Sopenharmony_ci hdr = (struct ethhdr *)((void *)mpls_hdr(skb) - ETH_HLEN); 621762306a36Sopenharmony_ci skb_mod_eth_type(skb, hdr, next_proto); 621862306a36Sopenharmony_ci } 621962306a36Sopenharmony_ci skb->protocol = next_proto; 622062306a36Sopenharmony_ci 622162306a36Sopenharmony_ci return 0; 622262306a36Sopenharmony_ci} 622362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_mpls_pop); 622462306a36Sopenharmony_ci 622562306a36Sopenharmony_ci/** 622662306a36Sopenharmony_ci * skb_mpls_update_lse() - modify outermost MPLS header and update csum 622762306a36Sopenharmony_ci * 622862306a36Sopenharmony_ci * @skb: buffer 622962306a36Sopenharmony_ci * @mpls_lse: new MPLS label stack entry to update to 623062306a36Sopenharmony_ci * 623162306a36Sopenharmony_ci * Expects skb->data at mac header. 623262306a36Sopenharmony_ci * 623362306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 623462306a36Sopenharmony_ci */ 623562306a36Sopenharmony_ciint skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse) 623662306a36Sopenharmony_ci{ 623762306a36Sopenharmony_ci int err; 623862306a36Sopenharmony_ci 623962306a36Sopenharmony_ci if (unlikely(!eth_p_mpls(skb->protocol))) 624062306a36Sopenharmony_ci return -EINVAL; 624162306a36Sopenharmony_ci 624262306a36Sopenharmony_ci err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); 624362306a36Sopenharmony_ci if (unlikely(err)) 624462306a36Sopenharmony_ci return err; 624562306a36Sopenharmony_ci 624662306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_COMPLETE) { 624762306a36Sopenharmony_ci __be32 diff[] = { ~mpls_hdr(skb)->label_stack_entry, mpls_lse }; 624862306a36Sopenharmony_ci 624962306a36Sopenharmony_ci skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum); 625062306a36Sopenharmony_ci } 625162306a36Sopenharmony_ci 625262306a36Sopenharmony_ci mpls_hdr(skb)->label_stack_entry = mpls_lse; 625362306a36Sopenharmony_ci 625462306a36Sopenharmony_ci return 0; 625562306a36Sopenharmony_ci} 625662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_mpls_update_lse); 625762306a36Sopenharmony_ci 625862306a36Sopenharmony_ci/** 625962306a36Sopenharmony_ci * skb_mpls_dec_ttl() - decrement the TTL of the outermost MPLS header 626062306a36Sopenharmony_ci * 626162306a36Sopenharmony_ci * @skb: buffer 626262306a36Sopenharmony_ci * 626362306a36Sopenharmony_ci * Expects skb->data at mac header. 626462306a36Sopenharmony_ci * 626562306a36Sopenharmony_ci * Returns 0 on success, -errno otherwise. 626662306a36Sopenharmony_ci */ 626762306a36Sopenharmony_ciint skb_mpls_dec_ttl(struct sk_buff *skb) 626862306a36Sopenharmony_ci{ 626962306a36Sopenharmony_ci u32 lse; 627062306a36Sopenharmony_ci u8 ttl; 627162306a36Sopenharmony_ci 627262306a36Sopenharmony_ci if (unlikely(!eth_p_mpls(skb->protocol))) 627362306a36Sopenharmony_ci return -EINVAL; 627462306a36Sopenharmony_ci 627562306a36Sopenharmony_ci if (!pskb_may_pull(skb, skb_network_offset(skb) + MPLS_HLEN)) 627662306a36Sopenharmony_ci return -ENOMEM; 627762306a36Sopenharmony_ci 627862306a36Sopenharmony_ci lse = be32_to_cpu(mpls_hdr(skb)->label_stack_entry); 627962306a36Sopenharmony_ci ttl = (lse & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT; 628062306a36Sopenharmony_ci if (!--ttl) 628162306a36Sopenharmony_ci return -EINVAL; 628262306a36Sopenharmony_ci 628362306a36Sopenharmony_ci lse &= ~MPLS_LS_TTL_MASK; 628462306a36Sopenharmony_ci lse |= ttl << MPLS_LS_TTL_SHIFT; 628562306a36Sopenharmony_ci 628662306a36Sopenharmony_ci return skb_mpls_update_lse(skb, cpu_to_be32(lse)); 628762306a36Sopenharmony_ci} 628862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(skb_mpls_dec_ttl); 628962306a36Sopenharmony_ci 629062306a36Sopenharmony_ci/** 629162306a36Sopenharmony_ci * alloc_skb_with_frags - allocate skb with page frags 629262306a36Sopenharmony_ci * 629362306a36Sopenharmony_ci * @header_len: size of linear part 629462306a36Sopenharmony_ci * @data_len: needed length in frags 629562306a36Sopenharmony_ci * @order: max page order desired. 629662306a36Sopenharmony_ci * @errcode: pointer to error code if any 629762306a36Sopenharmony_ci * @gfp_mask: allocation mask 629862306a36Sopenharmony_ci * 629962306a36Sopenharmony_ci * This can be used to allocate a paged skb, given a maximal order for frags. 630062306a36Sopenharmony_ci */ 630162306a36Sopenharmony_cistruct sk_buff *alloc_skb_with_frags(unsigned long header_len, 630262306a36Sopenharmony_ci unsigned long data_len, 630362306a36Sopenharmony_ci int order, 630462306a36Sopenharmony_ci int *errcode, 630562306a36Sopenharmony_ci gfp_t gfp_mask) 630662306a36Sopenharmony_ci{ 630762306a36Sopenharmony_ci unsigned long chunk; 630862306a36Sopenharmony_ci struct sk_buff *skb; 630962306a36Sopenharmony_ci struct page *page; 631062306a36Sopenharmony_ci int nr_frags = 0; 631162306a36Sopenharmony_ci 631262306a36Sopenharmony_ci *errcode = -EMSGSIZE; 631362306a36Sopenharmony_ci if (unlikely(data_len > MAX_SKB_FRAGS * (PAGE_SIZE << order))) 631462306a36Sopenharmony_ci return NULL; 631562306a36Sopenharmony_ci 631662306a36Sopenharmony_ci *errcode = -ENOBUFS; 631762306a36Sopenharmony_ci skb = alloc_skb(header_len, gfp_mask); 631862306a36Sopenharmony_ci if (!skb) 631962306a36Sopenharmony_ci return NULL; 632062306a36Sopenharmony_ci 632162306a36Sopenharmony_ci while (data_len) { 632262306a36Sopenharmony_ci if (nr_frags == MAX_SKB_FRAGS - 1) 632362306a36Sopenharmony_ci goto failure; 632462306a36Sopenharmony_ci while (order && PAGE_ALIGN(data_len) < (PAGE_SIZE << order)) 632562306a36Sopenharmony_ci order--; 632662306a36Sopenharmony_ci 632762306a36Sopenharmony_ci if (order) { 632862306a36Sopenharmony_ci page = alloc_pages((gfp_mask & ~__GFP_DIRECT_RECLAIM) | 632962306a36Sopenharmony_ci __GFP_COMP | 633062306a36Sopenharmony_ci __GFP_NOWARN, 633162306a36Sopenharmony_ci order); 633262306a36Sopenharmony_ci if (!page) { 633362306a36Sopenharmony_ci order--; 633462306a36Sopenharmony_ci continue; 633562306a36Sopenharmony_ci } 633662306a36Sopenharmony_ci } else { 633762306a36Sopenharmony_ci page = alloc_page(gfp_mask); 633862306a36Sopenharmony_ci if (!page) 633962306a36Sopenharmony_ci goto failure; 634062306a36Sopenharmony_ci } 634162306a36Sopenharmony_ci chunk = min_t(unsigned long, data_len, 634262306a36Sopenharmony_ci PAGE_SIZE << order); 634362306a36Sopenharmony_ci skb_fill_page_desc(skb, nr_frags, page, 0, chunk); 634462306a36Sopenharmony_ci nr_frags++; 634562306a36Sopenharmony_ci skb->truesize += (PAGE_SIZE << order); 634662306a36Sopenharmony_ci data_len -= chunk; 634762306a36Sopenharmony_ci } 634862306a36Sopenharmony_ci return skb; 634962306a36Sopenharmony_ci 635062306a36Sopenharmony_cifailure: 635162306a36Sopenharmony_ci kfree_skb(skb); 635262306a36Sopenharmony_ci return NULL; 635362306a36Sopenharmony_ci} 635462306a36Sopenharmony_ciEXPORT_SYMBOL(alloc_skb_with_frags); 635562306a36Sopenharmony_ci 635662306a36Sopenharmony_ci/* carve out the first off bytes from skb when off < headlen */ 635762306a36Sopenharmony_cistatic int pskb_carve_inside_header(struct sk_buff *skb, const u32 off, 635862306a36Sopenharmony_ci const int headlen, gfp_t gfp_mask) 635962306a36Sopenharmony_ci{ 636062306a36Sopenharmony_ci int i; 636162306a36Sopenharmony_ci unsigned int size = skb_end_offset(skb); 636262306a36Sopenharmony_ci int new_hlen = headlen - off; 636362306a36Sopenharmony_ci u8 *data; 636462306a36Sopenharmony_ci 636562306a36Sopenharmony_ci if (skb_pfmemalloc(skb)) 636662306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 636762306a36Sopenharmony_ci 636862306a36Sopenharmony_ci data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); 636962306a36Sopenharmony_ci if (!data) 637062306a36Sopenharmony_ci return -ENOMEM; 637162306a36Sopenharmony_ci size = SKB_WITH_OVERHEAD(size); 637262306a36Sopenharmony_ci 637362306a36Sopenharmony_ci /* Copy real data, and all frags */ 637462306a36Sopenharmony_ci skb_copy_from_linear_data_offset(skb, off, data, new_hlen); 637562306a36Sopenharmony_ci skb->len -= off; 637662306a36Sopenharmony_ci 637762306a36Sopenharmony_ci memcpy((struct skb_shared_info *)(data + size), 637862306a36Sopenharmony_ci skb_shinfo(skb), 637962306a36Sopenharmony_ci offsetof(struct skb_shared_info, 638062306a36Sopenharmony_ci frags[skb_shinfo(skb)->nr_frags])); 638162306a36Sopenharmony_ci if (skb_cloned(skb)) { 638262306a36Sopenharmony_ci /* drop the old head gracefully */ 638362306a36Sopenharmony_ci if (skb_orphan_frags(skb, gfp_mask)) { 638462306a36Sopenharmony_ci skb_kfree_head(data, size); 638562306a36Sopenharmony_ci return -ENOMEM; 638662306a36Sopenharmony_ci } 638762306a36Sopenharmony_ci for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 638862306a36Sopenharmony_ci skb_frag_ref(skb, i); 638962306a36Sopenharmony_ci if (skb_has_frag_list(skb)) 639062306a36Sopenharmony_ci skb_clone_fraglist(skb); 639162306a36Sopenharmony_ci skb_release_data(skb, SKB_CONSUMED, false); 639262306a36Sopenharmony_ci } else { 639362306a36Sopenharmony_ci /* we can reuse existing recount- all we did was 639462306a36Sopenharmony_ci * relocate values 639562306a36Sopenharmony_ci */ 639662306a36Sopenharmony_ci skb_free_head(skb, false); 639762306a36Sopenharmony_ci } 639862306a36Sopenharmony_ci 639962306a36Sopenharmony_ci skb->head = data; 640062306a36Sopenharmony_ci skb->data = data; 640162306a36Sopenharmony_ci skb->head_frag = 0; 640262306a36Sopenharmony_ci skb_set_end_offset(skb, size); 640362306a36Sopenharmony_ci skb_set_tail_pointer(skb, skb_headlen(skb)); 640462306a36Sopenharmony_ci skb_headers_offset_update(skb, 0); 640562306a36Sopenharmony_ci skb->cloned = 0; 640662306a36Sopenharmony_ci skb->hdr_len = 0; 640762306a36Sopenharmony_ci skb->nohdr = 0; 640862306a36Sopenharmony_ci atomic_set(&skb_shinfo(skb)->dataref, 1); 640962306a36Sopenharmony_ci 641062306a36Sopenharmony_ci return 0; 641162306a36Sopenharmony_ci} 641262306a36Sopenharmony_ci 641362306a36Sopenharmony_cistatic int pskb_carve(struct sk_buff *skb, const u32 off, gfp_t gfp); 641462306a36Sopenharmony_ci 641562306a36Sopenharmony_ci/* carve out the first eat bytes from skb's frag_list. May recurse into 641662306a36Sopenharmony_ci * pskb_carve() 641762306a36Sopenharmony_ci */ 641862306a36Sopenharmony_cistatic int pskb_carve_frag_list(struct sk_buff *skb, 641962306a36Sopenharmony_ci struct skb_shared_info *shinfo, int eat, 642062306a36Sopenharmony_ci gfp_t gfp_mask) 642162306a36Sopenharmony_ci{ 642262306a36Sopenharmony_ci struct sk_buff *list = shinfo->frag_list; 642362306a36Sopenharmony_ci struct sk_buff *clone = NULL; 642462306a36Sopenharmony_ci struct sk_buff *insp = NULL; 642562306a36Sopenharmony_ci 642662306a36Sopenharmony_ci do { 642762306a36Sopenharmony_ci if (!list) { 642862306a36Sopenharmony_ci pr_err("Not enough bytes to eat. Want %d\n", eat); 642962306a36Sopenharmony_ci return -EFAULT; 643062306a36Sopenharmony_ci } 643162306a36Sopenharmony_ci if (list->len <= eat) { 643262306a36Sopenharmony_ci /* Eaten as whole. */ 643362306a36Sopenharmony_ci eat -= list->len; 643462306a36Sopenharmony_ci list = list->next; 643562306a36Sopenharmony_ci insp = list; 643662306a36Sopenharmony_ci } else { 643762306a36Sopenharmony_ci /* Eaten partially. */ 643862306a36Sopenharmony_ci if (skb_shared(list)) { 643962306a36Sopenharmony_ci clone = skb_clone(list, gfp_mask); 644062306a36Sopenharmony_ci if (!clone) 644162306a36Sopenharmony_ci return -ENOMEM; 644262306a36Sopenharmony_ci insp = list->next; 644362306a36Sopenharmony_ci list = clone; 644462306a36Sopenharmony_ci } else { 644562306a36Sopenharmony_ci /* This may be pulled without problems. */ 644662306a36Sopenharmony_ci insp = list; 644762306a36Sopenharmony_ci } 644862306a36Sopenharmony_ci if (pskb_carve(list, eat, gfp_mask) < 0) { 644962306a36Sopenharmony_ci kfree_skb(clone); 645062306a36Sopenharmony_ci return -ENOMEM; 645162306a36Sopenharmony_ci } 645262306a36Sopenharmony_ci break; 645362306a36Sopenharmony_ci } 645462306a36Sopenharmony_ci } while (eat); 645562306a36Sopenharmony_ci 645662306a36Sopenharmony_ci /* Free pulled out fragments. */ 645762306a36Sopenharmony_ci while ((list = shinfo->frag_list) != insp) { 645862306a36Sopenharmony_ci shinfo->frag_list = list->next; 645962306a36Sopenharmony_ci consume_skb(list); 646062306a36Sopenharmony_ci } 646162306a36Sopenharmony_ci /* And insert new clone at head. */ 646262306a36Sopenharmony_ci if (clone) { 646362306a36Sopenharmony_ci clone->next = list; 646462306a36Sopenharmony_ci shinfo->frag_list = clone; 646562306a36Sopenharmony_ci } 646662306a36Sopenharmony_ci return 0; 646762306a36Sopenharmony_ci} 646862306a36Sopenharmony_ci 646962306a36Sopenharmony_ci/* carve off first len bytes from skb. Split line (off) is in the 647062306a36Sopenharmony_ci * non-linear part of skb 647162306a36Sopenharmony_ci */ 647262306a36Sopenharmony_cistatic int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off, 647362306a36Sopenharmony_ci int pos, gfp_t gfp_mask) 647462306a36Sopenharmony_ci{ 647562306a36Sopenharmony_ci int i, k = 0; 647662306a36Sopenharmony_ci unsigned int size = skb_end_offset(skb); 647762306a36Sopenharmony_ci u8 *data; 647862306a36Sopenharmony_ci const int nfrags = skb_shinfo(skb)->nr_frags; 647962306a36Sopenharmony_ci struct skb_shared_info *shinfo; 648062306a36Sopenharmony_ci 648162306a36Sopenharmony_ci if (skb_pfmemalloc(skb)) 648262306a36Sopenharmony_ci gfp_mask |= __GFP_MEMALLOC; 648362306a36Sopenharmony_ci 648462306a36Sopenharmony_ci data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); 648562306a36Sopenharmony_ci if (!data) 648662306a36Sopenharmony_ci return -ENOMEM; 648762306a36Sopenharmony_ci size = SKB_WITH_OVERHEAD(size); 648862306a36Sopenharmony_ci 648962306a36Sopenharmony_ci memcpy((struct skb_shared_info *)(data + size), 649062306a36Sopenharmony_ci skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0])); 649162306a36Sopenharmony_ci if (skb_orphan_frags(skb, gfp_mask)) { 649262306a36Sopenharmony_ci skb_kfree_head(data, size); 649362306a36Sopenharmony_ci return -ENOMEM; 649462306a36Sopenharmony_ci } 649562306a36Sopenharmony_ci shinfo = (struct skb_shared_info *)(data + size); 649662306a36Sopenharmony_ci for (i = 0; i < nfrags; i++) { 649762306a36Sopenharmony_ci int fsize = skb_frag_size(&skb_shinfo(skb)->frags[i]); 649862306a36Sopenharmony_ci 649962306a36Sopenharmony_ci if (pos + fsize > off) { 650062306a36Sopenharmony_ci shinfo->frags[k] = skb_shinfo(skb)->frags[i]; 650162306a36Sopenharmony_ci 650262306a36Sopenharmony_ci if (pos < off) { 650362306a36Sopenharmony_ci /* Split frag. 650462306a36Sopenharmony_ci * We have two variants in this case: 650562306a36Sopenharmony_ci * 1. Move all the frag to the second 650662306a36Sopenharmony_ci * part, if it is possible. F.e. 650762306a36Sopenharmony_ci * this approach is mandatory for TUX, 650862306a36Sopenharmony_ci * where splitting is expensive. 650962306a36Sopenharmony_ci * 2. Split is accurately. We make this. 651062306a36Sopenharmony_ci */ 651162306a36Sopenharmony_ci skb_frag_off_add(&shinfo->frags[0], off - pos); 651262306a36Sopenharmony_ci skb_frag_size_sub(&shinfo->frags[0], off - pos); 651362306a36Sopenharmony_ci } 651462306a36Sopenharmony_ci skb_frag_ref(skb, i); 651562306a36Sopenharmony_ci k++; 651662306a36Sopenharmony_ci } 651762306a36Sopenharmony_ci pos += fsize; 651862306a36Sopenharmony_ci } 651962306a36Sopenharmony_ci shinfo->nr_frags = k; 652062306a36Sopenharmony_ci if (skb_has_frag_list(skb)) 652162306a36Sopenharmony_ci skb_clone_fraglist(skb); 652262306a36Sopenharmony_ci 652362306a36Sopenharmony_ci /* split line is in frag list */ 652462306a36Sopenharmony_ci if (k == 0 && pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask)) { 652562306a36Sopenharmony_ci /* skb_frag_unref() is not needed here as shinfo->nr_frags = 0. */ 652662306a36Sopenharmony_ci if (skb_has_frag_list(skb)) 652762306a36Sopenharmony_ci kfree_skb_list(skb_shinfo(skb)->frag_list); 652862306a36Sopenharmony_ci skb_kfree_head(data, size); 652962306a36Sopenharmony_ci return -ENOMEM; 653062306a36Sopenharmony_ci } 653162306a36Sopenharmony_ci skb_release_data(skb, SKB_CONSUMED, false); 653262306a36Sopenharmony_ci 653362306a36Sopenharmony_ci skb->head = data; 653462306a36Sopenharmony_ci skb->head_frag = 0; 653562306a36Sopenharmony_ci skb->data = data; 653662306a36Sopenharmony_ci skb_set_end_offset(skb, size); 653762306a36Sopenharmony_ci skb_reset_tail_pointer(skb); 653862306a36Sopenharmony_ci skb_headers_offset_update(skb, 0); 653962306a36Sopenharmony_ci skb->cloned = 0; 654062306a36Sopenharmony_ci skb->hdr_len = 0; 654162306a36Sopenharmony_ci skb->nohdr = 0; 654262306a36Sopenharmony_ci skb->len -= off; 654362306a36Sopenharmony_ci skb->data_len = skb->len; 654462306a36Sopenharmony_ci atomic_set(&skb_shinfo(skb)->dataref, 1); 654562306a36Sopenharmony_ci return 0; 654662306a36Sopenharmony_ci} 654762306a36Sopenharmony_ci 654862306a36Sopenharmony_ci/* remove len bytes from the beginning of the skb */ 654962306a36Sopenharmony_cistatic int pskb_carve(struct sk_buff *skb, const u32 len, gfp_t gfp) 655062306a36Sopenharmony_ci{ 655162306a36Sopenharmony_ci int headlen = skb_headlen(skb); 655262306a36Sopenharmony_ci 655362306a36Sopenharmony_ci if (len < headlen) 655462306a36Sopenharmony_ci return pskb_carve_inside_header(skb, len, headlen, gfp); 655562306a36Sopenharmony_ci else 655662306a36Sopenharmony_ci return pskb_carve_inside_nonlinear(skb, len, headlen, gfp); 655762306a36Sopenharmony_ci} 655862306a36Sopenharmony_ci 655962306a36Sopenharmony_ci/* Extract to_copy bytes starting at off from skb, and return this in 656062306a36Sopenharmony_ci * a new skb 656162306a36Sopenharmony_ci */ 656262306a36Sopenharmony_cistruct sk_buff *pskb_extract(struct sk_buff *skb, int off, 656362306a36Sopenharmony_ci int to_copy, gfp_t gfp) 656462306a36Sopenharmony_ci{ 656562306a36Sopenharmony_ci struct sk_buff *clone = skb_clone(skb, gfp); 656662306a36Sopenharmony_ci 656762306a36Sopenharmony_ci if (!clone) 656862306a36Sopenharmony_ci return NULL; 656962306a36Sopenharmony_ci 657062306a36Sopenharmony_ci if (pskb_carve(clone, off, gfp) < 0 || 657162306a36Sopenharmony_ci pskb_trim(clone, to_copy)) { 657262306a36Sopenharmony_ci kfree_skb(clone); 657362306a36Sopenharmony_ci return NULL; 657462306a36Sopenharmony_ci } 657562306a36Sopenharmony_ci return clone; 657662306a36Sopenharmony_ci} 657762306a36Sopenharmony_ciEXPORT_SYMBOL(pskb_extract); 657862306a36Sopenharmony_ci 657962306a36Sopenharmony_ci/** 658062306a36Sopenharmony_ci * skb_condense - try to get rid of fragments/frag_list if possible 658162306a36Sopenharmony_ci * @skb: buffer 658262306a36Sopenharmony_ci * 658362306a36Sopenharmony_ci * Can be used to save memory before skb is added to a busy queue. 658462306a36Sopenharmony_ci * If packet has bytes in frags and enough tail room in skb->head, 658562306a36Sopenharmony_ci * pull all of them, so that we can free the frags right now and adjust 658662306a36Sopenharmony_ci * truesize. 658762306a36Sopenharmony_ci * Notes: 658862306a36Sopenharmony_ci * We do not reallocate skb->head thus can not fail. 658962306a36Sopenharmony_ci * Caller must re-evaluate skb->truesize if needed. 659062306a36Sopenharmony_ci */ 659162306a36Sopenharmony_civoid skb_condense(struct sk_buff *skb) 659262306a36Sopenharmony_ci{ 659362306a36Sopenharmony_ci if (skb->data_len) { 659462306a36Sopenharmony_ci if (skb->data_len > skb->end - skb->tail || 659562306a36Sopenharmony_ci skb_cloned(skb)) 659662306a36Sopenharmony_ci return; 659762306a36Sopenharmony_ci 659862306a36Sopenharmony_ci /* Nice, we can free page frag(s) right now */ 659962306a36Sopenharmony_ci __pskb_pull_tail(skb, skb->data_len); 660062306a36Sopenharmony_ci } 660162306a36Sopenharmony_ci /* At this point, skb->truesize might be over estimated, 660262306a36Sopenharmony_ci * because skb had a fragment, and fragments do not tell 660362306a36Sopenharmony_ci * their truesize. 660462306a36Sopenharmony_ci * When we pulled its content into skb->head, fragment 660562306a36Sopenharmony_ci * was freed, but __pskb_pull_tail() could not possibly 660662306a36Sopenharmony_ci * adjust skb->truesize, not knowing the frag truesize. 660762306a36Sopenharmony_ci */ 660862306a36Sopenharmony_ci skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); 660962306a36Sopenharmony_ci} 661062306a36Sopenharmony_ciEXPORT_SYMBOL(skb_condense); 661162306a36Sopenharmony_ci 661262306a36Sopenharmony_ci#ifdef CONFIG_SKB_EXTENSIONS 661362306a36Sopenharmony_cistatic void *skb_ext_get_ptr(struct skb_ext *ext, enum skb_ext_id id) 661462306a36Sopenharmony_ci{ 661562306a36Sopenharmony_ci return (void *)ext + (ext->offset[id] * SKB_EXT_ALIGN_VALUE); 661662306a36Sopenharmony_ci} 661762306a36Sopenharmony_ci 661862306a36Sopenharmony_ci/** 661962306a36Sopenharmony_ci * __skb_ext_alloc - allocate a new skb extensions storage 662062306a36Sopenharmony_ci * 662162306a36Sopenharmony_ci * @flags: See kmalloc(). 662262306a36Sopenharmony_ci * 662362306a36Sopenharmony_ci * Returns the newly allocated pointer. The pointer can later attached to a 662462306a36Sopenharmony_ci * skb via __skb_ext_set(). 662562306a36Sopenharmony_ci * Note: caller must handle the skb_ext as an opaque data. 662662306a36Sopenharmony_ci */ 662762306a36Sopenharmony_cistruct skb_ext *__skb_ext_alloc(gfp_t flags) 662862306a36Sopenharmony_ci{ 662962306a36Sopenharmony_ci struct skb_ext *new = kmem_cache_alloc(skbuff_ext_cache, flags); 663062306a36Sopenharmony_ci 663162306a36Sopenharmony_ci if (new) { 663262306a36Sopenharmony_ci memset(new->offset, 0, sizeof(new->offset)); 663362306a36Sopenharmony_ci refcount_set(&new->refcnt, 1); 663462306a36Sopenharmony_ci } 663562306a36Sopenharmony_ci 663662306a36Sopenharmony_ci return new; 663762306a36Sopenharmony_ci} 663862306a36Sopenharmony_ci 663962306a36Sopenharmony_cistatic struct skb_ext *skb_ext_maybe_cow(struct skb_ext *old, 664062306a36Sopenharmony_ci unsigned int old_active) 664162306a36Sopenharmony_ci{ 664262306a36Sopenharmony_ci struct skb_ext *new; 664362306a36Sopenharmony_ci 664462306a36Sopenharmony_ci if (refcount_read(&old->refcnt) == 1) 664562306a36Sopenharmony_ci return old; 664662306a36Sopenharmony_ci 664762306a36Sopenharmony_ci new = kmem_cache_alloc(skbuff_ext_cache, GFP_ATOMIC); 664862306a36Sopenharmony_ci if (!new) 664962306a36Sopenharmony_ci return NULL; 665062306a36Sopenharmony_ci 665162306a36Sopenharmony_ci memcpy(new, old, old->chunks * SKB_EXT_ALIGN_VALUE); 665262306a36Sopenharmony_ci refcount_set(&new->refcnt, 1); 665362306a36Sopenharmony_ci 665462306a36Sopenharmony_ci#ifdef CONFIG_XFRM 665562306a36Sopenharmony_ci if (old_active & (1 << SKB_EXT_SEC_PATH)) { 665662306a36Sopenharmony_ci struct sec_path *sp = skb_ext_get_ptr(old, SKB_EXT_SEC_PATH); 665762306a36Sopenharmony_ci unsigned int i; 665862306a36Sopenharmony_ci 665962306a36Sopenharmony_ci for (i = 0; i < sp->len; i++) 666062306a36Sopenharmony_ci xfrm_state_hold(sp->xvec[i]); 666162306a36Sopenharmony_ci } 666262306a36Sopenharmony_ci#endif 666362306a36Sopenharmony_ci#ifdef CONFIG_MCTP_FLOWS 666462306a36Sopenharmony_ci if (old_active & (1 << SKB_EXT_MCTP)) { 666562306a36Sopenharmony_ci struct mctp_flow *flow = skb_ext_get_ptr(old, SKB_EXT_MCTP); 666662306a36Sopenharmony_ci 666762306a36Sopenharmony_ci if (flow->key) 666862306a36Sopenharmony_ci refcount_inc(&flow->key->refs); 666962306a36Sopenharmony_ci } 667062306a36Sopenharmony_ci#endif 667162306a36Sopenharmony_ci __skb_ext_put(old); 667262306a36Sopenharmony_ci return new; 667362306a36Sopenharmony_ci} 667462306a36Sopenharmony_ci 667562306a36Sopenharmony_ci/** 667662306a36Sopenharmony_ci * __skb_ext_set - attach the specified extension storage to this skb 667762306a36Sopenharmony_ci * @skb: buffer 667862306a36Sopenharmony_ci * @id: extension id 667962306a36Sopenharmony_ci * @ext: extension storage previously allocated via __skb_ext_alloc() 668062306a36Sopenharmony_ci * 668162306a36Sopenharmony_ci * Existing extensions, if any, are cleared. 668262306a36Sopenharmony_ci * 668362306a36Sopenharmony_ci * Returns the pointer to the extension. 668462306a36Sopenharmony_ci */ 668562306a36Sopenharmony_civoid *__skb_ext_set(struct sk_buff *skb, enum skb_ext_id id, 668662306a36Sopenharmony_ci struct skb_ext *ext) 668762306a36Sopenharmony_ci{ 668862306a36Sopenharmony_ci unsigned int newlen, newoff = SKB_EXT_CHUNKSIZEOF(*ext); 668962306a36Sopenharmony_ci 669062306a36Sopenharmony_ci skb_ext_put(skb); 669162306a36Sopenharmony_ci newlen = newoff + skb_ext_type_len[id]; 669262306a36Sopenharmony_ci ext->chunks = newlen; 669362306a36Sopenharmony_ci ext->offset[id] = newoff; 669462306a36Sopenharmony_ci skb->extensions = ext; 669562306a36Sopenharmony_ci skb->active_extensions = 1 << id; 669662306a36Sopenharmony_ci return skb_ext_get_ptr(ext, id); 669762306a36Sopenharmony_ci} 669862306a36Sopenharmony_ci 669962306a36Sopenharmony_ci/** 670062306a36Sopenharmony_ci * skb_ext_add - allocate space for given extension, COW if needed 670162306a36Sopenharmony_ci * @skb: buffer 670262306a36Sopenharmony_ci * @id: extension to allocate space for 670362306a36Sopenharmony_ci * 670462306a36Sopenharmony_ci * Allocates enough space for the given extension. 670562306a36Sopenharmony_ci * If the extension is already present, a pointer to that extension 670662306a36Sopenharmony_ci * is returned. 670762306a36Sopenharmony_ci * 670862306a36Sopenharmony_ci * If the skb was cloned, COW applies and the returned memory can be 670962306a36Sopenharmony_ci * modified without changing the extension space of clones buffers. 671062306a36Sopenharmony_ci * 671162306a36Sopenharmony_ci * Returns pointer to the extension or NULL on allocation failure. 671262306a36Sopenharmony_ci */ 671362306a36Sopenharmony_civoid *skb_ext_add(struct sk_buff *skb, enum skb_ext_id id) 671462306a36Sopenharmony_ci{ 671562306a36Sopenharmony_ci struct skb_ext *new, *old = NULL; 671662306a36Sopenharmony_ci unsigned int newlen, newoff; 671762306a36Sopenharmony_ci 671862306a36Sopenharmony_ci if (skb->active_extensions) { 671962306a36Sopenharmony_ci old = skb->extensions; 672062306a36Sopenharmony_ci 672162306a36Sopenharmony_ci new = skb_ext_maybe_cow(old, skb->active_extensions); 672262306a36Sopenharmony_ci if (!new) 672362306a36Sopenharmony_ci return NULL; 672462306a36Sopenharmony_ci 672562306a36Sopenharmony_ci if (__skb_ext_exist(new, id)) 672662306a36Sopenharmony_ci goto set_active; 672762306a36Sopenharmony_ci 672862306a36Sopenharmony_ci newoff = new->chunks; 672962306a36Sopenharmony_ci } else { 673062306a36Sopenharmony_ci newoff = SKB_EXT_CHUNKSIZEOF(*new); 673162306a36Sopenharmony_ci 673262306a36Sopenharmony_ci new = __skb_ext_alloc(GFP_ATOMIC); 673362306a36Sopenharmony_ci if (!new) 673462306a36Sopenharmony_ci return NULL; 673562306a36Sopenharmony_ci } 673662306a36Sopenharmony_ci 673762306a36Sopenharmony_ci newlen = newoff + skb_ext_type_len[id]; 673862306a36Sopenharmony_ci new->chunks = newlen; 673962306a36Sopenharmony_ci new->offset[id] = newoff; 674062306a36Sopenharmony_ciset_active: 674162306a36Sopenharmony_ci skb->slow_gro = 1; 674262306a36Sopenharmony_ci skb->extensions = new; 674362306a36Sopenharmony_ci skb->active_extensions |= 1 << id; 674462306a36Sopenharmony_ci return skb_ext_get_ptr(new, id); 674562306a36Sopenharmony_ci} 674662306a36Sopenharmony_ciEXPORT_SYMBOL(skb_ext_add); 674762306a36Sopenharmony_ci 674862306a36Sopenharmony_ci#ifdef CONFIG_XFRM 674962306a36Sopenharmony_cistatic void skb_ext_put_sp(struct sec_path *sp) 675062306a36Sopenharmony_ci{ 675162306a36Sopenharmony_ci unsigned int i; 675262306a36Sopenharmony_ci 675362306a36Sopenharmony_ci for (i = 0; i < sp->len; i++) 675462306a36Sopenharmony_ci xfrm_state_put(sp->xvec[i]); 675562306a36Sopenharmony_ci} 675662306a36Sopenharmony_ci#endif 675762306a36Sopenharmony_ci 675862306a36Sopenharmony_ci#ifdef CONFIG_MCTP_FLOWS 675962306a36Sopenharmony_cistatic void skb_ext_put_mctp(struct mctp_flow *flow) 676062306a36Sopenharmony_ci{ 676162306a36Sopenharmony_ci if (flow->key) 676262306a36Sopenharmony_ci mctp_key_unref(flow->key); 676362306a36Sopenharmony_ci} 676462306a36Sopenharmony_ci#endif 676562306a36Sopenharmony_ci 676662306a36Sopenharmony_civoid __skb_ext_del(struct sk_buff *skb, enum skb_ext_id id) 676762306a36Sopenharmony_ci{ 676862306a36Sopenharmony_ci struct skb_ext *ext = skb->extensions; 676962306a36Sopenharmony_ci 677062306a36Sopenharmony_ci skb->active_extensions &= ~(1 << id); 677162306a36Sopenharmony_ci if (skb->active_extensions == 0) { 677262306a36Sopenharmony_ci skb->extensions = NULL; 677362306a36Sopenharmony_ci __skb_ext_put(ext); 677462306a36Sopenharmony_ci#ifdef CONFIG_XFRM 677562306a36Sopenharmony_ci } else if (id == SKB_EXT_SEC_PATH && 677662306a36Sopenharmony_ci refcount_read(&ext->refcnt) == 1) { 677762306a36Sopenharmony_ci struct sec_path *sp = skb_ext_get_ptr(ext, SKB_EXT_SEC_PATH); 677862306a36Sopenharmony_ci 677962306a36Sopenharmony_ci skb_ext_put_sp(sp); 678062306a36Sopenharmony_ci sp->len = 0; 678162306a36Sopenharmony_ci#endif 678262306a36Sopenharmony_ci } 678362306a36Sopenharmony_ci} 678462306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_ext_del); 678562306a36Sopenharmony_ci 678662306a36Sopenharmony_civoid __skb_ext_put(struct skb_ext *ext) 678762306a36Sopenharmony_ci{ 678862306a36Sopenharmony_ci /* If this is last clone, nothing can increment 678962306a36Sopenharmony_ci * it after check passes. Avoids one atomic op. 679062306a36Sopenharmony_ci */ 679162306a36Sopenharmony_ci if (refcount_read(&ext->refcnt) == 1) 679262306a36Sopenharmony_ci goto free_now; 679362306a36Sopenharmony_ci 679462306a36Sopenharmony_ci if (!refcount_dec_and_test(&ext->refcnt)) 679562306a36Sopenharmony_ci return; 679662306a36Sopenharmony_cifree_now: 679762306a36Sopenharmony_ci#ifdef CONFIG_XFRM 679862306a36Sopenharmony_ci if (__skb_ext_exist(ext, SKB_EXT_SEC_PATH)) 679962306a36Sopenharmony_ci skb_ext_put_sp(skb_ext_get_ptr(ext, SKB_EXT_SEC_PATH)); 680062306a36Sopenharmony_ci#endif 680162306a36Sopenharmony_ci#ifdef CONFIG_MCTP_FLOWS 680262306a36Sopenharmony_ci if (__skb_ext_exist(ext, SKB_EXT_MCTP)) 680362306a36Sopenharmony_ci skb_ext_put_mctp(skb_ext_get_ptr(ext, SKB_EXT_MCTP)); 680462306a36Sopenharmony_ci#endif 680562306a36Sopenharmony_ci 680662306a36Sopenharmony_ci kmem_cache_free(skbuff_ext_cache, ext); 680762306a36Sopenharmony_ci} 680862306a36Sopenharmony_ciEXPORT_SYMBOL(__skb_ext_put); 680962306a36Sopenharmony_ci#endif /* CONFIG_SKB_EXTENSIONS */ 681062306a36Sopenharmony_ci 681162306a36Sopenharmony_ci/** 681262306a36Sopenharmony_ci * skb_attempt_defer_free - queue skb for remote freeing 681362306a36Sopenharmony_ci * @skb: buffer 681462306a36Sopenharmony_ci * 681562306a36Sopenharmony_ci * Put @skb in a per-cpu list, using the cpu which 681662306a36Sopenharmony_ci * allocated the skb/pages to reduce false sharing 681762306a36Sopenharmony_ci * and memory zone spinlock contention. 681862306a36Sopenharmony_ci */ 681962306a36Sopenharmony_civoid skb_attempt_defer_free(struct sk_buff *skb) 682062306a36Sopenharmony_ci{ 682162306a36Sopenharmony_ci int cpu = skb->alloc_cpu; 682262306a36Sopenharmony_ci struct softnet_data *sd; 682362306a36Sopenharmony_ci unsigned int defer_max; 682462306a36Sopenharmony_ci bool kick; 682562306a36Sopenharmony_ci 682662306a36Sopenharmony_ci if (WARN_ON_ONCE(cpu >= nr_cpu_ids) || 682762306a36Sopenharmony_ci !cpu_online(cpu) || 682862306a36Sopenharmony_ci cpu == raw_smp_processor_id()) { 682962306a36Sopenharmony_cinodefer: __kfree_skb(skb); 683062306a36Sopenharmony_ci return; 683162306a36Sopenharmony_ci } 683262306a36Sopenharmony_ci 683362306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); 683462306a36Sopenharmony_ci DEBUG_NET_WARN_ON_ONCE(skb->destructor); 683562306a36Sopenharmony_ci 683662306a36Sopenharmony_ci sd = &per_cpu(softnet_data, cpu); 683762306a36Sopenharmony_ci defer_max = READ_ONCE(sysctl_skb_defer_max); 683862306a36Sopenharmony_ci if (READ_ONCE(sd->defer_count) >= defer_max) 683962306a36Sopenharmony_ci goto nodefer; 684062306a36Sopenharmony_ci 684162306a36Sopenharmony_ci spin_lock_bh(&sd->defer_lock); 684262306a36Sopenharmony_ci /* Send an IPI every time queue reaches half capacity. */ 684362306a36Sopenharmony_ci kick = sd->defer_count == (defer_max >> 1); 684462306a36Sopenharmony_ci /* Paired with the READ_ONCE() few lines above */ 684562306a36Sopenharmony_ci WRITE_ONCE(sd->defer_count, sd->defer_count + 1); 684662306a36Sopenharmony_ci 684762306a36Sopenharmony_ci skb->next = sd->defer_list; 684862306a36Sopenharmony_ci /* Paired with READ_ONCE() in skb_defer_free_flush() */ 684962306a36Sopenharmony_ci WRITE_ONCE(sd->defer_list, skb); 685062306a36Sopenharmony_ci spin_unlock_bh(&sd->defer_lock); 685162306a36Sopenharmony_ci 685262306a36Sopenharmony_ci /* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU 685362306a36Sopenharmony_ci * if we are unlucky enough (this seems very unlikely). 685462306a36Sopenharmony_ci */ 685562306a36Sopenharmony_ci if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) 685662306a36Sopenharmony_ci smp_call_function_single_async(cpu, &sd->defer_csd); 685762306a36Sopenharmony_ci} 685862306a36Sopenharmony_ci 685962306a36Sopenharmony_cistatic void skb_splice_csum_page(struct sk_buff *skb, struct page *page, 686062306a36Sopenharmony_ci size_t offset, size_t len) 686162306a36Sopenharmony_ci{ 686262306a36Sopenharmony_ci const char *kaddr; 686362306a36Sopenharmony_ci __wsum csum; 686462306a36Sopenharmony_ci 686562306a36Sopenharmony_ci kaddr = kmap_local_page(page); 686662306a36Sopenharmony_ci csum = csum_partial(kaddr + offset, len, 0); 686762306a36Sopenharmony_ci kunmap_local(kaddr); 686862306a36Sopenharmony_ci skb->csum = csum_block_add(skb->csum, csum, skb->len); 686962306a36Sopenharmony_ci} 687062306a36Sopenharmony_ci 687162306a36Sopenharmony_ci/** 687262306a36Sopenharmony_ci * skb_splice_from_iter - Splice (or copy) pages to skbuff 687362306a36Sopenharmony_ci * @skb: The buffer to add pages to 687462306a36Sopenharmony_ci * @iter: Iterator representing the pages to be added 687562306a36Sopenharmony_ci * @maxsize: Maximum amount of pages to be added 687662306a36Sopenharmony_ci * @gfp: Allocation flags 687762306a36Sopenharmony_ci * 687862306a36Sopenharmony_ci * This is a common helper function for supporting MSG_SPLICE_PAGES. It 687962306a36Sopenharmony_ci * extracts pages from an iterator and adds them to the socket buffer if 688062306a36Sopenharmony_ci * possible, copying them to fragments if not possible (such as if they're slab 688162306a36Sopenharmony_ci * pages). 688262306a36Sopenharmony_ci * 688362306a36Sopenharmony_ci * Returns the amount of data spliced/copied or -EMSGSIZE if there's 688462306a36Sopenharmony_ci * insufficient space in the buffer to transfer anything. 688562306a36Sopenharmony_ci */ 688662306a36Sopenharmony_cissize_t skb_splice_from_iter(struct sk_buff *skb, struct iov_iter *iter, 688762306a36Sopenharmony_ci ssize_t maxsize, gfp_t gfp) 688862306a36Sopenharmony_ci{ 688962306a36Sopenharmony_ci size_t frag_limit = READ_ONCE(sysctl_max_skb_frags); 689062306a36Sopenharmony_ci struct page *pages[8], **ppages = pages; 689162306a36Sopenharmony_ci ssize_t spliced = 0, ret = 0; 689262306a36Sopenharmony_ci unsigned int i; 689362306a36Sopenharmony_ci 689462306a36Sopenharmony_ci while (iter->count > 0) { 689562306a36Sopenharmony_ci ssize_t space, nr, len; 689662306a36Sopenharmony_ci size_t off; 689762306a36Sopenharmony_ci 689862306a36Sopenharmony_ci ret = -EMSGSIZE; 689962306a36Sopenharmony_ci space = frag_limit - skb_shinfo(skb)->nr_frags; 690062306a36Sopenharmony_ci if (space < 0) 690162306a36Sopenharmony_ci break; 690262306a36Sopenharmony_ci 690362306a36Sopenharmony_ci /* We might be able to coalesce without increasing nr_frags */ 690462306a36Sopenharmony_ci nr = clamp_t(size_t, space, 1, ARRAY_SIZE(pages)); 690562306a36Sopenharmony_ci 690662306a36Sopenharmony_ci len = iov_iter_extract_pages(iter, &ppages, maxsize, nr, 0, &off); 690762306a36Sopenharmony_ci if (len <= 0) { 690862306a36Sopenharmony_ci ret = len ?: -EIO; 690962306a36Sopenharmony_ci break; 691062306a36Sopenharmony_ci } 691162306a36Sopenharmony_ci 691262306a36Sopenharmony_ci i = 0; 691362306a36Sopenharmony_ci do { 691462306a36Sopenharmony_ci struct page *page = pages[i++]; 691562306a36Sopenharmony_ci size_t part = min_t(size_t, PAGE_SIZE - off, len); 691662306a36Sopenharmony_ci 691762306a36Sopenharmony_ci ret = -EIO; 691862306a36Sopenharmony_ci if (WARN_ON_ONCE(!sendpage_ok(page))) 691962306a36Sopenharmony_ci goto out; 692062306a36Sopenharmony_ci 692162306a36Sopenharmony_ci ret = skb_append_pagefrags(skb, page, off, part, 692262306a36Sopenharmony_ci frag_limit); 692362306a36Sopenharmony_ci if (ret < 0) { 692462306a36Sopenharmony_ci iov_iter_revert(iter, len); 692562306a36Sopenharmony_ci goto out; 692662306a36Sopenharmony_ci } 692762306a36Sopenharmony_ci 692862306a36Sopenharmony_ci if (skb->ip_summed == CHECKSUM_NONE) 692962306a36Sopenharmony_ci skb_splice_csum_page(skb, page, off, part); 693062306a36Sopenharmony_ci 693162306a36Sopenharmony_ci off = 0; 693262306a36Sopenharmony_ci spliced += part; 693362306a36Sopenharmony_ci maxsize -= part; 693462306a36Sopenharmony_ci len -= part; 693562306a36Sopenharmony_ci } while (len > 0); 693662306a36Sopenharmony_ci 693762306a36Sopenharmony_ci if (maxsize <= 0) 693862306a36Sopenharmony_ci break; 693962306a36Sopenharmony_ci } 694062306a36Sopenharmony_ci 694162306a36Sopenharmony_ciout: 694262306a36Sopenharmony_ci skb_len_add(skb, spliced); 694362306a36Sopenharmony_ci return spliced ?: ret; 694462306a36Sopenharmony_ci} 694562306a36Sopenharmony_ciEXPORT_SYMBOL(skb_splice_from_iter); 6946