//调用路径ip_defrag->ip_frag_reasm
// 所有ip分片都被接收到时,重组ip数据包
// 判断ip所有分片都接收到的条件:
// 1.FIRST_IN, LAST_IN
// 2.meat = len,即 根据offset推断出的最大封包长度等于已接收到的封包长度
// 重组过程:
// 1.将sk_buff链表从ipq->fragments取下
// 2.将第一个分片以后的分片挂在第一个分片的frag_list域
// 3.从分片子系统使用内存中减去该ip数据包的内存
// 4.返回第一个分片
1.1 static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
{
struct iphdr *iph;
struct sk_buff *fp, *head = qp->fragments;
int len;
int ihlen;
//
ipq_kill(qp);
//ip报头+ip选项大小
ihlen = head->nh.iph->ihl*4;
//ipq->len只包括ip有效载荷的长度
len = ihlen + qp->len;//ip分包总长度
//ip报文最大长度为64k
if(len > 65535)
goto out_oversize;
//由于第一个skb是通过skb_cloned构造,则需要重新拷贝一份skb缓存区
//skb_cloned与skb_shared区别:
// 1.skb_cloned 表示该sk_buff与另一个sk_buff共享同一个缓存区
// 2.skb_shared 表示该sk_buff引用计数大于1
if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
goto out_nomem;
//保证第一个ip分片没有
网络子系统56_ip协议分片重组_重组分片
最新推荐文章于 2021-05-13 05:26:45 发布