VIDEOS 》 Linux Kernel sk_buff data-structure - Episode-11 to Episode-18
Watch Linux Kernel sk_buff data-structure - Episode-1 to Episode-10 Videos HERE.
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
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);
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; }
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:
Video Episodes :: Linux Kernel programming
Saturday' 13-Mar-2021
Wednesday' 18-May-2022
Saturday' 13-Mar-2021
Saturday' 14-May-2022
Saturday' 13-Mar-2021
Join The Linux Channel :: Facebook Group ↗
Visit The Linux Channel :: on Youtube ↗
💗 Help shape the future: Sponsor/Donate
Recommended Topics:
Featured Video:
Saturday' 13-Mar-2021
Trending Video:
Recommended Video: