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