网络子系统55_ip协议分片重组_加入ipq
//ip分片加入到正确的ipq结构
//调用路径:ip_defrag->ip_frag_queue // 处理过程:
// 1.正在被释放的ipq,不处理新加入的分片(ipq正在被释放由last_in设置COMPLETE指出)
// 2.处理分片的合法性
// 2.1当该封包为最后一个分片时
// 2.1.1如果之前没有接收到最后一个分片,则该分片在总有效载荷中的结尾位置需要大于等于以推测出的最大长度
// 2.1.2如果之前已经接收到最后一个分片,则该分片在总有效载荷中的结尾位置需要等于之前接收到的最后一个分片给出的结尾位置
// 2.2结尾位置对齐到8字节边界,截去多余的字节,希望后续到达的分片补齐
// 3.更新该分片的skb->data移动到ip有效载荷,skb->tail到8字节
// 4.处理重叠
// 5.将分片插入到ipq的分片列表中
// 6.更新ipq的时间戳,移动ipq到rcu链表尾部 // 重叠的处理:
// 1.一个分片最多只会与一个前边的分片发生重叠,此时,截去该分片发生重叠的部分
// 2.一个分片可能会与多个后边的分片发生重叠,此时
// 2.1 如果后边的一个分片完全被重叠,则释放后边的这个分片
// 2.2 如果后边的这个分片只有部分被重叠,则从后边的这个分片中截去重叠的部分
// 3.使被截去缓存区的skb的校验和失效 1.1 static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
{
struct sk_buff *prev, *next;
int flags, offset;
int ihl, end;
//ipq正在被释放
if (qp->last_in & COMPLETE)
goto err;
//此ip分片(ip有效载荷)在所有有效载荷中的偏移量
offset = ntohs(skb->nh.iph->frag_off);
flags = offset & ~IP_OFFSET;//DF MF标志
offset &= IP_OFFSET;////偏移量为13bit的字段,去掉高3bit的flag
offset <<= 3; //偏移量以8字节为单位
ihl = skb->nh.iph->ihl * 4; end = offset + skb->len - ihl;//该ip分片的有效载荷在总有效载荷的最后一个字节的位置 //接收到最后一个分片
if ((flags & IP_MF) == 0) {
//1.该分片指示的总有效载荷大小不足从已接收到的报文推断出的长度
if (end < qp->len ||
((qp->last_in & LAST_IN) && end != qp->len))//2.已经接收到最后一个分片,又接收到一个最后一个分片,但是长度不等
goto err;
qp->last_in |= LAST_IN;//LAST_IN表示已经接收到最后一个分片
qp->len = end;//总有效载荷的长度
} else {//非最后一个分片
if (end&7) {//结尾位置没有对齐到8字节
end &= ~7;//去掉结尾的字节,希望后来的数据补齐
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;//由于截去了末尾的字节,因此表示校验和失效
}
if (end > qp->len) {//非最后一个分片,但是长度超过了总有效载荷长度
if (qp->last_in & LAST_IN)
goto err;//有错误
qp->len = end;//由于新接收到的分片其结尾字节位置大于最大的结尾位置,更新最大的结尾位置
}
}
if (end == offset)//长度为0分片的
goto err; //pskb_pull 与 skb_pull的区别:
// 1.skb_pull只简单移动 skb->data的指针
// 2.pskb_pull考虑当skb->data到skb->tail之间的数据量如果不足够移动时,从frags或者frag_list中向前拷贝
if (pskb_pull(skb, ihl) == NULL)//更新skb->data,使其指向ip有效载荷
goto err;
if (pskb_trim(skb, end-offset))//更新skb->tail指针,使skb->data与skb->tail之间的数据量为end-offset
goto err; //在ipq->fragments中寻找该分片前边的分片
//一个分片前边分片的满足条件:
// 1.它的偏移量小于该分片的偏移量
// 2.它后边分片的偏移量大于等于该分片的偏移量
prev = NULL;
for(next = qp->fragments; next != NULL; next = next->next) {
if (FRAG_CB(next)->offset >= offset)
break;
prev = next;
} //已经接收到该分片前边的分片
//该分片最多只会与前边的一个分片重叠
if (prev) {
int i = (FRAG_CB(prev)->offset + prev->len) - offset;
//该分片与前边的分片存在重叠的部分
if (i > 0) {
offset += i;//更新该分片的offset
if (end <= offset)
goto err;
if (!pskb_pull(skb, i))//从该分片中删除重叠的部分
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;//由于该分片长度被截取,因此校验和失效
}
}
//接着之前的搜索,寻找该分片的后边的分片
//该分片会与多个后边的分片重叠
while (next && FRAG_CB(next)->offset < end) {
int i = end - FRAG_CB(next)->offset;//与后边第一个分片重叠的字节数 //重叠的字节数小于后边分片的长度,说明只与后边一个分片发生了重叠
if (i < next->len) {
//更新后边分片的data指针,截取重叠的部分
if (!pskb_pull(next, i))
goto err;
//更新后边分片的偏移量
FRAG_CB(next)->offset += i;
//由于从后边分片截取了重叠的部分,从已接收到的数据量减去这部分字节
qp->meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;//由于截取了后边的这个分片,使其校验和失效
break;
} else {//否则完全包含了后边的这个分片, 则直接释放掉被重叠的这个分片
struct sk_buff *free_it = next; next = next->next; if (prev)
prev->next = next;
else
qp->fragments = next;
qp->meat -= free_it->len;
frag_kfree_skb(free_it, NULL);
}
}
//强制转换skb->cb为分片控制块
//经过与前边,后边的分片比较,最终确定该分片的偏移量
//设置该分片的偏移量
FRAG_CB(skb)->offset = offset;
//将分片添加到ipq的fragments链表中
skb->next = next;
if (prev)
prev->next = skb;
else
qp->fragments = skb;//此分片为第一个分片 if (skb->dev)
qp->iif = skb->dev->ifindex;
skb->dev = NULL;
qp->stamp = skb->stamp;//更新ipq的时间戳为最新收到的这个skb的时间戳
qp->meat += skb->len;
//skb->truesize为skb中所有缓存区占用的总大小
atomic_add(skb->truesize, &ip_frag_mem);//增加分片子系统使用的内存量
if (offset == 0)
qp->last_in |= FIRST_IN; write_lock(&ipfrag_lock);
list_move_tail(&qp->lru_list, &ipq_lru_list);
write_unlock(&ipfrag_lock); return; err:
kfree_skb(skb);
}
网络子系统55_ip协议分片重组_加入ipq的更多相关文章
- 网络子系统54_ip协议分片重组_定位ipq
//为分片确定正确的ipq结构 // 定位5元组 // 1.<id, 源ip, 目的ip, l4协议> 可通过ip报文获取 // 2.user 通过ip_defrag给出,指出重组是由谁发 ...
- 网络子系统53_ip协议分片重组_内存阈值
//调用路径:ip_defrag->ip_evictor // 分片重组时,可使用内存上下限: // 1.sysctl_ipfrag_high_thresh 可用内存上限 // 2.sysctl ...
- 网络子系统42_ip协议处理函数_数据帧的接收
//向协议栈注册l3处理函数 1.1 void dev_add_pack(struct packet_type *pt) { int hash; //ptype_all ptype_base共用一把锁 ...
- 网络子系统48_ip协议数据帧的发送
//ip协议与l4协议接口,l4通过此接口向下l3传递数据帧 //函数主要任务: // 1.通过路由子系统路由封包 // 2.填充l3报头 // 3.ip分片 // 4.计算校验和 // 5.衔接邻居 ...
- 网络子系统45_ip协议tos处理
//ip报头tos字段,一个字节 // 二进制位:[0 1 2] [3] [4] [5] [6] [7] // 1.[0 1 2] 表示优先级: // 000 路由 // 001 优先级 // 010 ...
- 网络子系统46_ip协议数据帧的转发
//调用路径ip_rcv->ip_rcv_finish->dst_input->(skb->dst->input) //ip_forward以回调函数的形式,保存在skb ...
- Linux 网络子系统之网络协议接口层(一)
Linux 网络设备驱动之网络协议接口层介绍. 网络协议接口层最主要的功能是给上层协议提供透明的数据包发送和接收接口. 当上层ARP或IP需要发送数据包时,它将调用网络协议接口层的dev_queue_ ...
- Linux内核笔记--网络子系统初探
内核版本:linux-2.6.11 本文对Linux网络子系统的收发包的流程进行一个大致梳理,以流水账的形式记录从应用层write一个socket开始到这些数据被应用层read出来的这个过程中linu ...
- 《Linux 性能及调优指南》1.5 网络子系统
翻译:飞哥 (http://hi.baidu.com/imlidapeng) 版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明. 原文名称:<Linux Performance a ...
随机推荐
- Java面试题-锁
1. 什么是可重入锁(ReentrantLock)? 答: java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作 ...
- poj 2195 Going Home(最小费用最大流)
题目:http://poj.org/problem?id=2195 有若干个人和若干个房子在一个给定网格中,每人走一个都要一定花费,每个房子只能容纳一人,现要求让所有人进入房子,且总花费最小. 构造一 ...
- poj 3414 Pots ( bfs )
题目:http://poj.org/problem?id=3414 题意:给出了两个瓶子的容量A,B, 以及一个目标水量C, 对A.B可以有如下操作: FILL(i) fill the ...
- 深入理解Java虚拟机 - 类加载器
引子: 类加载器(classloader)是独立于虚拟机之外,可以独立实现的代码模块. OSGi使用了类加载器的这一特点实现其热插拔的特性 Java同C++等语言不通, ...
- (转载)Let's Play Games!
第1题 Alice和她的同学Bob通过网上聊天商量明天早晨谁去教室打扫卫生的事,Bob说:“我在桌上放了一枚硬币,你猜一下,是正面朝上还是反面朝上?如果猜对了,我去扫地.如果猜错了,嘿嘿….” Al ...
- (十三)学习CSS之两个class连一起隔空格和逗号
1.时常见到css的这两种种写法: a.两个class隔空格连一起: .class1 .class2{......} b.两个class隔逗号连一起: .class1,.class2{......} ...
- MySQL 视图知识点小结
视图本身是一个虚拟表,不存放任何数据.在使用SQL语句访问视图的时候,它返回的数据是MySQL从其他表中生成的.视图和表在同一个命名空间, MySQL在很多地方对于视图和表是同样对待的.不过视图和表也 ...
- Java多线程 -- 深入理解JMM(Java内存模型) --(五)锁
锁的释放-获取建立的happens before 关系 锁是Java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代 ...
- 《深入Java虚拟机学习笔记》- 第15章 对象和数组
1.针对对象的操作码 实例化一个新对象需要通过new操作码来实现. 对象的创建 操作码 操作数 说明 new index 在堆中创建一个新的对象,将其引用压入栈 new操作码后面紧跟一个无符号16位数 ...
- 犯罪构成三层次记忆口诀 zt
犯罪构成三层次记忆口诀 2012-02-17 来源:为你辩护网 浏览次数:232 0 众所周知,犯罪构成“四要件”和犯罪构成“三层次”(“三阶层”)都是分析具体刑事案件的辅助性工具.犯罪构成四要件是指 ...