skb_clone/pskb_copy/skb_copy

Posted johnson37

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了skb_clone/pskb_copy/skb_copy相关的知识,希望对你有一定的参考价值。

在Linux对网络数据包的处理过程中,会用到对skb的拷贝,skb的拷贝分成了几种拷贝,之所以分成几种拷贝,在于不同情况下,可能需要修改的skb范围不同,核心思想在于尽可能小的重新开辟内存,尽可能的共享内存,共享数据区。
对一个正常的skb来讲,一般要包括sk_buff以及数据区两部分。而数据区又分成普通数据区和skb_shared_info.

  • skb_clone: 只拷贝sk_buff, 换而言之,整个数据区从策略上讲,是没有计划修改的。
  • pskb_copy: 拷贝sk_buff以及普通数据区两部分,对于skb_shared_info,会使用指针指向的方式。
  • skb_copy: 实现全部拷贝

skb_clone

struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
{
    struct sk_buff *n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
    ...
    atomic_set(&n->users, 1);
    C(head);
    C(data);
    C(tail);
    C(end);

    atomic_inc(&(skb_shinfo(skb)->dataref));
    skb->cloned = 1;
    
    return n;
}

skb_clone的两个常见用法

  • br_flood 当中,会skb_clone
  • 当skb向上层协议栈传递时。
    例如在ip_rcv当中:
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
    struct iphdr *iph;

    /* When the interface is in promisc. mode, drop all the crap
     * that it receives, do not try to analyse it.
     */
    if (skb->pkt_type == PACKET_OTHERHOST)
        goto drop;

    IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);

    if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
        IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
        goto out;
    }   
    ...
}
static inline int skb_shared(const struct sk_buff *skb)
{                                                                                                                                                     
    return atomic_read(&skb->users) != 1;
}

static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri) 
{
    might_sleep_if(pri & __GFP_WAIT);
    if (skb_shared(skb)) {                                                                                                                            
        struct sk_buff *nskb = skb_clone(skb, pri);
        kfree_skb(skb);
        skb = nskb;
    }    
    return skb; 
}

pskb_copy

skb_copy

以上是关于skb_clone/pskb_copy/skb_copy的主要内容,如果未能解决你的问题,请参考以下文章