diff options
Diffstat (limited to 'net/core/skbuff.c')
| -rw-r--r-- | net/core/skbuff.c | 1966 | 
1 files changed, 1426 insertions, 540 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8814a9a52f4..c1a33033cbe 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -36,6 +36,8 @@   *	The functions in this file will not compile correctly with gcc 2.4.x   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/module.h>  #include <linux/types.h>  #include <linux/kernel.h> @@ -45,6 +47,8 @@  #include <linux/in.h>  #include <linux/inet.h>  #include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/udp.h>  #include <linux/netdevice.h>  #ifdef CONFIG_NET_CLS_ACT  #include <net/pkt_sched.h> @@ -57,93 +61,89 @@  #include <linux/init.h>  #include <linux/scatterlist.h>  #include <linux/errqueue.h> +#include <linux/prefetch.h>  #include <net/protocol.h>  #include <net/dst.h>  #include <net/sock.h>  #include <net/checksum.h> +#include <net/ip6_checksum.h>  #include <net/xfrm.h>  #include <asm/uaccess.h> -#include <asm/system.h>  #include <trace/events/skb.h> +#include <linux/highmem.h> -#include "kmap_skb.h" - -static struct kmem_cache *skbuff_head_cache __read_mostly; +struct kmem_cache *skbuff_head_cache __read_mostly;  static struct kmem_cache *skbuff_fclone_cache __read_mostly; -static void sock_pipe_buf_release(struct pipe_inode_info *pipe, -				  struct pipe_buffer *buf) +/** + *	skb_panic - private function for out-of-line support + *	@skb:	buffer + *	@sz:	size + *	@addr:	address + *	@msg:	skb_over_panic or skb_under_panic + * + *	Out-of-line support for skb_put() and skb_push(). + *	Called via the wrapper skb_over_panic() or skb_under_panic(). + *	Keep out of line to prevent kernel bloat. + *	__builtin_return_address is not used because it is not always reliable. + */ +static void skb_panic(struct sk_buff *skb, unsigned int sz, void *addr, +		      const char msg[])  { -	put_page(buf->page); +	pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", +		 msg, addr, skb->len, sz, skb->head, skb->data, +		 (unsigned long)skb->tail, (unsigned long)skb->end, +		 skb->dev ? skb->dev->name : "<NULL>"); +	BUG();  } -static void sock_pipe_buf_get(struct pipe_inode_info *pipe, -				struct pipe_buffer *buf) +static void skb_over_panic(struct sk_buff *skb, unsigned int sz, void *addr)  { -	get_page(buf->page); +	skb_panic(skb, sz, addr, __func__);  } -static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, -			       struct pipe_buffer *buf) +static void skb_under_panic(struct sk_buff *skb, unsigned int sz, void *addr)  { -	return 1; +	skb_panic(skb, sz, addr, __func__);  } - -/* Pipe buffer operations for a socket. */ -static const struct pipe_buf_operations sock_pipe_buf_ops = { -	.can_merge = 0, -	.map = generic_pipe_buf_map, -	.unmap = generic_pipe_buf_unmap, -	.confirm = generic_pipe_buf_confirm, -	.release = sock_pipe_buf_release, -	.steal = sock_pipe_buf_steal, -	.get = sock_pipe_buf_get, -}; -  /* - *	Keep out-of-line to prevent kernel bloat. - *	__builtin_return_address is not used because it is not always - *	reliable. + * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tells + * the caller if emergency pfmemalloc reserves are being used. If it is and + * the socket is later found to be SOCK_MEMALLOC then PFMEMALLOC reserves + * may be used. Otherwise, the packet data may be discarded until enough + * memory is free   */ +#define kmalloc_reserve(size, gfp, node, pfmemalloc) \ +	 __kmalloc_reserve(size, gfp, node, _RET_IP_, pfmemalloc) -/** - *	skb_over_panic	- 	private function - *	@skb: buffer - *	@sz: size - *	@here: address - * - *	Out of line support code for skb_put(). Not user callable. - */ -static void skb_over_panic(struct sk_buff *skb, int sz, void *here) +static void *__kmalloc_reserve(size_t size, gfp_t flags, int node, +			       unsigned long ip, bool *pfmemalloc)  { -	printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p " -			  "data:%p tail:%#lx end:%#lx dev:%s\n", -	       here, skb->len, sz, skb->head, skb->data, -	       (unsigned long)skb->tail, (unsigned long)skb->end, -	       skb->dev ? skb->dev->name : "<NULL>"); -	BUG(); -} +	void *obj; +	bool ret_pfmemalloc = false; -/** - *	skb_under_panic	- 	private function - *	@skb: buffer - *	@sz: size - *	@here: address - * - *	Out of line support code for skb_push(). Not user callable. - */ +	/* +	 * Try a regular allocation, when that fails and we're not entitled +	 * to the reserves, fail. +	 */ +	obj = kmalloc_node_track_caller(size, +					flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +					node); +	if (obj || !(gfp_pfmemalloc_allowed(flags))) +		goto out; -static void skb_under_panic(struct sk_buff *skb, int sz, void *here) -{ -	printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p " -			  "data:%p tail:%#lx end:%#lx dev:%s\n", -	       here, skb->len, sz, skb->head, skb->data, -	       (unsigned long)skb->tail, (unsigned long)skb->end, -	       skb->dev ? skb->dev->name : "<NULL>"); -	BUG(); +	/* Try again but now we are using pfmemalloc reserves */ +	ret_pfmemalloc = true; +	obj = kmalloc_node_track_caller(size, flags, node); + +out: +	if (pfmemalloc) +		*pfmemalloc = ret_pfmemalloc; + +	return obj;  }  /* 	Allocate a new skbuff. We do this ourselves so we can fill in a few @@ -152,30 +152,62 @@ static void skb_under_panic(struct sk_buff *skb, int sz, void *here)   *   */ +struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) +{ +	struct sk_buff *skb; + +	/* Get the HEAD */ +	skb = kmem_cache_alloc_node(skbuff_head_cache, +				    gfp_mask & ~__GFP_DMA, node); +	if (!skb) +		goto out; + +	/* +	 * Only clear those fields we need to clear, not those that we will +	 * actually initialise below. Hence, don't put any more fields after +	 * the tail pointer in struct sk_buff! +	 */ +	memset(skb, 0, offsetof(struct sk_buff, tail)); +	skb->head = NULL; +	skb->truesize = sizeof(struct sk_buff); +	atomic_set(&skb->users, 1); + +	skb->mac_header = (typeof(skb->mac_header))~0U; +out: +	return skb; +} +  /**   *	__alloc_skb	-	allocate a network buffer   *	@size: size to allocate   *	@gfp_mask: allocation mask - *	@fclone: allocate from fclone cache instead of head cache - *		and allocate a cloned (child) skb + *	@flags: If SKB_ALLOC_FCLONE is set, allocate from fclone cache + *		instead of head cache and allocate a cloned (child) skb. + *		If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for + *		allocations in case the data is required for writeback   *	@node: numa node to allocate memory on   *   *	Allocate a new &sk_buff. The returned buffer has no headroom and a - *	tail room of size bytes. The object has a reference count of one. - *	The return is the buffer. On a failure the return is %NULL. + *	tail room of at least size bytes. The object has a reference count + *	of one. The return is the buffer. On a failure the return is %NULL.   *   *	Buffers may only be allocated from interrupts using a @gfp_mask of   *	%GFP_ATOMIC.   */  struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, -			    int fclone, int node) +			    int flags, int node)  {  	struct kmem_cache *cache;  	struct skb_shared_info *shinfo;  	struct sk_buff *skb;  	u8 *data; +	bool pfmemalloc; + +	cache = (flags & SKB_ALLOC_FCLONE) +		? skbuff_fclone_cache : skbuff_head_cache; -	cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; +	if (sk_memalloc_socks() && (flags & SKB_ALLOC_RX)) +		gfp_mask |= __GFP_MEMALLOC;  	/* Get the HEAD */  	skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); @@ -183,11 +215,21 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,  		goto out;  	prefetchw(skb); +	/* We do our best to align skb_shared_info on a separate cache +	 * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives +	 * aligned memory blocks, unless SLUB/SLAB debug is enabled. +	 * Both skb->head and skb_shared_info are cache line aligned. +	 */  	size = SKB_DATA_ALIGN(size); -	data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), -			gfp_mask, node); +	size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +	data = kmalloc_reserve(size, gfp_mask, node, &pfmemalloc);  	if (!data)  		goto nodata; +	/* kmalloc(size) might give us more room than requested. +	 * Put skb_shared_info exactly at the end of allocated zone, +	 * to allow max possible filling before reallocation. +	 */ +	size = SKB_WITH_OVERHEAD(ksize(data));  	prefetchw(data + size);  	/* @@ -196,22 +238,24 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,  	 * the tail pointer in struct sk_buff!  	 */  	memset(skb, 0, offsetof(struct sk_buff, tail)); -	skb->truesize = size + sizeof(struct sk_buff); +	/* Account for allocated memory : skb + skb->head */ +	skb->truesize = SKB_TRUESIZE(size); +	skb->pfmemalloc = pfmemalloc;  	atomic_set(&skb->users, 1);  	skb->head = data;  	skb->data = data;  	skb_reset_tail_pointer(skb);  	skb->end = skb->tail + size; -#ifdef NET_SKBUFF_DATA_USES_OFFSET -	skb->mac_header = ~0U; -#endif +	skb->mac_header = (typeof(skb->mac_header))~0U; +	skb->transport_header = (typeof(skb->transport_header))~0U;  	/* make sure we initialize shinfo sequentially */  	shinfo = skb_shinfo(skb);  	memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));  	atomic_set(&shinfo->dataref, 1); +	kmemcheck_annotate_variable(shinfo->destructor_arg); -	if (fclone) { +	if (flags & SKB_ALLOC_FCLONE) {  		struct sk_buff *child = skb + 1;  		atomic_t *fclone_ref = (atomic_t *) (child + 1); @@ -221,6 +265,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,  		atomic_set(fclone_ref, 1);  		child->fclone = SKB_FCLONE_UNAVAILABLE; +		child->pfmemalloc = pfmemalloc;  	}  out:  	return skb; @@ -232,6 +277,124 @@ nodata:  EXPORT_SYMBOL(__alloc_skb);  /** + * build_skb - build a network buffer + * @data: data buffer provided by caller + * @frag_size: size of fragment, or 0 if head was kmalloced + * + * Allocate a new &sk_buff. Caller provides space holding head and + * skb_shared_info. @data must have been allocated by kmalloc() only if + * @frag_size is 0, otherwise data should come from the page allocator. + * The return is the new skb buffer. + * On a failure the return is %NULL, and @data is not freed. + * Notes : + *  Before IO, driver allocates only data buffer where NIC put incoming frame + *  Driver should add room at head (NET_SKB_PAD) and + *  MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info)) + *  After IO, driver calls build_skb(), to allocate sk_buff and populate it + *  before giving packet to stack. + *  RX rings only contains data buffers, not full skbs. + */ +struct sk_buff *build_skb(void *data, unsigned int frag_size) +{ +	struct skb_shared_info *shinfo; +	struct sk_buff *skb; +	unsigned int size = frag_size ? : ksize(data); + +	skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC); +	if (!skb) +		return NULL; + +	size -= SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + +	memset(skb, 0, offsetof(struct sk_buff, tail)); +	skb->truesize = SKB_TRUESIZE(size); +	skb->head_frag = frag_size != 0; +	atomic_set(&skb->users, 1); +	skb->head = data; +	skb->data = data; +	skb_reset_tail_pointer(skb); +	skb->end = skb->tail + size; +	skb->mac_header = (typeof(skb->mac_header))~0U; +	skb->transport_header = (typeof(skb->transport_header))~0U; + +	/* make sure we initialize shinfo sequentially */ +	shinfo = skb_shinfo(skb); +	memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); +	atomic_set(&shinfo->dataref, 1); +	kmemcheck_annotate_variable(shinfo->destructor_arg); + +	return skb; +} +EXPORT_SYMBOL(build_skb); + +struct netdev_alloc_cache { +	struct page_frag	frag; +	/* we maintain a pagecount bias, so that we dont dirty cache line +	 * containing page->_count every time we allocate a fragment. +	 */ +	unsigned int		pagecnt_bias; +}; +static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); + +static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) +{ +	struct netdev_alloc_cache *nc; +	void *data = NULL; +	int order; +	unsigned long flags; + +	local_irq_save(flags); +	nc = &__get_cpu_var(netdev_alloc_cache); +	if (unlikely(!nc->frag.page)) { +refill: +		for (order = NETDEV_FRAG_PAGE_MAX_ORDER; ;) { +			gfp_t gfp = gfp_mask; + +			if (order) +				gfp |= __GFP_COMP | __GFP_NOWARN; +			nc->frag.page = alloc_pages(gfp, order); +			if (likely(nc->frag.page)) +				break; +			if (--order < 0) +				goto end; +		} +		nc->frag.size = PAGE_SIZE << order; +recycle: +		atomic_set(&nc->frag.page->_count, NETDEV_PAGECNT_MAX_BIAS); +		nc->pagecnt_bias = NETDEV_PAGECNT_MAX_BIAS; +		nc->frag.offset = 0; +	} + +	if (nc->frag.offset + fragsz > nc->frag.size) { +		/* avoid unnecessary locked operations if possible */ +		if ((atomic_read(&nc->frag.page->_count) == nc->pagecnt_bias) || +		    atomic_sub_and_test(nc->pagecnt_bias, &nc->frag.page->_count)) +			goto recycle; +		goto refill; +	} + +	data = page_address(nc->frag.page) + nc->frag.offset; +	nc->frag.offset += fragsz; +	nc->pagecnt_bias--; +end: +	local_irq_restore(flags); +	return data; +} + +/** + * netdev_alloc_frag - allocate a page fragment + * @fragsz: fragment size + * + * Allocates a frag from a page for receive buffer. + * Uses GFP_ATOMIC allocations. + */ +void *netdev_alloc_frag(unsigned int fragsz) +{ +	return __netdev_alloc_frag(fragsz, GFP_ATOMIC | __GFP_COLD); +} +EXPORT_SYMBOL(netdev_alloc_frag); + +/**   *	__netdev_alloc_skb - allocate an skbuff for rx on a specific device   *	@dev: network device to receive on   *	@length: length to allocate @@ -245,11 +408,29 @@ EXPORT_SYMBOL(__alloc_skb);   *	%NULL is returned if there is no free memory.   */  struct sk_buff *__netdev_alloc_skb(struct net_device *dev, -		unsigned int length, gfp_t gfp_mask) +				   unsigned int length, gfp_t gfp_mask)  { -	struct sk_buff *skb; +	struct sk_buff *skb = NULL; +	unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + +			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -	skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); +	if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) { +		void *data; + +		if (sk_memalloc_socks()) +			gfp_mask |= __GFP_MEMALLOC; + +		data = __netdev_alloc_frag(fragsz, gfp_mask); + +		if (likely(data)) { +			skb = build_skb(data, fragsz); +			if (unlikely(!skb)) +				put_page(virt_to_head_page(data)); +		} +	} else { +		skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, +				  SKB_ALLOC_RX, NUMA_NO_NODE); +	}  	if (likely(skb)) {  		skb_reserve(skb, NET_SKB_PAD);  		skb->dev = dev; @@ -259,48 +440,31 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,  EXPORT_SYMBOL(__netdev_alloc_skb);  void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, -		int size) +		     int size, unsigned int truesize)  {  	skb_fill_page_desc(skb, i, page, off, size);  	skb->len += size;  	skb->data_len += size; -	skb->truesize += size; +	skb->truesize += truesize;  }  EXPORT_SYMBOL(skb_add_rx_frag); -/** - *	dev_alloc_skb - allocate an skbuff for receiving - *	@length: length to allocate - * - *	Allocate a new &sk_buff and assign it a usage count of one. The - *	buffer has unspecified headroom built in. Users should allocate - *	the headroom they think they need without accounting for the - *	built in space. The built in space is used for optimisations. - * - *	%NULL is returned if there is no free memory. Although this function - *	allocates memory it can be called from an interrupt. - */ -struct sk_buff *dev_alloc_skb(unsigned int length) +void skb_coalesce_rx_frag(struct sk_buff *skb, int i, int size, +			  unsigned int truesize)  { -	/* -	 * There is more code here than it seems: -	 * __dev_alloc_skb is an inline -	 */ -	return __dev_alloc_skb(length, GFP_ATOMIC); +	skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + +	skb_frag_size_add(frag, size); +	skb->len += size; +	skb->data_len += size; +	skb->truesize += truesize;  } -EXPORT_SYMBOL(dev_alloc_skb); +EXPORT_SYMBOL(skb_coalesce_rx_frag);  static void skb_drop_list(struct sk_buff **listp)  { -	struct sk_buff *list = *listp; - +	kfree_skb_list(*listp);  	*listp = NULL; - -	do { -		struct sk_buff *this = list; -		list = list->next; -		kfree_skb(this); -	} while (list);  }  static inline void skb_drop_fraglist(struct sk_buff *skb) @@ -316,6 +480,14 @@ static void skb_clone_fraglist(struct sk_buff *skb)  		skb_get(list);  } +static void skb_free_head(struct sk_buff *skb) +{ +	if (skb->head_frag) +		put_page(virt_to_head_page(skb->head)); +	else +		kfree(skb->head); +} +  static void skb_release_data(struct sk_buff *skb)  {  	if (!skb->cloned || @@ -324,13 +496,25 @@ static void skb_release_data(struct sk_buff *skb)  		if (skb_shinfo(skb)->nr_frags) {  			int i;  			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -				put_page(skb_shinfo(skb)->frags[i].page); +				skb_frag_unref(skb, i); +		} + +		/* +		 * If skb buf is from userspace, we need to notify the caller +		 * the lower device DMA has done; +		 */ +		if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { +			struct ubuf_info *uarg; + +			uarg = skb_shinfo(skb)->destructor_arg; +			if (uarg->callback) +				uarg->callback(uarg, true);  		}  		if (skb_has_frag_list(skb))  			skb_drop_fraglist(skb); -		kfree(skb->head); +		skb_free_head(skb);  	}  } @@ -378,9 +562,8 @@ static void skb_release_head_state(struct sk_buff *skb)  		WARN_ON(in_irq());  		skb->destructor(skb);  	} -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +#if IS_ENABLED(CONFIG_NF_CONNTRACK)  	nf_conntrack_put(skb->nfct); -	nf_conntrack_put_reasm(skb->nfct_reasm);  #endif  #ifdef CONFIG_BRIDGE_NETFILTER  	nf_bridge_put(skb->nf_bridge); @@ -398,7 +581,8 @@ static void skb_release_head_state(struct sk_buff *skb)  static void skb_release_all(struct sk_buff *skb)  {  	skb_release_head_state(skb); -	skb_release_data(skb); +	if (likely(skb->head)) +		skb_release_data(skb);  }  /** @@ -437,6 +621,37 @@ void kfree_skb(struct sk_buff *skb)  }  EXPORT_SYMBOL(kfree_skb); +void kfree_skb_list(struct sk_buff *segs) +{ +	while (segs) { +		struct sk_buff *next = segs->next; + +		kfree_skb(segs); +		segs = next; +	} +} +EXPORT_SYMBOL(kfree_skb_list); + +/** + *	skb_tx_error - report an sk_buff xmit error + *	@skb: buffer that triggered an error + * + *	Report xmit error if a device callback is tracking this skb. + *	skb must be freed afterwards. + */ +void skb_tx_error(struct sk_buff *skb) +{ +	if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { +		struct ubuf_info *uarg; + +		uarg = skb_shinfo(skb)->destructor_arg; +		if (uarg->callback) +			uarg->callback(uarg, false); +		skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; +	} +} +EXPORT_SYMBOL(skb_tx_error); +  /**   *	consume_skb - free an skbuff   *	@skb: buffer to free @@ -458,49 +673,6 @@ void consume_skb(struct sk_buff *skb)  }  EXPORT_SYMBOL(consume_skb); -/** - *	skb_recycle_check - check if skb can be reused for receive - *	@skb: buffer - *	@skb_size: minimum receive buffer size - * - *	Checks that the skb passed in is not shared or cloned, and - *	that it is linear and its head portion at least as large as - *	skb_size so that it can be recycled as a receive buffer. - *	If these conditions are met, this function does any necessary - *	reference count dropping and cleans up the skbuff as if it - *	just came from __alloc_skb(). - */ -bool skb_recycle_check(struct sk_buff *skb, int skb_size) -{ -	struct skb_shared_info *shinfo; - -	if (irqs_disabled()) -		return false; - -	if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) -		return false; - -	skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD); -	if (skb_end_pointer(skb) - skb->head < skb_size) -		return false; - -	if (skb_shared(skb) || skb_cloned(skb)) -		return false; - -	skb_release_head_state(skb); - -	shinfo = skb_shinfo(skb); -	memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); -	atomic_set(&shinfo->dataref, 1); - -	memset(skb, 0, offsetof(struct sk_buff, tail)); -	skb->data = skb->head + NET_SKB_PAD; -	skb_reset_tail_pointer(skb); - -	return true; -} -EXPORT_SYMBOL(skb_recycle_check); -  static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)  {  	new->tstamp		= old->tstamp; @@ -508,39 +680,50 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)  	new->transport_header	= old->transport_header;  	new->network_header	= old->network_header;  	new->mac_header		= old->mac_header; +	new->inner_protocol	= old->inner_protocol; +	new->inner_transport_header = old->inner_transport_header; +	new->inner_network_header = old->inner_network_header; +	new->inner_mac_header = old->inner_mac_header;  	skb_dst_copy(new, old); -	new->rxhash		= old->rxhash; +	skb_copy_hash(new, old); +	new->ooo_okay		= old->ooo_okay; +	new->no_fcs		= old->no_fcs; +	new->encapsulation	= old->encapsulation; +	new->encap_hdr_csum	= old->encap_hdr_csum; +	new->csum_valid		= old->csum_valid; +	new->csum_complete_sw	= old->csum_complete_sw;  #ifdef CONFIG_XFRM  	new->sp			= secpath_get(old->sp);  #endif  	memcpy(new->cb, old->cb, sizeof(old->cb));  	new->csum		= old->csum; -	new->local_df		= old->local_df; +	new->ignore_df		= old->ignore_df;  	new->pkt_type		= old->pkt_type;  	new->ip_summed		= old->ip_summed;  	skb_copy_queue_mapping(new, old);  	new->priority		= old->priority; -	new->deliver_no_wcard	= old->deliver_no_wcard; -#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) +#if IS_ENABLED(CONFIG_IP_VS)  	new->ipvs_property	= old->ipvs_property;  #endif +	new->pfmemalloc		= old->pfmemalloc;  	new->protocol		= old->protocol;  	new->mark		= old->mark;  	new->skb_iif		= old->skb_iif;  	__nf_copy(new, old); -#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ -    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) -	new->nf_trace		= old->nf_trace; -#endif  #ifdef CONFIG_NET_SCHED  	new->tc_index		= old->tc_index;  #ifdef CONFIG_NET_CLS_ACT  	new->tc_verd		= old->tc_verd;  #endif  #endif +	new->vlan_proto		= old->vlan_proto;  	new->vlan_tci		= old->vlan_tci;  	skb_copy_secmark(new, old); + +#ifdef CONFIG_NET_RX_BUSY_POLL +	new->napi_id	= old->napi_id; +#endif  }  /* @@ -565,6 +748,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)  	C(tail);  	C(end);  	C(head); +	C(head_frag);  	C(data);  	C(truesize);  	atomic_set(&n->users, 1); @@ -594,6 +778,67 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)  EXPORT_SYMBOL_GPL(skb_morph);  /** + *	skb_copy_ubufs	-	copy userspace skb frags buffers to kernel + *	@skb: the skb to modify + *	@gfp_mask: allocation priority + * + *	This must be called on SKBTX_DEV_ZEROCOPY skb. + *	It will copy all frags into kernel and drop the reference + *	to userspace pages. + * + *	If this function is called from an interrupt gfp_mask() must be + *	%GFP_ATOMIC. + * + *	Returns 0 on success or a negative error code on failure + *	to allocate kernel memory to copy to. + */ +int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) +{ +	int i; +	int num_frags = skb_shinfo(skb)->nr_frags; +	struct page *page, *head = NULL; +	struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg; + +	for (i = 0; i < num_frags; i++) { +		u8 *vaddr; +		skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + +		page = alloc_page(gfp_mask); +		if (!page) { +			while (head) { +				struct page *next = (struct page *)page_private(head); +				put_page(head); +				head = next; +			} +			return -ENOMEM; +		} +		vaddr = kmap_atomic(skb_frag_page(f)); +		memcpy(page_address(page), +		       vaddr + f->page_offset, skb_frag_size(f)); +		kunmap_atomic(vaddr); +		set_page_private(page, (unsigned long)head); +		head = page; +	} + +	/* skb frags release userspace buffers */ +	for (i = 0; i < num_frags; i++) +		skb_frag_unref(skb, i); + +	uarg->callback(uarg, false); + +	/* skb frags point to kernel buffers */ +	for (i = num_frags - 1; i >= 0; i--) { +		__skb_fill_page_desc(skb, i, head, 0, +				     skb_shinfo(skb)->frags[i].size); +		head = (struct page *)page_private(head); +	} + +	skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; +	return 0; +} +EXPORT_SYMBOL_GPL(skb_copy_ubufs); + +/**   *	skb_clone	-	duplicate an sk_buff   *	@skb: buffer to clone   *	@gfp_mask: allocation priority @@ -611,6 +856,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)  {  	struct sk_buff *n; +	if (skb_orphan_frags(skb, gfp_mask)) +		return NULL; +  	n = skb + 1;  	if (skb->fclone == SKB_FCLONE_ORIG &&  	    n->fclone == SKB_FCLONE_UNAVAILABLE) { @@ -618,6 +866,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)  		n->fclone = SKB_FCLONE_CLONE;  		atomic_inc(fclone_ref);  	} else { +		if (skb_pfmemalloc(skb)) +			gfp_mask |= __GFP_MEMALLOC; +  		n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);  		if (!n)  			return NULL; @@ -631,29 +882,37 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)  }  EXPORT_SYMBOL(skb_clone); -static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) +static void skb_headers_offset_update(struct sk_buff *skb, int off)  { -#ifndef NET_SKBUFF_DATA_USES_OFFSET -	/* -	 *	Shift between the two data areas in bytes -	 */ -	unsigned long offset = new->data - old->data; -#endif +	/* Only adjust this if it actually is csum_start rather than csum */ +	if (skb->ip_summed == CHECKSUM_PARTIAL) +		skb->csum_start += off; +	/* {transport,network,mac}_header and tail are relative to skb->head */ +	skb->transport_header += off; +	skb->network_header   += off; +	if (skb_mac_header_was_set(skb)) +		skb->mac_header += off; +	skb->inner_transport_header += off; +	skb->inner_network_header += off; +	skb->inner_mac_header += off; +} +static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) +{  	__copy_skb_header(new, old); -#ifndef NET_SKBUFF_DATA_USES_OFFSET -	/* {transport,network,mac}_header are relative to skb->head */ -	new->transport_header += offset; -	new->network_header   += offset; -	if (skb_mac_header_was_set(new)) -		new->mac_header	      += offset; -#endif  	skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;  	skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;  	skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;  } +static inline int skb_alloc_rx_flag(const struct sk_buff *skb) +{ +	if (skb_pfmemalloc(skb)) +		return SKB_ALLOC_RX; +	return 0; +} +  /**   *	skb_copy	-	create private copy of an sk_buff   *	@skb: buffer to copy @@ -674,8 +933,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)  struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)  {  	int headerlen = skb_headroom(skb); -	unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len; -	struct sk_buff *n = alloc_skb(size, gfp_mask); +	unsigned int size = skb_end_offset(skb) + skb->data_len; +	struct sk_buff *n = __alloc_skb(size, gfp_mask, +					skb_alloc_rx_flag(skb), NUMA_NO_NODE);  	if (!n)  		return NULL; @@ -694,9 +954,13 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)  EXPORT_SYMBOL(skb_copy);  /** - *	pskb_copy	-	create copy of an sk_buff with private head. + *	__pskb_copy_fclone	-  create copy of an sk_buff with private head.   *	@skb: buffer to copy + *	@headroom: headroom of new skb   *	@gfp_mask: allocation priority + *	@fclone: if true allocate the copy of the skb from the fclone + *	cache instead of the head cache; it is recommended to set this + *	to true for the cases where the copy will likely be cloned   *   *	Make a copy of both an &sk_buff and part of its data, located   *	in header. Fragmented data remain shared. This is used when @@ -706,16 +970,18 @@ EXPORT_SYMBOL(skb_copy);   *	The returned buffer has a reference count of 1.   */ -struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) +struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom, +				   gfp_t gfp_mask, bool fclone)  { -	unsigned int size = skb_end_pointer(skb) - skb->head; -	struct sk_buff *n = alloc_skb(size, gfp_mask); +	unsigned int size = skb_headlen(skb) + headroom; +	int flags = skb_alloc_rx_flag(skb) | (fclone ? SKB_ALLOC_FCLONE : 0); +	struct sk_buff *n = __alloc_skb(size, gfp_mask, flags, NUMA_NO_NODE);  	if (!n)  		goto out;  	/* Set the data pointer */ -	skb_reserve(n, skb_headroom(skb)); +	skb_reserve(n, headroom);  	/* Set the tail pointer and length */  	skb_put(n, skb_headlen(skb));  	/* Copy the bytes */ @@ -728,9 +994,14 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)  	if (skb_shinfo(skb)->nr_frags) {  		int i; +		if (skb_orphan_frags(skb, gfp_mask)) { +			kfree_skb(n); +			n = NULL; +			goto out; +		}  		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {  			skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; -			get_page(skb_shinfo(n)->frags[i].page); +			skb_frag_ref(skb, i);  		}  		skb_shinfo(n)->nr_frags = i;  	} @@ -744,7 +1015,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)  out:  	return n;  } -EXPORT_SYMBOL(pskb_copy); +EXPORT_SYMBOL(__pskb_copy_fclone);  /**   *	pskb_expand_head - reallocate header of &sk_buff @@ -753,8 +1024,8 @@ EXPORT_SYMBOL(pskb_copy);   *	@ntail: room to add at tail   *	@gfp_mask: allocation priority   * - *	Expands (or creates identical copy, if &nhead and &ntail are zero) - *	header of skb. &sk_buff itself is not changed. &sk_buff MUST have + *	Expands (or creates identical copy, if @nhead and @ntail are zero) + *	header of @skb. &sk_buff itself is not changed. &sk_buff MUST have   *	reference count of 1. Returns zero in the case of success or error,   *	if expansion failed. In the last case, &sk_buff is not changed.   * @@ -767,9 +1038,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,  {  	int i;  	u8 *data; -	int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail; +	int size = nhead + skb_end_offset(skb) + ntail;  	long off; -	bool fastpath;  	BUG_ON(nhead < 0); @@ -778,31 +1048,13 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,  	size = SKB_DATA_ALIGN(size); -	/* Check if we can avoid taking references on fragments if we own -	 * the last reference on skb->head. (see skb_release_data()) -	 */ -	if (!skb->cloned) -		fastpath = true; -	else { -		int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; - -		fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; -	} - -	if (fastpath && -	    size + sizeof(struct skb_shared_info) <= ksize(skb->head)) { -		memmove(skb->head + size, skb_shinfo(skb), -			offsetof(struct skb_shared_info, -				 frags[skb_shinfo(skb)->nr_frags])); -		memmove(skb->head + nhead, skb->head, -			skb_tail_pointer(skb) - skb->head); -		off = nhead; -		goto adjust_others; -	} - -	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); +	if (skb_pfmemalloc(skb)) +		gfp_mask |= __GFP_MEMALLOC; +	data = kmalloc_reserve(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), +			       gfp_mask, NUMA_NO_NODE, NULL);  	if (!data)  		goto nodata; +	size = SKB_WITH_OVERHEAD(ksize(data));  	/* Copy only real data... and, alas, header. This should be  	 * optimized for the cases when header is void. @@ -813,21 +1065,29 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,  	       skb_shinfo(skb),  	       offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); -	if (fastpath) { -		kfree(skb->head); -	} else { +	/* +	 * if shinfo is shared we must drop the old head gracefully, but if it +	 * is not we can just drop the old head and let the existing refcount +	 * be since all we did is relocate the values +	 */ +	if (skb_cloned(skb)) { +		/* copy this zero copy skb frags */ +		if (skb_orphan_frags(skb, gfp_mask)) +			goto nofrags;  		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -			get_page(skb_shinfo(skb)->frags[i].page); +			skb_frag_ref(skb, i);  		if (skb_has_frag_list(skb))  			skb_clone_fraglist(skb);  		skb_release_data(skb); +	} else { +		skb_free_head(skb);  	}  	off = (data + nhead) - skb->head;  	skb->head     = data; -adjust_others: +	skb->head_frag = 0;  	skb->data    += off;  #ifdef NET_SKBUFF_DATA_USES_OFFSET  	skb->end      = size; @@ -835,21 +1095,16 @@ adjust_others:  #else  	skb->end      = skb->head + size;  #endif -	/* {transport,network,mac}_header and tail are relative to skb->head */  	skb->tail	      += off; -	skb->transport_header += off; -	skb->network_header   += off; -	if (skb_mac_header_was_set(skb)) -		skb->mac_header += off; -	/* Only adjust this if it actually is csum_start rather than csum */ -	if (skb->ip_summed == CHECKSUM_PARTIAL) -		skb->csum_start += nhead; +	skb_headers_offset_update(skb, nhead);  	skb->cloned   = 0;  	skb->hdr_len  = 0;  	skb->nohdr    = 0;  	atomic_set(&skb_shinfo(skb)->dataref, 1);  	return 0; +nofrags: +	kfree(data);  nodata:  	return -ENOMEM;  } @@ -901,11 +1156,11 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,  	/*  	 *	Allocate the copy buffer  	 */ -	struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom, -				      gfp_mask); +	struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, +					gfp_mask, skb_alloc_rx_flag(skb), +					NUMA_NO_NODE);  	int oldheadroom = skb_headroom(skb);  	int head_copy_len, head_copy_off; -	int off;  	if (!n)  		return NULL; @@ -929,15 +1184,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,  	copy_skb_header(n, skb); -	off                  = newheadroom - oldheadroom; -	if (n->ip_summed == CHECKSUM_PARTIAL) -		n->csum_start += off; -#ifdef NET_SKBUFF_DATA_USES_OFFSET -	n->transport_header += off; -	n->network_header   += off; -	if (skb_mac_header_was_set(skb)) -		n->mac_header += off; -#endif +	skb_headers_offset_update(n, newheadroom - oldheadroom);  	return n;  } @@ -990,6 +1237,29 @@ free_skb:  EXPORT_SYMBOL(skb_pad);  /** + *	pskb_put - add data to the tail of a potentially fragmented buffer + *	@skb: start of the buffer to use + *	@tail: tail fragment of the buffer to use + *	@len: amount of data to add + * + *	This function extends the used data area of the potentially + *	fragmented buffer. @tail must be the last fragment of @skb -- or + *	@skb itself. If this would exceed the total buffer size the kernel + *	will panic. A pointer to the first byte of the extra data is + *	returned. + */ + +unsigned char *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len) +{ +	if (tail != skb) { +		skb->data_len += len; +		skb->len += len; +	} +	return skb_put(tail, len); +} +EXPORT_SYMBOL_GPL(pskb_put); + +/**   *	skb_put - add data to a buffer   *	@skb: buffer to use   *	@len: amount of data to add @@ -1082,20 +1352,20 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)  		goto drop_pages;  	for (; i < nfrags; i++) { -		int end = offset + skb_shinfo(skb)->frags[i].size; +		int end = offset + skb_frag_size(&skb_shinfo(skb)->frags[i]);  		if (end < len) {  			offset = end;  			continue;  		} -		skb_shinfo(skb)->frags[i++].size = len - offset; +		skb_frag_size_set(&skb_shinfo(skb)->frags[i++], len - offset);  drop_pages:  		skb_shinfo(skb)->nr_frags = i;  		for (; i < nfrags; i++) -			put_page(skb_shinfo(skb)->frags[i].page); +			skb_frag_unref(skb, i);  		if (skb_has_frag_list(skb))  			skb_drop_fraglist(skb); @@ -1114,7 +1384,7 @@ drop_pages:  				return -ENOMEM;  			nfrag->next = frag->next; -			kfree_skb(frag); +			consume_skb(frag);  			frag = nfrag;  			*fragp = frag;  		} @@ -1198,9 +1468,11 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)  	/* Estimate size of pulled pages. */  	eat = delta;  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -		if (skb_shinfo(skb)->frags[i].size >= eat) +		int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + +		if (size >= eat)  			goto pull_pages; -		eat -= skb_shinfo(skb)->frags[i].size; +		eat -= size;  	}  	/* If we need update frag list, we are in troubles. @@ -1263,14 +1535,16 @@ pull_pages:  	eat = delta;  	k = 0;  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -		if (skb_shinfo(skb)->frags[i].size <= eat) { -			put_page(skb_shinfo(skb)->frags[i].page); -			eat -= skb_shinfo(skb)->frags[i].size; +		int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + +		if (size <= eat) { +			skb_frag_unref(skb, i); +			eat -= size;  		} else {  			skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];  			if (eat) {  				skb_shinfo(skb)->frags[k].page_offset += eat; -				skb_shinfo(skb)->frags[k].size -= eat; +				skb_frag_size_sub(&skb_shinfo(skb)->frags[k], eat);  				eat = 0;  			}  			k++; @@ -1285,8 +1559,21 @@ pull_pages:  }  EXPORT_SYMBOL(__pskb_pull_tail); -/* Copy some data bits from skb to kernel buffer. */ - +/** + *	skb_copy_bits - copy bits from skb to kernel buffer + *	@skb: source skb + *	@offset: offset in source + *	@to: destination buffer + *	@len: number of bytes to copy + * + *	Copy the specified number of bytes from the source skb to the + *	destination buffer. + * + *	CAUTION ! : + *		If its prototype is ever changed, + *		check arch/{*}/net/{*}.S files, + *		since it is called from BPF assembly code. + */  int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)  {  	int start = skb_headlen(skb); @@ -1309,21 +1596,22 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {  		int end; +		skb_frag_t *f = &skb_shinfo(skb)->frags[i];  		WARN_ON(start > offset + len); -		end = start + skb_shinfo(skb)->frags[i].size; +		end = start + skb_frag_size(f);  		if ((copy = end - offset) > 0) {  			u8 *vaddr;  			if (copy > len)  				copy = len; -			vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); +			vaddr = kmap_atomic(skb_frag_page(f));  			memcpy(to, -			       vaddr + skb_shinfo(skb)->frags[i].page_offset+ -			       offset - start, copy); -			kunmap_skb_frag(vaddr); +			       vaddr + f->page_offset + offset - start, +			       copy); +			kunmap_atomic(vaddr);  			if ((len -= copy) == 0)  				return 0; @@ -1351,6 +1639,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)  		}  		start = end;  	} +  	if (!len)  		return 0; @@ -1368,140 +1657,122 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)  	put_page(spd->pages[i]);  } -static inline struct page *linear_to_page(struct page *page, unsigned int *len, -					  unsigned int *offset, -					  struct sk_buff *skb, struct sock *sk) +static struct page *linear_to_page(struct page *page, unsigned int *len, +				   unsigned int *offset, +				   struct sock *sk)  { -	struct page *p = sk->sk_sndmsg_page; -	unsigned int off; - -	if (!p) { -new_page: -		p = sk->sk_sndmsg_page = alloc_pages(sk->sk_allocation, 0); -		if (!p) -			return NULL; +	struct page_frag *pfrag = sk_page_frag(sk); -		off = sk->sk_sndmsg_off = 0; -		/* hold one ref to this page until it's full */ -	} else { -		unsigned int mlen; +	if (!sk_page_frag_refill(sk, pfrag)) +		return NULL; -		off = sk->sk_sndmsg_off; -		mlen = PAGE_SIZE - off; -		if (mlen < 64 && mlen < *len) { -			put_page(p); -			goto new_page; -		} +	*len = min_t(unsigned int, *len, pfrag->size - pfrag->offset); -		*len = min_t(unsigned int, *len, mlen); -	} +	memcpy(page_address(pfrag->page) + pfrag->offset, +	       page_address(page) + *offset, *len); +	*offset = pfrag->offset; +	pfrag->offset += *len; -	memcpy(page_address(p) + off, page_address(page) + *offset, *len); -	sk->sk_sndmsg_off += *len; -	*offset = off; -	get_page(p); +	return pfrag->page; +} -	return p; +static bool spd_can_coalesce(const struct splice_pipe_desc *spd, +			     struct page *page, +			     unsigned int offset) +{ +	return	spd->nr_pages && +		spd->pages[spd->nr_pages - 1] == page && +		(spd->partial[spd->nr_pages - 1].offset + +		 spd->partial[spd->nr_pages - 1].len == offset);  }  /*   * Fill page/offset/length into spd, if it can hold more pages.   */ -static inline int spd_fill_page(struct splice_pipe_desc *spd, -				struct pipe_inode_info *pipe, struct page *page, -				unsigned int *len, unsigned int offset, -				struct sk_buff *skb, int linear, -				struct sock *sk) +static bool spd_fill_page(struct splice_pipe_desc *spd, +			  struct pipe_inode_info *pipe, struct page *page, +			  unsigned int *len, unsigned int offset, +			  bool linear, +			  struct sock *sk)  { -	if (unlikely(spd->nr_pages == pipe->buffers)) -		return 1; +	if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) +		return true;  	if (linear) { -		page = linear_to_page(page, len, &offset, skb, sk); +		page = linear_to_page(page, len, &offset, sk);  		if (!page) -			return 1; -	} else -		get_page(page); - +			return true; +	} +	if (spd_can_coalesce(spd, page, offset)) { +		spd->partial[spd->nr_pages - 1].len += *len; +		return false; +	} +	get_page(page);  	spd->pages[spd->nr_pages] = page;  	spd->partial[spd->nr_pages].len = *len;  	spd->partial[spd->nr_pages].offset = offset;  	spd->nr_pages++; -	return 0; +	return false;  } -static inline void __segment_seek(struct page **page, unsigned int *poff, -				  unsigned int *plen, unsigned int off) -{ -	unsigned long n; - -	*poff += off; -	n = *poff / PAGE_SIZE; -	if (n) -		*page = nth_page(*page, n); - -	*poff = *poff % PAGE_SIZE; -	*plen -= off; -} - -static inline int __splice_segment(struct page *page, unsigned int poff, -				   unsigned int plen, unsigned int *off, -				   unsigned int *len, struct sk_buff *skb, -				   struct splice_pipe_desc *spd, int linear, -				   struct sock *sk, -				   struct pipe_inode_info *pipe) +static bool __splice_segment(struct page *page, unsigned int poff, +			     unsigned int plen, unsigned int *off, +			     unsigned int *len, +			     struct splice_pipe_desc *spd, bool linear, +			     struct sock *sk, +			     struct pipe_inode_info *pipe)  {  	if (!*len) -		return 1; +		return true;  	/* skip this segment if already processed */  	if (*off >= plen) {  		*off -= plen; -		return 0; +		return false;  	}  	/* ignore any bits we already processed */ -	if (*off) { -		__segment_seek(&page, &poff, &plen, *off); -		*off = 0; -	} +	poff += *off; +	plen -= *off; +	*off = 0;  	do {  		unsigned int flen = min(*len, plen); -		/* the linear region may spread across several pages  */ -		flen = min_t(unsigned int, flen, PAGE_SIZE - poff); - -		if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) -			return 1; - -		__segment_seek(&page, &poff, &plen, flen); +		if (spd_fill_page(spd, pipe, page, &flen, poff, +				  linear, sk)) +			return true; +		poff += flen; +		plen -= flen;  		*len -= flen; -  	} while (*len && plen); -	return 0; +	return false;  }  /* - * Map linear and fragment data from the skb to spd. It reports failure if the + * Map linear and fragment data from the skb to spd. It reports true if the   * pipe is full or if we already spliced the requested length.   */ -static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, -			     unsigned int *offset, unsigned int *len, -			     struct splice_pipe_desc *spd, struct sock *sk) +static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, +			      unsigned int *offset, unsigned int *len, +			      struct splice_pipe_desc *spd, struct sock *sk)  {  	int seg; -	/* -	 * map the linear part +	/* map the linear part : +	 * If skb->head_frag is set, this 'linear' part is backed by a +	 * fragment, and if the head is not shared with any clones then +	 * we can avoid a copy since we own the head portion of this page.  	 */  	if (__splice_segment(virt_to_page(skb->data),  			     (unsigned long) skb->data & (PAGE_SIZE - 1),  			     skb_headlen(skb), -			     offset, len, skb, spd, 1, sk, pipe)) -		return 1; +			     offset, len, spd, +			     skb_head_is_locked(skb), +			     sk, pipe)) +		return true;  	/*  	 * then map the fragments @@ -1509,12 +1780,13 @@ static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,  	for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) {  		const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; -		if (__splice_segment(f->page, f->page_offset, f->size, -				     offset, len, skb, spd, 0, sk, pipe)) -			return 1; +		if (__splice_segment(skb_frag_page(f), +				     f->page_offset, skb_frag_size(f), +				     offset, len, spd, false, sk, pipe)) +			return true;  	} -	return 0; +	return false;  }  /* @@ -1527,22 +1799,20 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,  		    struct pipe_inode_info *pipe, unsigned int tlen,  		    unsigned int flags)  { -	struct partial_page partial[PIPE_DEF_BUFFERS]; -	struct page *pages[PIPE_DEF_BUFFERS]; +	struct partial_page partial[MAX_SKB_FRAGS]; +	struct page *pages[MAX_SKB_FRAGS];  	struct splice_pipe_desc spd = {  		.pages = pages,  		.partial = partial, +		.nr_pages_max = MAX_SKB_FRAGS,  		.flags = flags, -		.ops = &sock_pipe_buf_ops, +		.ops = &nosteal_pipe_buf_ops,  		.spd_release = sock_spd_release,  	};  	struct sk_buff *frag_iter;  	struct sock *sk = skb->sk;  	int ret = 0; -	if (splice_grow_spd(pipe, &spd)) -		return -ENOMEM; -  	/*  	 * __skb_splice_bits() only fails if the output has no room left,  	 * so no point in going over the frag_list for the error case. @@ -1578,7 +1848,6 @@ done:  		lock_sock(sk);  	} -	splice_shrink_spd(pipe, &spd);  	return ret;  } @@ -1619,17 +1888,17 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len)  		WARN_ON(start > offset + len); -		end = start + frag->size; +		end = start + skb_frag_size(frag);  		if ((copy = end - offset) > 0) {  			u8 *vaddr;  			if (copy > len)  				copy = len; -			vaddr = kmap_skb_frag(frag); +			vaddr = kmap_atomic(skb_frag_page(frag));  			memcpy(vaddr + frag->page_offset + offset - start,  			       from, copy); -			kunmap_skb_frag(vaddr); +			kunmap_atomic(vaddr);  			if ((len -= copy) == 0)  				return 0; @@ -1667,9 +1936,8 @@ fault:  EXPORT_SYMBOL(skb_store_bits);  /* Checksum skb data. */ - -__wsum skb_checksum(const struct sk_buff *skb, int offset, -			  int len, __wsum csum) +__wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, +		      __wsum csum, const struct skb_checksum_ops *ops)  {  	int start = skb_headlen(skb);  	int i, copy = start - offset; @@ -1680,7 +1948,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,  	if (copy > 0) {  		if (copy > len)  			copy = len; -		csum = csum_partial(skb->data + offset, copy, csum); +		csum = ops->update(skb->data + offset, copy, csum);  		if ((len -= copy) == 0)  			return csum;  		offset += copy; @@ -1689,22 +1957,22 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {  		int end; +		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];  		WARN_ON(start > offset + len); -		end = start + skb_shinfo(skb)->frags[i].size; +		end = start + skb_frag_size(frag);  		if ((copy = end - offset) > 0) {  			__wsum csum2;  			u8 *vaddr; -			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];  			if (copy > len)  				copy = len; -			vaddr = kmap_skb_frag(frag); -			csum2 = csum_partial(vaddr + frag->page_offset + -					     offset - start, copy, 0); -			kunmap_skb_frag(vaddr); -			csum = csum_block_add(csum, csum2, pos); +			vaddr = kmap_atomic(skb_frag_page(frag)); +			csum2 = ops->update(vaddr + frag->page_offset + +					    offset - start, copy, 0); +			kunmap_atomic(vaddr); +			csum = ops->combine(csum, csum2, pos, copy);  			if (!(len -= copy))  				return csum;  			offset += copy; @@ -1723,9 +1991,9 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,  			__wsum csum2;  			if (copy > len)  				copy = len; -			csum2 = skb_checksum(frag_iter, offset - start, -					     copy, 0); -			csum = csum_block_add(csum, csum2, pos); +			csum2 = __skb_checksum(frag_iter, offset - start, +					       copy, 0, ops); +			csum = ops->combine(csum, csum2, pos, copy);  			if ((len -= copy) == 0)  				return csum;  			offset += copy; @@ -1737,6 +2005,18 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,  	return csum;  } +EXPORT_SYMBOL(__skb_checksum); + +__wsum skb_checksum(const struct sk_buff *skb, int offset, +		    int len, __wsum csum) +{ +	const struct skb_checksum_ops ops = { +		.update  = csum_partial_ext, +		.combine = csum_block_add_ext, +	}; + +	return __skb_checksum(skb, offset, len, csum, &ops); +}  EXPORT_SYMBOL(skb_checksum);  /* Both of above in one bottle. */ @@ -1767,7 +2047,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,  		WARN_ON(start > offset + len); -		end = start + skb_shinfo(skb)->frags[i].size; +		end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);  		if ((copy = end - offset) > 0) {  			__wsum csum2;  			u8 *vaddr; @@ -1775,12 +2055,12 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,  			if (copy > len)  				copy = len; -			vaddr = kmap_skb_frag(frag); +			vaddr = kmap_atomic(skb_frag_page(frag));  			csum2 = csum_partial_copy_nocheck(vaddr +  							  frag->page_offset +  							  offset - start, to,  							  copy, 0); -			kunmap_skb_frag(vaddr); +			kunmap_atomic(vaddr);  			csum = csum_block_add(csum, csum2, pos);  			if (!(len -= copy))  				return csum; @@ -1818,13 +2098,111 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,  }  EXPORT_SYMBOL(skb_copy_and_csum_bits); + /** + *	skb_zerocopy_headlen - Calculate headroom needed for skb_zerocopy() + *	@from: source buffer + * + *	Calculates the amount of linear headroom needed in the 'to' skb passed + *	into skb_zerocopy(). + */ +unsigned int +skb_zerocopy_headlen(const struct sk_buff *from) +{ +	unsigned int hlen = 0; + +	if (!from->head_frag || +	    skb_headlen(from) < L1_CACHE_BYTES || +	    skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) +		hlen = skb_headlen(from); + +	if (skb_has_frag_list(from)) +		hlen = from->len; + +	return hlen; +} +EXPORT_SYMBOL_GPL(skb_zerocopy_headlen); + +/** + *	skb_zerocopy - Zero copy skb to skb + *	@to: destination buffer + *	@from: source buffer + *	@len: number of bytes to copy from source buffer + *	@hlen: size of linear headroom in destination buffer + * + *	Copies up to `len` bytes from `from` to `to` by creating references + *	to the frags in the source buffer. + * + *	The `hlen` as calculated by skb_zerocopy_headlen() specifies the + *	headroom in the `to` buffer. + * + *	Return value: + *	0: everything is OK + *	-ENOMEM: couldn't orphan frags of @from due to lack of memory + *	-EFAULT: skb_copy_bits() found some problem with skb geometry + */ +int +skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) +{ +	int i, j = 0; +	int plen = 0; /* length of skb->head fragment */ +	int ret; +	struct page *page; +	unsigned int offset; + +	BUG_ON(!from->head_frag && !hlen); + +	/* dont bother with small payloads */ +	if (len <= skb_tailroom(to)) +		return skb_copy_bits(from, 0, skb_put(to, len), len); + +	if (hlen) { +		ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen); +		if (unlikely(ret)) +			return ret; +		len -= hlen; +	} else { +		plen = min_t(int, skb_headlen(from), len); +		if (plen) { +			page = virt_to_head_page(from->head); +			offset = from->data - (unsigned char *)page_address(page); +			__skb_fill_page_desc(to, 0, page, offset, plen); +			get_page(page); +			j = 1; +			len -= plen; +		} +	} + +	to->truesize += len + plen; +	to->len += len + plen; +	to->data_len += len + plen; + +	if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) { +		skb_tx_error(from); +		return -ENOMEM; +	} + +	for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { +		if (!len) +			break; +		skb_shinfo(to)->frags[j] = skb_shinfo(from)->frags[i]; +		skb_shinfo(to)->frags[j].size = min_t(int, skb_shinfo(to)->frags[j].size, len); +		len -= skb_shinfo(to)->frags[j].size; +		skb_frag_ref(to, j); +		j++; +	} +	skb_shinfo(to)->nr_frags = j; + +	return 0; +} +EXPORT_SYMBOL_GPL(skb_zerocopy); +  void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)  {  	__wsum csum;  	long csstart;  	if (skb->ip_summed == CHECKSUM_PARTIAL) -		csstart = skb->csum_start - skb_headroom(skb); +		csstart = skb_checksum_start_offset(skb);  	else  		csstart = skb_headlen(skb); @@ -2040,7 +2418,7 @@ static inline void skb_split_no_header(struct sk_buff *skb,  	skb->data_len		  = len - pos;  	for (i = 0; i < nfrags; i++) { -		int size = skb_shinfo(skb)->frags[i].size; +		int size = skb_frag_size(&skb_shinfo(skb)->frags[i]);  		if (pos + size > len) {  			skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i]; @@ -2054,10 +2432,10 @@ static inline void skb_split_no_header(struct sk_buff *skb,  				 *    where splitting is expensive.  				 * 2. Split is accurately. We make this.  				 */ -				get_page(skb_shinfo(skb)->frags[i].page); +				skb_frag_ref(skb, i);  				skb_shinfo(skb1)->frags[0].page_offset += len - pos; -				skb_shinfo(skb1)->frags[0].size -= len - pos; -				skb_shinfo(skb)->frags[i].size	= len - pos; +				skb_frag_size_sub(&skb_shinfo(skb1)->frags[0], len - pos); +				skb_frag_size_set(&skb_shinfo(skb)->frags[i], len - pos);  				skb_shinfo(skb)->nr_frags++;  			}  			k++; @@ -2078,6 +2456,7 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)  {  	int pos = skb_headlen(skb); +	skb_shinfo(skb1)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;  	if (len < pos)	/* Split line is inside header. */  		skb_split_inside_header(skb, skb1, len, pos);  	else		/* Second chunk has no header, nothing to copy. */ @@ -2101,7 +2480,7 @@ static int skb_prepare_for_shift(struct sk_buff *skb)   * @shiftlen: shift up to this many bytes   *   * Attempts to shift up to shiftlen worth of bytes, which may be less than - * the length of the skb, from tgt to skb. Returns number bytes shifted. + * the length of the skb, from skb to tgt. Returns number bytes shifted.   * It's up to caller to free skb if everything was shifted.   *   * If @tgt runs out of frags, the whole operation is aborted. @@ -2129,12 +2508,13 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)  	 * commit all, so that we don't have to undo partial changes  	 */  	if (!to || -	    !skb_can_coalesce(tgt, to, fragfrom->page, fragfrom->page_offset)) { +	    !skb_can_coalesce(tgt, to, skb_frag_page(fragfrom), +			      fragfrom->page_offset)) {  		merge = -1;  	} else {  		merge = to - 1; -		todo -= fragfrom->size; +		todo -= skb_frag_size(fragfrom);  		if (todo < 0) {  			if (skb_prepare_for_shift(skb) ||  			    skb_prepare_for_shift(tgt)) @@ -2144,8 +2524,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)  			fragfrom = &skb_shinfo(skb)->frags[from];  			fragto = &skb_shinfo(tgt)->frags[merge]; -			fragto->size += shiftlen; -			fragfrom->size -= shiftlen; +			skb_frag_size_add(fragto, shiftlen); +			skb_frag_size_sub(fragfrom, shiftlen);  			fragfrom->page_offset += shiftlen;  			goto onlymerged; @@ -2169,20 +2549,20 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)  		fragfrom = &skb_shinfo(skb)->frags[from];  		fragto = &skb_shinfo(tgt)->frags[to]; -		if (todo >= fragfrom->size) { +		if (todo >= skb_frag_size(fragfrom)) {  			*fragto = *fragfrom; -			todo -= fragfrom->size; +			todo -= skb_frag_size(fragfrom);  			from++;  			to++;  		} else { -			get_page(fragfrom->page); +			__skb_frag_ref(fragfrom);  			fragto->page = fragfrom->page;  			fragto->page_offset = fragfrom->page_offset; -			fragto->size = todo; +			skb_frag_size_set(fragto, todo);  			fragfrom->page_offset += todo; -			fragfrom->size -= todo; +			skb_frag_size_sub(fragfrom, todo);  			todo = 0;  			to++; @@ -2197,8 +2577,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)  		fragfrom = &skb_shinfo(skb)->frags[0];  		fragto = &skb_shinfo(tgt)->frags[merge]; -		fragto->size += fragfrom->size; -		put_page(fragfrom->page); +		skb_frag_size_add(fragto, skb_frag_size(fragfrom)); +		__skb_frag_unref(fragfrom);  	}  	/* Reposition in the original skb */ @@ -2254,18 +2634,18 @@ EXPORT_SYMBOL(skb_prepare_seq_read);   * @data: destination pointer for data to be returned   * @st: state variable   * - * Reads a block of skb data at &consumed relative to the + * Reads a block of skb data at @consumed relative to the   * lower offset specified to skb_prepare_seq_read(). Assigns - * the head of the data block to &data and returns the length + * the head of the data block to @data and returns the length   * of the block or 0 if the end of the skb data or the upper   * offset has been reached.   *   * The caller is not required to consume all of the data - * returned, i.e. &consumed is typically set to the number + * returned, i.e. @consumed is typically set to the number   * of bytes already consumed and the next call to   * skb_seq_read() will return the remaining part of the block.   * - * Note 1: The size of each block of data returned can be arbitary, + * Note 1: The size of each block of data returned can be arbitrary,   *       this limitation is the cost for zerocopy seqeuental   *       reads of potentially non linear data.   * @@ -2279,8 +2659,13 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data,  	unsigned int block_limit, abs_offset = consumed + st->lower_offset;  	skb_frag_t *frag; -	if (unlikely(abs_offset >= st->upper_offset)) +	if (unlikely(abs_offset >= st->upper_offset)) { +		if (st->frag_data) { +			kunmap_atomic(st->frag_data); +			st->frag_data = NULL; +		}  		return 0; +	}  next_skb:  	block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; @@ -2295,11 +2680,11 @@ next_skb:  	while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) {  		frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx]; -		block_limit = frag->size + st->stepped_offset; +		block_limit = skb_frag_size(frag) + st->stepped_offset;  		if (abs_offset < block_limit) {  			if (!st->frag_data) -				st->frag_data = kmap_skb_frag(frag); +				st->frag_data = kmap_atomic(skb_frag_page(frag));  			*data = (u8 *) st->frag_data + frag->page_offset +  				(abs_offset - st->stepped_offset); @@ -2308,16 +2693,16 @@ next_skb:  		}  		if (st->frag_data) { -			kunmap_skb_frag(st->frag_data); +			kunmap_atomic(st->frag_data);  			st->frag_data = NULL;  		}  		st->frag_idx++; -		st->stepped_offset += frag->size; +		st->stepped_offset += skb_frag_size(frag);  	}  	if (st->frag_data) { -		kunmap_skb_frag(st->frag_data); +		kunmap_atomic(st->frag_data);  		st->frag_data = NULL;  	} @@ -2345,7 +2730,7 @@ EXPORT_SYMBOL(skb_seq_read);  void skb_abort_seq_read(struct skb_seq_state *st)  {  	if (st->frag_data) -		kunmap_skb_frag(st->frag_data); +		kunmap_atomic(st->frag_data);  }  EXPORT_SYMBOL(skb_abort_seq_read); @@ -2393,7 +2778,7 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,  EXPORT_SYMBOL(skb_find_text);  /** - * skb_append_datato_frags: - append the user data to a skb + * skb_append_datato_frags - append the user data to a skb   * @sk: sock  structure   * @skb: skb structure to be appened with user data.   * @getfrag: call back function to be used for getting the user data @@ -2408,52 +2793,37 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,  					int len, int odd, struct sk_buff *skb),  			void *from, int length)  { -	int frg_cnt = 0; -	skb_frag_t *frag = NULL; -	struct page *page = NULL; -	int copy, left; +	int frg_cnt = skb_shinfo(skb)->nr_frags; +	int copy;  	int offset = 0;  	int ret; +	struct page_frag *pfrag = ¤t->task_frag;  	do {  		/* Return error if we don't have space for new frag */ -		frg_cnt = skb_shinfo(skb)->nr_frags;  		if (frg_cnt >= MAX_SKB_FRAGS) -			return -EFAULT; +			return -EMSGSIZE; -		/* allocate a new page for next frag */ -		page = alloc_pages(sk->sk_allocation, 0); - -		/* If alloc_page fails just return failure and caller will -		 * free previous allocated pages by doing kfree_skb() -		 */ -		if (page == NULL) +		if (!sk_page_frag_refill(sk, pfrag))  			return -ENOMEM; -		/* initialize the next frag */ -		sk->sk_sndmsg_page = page; -		sk->sk_sndmsg_off = 0; -		skb_fill_page_desc(skb, frg_cnt, page, 0, 0); -		skb->truesize += PAGE_SIZE; -		atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); - -		/* get the new initialized frag */ -		frg_cnt = skb_shinfo(skb)->nr_frags; -		frag = &skb_shinfo(skb)->frags[frg_cnt - 1]; -  		/* copy the user data to page */ -		left = PAGE_SIZE - frag->page_offset; -		copy = (length > left)? left : length; +		copy = min_t(int, length, pfrag->size - pfrag->offset); -		ret = getfrag(from, (page_address(frag->page) + -			    frag->page_offset + frag->size), -			    offset, copy, 0, skb); +		ret = getfrag(from, page_address(pfrag->page) + pfrag->offset, +			      offset, copy, 0, skb);  		if (ret < 0)  			return -EFAULT;  		/* copy was successful so update the size parameters */ -		sk->sk_sndmsg_off += copy; -		frag->size += copy; +		skb_fill_page_desc(skb, frg_cnt, pfrag->page, pfrag->offset, +				   copy); +		frg_cnt++; +		pfrag->offset += copy; +		get_page(pfrag->page); + +		skb->truesize += copy; +		atomic_add(copy, &sk->sk_wmem_alloc);  		skb->len += copy;  		skb->data_len += copy;  		offset += copy; @@ -2488,72 +2858,109 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);  /**   *	skb_segment - Perform protocol segmentation on skb. - *	@skb: buffer to segment + *	@head_skb: buffer to segment   *	@features: features for the output path (see dev->features)   *   *	This function performs segmentation on the given skb.  It returns   *	a pointer to the first in a list of new skbs for the segments.   *	In case of error it returns ERR_PTR(err).   */ -struct sk_buff *skb_segment(struct sk_buff *skb, int features) +struct sk_buff *skb_segment(struct sk_buff *head_skb, +			    netdev_features_t features)  {  	struct sk_buff *segs = NULL;  	struct sk_buff *tail = NULL; -	struct sk_buff *fskb = skb_shinfo(skb)->frag_list; -	unsigned int mss = skb_shinfo(skb)->gso_size; -	unsigned int doffset = skb->data - skb_mac_header(skb); +	struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; +	skb_frag_t *frag = skb_shinfo(head_skb)->frags; +	unsigned int mss = skb_shinfo(head_skb)->gso_size; +	unsigned int doffset = head_skb->data - skb_mac_header(head_skb); +	struct sk_buff *frag_skb = head_skb;  	unsigned int offset = doffset; +	unsigned int tnl_hlen = skb_tnl_header_len(head_skb);  	unsigned int headroom;  	unsigned int len; -	int sg = features & NETIF_F_SG; -	int nfrags = skb_shinfo(skb)->nr_frags; +	__be16 proto; +	bool csum; +	int sg = !!(features & NETIF_F_SG); +	int nfrags = skb_shinfo(head_skb)->nr_frags;  	int err = -ENOMEM;  	int i = 0;  	int pos; +	int dummy; + +	__skb_push(head_skb, doffset); +	proto = skb_network_protocol(head_skb, &dummy); +	if (unlikely(!proto)) +		return ERR_PTR(-EINVAL); + +	csum = !head_skb->encap_hdr_csum && +	    !!can_checksum_protocol(features, proto); -	__skb_push(skb, doffset); -	headroom = skb_headroom(skb); -	pos = skb_headlen(skb); +	headroom = skb_headroom(head_skb); +	pos = skb_headlen(head_skb);  	do {  		struct sk_buff *nskb; -		skb_frag_t *frag; +		skb_frag_t *nskb_frag;  		int hsize;  		int size; -		len = skb->len - offset; +		len = head_skb->len - offset;  		if (len > mss)  			len = mss; -		hsize = skb_headlen(skb) - offset; +		hsize = skb_headlen(head_skb) - offset;  		if (hsize < 0)  			hsize = 0;  		if (hsize > len || !sg)  			hsize = len; -		if (!hsize && i >= nfrags) { -			BUG_ON(fskb->len != len); +		if (!hsize && i >= nfrags && skb_headlen(list_skb) && +		    (skb_headlen(list_skb) == len || sg)) { +			BUG_ON(skb_headlen(list_skb) > len); + +			i = 0; +			nfrags = skb_shinfo(list_skb)->nr_frags; +			frag = skb_shinfo(list_skb)->frags; +			frag_skb = list_skb; +			pos += skb_headlen(list_skb); + +			while (pos < offset + len) { +				BUG_ON(i >= nfrags); + +				size = skb_frag_size(frag); +				if (pos + size > offset + len) +					break; -			pos += len; -			nskb = skb_clone(fskb, GFP_ATOMIC); -			fskb = fskb->next; +				i++; +				pos += size; +				frag++; +			} + +			nskb = skb_clone(list_skb, GFP_ATOMIC); +			list_skb = list_skb->next;  			if (unlikely(!nskb))  				goto err; -			hsize = skb_end_pointer(nskb) - nskb->head; +			if (unlikely(pskb_trim(nskb, len))) { +				kfree_skb(nskb); +				goto err; +			} + +			hsize = skb_end_offset(nskb);  			if (skb_cow_head(nskb, doffset + headroom)) {  				kfree_skb(nskb);  				goto err;  			} -			nskb->truesize += skb_end_pointer(nskb) - nskb->head - -					  hsize; +			nskb->truesize += skb_end_offset(nskb) - hsize;  			skb_release_head_state(nskb);  			__skb_push(nskb, doffset);  		} else { -			nskb = alloc_skb(hsize + doffset + headroom, -					 GFP_ATOMIC); +			nskb = __alloc_skb(hsize + doffset + headroom, +					   GFP_ATOMIC, skb_alloc_rx_flag(head_skb), +					   NUMA_NO_NODE);  			if (unlikely(!nskb))  				goto err; @@ -2568,121 +2975,133 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)  			segs = nskb;  		tail = nskb; -		__copy_skb_header(nskb, skb); -		nskb->mac_len = skb->mac_len; +		__copy_skb_header(nskb, head_skb); +		nskb->mac_len = head_skb->mac_len; -		/* nskb and skb might have different headroom */ -		if (nskb->ip_summed == CHECKSUM_PARTIAL) -			nskb->csum_start += skb_headroom(nskb) - headroom; +		skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); -		skb_reset_mac_header(nskb); -		skb_set_network_header(nskb, skb->mac_len); -		nskb->transport_header = (nskb->network_header + -					  skb_network_header_len(skb)); -		skb_copy_from_linear_data(skb, nskb->data, doffset); +		skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, +						 nskb->data - tnl_hlen, +						 doffset + tnl_hlen); -		if (fskb != skb_shinfo(skb)->frag_list) -			continue; +		if (nskb->len == len + doffset) +			goto perform_csum_check;  		if (!sg) {  			nskb->ip_summed = CHECKSUM_NONE; -			nskb->csum = skb_copy_and_csum_bits(skb, offset, +			nskb->csum = skb_copy_and_csum_bits(head_skb, offset,  							    skb_put(nskb, len),  							    len, 0); +			SKB_GSO_CB(nskb)->csum_start = +			    skb_headroom(nskb) + doffset;  			continue;  		} -		frag = skb_shinfo(nskb)->frags; +		nskb_frag = skb_shinfo(nskb)->frags; -		skb_copy_from_linear_data_offset(skb, offset, +		skb_copy_from_linear_data_offset(head_skb, offset,  						 skb_put(nskb, hsize), hsize); -		while (pos < offset + len && i < nfrags) { -			*frag = skb_shinfo(skb)->frags[i]; -			get_page(frag->page); -			size = frag->size; +		skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags & +			SKBTX_SHARED_FRAG; + +		while (pos < offset + len) { +			if (i >= nfrags) { +				BUG_ON(skb_headlen(list_skb)); + +				i = 0; +				nfrags = skb_shinfo(list_skb)->nr_frags; +				frag = skb_shinfo(list_skb)->frags; +				frag_skb = list_skb; + +				BUG_ON(!nfrags); + +				list_skb = list_skb->next; +			} + +			if (unlikely(skb_shinfo(nskb)->nr_frags >= +				     MAX_SKB_FRAGS)) { +				net_warn_ratelimited( +					"skb_segment: too many frags: %u %u\n", +					pos, mss); +				goto err; +			} + +			if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) +				goto err; + +			*nskb_frag = *frag; +			__skb_frag_ref(nskb_frag); +			size = skb_frag_size(nskb_frag);  			if (pos < offset) { -				frag->page_offset += offset - pos; -				frag->size -= offset - pos; +				nskb_frag->page_offset += offset - pos; +				skb_frag_size_sub(nskb_frag, offset - pos);  			}  			skb_shinfo(nskb)->nr_frags++;  			if (pos + size <= offset + len) {  				i++; +				frag++;  				pos += size;  			} else { -				frag->size -= pos + size - (offset + len); +				skb_frag_size_sub(nskb_frag, pos + size - (offset + len));  				goto skip_fraglist;  			} -			frag++; -		} - -		if (pos < offset + len) { -			struct sk_buff *fskb2 = fskb; - -			BUG_ON(pos + fskb->len != offset + len); - -			pos += fskb->len; -			fskb = fskb->next; - -			if (fskb2->next) { -				fskb2 = skb_clone(fskb2, GFP_ATOMIC); -				if (!fskb2) -					goto err; -			} else -				skb_get(fskb2); - -			SKB_FRAG_ASSERT(nskb); -			skb_shinfo(nskb)->frag_list = fskb2; +			nskb_frag++;  		}  skip_fraglist:  		nskb->data_len = len - hsize;  		nskb->len += nskb->data_len;  		nskb->truesize += nskb->data_len; -	} while ((offset += len) < skb->len); + +perform_csum_check: +		if (!csum) { +			nskb->csum = skb_checksum(nskb, doffset, +						  nskb->len - doffset, 0); +			nskb->ip_summed = CHECKSUM_NONE; +			SKB_GSO_CB(nskb)->csum_start = +			    skb_headroom(nskb) + doffset; +		} +	} while ((offset += len) < head_skb->len);  	return segs;  err: -	while ((skb = segs)) { -		segs = skb->next; -		kfree_skb(skb); -	} +	kfree_skb_list(segs);  	return ERR_PTR(err);  }  EXPORT_SYMBOL_GPL(skb_segment);  int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)  { -	struct sk_buff *p = *head; -	struct sk_buff *nskb; -	struct skb_shared_info *skbinfo = skb_shinfo(skb); -	struct skb_shared_info *pinfo = skb_shinfo(p); -	unsigned int headroom; -	unsigned int len = skb_gro_len(skb); +	struct skb_shared_info *pinfo, *skbinfo = skb_shinfo(skb);  	unsigned int offset = skb_gro_offset(skb);  	unsigned int headlen = skb_headlen(skb); +	struct sk_buff *nskb, *lp, *p = *head; +	unsigned int len = skb_gro_len(skb); +	unsigned int delta_truesize; +	unsigned int headroom; -	if (p->len + len >= 65536) +	if (unlikely(p->len + len >= 65536))  		return -E2BIG; -	if (pinfo->frag_list) -		goto merge; -	else if (headlen <= offset) { +	lp = NAPI_GRO_CB(p)->last; +	pinfo = skb_shinfo(lp); + +	if (headlen <= offset) {  		skb_frag_t *frag;  		skb_frag_t *frag2;  		int i = skbinfo->nr_frags;  		int nr_frags = pinfo->nr_frags + i; -		offset -= headlen; -  		if (nr_frags > MAX_SKB_FRAGS) -			return -E2BIG; +			goto merge; +		offset -= headlen;  		pinfo->nr_frags = nr_frags;  		skbinfo->nr_frags = 0; @@ -2693,15 +3112,48 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)  		} while (--i);  		frag->page_offset += offset; -		frag->size -= offset; +		skb_frag_size_sub(frag, offset); + +		/* all fragments truesize : remove (head size + sk_buff) */ +		delta_truesize = skb->truesize - +				 SKB_TRUESIZE(skb_end_offset(skb));  		skb->truesize -= skb->data_len;  		skb->len -= skb->data_len;  		skb->data_len = 0; -		NAPI_GRO_CB(skb)->free = 1; +		NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE; +		goto done; +	} else if (skb->head_frag) { +		int nr_frags = pinfo->nr_frags; +		skb_frag_t *frag = pinfo->frags + nr_frags; +		struct page *page = virt_to_head_page(skb->head); +		unsigned int first_size = headlen - offset; +		unsigned int first_offset; + +		if (nr_frags + 1 + skbinfo->nr_frags > MAX_SKB_FRAGS) +			goto merge; + +		first_offset = skb->data - +			       (unsigned char *)page_address(page) + +			       offset; + +		pinfo->nr_frags = nr_frags + 1 + skbinfo->nr_frags; + +		frag->page.p	  = page; +		frag->page_offset = first_offset; +		skb_frag_size_set(frag, first_size); + +		memcpy(frag + 1, skbinfo->frags, sizeof(*frag) * skbinfo->nr_frags); +		/* We dont need to clear skbinfo->nr_frags here */ + +		delta_truesize = skb->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); +		NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD;  		goto done; -	} else if (skb_gro_len(p) != pinfo->gso_size) +	} +	if (pinfo->frag_list) +		goto merge; +	if (skb_gro_len(p) != pinfo->gso_size)  		return -E2BIG;  	headroom = skb_headroom(p); @@ -2723,15 +3175,14 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)  	memcpy(skb_mac_header(nskb), skb_mac_header(p),  	       p->data - skb_mac_header(p)); -	*NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);  	skb_shinfo(nskb)->frag_list = p;  	skb_shinfo(nskb)->gso_size = pinfo->gso_size;  	pinfo->gso_size = 0;  	skb_header_release(p); -	nskb->prev = p; +	NAPI_GRO_CB(nskb)->last = p;  	nskb->data_len += p->len; -	nskb->truesize += p->len; +	nskb->truesize += p->truesize;  	nskb->len += p->len;  	*head = nskb; @@ -2741,24 +3192,37 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)  	p = nskb;  merge: +	delta_truesize = skb->truesize;  	if (offset > headlen) { -		skbinfo->frags[0].page_offset += offset - headlen; -		skbinfo->frags[0].size -= offset - headlen; +		unsigned int eat = offset - headlen; + +		skbinfo->frags[0].page_offset += eat; +		skb_frag_size_sub(&skbinfo->frags[0], eat); +		skb->data_len -= eat; +		skb->len -= eat;  		offset = headlen;  	}  	__skb_pull(skb, offset); -	p->prev->next = skb; -	p->prev = skb; +	if (NAPI_GRO_CB(p)->last == p) +		skb_shinfo(p)->frag_list = skb; +	else +		NAPI_GRO_CB(p)->last->next = skb; +	NAPI_GRO_CB(p)->last = skb;  	skb_header_release(skb); +	lp = p;  done:  	NAPI_GRO_CB(p)->count++;  	p->data_len += len; -	p->truesize += len; +	p->truesize += delta_truesize;  	p->len += len; - +	if (lp != p) { +		lp->data_len += len; +		lp->truesize += delta_truesize; +		lp->len += len; +	}  	NAPI_GRO_CB(skb)->same_flow = 1;  	return 0;  } @@ -2812,13 +3276,13 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)  		WARN_ON(start > offset + len); -		end = start + skb_shinfo(skb)->frags[i].size; +		end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);  		if ((copy = end - offset) > 0) {  			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];  			if (copy > len)  				copy = len; -			sg_set_page(&sg[elt], frag->page, copy, +			sg_set_page(&sg[elt], skb_frag_page(frag), copy,  					frag->page_offset+offset-start);  			elt++;  			if (!(len -= copy)) @@ -2849,6 +3313,32 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)  	return elt;  } +/* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to given + * sglist without mark the sg which contain last skb data as the end. + * So the caller can mannipulate sg list as will when padding new data after + * the first call without calling sg_unmark_end to expend sg list. + * + * Scenario to use skb_to_sgvec_nomark: + * 1. sg_init_table + * 2. skb_to_sgvec_nomark(payload1) + * 3. skb_to_sgvec_nomark(payload2) + * + * This is equivalent to: + * 1. sg_init_table + * 2. skb_to_sgvec(payload1) + * 3. sg_unmark_end + * 4. skb_to_sgvec(payload2) + * + * When mapping mutilple payload conditionally, skb_to_sgvec_nomark + * is more preferable. + */ +int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, +			int offset, int len) +{ +	return __skb_to_sgvec(skb, sg, offset, len); +} +EXPORT_SYMBOL_GPL(skb_to_sgvec_nomark); +  int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)  {  	int nsg = __skb_to_sgvec(skb, sg, offset, len); @@ -2982,7 +3472,7 @@ static void sock_rmem_free(struct sk_buff *skb)  int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)  {  	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= -	    (unsigned)sk->sk_rcvbuf) +	    (unsigned int)sk->sk_rcvbuf)  		return -ENOMEM;  	skb_orphan(skb); @@ -2990,9 +3480,12 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)  	skb->destructor = sock_rmem_free;  	atomic_add(skb->truesize, &sk->sk_rmem_alloc); +	/* before exiting rcu section, make sure dst is refcounted */ +	skb_dst_force(skb); +  	skb_queue_tail(&sk->sk_error_queue, skb);  	if (!sock_flag(sk, SOCK_DEAD)) -		sk->sk_data_ready(sk, skb->len); +		sk->sk_data_ready(sk);  	return 0;  }  EXPORT_SYMBOL(sock_queue_err_skb); @@ -3008,12 +3501,8 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,  	if (!sk)  		return; -	skb = skb_clone(orig_skb, GFP_ATOMIC); -	if (!skb) -		return; -  	if (hwtstamps) { -		*skb_hwtstamps(skb) = +		*skb_hwtstamps(orig_skb) =  			*hwtstamps;  	} else {  		/* @@ -3021,9 +3510,13 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,  		 * so keep the shared tx_flags and only  		 * store software time stamp  		 */ -		skb->tstamp = ktime_get_real(); +		orig_skb->tstamp = ktime_get_real();  	} +	skb = skb_clone(orig_skb, GFP_ATOMIC); +	if (!skb) +		return; +  	serr = SKB_EXT_ERR(skb);  	memset(serr, 0, sizeof(*serr));  	serr->ee.ee_errno = ENOMSG; @@ -3036,6 +3529,26 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,  }  EXPORT_SYMBOL_GPL(skb_tstamp_tx); +void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) +{ +	struct sock *sk = skb->sk; +	struct sock_exterr_skb *serr; +	int err; + +	skb->wifi_acked_valid = 1; +	skb->wifi_acked = acked; + +	serr = SKB_EXT_ERR(skb); +	memset(serr, 0, sizeof(*serr)); +	serr->ee.ee_errno = ENOMSG; +	serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; + +	err = sock_queue_err_skb(sk, skb); +	if (err) +		kfree_skb(skb); +} +EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); +  /**   * skb_partial_csum_set - set up and verify partial csum values for packet @@ -3053,23 +3566,396 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)  {  	if (unlikely(start > skb_headlen(skb)) ||  	    unlikely((int)start + off > skb_headlen(skb) - 2)) { -		if (net_ratelimit()) -			printk(KERN_WARNING -			       "bad partial csum: csum=%u/%u len=%u\n", -			       start, off, skb_headlen(skb)); +		net_warn_ratelimited("bad partial csum: csum=%u/%u len=%u\n", +				     start, off, skb_headlen(skb));  		return false;  	}  	skb->ip_summed = CHECKSUM_PARTIAL;  	skb->csum_start = skb_headroom(skb) + start;  	skb->csum_offset = off; +	skb_set_transport_header(skb, start);  	return true;  }  EXPORT_SYMBOL_GPL(skb_partial_csum_set); +static int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len, +			       unsigned int max) +{ +	if (skb_headlen(skb) >= len) +		return 0; + +	/* If we need to pullup then pullup to the max, so we +	 * won't need to do it again. +	 */ +	if (max > skb->len) +		max = skb->len; + +	if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL) +		return -ENOMEM; + +	if (skb_headlen(skb) < len) +		return -EPROTO; + +	return 0; +} + +#define MAX_TCP_HDR_LEN (15 * 4) + +static __sum16 *skb_checksum_setup_ip(struct sk_buff *skb, +				      typeof(IPPROTO_IP) proto, +				      unsigned int off) +{ +	switch (proto) { +		int err; + +	case IPPROTO_TCP: +		err = skb_maybe_pull_tail(skb, off + sizeof(struct tcphdr), +					  off + MAX_TCP_HDR_LEN); +		if (!err && !skb_partial_csum_set(skb, off, +						  offsetof(struct tcphdr, +							   check))) +			err = -EPROTO; +		return err ? ERR_PTR(err) : &tcp_hdr(skb)->check; + +	case IPPROTO_UDP: +		err = skb_maybe_pull_tail(skb, off + sizeof(struct udphdr), +					  off + sizeof(struct udphdr)); +		if (!err && !skb_partial_csum_set(skb, off, +						  offsetof(struct udphdr, +							   check))) +			err = -EPROTO; +		return err ? ERR_PTR(err) : &udp_hdr(skb)->check; +	} + +	return ERR_PTR(-EPROTO); +} + +/* This value should be large enough to cover a tagged ethernet header plus + * maximally sized IP and TCP or UDP headers. + */ +#define MAX_IP_HDR_LEN 128 + +static int skb_checksum_setup_ipv4(struct sk_buff *skb, bool recalculate) +{ +	unsigned int off; +	bool fragment; +	__sum16 *csum; +	int err; + +	fragment = false; + +	err = skb_maybe_pull_tail(skb, +				  sizeof(struct iphdr), +				  MAX_IP_HDR_LEN); +	if (err < 0) +		goto out; + +	if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF)) +		fragment = true; + +	off = ip_hdrlen(skb); + +	err = -EPROTO; + +	if (fragment) +		goto out; + +	csum = skb_checksum_setup_ip(skb, ip_hdr(skb)->protocol, off); +	if (IS_ERR(csum)) +		return PTR_ERR(csum); + +	if (recalculate) +		*csum = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, +					   ip_hdr(skb)->daddr, +					   skb->len - off, +					   ip_hdr(skb)->protocol, 0); +	err = 0; + +out: +	return err; +} + +/* This value should be large enough to cover a tagged ethernet header plus + * an IPv6 header, all options, and a maximal TCP or UDP header. + */ +#define MAX_IPV6_HDR_LEN 256 + +#define OPT_HDR(type, skb, off) \ +	(type *)(skb_network_header(skb) + (off)) + +static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate) +{ +	int err; +	u8 nexthdr; +	unsigned int off; +	unsigned int len; +	bool fragment; +	bool done; +	__sum16 *csum; + +	fragment = false; +	done = false; + +	off = sizeof(struct ipv6hdr); + +	err = skb_maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN); +	if (err < 0) +		goto out; + +	nexthdr = ipv6_hdr(skb)->nexthdr; + +	len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len); +	while (off <= len && !done) { +		switch (nexthdr) { +		case IPPROTO_DSTOPTS: +		case IPPROTO_HOPOPTS: +		case IPPROTO_ROUTING: { +			struct ipv6_opt_hdr *hp; + +			err = skb_maybe_pull_tail(skb, +						  off + +						  sizeof(struct ipv6_opt_hdr), +						  MAX_IPV6_HDR_LEN); +			if (err < 0) +				goto out; + +			hp = OPT_HDR(struct ipv6_opt_hdr, skb, off); +			nexthdr = hp->nexthdr; +			off += ipv6_optlen(hp); +			break; +		} +		case IPPROTO_AH: { +			struct ip_auth_hdr *hp; + +			err = skb_maybe_pull_tail(skb, +						  off + +						  sizeof(struct ip_auth_hdr), +						  MAX_IPV6_HDR_LEN); +			if (err < 0) +				goto out; + +			hp = OPT_HDR(struct ip_auth_hdr, skb, off); +			nexthdr = hp->nexthdr; +			off += ipv6_authlen(hp); +			break; +		} +		case IPPROTO_FRAGMENT: { +			struct frag_hdr *hp; + +			err = skb_maybe_pull_tail(skb, +						  off + +						  sizeof(struct frag_hdr), +						  MAX_IPV6_HDR_LEN); +			if (err < 0) +				goto out; + +			hp = OPT_HDR(struct frag_hdr, skb, off); + +			if (hp->frag_off & htons(IP6_OFFSET | IP6_MF)) +				fragment = true; + +			nexthdr = hp->nexthdr; +			off += sizeof(struct frag_hdr); +			break; +		} +		default: +			done = true; +			break; +		} +	} + +	err = -EPROTO; + +	if (!done || fragment) +		goto out; + +	csum = skb_checksum_setup_ip(skb, nexthdr, off); +	if (IS_ERR(csum)) +		return PTR_ERR(csum); + +	if (recalculate) +		*csum = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, +					 &ipv6_hdr(skb)->daddr, +					 skb->len - off, nexthdr, 0); +	err = 0; + +out: +	return err; +} + +/** + * skb_checksum_setup - set up partial checksum offset + * @skb: the skb to set up + * @recalculate: if true the pseudo-header checksum will be recalculated + */ +int skb_checksum_setup(struct sk_buff *skb, bool recalculate) +{ +	int err; + +	switch (skb->protocol) { +	case htons(ETH_P_IP): +		err = skb_checksum_setup_ipv4(skb, recalculate); +		break; + +	case htons(ETH_P_IPV6): +		err = skb_checksum_setup_ipv6(skb, recalculate); +		break; + +	default: +		err = -EPROTO; +		break; +	} + +	return err; +} +EXPORT_SYMBOL(skb_checksum_setup); +  void __skb_warn_lro_forwarding(const struct sk_buff *skb)  { -	if (net_ratelimit()) -		pr_warning("%s: received packets cannot be forwarded" -			   " while LRO is enabled\n", skb->dev->name); +	net_warn_ratelimited("%s: received packets cannot be forwarded while LRO is enabled\n", +			     skb->dev->name);  }  EXPORT_SYMBOL(__skb_warn_lro_forwarding); + +void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) +{ +	if (head_stolen) { +		skb_release_head_state(skb); +		kmem_cache_free(skbuff_head_cache, skb); +	} else { +		__kfree_skb(skb); +	} +} +EXPORT_SYMBOL(kfree_skb_partial); + +/** + * skb_try_coalesce - try to merge skb to prior one + * @to: prior buffer + * @from: buffer to add + * @fragstolen: pointer to boolean + * @delta_truesize: how much more was allocated than was requested + */ +bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, +		      bool *fragstolen, int *delta_truesize) +{ +	int i, delta, len = from->len; + +	*fragstolen = false; + +	if (skb_cloned(to)) +		return false; + +	if (len <= skb_tailroom(to)) { +		BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); +		*delta_truesize = 0; +		return true; +	} + +	if (skb_has_frag_list(to) || skb_has_frag_list(from)) +		return false; + +	if (skb_headlen(from) != 0) { +		struct page *page; +		unsigned int offset; + +		if (skb_shinfo(to)->nr_frags + +		    skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) +			return false; + +		if (skb_head_is_locked(from)) +			return false; + +		delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); + +		page = virt_to_head_page(from->head); +		offset = from->data - (unsigned char *)page_address(page); + +		skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, +				   page, offset, skb_headlen(from)); +		*fragstolen = true; +	} else { +		if (skb_shinfo(to)->nr_frags + +		    skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) +			return false; + +		delta = from->truesize - SKB_TRUESIZE(skb_end_offset(from)); +	} + +	WARN_ON_ONCE(delta < len); + +	memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, +	       skb_shinfo(from)->frags, +	       skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); +	skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; + +	if (!skb_cloned(from)) +		skb_shinfo(from)->nr_frags = 0; + +	/* if the skb is not cloned this does nothing +	 * since we set nr_frags to 0. +	 */ +	for (i = 0; i < skb_shinfo(from)->nr_frags; i++) +		skb_frag_ref(from, i); + +	to->truesize += delta; +	to->len += len; +	to->data_len += len; + +	*delta_truesize = delta; +	return true; +} +EXPORT_SYMBOL(skb_try_coalesce); + +/** + * skb_scrub_packet - scrub an skb + * + * @skb: buffer to clean + * @xnet: packet is crossing netns + * + * skb_scrub_packet can be used after encapsulating or decapsulting a packet + * into/from a tunnel. Some information have to be cleared during these + * operations. + * skb_scrub_packet can also be used to clean a skb before injecting it in + * another namespace (@xnet == true). We have to clear all information in the + * skb that could impact namespace isolation. + */ +void skb_scrub_packet(struct sk_buff *skb, bool xnet) +{ +	if (xnet) +		skb_orphan(skb); +	skb->tstamp.tv64 = 0; +	skb->pkt_type = PACKET_HOST; +	skb->skb_iif = 0; +	skb->ignore_df = 0; +	skb_dst_drop(skb); +	skb->mark = 0; +	secpath_reset(skb); +	nf_reset(skb); +	nf_reset_trace(skb); +} +EXPORT_SYMBOL_GPL(skb_scrub_packet); + +/** + * skb_gso_transport_seglen - Return length of individual segments of a gso packet + * + * @skb: GSO skb + * + * skb_gso_transport_seglen is used to determine the real size of the + * individual segments, including Layer4 headers (TCP/UDP). + * + * The MAC/L2 or network (IP, IPv6) headers are not accounted for. + */ +unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) +{ +	const struct skb_shared_info *shinfo = skb_shinfo(skb); + +	if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) +		return tcp_hdrlen(skb) + shinfo->gso_size; + +	/* UFO sets gso_size to the size of the fragmentation +	 * payload, i.e. the size of the L4 (UDP) header is already +	 * accounted for. +	 */ +	return shinfo->gso_size; +} +EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);  | 
