标签:策略 linu == ... mib info 用法 ice 网络数
在Linux对网络数据包的处理过程中,会用到对skb的拷贝,skb的拷贝分成了几种拷贝,之所以分成几种拷贝,在于不同情况下,可能需要修改的skb范围不同,核心思想在于尽可能小的重新开辟内存,尽可能的共享内存,共享数据区。
对一个正常的skb来讲,一般要包括sk_buff以及数据区两部分。而数据区又分成普通数据区和skb_shared_info.
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的两个常见用法
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;
}
标签:策略 linu == ... mib info 用法 ice 网络数
原文地址:https://www.cnblogs.com/johnson37/p/8976697.html