The TOFFEE Project
The TOFFEE Project

Videos :: Linux Kernel sk_buff data-structure - Episode-11 to Episode-18

Written by: Kiran Kankipati - Published: 26-Mar-2017

 

Watch Linux Kernel sk_buff data-structure - Episode-1 to Episode-10 Videos HERE.


Download/watch this video - 201 Demo :: Fragmented skbuff - Linux Kernel skbuff data-structure - part18
[+] via HTTP - CDN - SAMP
[+] via Google Drive
[+] watch in dailymotion

You can check fragmented packets as suggested in the video by tapping RX path in net/core/dev.c :: __netif_receive_skb_core() API as shown below:

static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
{

...

//thelinuxchannel - start
	if(skb_shinfo(skb)->nr_frags) {  printk("skb - is fragmented !\n"); }
//thelinuxchannel - end

...

}

For more details refer Linux Source:
http://lxr.free-electrons.com/source/include/linux/netfilter.h#L276
http://lxr.free-electrons.com/source/net/netfilter/core.c#L339
http://lxr.free-electrons.com/source/net/core/dev.c#L4053


Download/watch this video - 181 skbuff kfree_skb API and skb packet drop API return code - Linux Kernel skbuff data-structure - part17
[+] via HTTP - CDN - SAMP
[+] via Google Drive
[+] watch in dailymotion

Download/watch this video - 176 skbuff skb->next, skb->prev linked-list experiments - Linux Kernel skbuff data-structure - part16
[+] via HTTP - CDN - SAMP
[+] via Google Drive
[+] watch in dailymotion
Using skbuff APIs - Linux Kernel skbuff data-structure - part15
skb_clone(), skb_copy() - Linux Kernel skbuff data-structure - part14

Refer:
skb_clone - duplicate an sk_buff - http://elixir.free-electrons.com/linux/latest/source/net/core/skbuff.c#L1016
skb_copy - create private copy of an sk_buff - http://elixir.free-electrons.com/linux/latest/source/net/core/skbuff.c#L1094

And here is the copy paste of skb_clone() and skb_copy() APIs (/net/core/skbuff.c) from the Kernel-source version 4.13 for quick reference:

/**
 *	skb_clone	-	duplicate an sk_buff
 *	@skb: buffer to clone
 *	@gfp_mask: allocation priority
 *
 *	Duplicate an &sk_buff. The new one is not owned by a socket. Both
 *	copies share the same packet data but not structure. The new
 *	buffer has a reference count of 1. If the allocation fails the
 *	function returns %NULL otherwise the new buffer is returned.
 *
 *	If this function is called from an interrupt gfp_mask() must be
 *	%GFP_ATOMIC.
 */

struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
{
	struct sk_buff_fclones *fclones = container_of(skb,
						       struct sk_buff_fclones,
						       skb1);
	struct sk_buff *n;

	if (skb_orphan_frags(skb, gfp_mask))
		return NULL;

	if (skb->fclone == SKB_FCLONE_ORIG &&
	    refcount_read(&fclones->fclone_ref) == 1) {
		n = &fclones->skb2;
		refcount_set(&fclones->fclone_ref, 2);
	} else {
		if (skb_pfmemalloc(skb))
			gfp_mask |= __GFP_MEMALLOC;

		n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
		if (!n)
			return NULL;

		kmemcheck_annotate_bitfield(n, flags1);
		n->fclone = SKB_FCLONE_UNAVAILABLE;
	}

	return __skb_clone(n, skb);
}
EXPORT_SYMBOL(skb_clone);

...
...

/**
 *	skb_copy	-	create private copy of an sk_buff
 *	@skb: buffer to copy
 *	@gfp_mask: allocation priority
 *
 *	Make a copy of both an &sk_buff and its data. This is used when the
 *	caller wishes to modify the data and needs a private copy of the
 *	data to alter. Returns %NULL on failure or the pointer to the buffer
 *	on success. The returned buffer has a reference count of 1.
 *
 *	As by-product this function converts non-linear &sk_buff to linear
 *	one, so that &sk_buff becomes completely private and caller is allowed
 *	to modify all the data of returned buffer. This means that this
 *	function is not recommended for use in circumstances when only
 *	header is going to be modified. Use pskb_copy() instead.
 */

struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
{
	int headerlen = skb_headroom(skb);
	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;

	/* Set the data pointer */
	skb_reserve(n, headerlen);
	/* Set the tail pointer and length */
	skb_put(n, skb->len);

	if (skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len))
		BUG();

	copy_skb_header(n, skb);
	return n;
}
EXPORT_SYMBOL(skb_copy);

Linux Kernel skbuff data-structure - part13 - Parsing skb ip-packet
Linux Kernel skbuff data-structure - part12 - skb_headroom() skb_tailroom()

Refer:
skb_headroom - bytes at buffer head - http://elixir.free-electrons.com/linux/latest/source/include/linux/skbuff.h#L2023
skb_tailroom - bytes at buffer end - http://elixir.free-electrons.com/linux/latest/source/include/linux/skbuff.h#L2034

And here is the copy paste of skb_headroom() and skb_tailroom() APIs (/include/linux/skbuff.h) from the Kernel-source version 4.13 for quick reference:

/**
 *	skb_headroom - bytes at buffer head
 *	@skb: buffer to check
 *
 *	Return the number of bytes of free space at the head of an &sk_buff.
 */
static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
	return skb->data - skb->head;
}

/**
 *	skb_tailroom - bytes at buffer end
 *	@skb: buffer to check
 *
 *	Return the number of bytes of free space at the tail of an sk_buff
 */
static inline int skb_tailroom(const struct sk_buff *skb)
{
	return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;
}

Linux Kernel skbuff data-structure - part11 - skb_put()

Refer:
skb_put - add data to a buffer - http://elixir.free-electrons.com/linux/latest/source/net/core/skbuff.c#L1443

And here is the copy paste of skb_put() API (/net/core/skbuff.c) from the Kernel-source version 4.13 for quick reference:

/**
 *	skb_put - add data to a buffer
 *	@skb: buffer to use
 *	@len: amount of data to add
 *
 *	This function extends the used data area of the buffer. If this would
 *	exceed the total buffer size the kernel will panic. A pointer to the
 *	first byte of the extra data is returned.
 */
void *skb_put(struct sk_buff *skb, unsigned int len)
{
	void *tmp = skb_tail_pointer(skb);
	SKB_LINEAR_ASSERT(skb);
	skb->tail += len;
	skb->len  += len;
	if (unlikely(skb->tail > skb->end))
		skb_over_panic(skb, len, __builtin_return_address(0));
	return tmp;
}
EXPORT_SYMBOL(skb_put);



Suggested Topics:

Linux Kernel programming
Linux Kernel struct socket and struct sock data-structure
31-Oct-2017
Linux Kernel /proc Interface
22-Feb-2017
Linux ioctl() API interface
11-Oct-2017
Linux Kernel Network Programming
05-Nov-2017
Linux Kernel Programming
05-Jul-2016
Linux Kernel sk_buff data-structure - Episode-11 to Episode-18
26-Mar-2017
Linux Kernel sk_buff data-structure - Episode-1 to Episode-10
05-Jul-2016
Linux Kernel net_device data-structure
05-Jul-2016
Linux Kernel dst_entry data-structure
04-May-2017
Linux Kernel struct ethhdr data-structure
02-Nov-2016
Linux Kernel struct iphdr data-structure
05-Jul-2016
Linux Kernel struct tcphdr data-structure
05-Jul-2016
Linux Kernel struct udphdr data-structure
05-Jul-2016
Linux Kernel Networking Sub-system
05-Jul-2016
Linux Kernel Compilation
05-Jul-2016
Linux Kernel Architecture - Generic
13-May-2017



The TOFFEE Project - v6.5 :: Updated: 12-Nov-2017 :: © 2017 :: Author: Kiran Kankipati
Your IP: 54.198.2.110 :: Browser: CCBot/2.0 (http://commoncrawl.org/faq/)