linux 4.19 ip重组
IP重组
ip重组这部分 4.19内核与3.10内核有些差别,4.9.134以后内核中不使用低水位和工作队列了,同时使用了rhashtable 替代了 hash bucket的概念,在3.10内核中使用1024个hash bucket, 每个bucket中最多存放128个分片队列,在4.19内核中所有的分片队列都保存在可动态调整的rhashtable 中,同时不再使用低水位和工作队列对ip 分片进行回收
4.19内核中,在内存中会分配一个reassembly buffer用于IP分片的重组。同时,也定义了一系列的参数用于控制IP分片处理过程:
net.ipv4.ipfrag_high_thresh: 用于IP分片重组的最大内存用量(默认为4194304 ,即4Mb)。
net.ipv4.ipfrag_time: IP分片在内存中的保留时间(默认30,单位:秒)。
对应上述网络协议栈的内核参数,内核层定义了结构体netns_frags,包含分片重组功能需要的全局控制信息,其定义如下:
struct netns_frags {
struct percpu_counter mem ____cacheline_aligned_in_smp;
/* sysctls */
int timeout;
int high_thresh;
int low_thresh;
int max_dist;
struct inet_frags *f;
struct rhashtable rhashtable ____cacheline_aligned_in_smp;
atomic_long_t mem ____cacheline_aligned_in_smp;
};
其中rhashtable为分片队列(inet_frag_queue)所在的hash表,IP分片包在内核中根据IP报头的4个字段计算得到一个hash值(key值),每个hash值对应一个分片队列,在实现分片包重组功能时,IP层需要先缓存收到的所有分片包,等待同一个IP报文的所有分片包都到达后,把它们重组成一个大包再提交给L4(TCP/UDP... ...)协议。
当收到新的ip分片包时,将查找是否存在同一数据包的分片队列。首先检查当前内存中所有待重组分片包占用的内存(frag_mem_limit)是否高于高水位(net.ipv4.ipfrag_high_thresh),如果高于则丢弃分片包;否则接着对接收到的分片包与rhashtable表中缓存的分片队列进行匹配(即从rhashtable表查找分片队列)将属于同一数据包的分片包放在同一个分片队列中,如果一个数据包的所有分片包都接收完成,那么将进入数据包的重构流程;如果匹配失败,说明该分片属于一个新的数据包,那么进入分片队列新建流程。分片队列的接收查找函数inet_frag_find定义如下:
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key)
{
struct inet_frag_queue *fq = NULL, *prev;
//①高水位判断
if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh)
return NULL;
rcu_read_lock();
prev = rhashtable_lookup(&nf->rhashtable, key, nf->f->rhash_params); //② 查找rhashtable中的分片队列
if (!prev)
fq = inet_frag_create(nf, key, &prev); //③ 创建新分片队列
if (prev && !IS_ERR(prev)) {
fq = prev;
if (!refcount_inc_not_zero(&fq->refcnt))
fq = NULL;
}
rcu_read_unlock();
return fq;
}
在分片队列的新建流程中,将从slab中分配一段空间,相应增加分片包占用的内存,同时设置定时器(超时时常为30秒)用来检查重组结果,如果定时器超时未重组成功,该分片包也将丢弃。分片包的新建函数inet_frag_alloc定义如下:
static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
struct inet_frags *f,
void *arg)
{
struct inet_frag_queue *q;
q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC);
if (!q)
return NULL;
... ...
add_frag_mem_limit(nf, f->qsize); //①增加分片报文占用内存
setup_timer(&q->timer, //②设置超时定时器
f->frag_expire, (unsigned long)q);
... ...
return q;
}
int ip_defrag(struct net *net, struct sk_buff *skb, u32 user)
{
... ...
qp = ip_find(net, ip_hdr(skb), user, vif); //①查找分片队列
if (qp) {
... ...
ret = ip_frag_queue(qp, skb); //②分片队列入队操作
... ...
return ret;
}
kfree_skb(skb);
return -ENOMEM;
}
如果一个数据包的所有分片包都已接收,则需将所有分片包整合获得原始数据包,并将整合后的数据包提交给高层协议。同时,处理与分片包相关的数据结构,譬如更新当前分片包占用的内存(frag_mem_limit),停止与分片包相关的定时器等。数据包的重构函数ip_frag_reasm定义如下:
static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb,
struct sk_buff *prev_tail, struct net_device *dev)
{
... ...
ipq_kill(qp); //①减少分片包引用计数
... ...
sub_frag_mem_limit(qp->q.net, //②减少分片包占用内存
head->truesize);
... ...
}
所以,一个分片包的接收通常经历了查找分片、缓存、重组、释放等阶段,下图是分片包的接收流程。
file:///home/zxq/%E4%B8%8B%E8%BD%BD/ip%E9%87%8D%E7%BB%84.png
图1 4.19分片包接收流程
根据分析,内核中待重组的分片包占用内存量由高水位(net.ipv4.ipfrag_high_thresh)阈值和分片保留时间(net.ipv4.ipfrag_time)来控制,如果待重组分片包内存占用高于高水位(high_thresh),那么新收到的数据包分片将会直接丢弃, 如果分片包超过最大保留时间(ipfrag_time),那么已经收到的数据包也会被丢弃。
附3.10 ip重组

linux 4.19 ip重组的更多相关文章
- linux下取IP(正则)
linux下取IP(正则) 常见方法: ifconfig eth0|grep "inet addr"|awk -F ":" '{print $2}'|awk ' ...
- Linux 能PING IP 但不能PING 主机域名的解决方法 vim /etc/nsswitch.conf hosts: files dns wins
Linux 能PING IP 但不能PING 主机域名的解决方法 转载 2013年12月25日 10:24:27 13749 . vi /etc/nsswitch.conf hosts: files ...
- linux配置网卡IP地址命令详细介绍及一些常用网络配置命令
linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...
- linux下TCP/IP及内核参数优化调优(转)
Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等. 如下配置是写在sysctl.con ...
- Linux内核 TCP/IP、Socket参数调优
Linux内核 TCP/IP.Socket参数调优 2014-06-06 Harrison.... 阅 9611 转 165 转藏到我的图书馆 微信分享: Doc1: /proc/sy ...
- Linux下检测IP地址冲突及解决方法
问题说明:在公司办公网内的一台物理机A上安装了linux系统(ip:192.168.9.120),在上面部署了jenkins,redmine,svn程序.由于是在办公网内,这台机器和同事电脑都是在同一 ...
- linux c/c++ IP字符串转换成可比较大小的数字
由www.169it.com搜集整理 IP字符串转换成可比较大小的数字,具体代码如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include "stdio. ...
- linux下设置ip地址 gw网关,dns的方法
本文介绍下,在linux中设置IP地址.网关.dns的方法,有需要的朋友作个参考吧. 设置linux网络的方法有两种:第一种:使用命令修改(直接即时生效) 复制代码代码示例: ip and net ...
- Ubuntu Linux下设置IP的配置命令
Ubuntu Linux下设置IP的配置命令 今天装了Ubuntu,但是发现不能上网,开始排查问题: 1.首先确定网络连接是否正确,所用的网线是否可以正常工作 2.查看网卡是否能正常工作,检测的方法如 ...
- Linux tomcat设置ip地址直接访问,tomcat设置ip地址直接访问,tomcat绑定ip地址
Linux tomcat设置ip地址直接访问,tomcat设置ip地址直接访问,tomcat绑定ip地址 >>>>>>>>>>>> ...
随机推荐
- link标签的media属性
media属性表示被链接的文档将显示在什么设备上.比如下面的例子: <head> <link rel="stylesheet" type="text/c ...
- python教程6.2-OS模块random模块
OS模块 random模块
- shape-outside
shape-outside定义一个由内容区域的外边缘封闭形成的形状 shape-outside 是一个非常实用的属性,可以实现一些比较复杂的文本环绕效果. shape-outside 的兼容性比较好, ...
- 前端scale负数表示翻转
https://blog.csdn.net/wang_yu_shun/article/details/121299208 极力推荐这个博主写的,前端有关负数的小技巧
- Selenium4自动化测试6--控件获取数据--下拉框级联选择、checkbox选择、时间选择器
4-下拉框级联选择 import time from selenium.webdriver.support.select import Select #pip install selenium fro ...
- 化繁为简|AIRIOT智慧水务信息化建设解决方案
"生产自动化,管理信息化"是现代化水厂建设的目标之一,需要在水质要求.工艺.生产.管理.环境等监测方面达到精细化管理标准,这是一个高度智能化,实现化繁为简智慧进阶的工程.传统水 ...
- AIRIOT答疑第1期 | 零开发基础也能干物联网平台项目?
当然可以! 物联网低代码平台以零门槛.部署快.灵活性高.满足二次开发等特点,成为近两年来IOT服务的生力军.项目团队即使没有研发人员,也可以像拼乐高一样快速搭建物联网平台,功能全面,满足多数业务场景下 ...
- 显示锁之ReentrantLock
ReentrantLock显示锁 在Java 1.5之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile两种.Java1.5增加了一种新的机制:ReentrantLo ...
- 深入探讨Function Calling:实现外部函数调用的工作原理
引言 Function Calling 是一个允许大型语言模型(如 GPT)在生成文本的过程中调用外部函数或服务的功能. Function Calling允许我们以 JSON 格式向 LLM 模型描述 ...
- openssl升级nginx升级支持openssl http2
mkdir -p /usr/local/openssl #wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz tar -xf opens ...