Linux数据报文的来龙去脉

TCP四次挥手详解:从状态机到TIME_WAIT的工程实践 TCP协议作为网络通信的基石,其连接管理机制是保障可靠数据传输的核心。协议通过状态机模型精确控制连接的建立与终止,其中四次挥手过程确保了全双工通信的可靠关闭。这一机制通过FIN和ACK报文的交换,让通信双方能独立确认数据发送完毕,避免数据丢失和资源泄漏,体现了在不可靠网络上实现可靠通信的工程智慧。在服务器编程和高并发场景中,深入理解CLOSE_WAIT和TIME_WAIT等状态至关重要,它们直接关系到连接泄漏、端口占用等线上问题的排查与优化。通过分析TCP状态变迁和抓包实践,开发者可以掌握网络问题定位的关键 阅读详情

作为网络领域的开发人员,我们经常要与Linux的数据报文打交道,一定要搞清楚数据报文是从何而来,又是如何离去。以前针对这个主题写过一些文章(主要是从源码角度),这次会更重视流程示意图(在细节上必然有所简化),争取在一篇文章中,就让大家理清数据报文的来龙去脉。

一、网卡把报文传到内核的流程图

 

图1. 网卡传递数据包到内核的流程图

1. 网卡在启动时会申请一个接收ring buffer,其条目都会指向一个skb的内存。

2. DMA完成数据报文从网卡硬件到内存到拷贝后,网卡发送一个中断通知CPU。

3. CPU执行网卡驱动注册的中断处理函数,中断处理函数只做一些必要的工作,如读取硬件状态等,并把当前该网卡挂在NAPI的链表中,同时会“触发”NET_RX_SOFTIRQ(其实就是设置对应软中断的标志位)。

4. CPU中断处理函数返回后,会检查是否有软中断需要执行。因第三步设置了NET_RX_SOFTIRQ,则执行报文接收软中断。

5. 在NET_RX_SOFTIRQ软中断中,执行NAPI操作,回调第三步挂载的驱动poll函数。

6. 驱动会对interface进行poll操作,检查网卡是否有接收完毕的数据报文。

7. 将网卡中已经接收完毕的数据报文取出,继续在软中断进行后续处理。

注:驱动对interface执行poll操作时,会尝试循环检查网卡是否有接收完毕的报文,直到设置的budget上限,或者已经就绪报文。

 

二、接收软中断将报文分发给协议栈的示意图

 

图2. 接收软中断将报文分发给对应协议栈

1. 假设是CPU0在执行接收软中断net_rx_action

2. 接收报文的网卡是否支持XDP,若支持且启用,则进行xdp的检查。

3. 查看是否启用了RPS & RFS。若启用且目的CPU非当前CPU,则将数据报文enque到目的CPU的backlog队列中,并在软中断中发送IPI中断给目的CPU。目的CPU的IPI处理函数会将目的CPU的backlog挂到其NAPI列表中,这样由其他CPU发送过来的报文,就会在其后面NAPI中被处理。

4. CPU0负责处理当前报文。如果网卡没有vlan offload,则需要软件剥掉vlan头,以便后面的报文处理。

5. 在分发报文时,可能会有多个handler关心此报文。所以在分发时,需要先增加skb的引用计数,然后传递给该handler。

(注:感谢 @alawnfeng同学指正,我之前记错了,写成clone了)

6. 将报文分发给“ETH_P_ALL”的handler,即关心所有以太网报文的handler(不限于任何协议)

7. 通过以太网报文的协议,将数据报文分发给该协议的handler,如IPv4,IPv6,PPPoE等。

 

三、协议栈将数据报文发给套接字(以IPv4为例)的流程图

 

图3. 协议栈将报文发给套接字的流程图

报文从上到下的分发过程很相似。每层协议都会包含上层协议类型,然后根据类型进行分发。以IPv4协议栈(inet协议族)来说,初始化阶段,调用dev_add_pack注册了二层以太网的IP协议类型。而四层协议icmp、udp、tcp也是在inet初始化阶段,调用inet_add_protocol注册。

那么,报文接收的流程如下:

1. __netif_receive_skb_core处于二层协议处理阶段,其根据以太网的报文类型,从packet_type中找到匹配的三层协议。

2. 进入ip报文的处理函数ip_rcv,进行netfiler的prerouting阶段的检查。

3. 获得四层协议类型,调用其early_demux。这是一个优化,对于符合条件的报文,可以尽早处理。

4. 查找路由。对于发给本机的IP报文,其路由的input处理函数,即ip_local_deliver。

5. 继续netfilter的localin阶段的检查。

6. 通过检查后,将报文发给本机的raw socket。

7. 根据四层协议类型,调用匹配的四层协议处理函数。对于UDP报文来说,就是udp_rcv。

8. 根据源端口和目的端口,确定socket套接字。

9. 将skb报文加入套接字的接收队列。

 

四、报文从应用层到网卡的流程图

 

图4. 应用层发包到网卡的流程

1. 应用层调用socket系统调用,内核会在内部根据协议类型,创建一个socket对象,且其成员变量ops指向udp_proto(以UDP为例)。

2. 应用层调用send,write等发送函数,将socket fd和数据data传给内核。

3. 内核通过fd获得socket对象,并将应用层的数据复制到内核,调用socket成员变量对应的sendmsg。

4. 内核调用ip_route_output_flow查询路由。

5. 调用ip_make_skb,申请一个skb用于发送报文,并填充了IP头。

6. 调用udp_send、ip_send_skb,填充UDP报文头,计算IP头的checksum等。

7. 调用ip_localout,到达本机IP层发送报文的最后阶段,进行netfilter localout阶段的检查。

8. 调用neigh_output,即邻居层填充二层目的MAC。如果没有ARP信息,则缓存报文,发送ARP报文,进行二层地址解析。

9. 调用dev_queue_xmit,进入qdisc schedule即流量控制,也就是TC的实现。

10. 默认情况,网卡的qdisc策略是FIFO。被schedule的数据报文,通过dev_hard_start_xmit调用网卡驱动的ndo_start_xmit,将报文交给网卡进行发送。

 

通过以上四个分解的流程图,相信大家对于Linux数据报文的来龙去脉,有了一定的了解。如在文章开头所云,这些流程图都做了必要的简化。在很多步骤都可以进行展开,也涉及了更多细节。

一句话,内核的网络模块,既简单又复杂。它的流程很简单,但每一步的处理又涉及了很多细节,欢迎大家和我一起讨论研究

linux网络报文接收发送浅析  对于linux内核来说,网络报文由网络设备来进行接收。设备驱动程序从网络设备中读取报文,通过内核提供的网络接口函数,将报文传递到内核中的网络协议栈。报文经过协议栈的处理,或转发、或丢弃、或被传送给某个进程。网络报文的发送与之相反,进程通过系统调用将数据送入网络协议栈,或者由网络协议栈自己发起报文的发送,然后协议栈通过调用网络接口函数来调度驱动程序,使其将报文传送给网络设备,从而发送出去。本文讨论 阅读详情

相关推荐

Linux命令:查看网络报文的工具和方法

这些工具提供了不同的特性和使用方式,可以根据具体需求选择合适的工具进行网络报文的捕获和分析。这些工具提供了不同的特性和使用方式,可以根据具体需求选择合适的工具进行网络报文的捕获和分析。在Linux系统中,我们经常需要查看网络通信中的报文,以便调试和分析网络问题。下面介绍几个常用的命令和工具,用于在Linux中查看网络报文。其中,options是一些选项参数,expression是过滤表达式,用于过滤要捕获的报文。其中,options是一些选项参数,expression是过滤表达式,用于过滤要捕获的报文。

LogicODER的博客 1188

Linux网络编程:报文理解与传输层协议TCP

本文摘要: 本文深入讲解了TCP协议的核心机制和工作原理。主要内容包括:1)TCP报文结构,包含报头和数据部分,以及不同网络层的不同称呼;2)Linux内核中描述报文的结构体sk_buff及其工作原理;3)TCP可靠性保证机制,如确认应答、超时重传、连接管理等;4)TCP性能优化技术,包括滑动窗口、流量控制、拥塞控制等;5)TCP连接建立和断开的三次握手与四次挥手过程;6)TCP异常情况处理;7)TCP与UDP协议的对比。文章通过大量实例详细阐述了TCP如何同时保证可靠性和高效性,是理解网络协议栈的重要参考

_dindong的博客 751

Proxmox VE安装卡顿深度解析:显卡驱动与BIOS设置的黄金法则

本文深度解析Proxmox VE安装卡顿的根本原因,指出显卡驱动与BIOS设置是两大关键因素。文章详细阐述了如何通过添加`nomodeset`内核参数解决显卡兼容性问题,并提供了针对不同主板品牌的BIOS显卡优先级设置黄金法则。同时,还分享了从预处理到高级调试的完整实战排查流程,帮助用户从源头杜绝安装卡顿,确保PVE系统顺利部署。

weixin_29278805的博客 472

【Linux内核一】在Linux系统下网口数据收发包的具体流向是什么?

简述Linux系统下网络收发包流程

highman110的博客 1942

EB TRESOS 29.0.0安装教程用于MCAL配置开发

本文介绍的搭建基于NXP官网提供EB软件,进行基于标准AUTOSAR软件底层驱动配置的开发

qq_53260940的博客 1879

手把手教你用Arduino IDE玩转ESP32-S3-wroom(附串口调试技巧)

本文详细介绍了如何在Arduino IDE环境下配置和使用ESP32-S3-WROOM模块,包括开发环境搭建、硬件连接、程序烧录及高级调试技巧。通过实战步骤和常见问题解决方案,帮助开发者快速上手这一高性能Wi-Fi/蓝牙双模模组,提升物联网开发效率。

weixin_30487201的博客 293

深入网络底层,了解Linux系统收发网络数据包的过程、原理、流程,附图文说明

深入网络底层,了解Linux系统收发网络数据包的过程、原理、流程,附图文说明。

代码讲故事 1108

HC32F460 FPU实战:从零开启硬件浮点加速

本文详细介绍了如何在HC32F460开发板上启用和优化FPU(浮点运算单元),以显著提升硬件浮点运算性能。从工程配置、关键代码修改到实战优化技巧,全面解析FPU加速的实现方法,并分享常见问题的解决方案,帮助开发者避免常见陷阱,充分发挥HC32F460的硬件潜力。

weixin_42620340的博客 348

linux下的数据报文截获机制

linux下的数据报文截获机制很多数据包截获软件都使用特定的库,在windows下一般使用winpcap,而在linux和unix下一般都选用libpcap,使用这些库能在一定程度上减少工作量,加快程序的进程,但往往容易忽略了一些本质的东西,例如libpcap又是怎样来截获数据报文的。分析和了解数据报文截获的机制对于了解如何才能截获到无线网络的管理报文有着重要的意义。1、   通常数据报处理流程  通常的数据报文是如何被处理的呢?如图3-1所示。当数据到达网卡时,网卡就把数据交给网卡的驱动程序,当驱动程序处

jackywgw的专栏 2260

DQN网络代码调用env.reset()后存储观测信息报错问题ValueError: setting an array element with a sequence.解决处理

**reset()函数返回的是一个array类型以及其中数据的type!模拟游戏进行学习任务。因此需要将observation指定为真正需要的array信息即可,得到的的变量observation类型与Agent存储时的。因此怀疑返回的observation有问题,于是通过。报错信息提示为数据维度不对应,也即最初通过。在强化学习DQN网络代码实现过程中,针对。

Vulcan_Q的博客 4093

C#上位机+YOLO入门:工业视觉检测最小demo(复制就能跑,附完整代码)

新手入门C#上位机+YOLO,最忌讳的是上来就追求“大而全”,结果卡在某个外围功能上,连核心逻辑都没搞懂。这个最小demo的目的就是让大家先掌握“图像预处理→模型推理→结果解析”的核心链路,后续再逐步添加工业场景的功能,这样学习效率会高很多。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 728

python怎么接收udp报文_Linux数据报文的来龙去脉

作者:gfree.wind@gmail.com作为网络领域的开发人员,我们经常要与Linux的数据报文打交道,一定要搞清楚数据报文是从何而来,又是如何离去。以前针对这个主题写过一些文章(主要是从源码角度),这次会更重视流程示意图(在细节上必然有所简化),争取在一篇文章中,就让大家理清数据报文的来龙去脉。一、网卡把报文传到内核的流程图图1. 网卡传递数据包到内核的流程图1. 网卡在启动时会...

weixin_42129970的博客 411

UE5 Niagara基础知识讲解

在UE5版本中,Niagara粒子系统引入了许多可添加的模块,分别用于控制发射器的生成和更新、粒子的生成和更新以及渲染效果。本文采用虚幻5.2.1版本,以图文方式对Niagara基础知识进行讲解。

一碗清深的博客 2472

Linux数据报文的来龙去脉,Linux下的数据报文截获机制

很多数据包截获软件都使用特定的库,在Windows下一般使用winpcap,而在Linux和unix下一般都选用libpcap,使用这些库能在一定程度上减少工作量,加快程序的进程,但往往容易忽略了一些本质的东西,例如libpcap又是怎样来截获数据报文的。分析和了解数据报文截获的机制对于了解如何才能截获到无线网络的管理报文有着重要的意义。通常的数据报文是如何被处理的呢?如图3-1所示。当数据到达网...

weixin_29790175的博客 223

MATLAB基础应用精讲-【数模应用】数字预失真(DPD)(附MATLAB代码实现)

近年来,随着无线通信技术的发展,高功率放大器 (PA) 在提高信号传输功率的同时,也带来了非线性失真问题。PA的非线性失真会造成信号频谱扩展、功率下降、邻道干扰等问题,严重影响系统性能。为了克服PA的非线性失真,数字预失真 (DPD) 技术应运而生。DPD技术通过在发射机中引入一个非线性模块,对信号进行预失真处理,从而补偿PA的非线性失真。

qq_36130719的博客 896

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

无线网络安全演进:从WEP、TKIP到现代加密协议的原理与实战

无线网络安全的核心在于加密协议,它通过算法保障数据传输的机密性与完整性。其基本原理是利用密钥对明文进行转换,防止未授权访问。在技术价值上,加密协议是构建可信网络环境的基石,直接影响着企业数据安全与个人隐私保护。从WEP到TKIP,再到WPA2/WPA3,加密技术的演进反映了对安全漏洞的持续修补与对抗。WEP作为早期协议,因RC4流密码的脆弱性和密钥管理缺陷而极易被破解;TKIP作为过渡方案,虽引入了动态密钥混合等增强机制,但仍受限于性能与安全上限。在实际应用场景中,理解这些协议的工作原理与缺陷,对于网络架构

weixin_30552811的博客 300

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Linux内核网络数据发送(六)——网络设备驱动

Linux内核网络数据发送(六)——网络设备驱动1. 前言2. 驱动回调函数注册3. `ndo_start_xmit` 发送数据4. `igb_tx_map` 1. 前言 本文主要介绍设备通过 DMA 从 RAM 中读取数据并将其发送到网络,主要分析dev_hard_start_xmit 通过调用 ndo_start_xmit来发送数据的过程。 2. 驱动回调函数注册 驱动程序实现了一系列方法来支持设备操作,例如: 发送数据(ndo_start_xmit) 获取统计信息(ndo_get_stats64

金荣的个人技术博客 5992

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

WebServer 之 http连接处理(下)

请求报文 -- 解析 + 响应

IT OR 考公? 2384

网络数据被网卡接收后在电脑内部的流转过程

网络数据被网卡接收后在电脑内部的流转过程

HilariousBojack的博客 2700

IP报文发送过程和原理

在整个的大网络中,我们会发现,不同的局域网中可以有相同IP的主机。当一台主机想像另一台主机发消息的时候,会首先查看自己的网络号与当前局域网的网络号是否相同,如果不相同,就会到路由器构成的网络中去查找哪个网络号符合条件,找到符合条件的网络号之后,再到该网络号对应的局域网中根据主机号找到对应的主机。13位分片偏移:是分片相对于原始IP报文开始处的偏移,其实就是在表示当前分片在原报文处在哪个位置,实际偏移的字节数是这个值*8得到的,因此除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)。

分享学习的知识,记录我的技术成长道路 3195

Linux--报文详解

A到B发一个信号,网桥也能收到信号,它去数据库里面进行一个查询,发现A和B来自同一个接口,网桥就不会转发信号到C,D那边。A和B发信号同时C能和D发信号,所以说网桥隔离了冲突。 发送报文时,如果目标地址是FFFFFF,那么可以发送到任何地方,网桥也是无条件转发。 网桥就是交换机,早起的网桥只能接2个网络. 子网掩码:根据IP地址取网络地址,子网掩码是一堆0和1,IP地址转成二进制和子网掩码相

iwantyou741的博客 2955

linux 报文处理,linux报文处理.docx

linux报文处理对于linux内核来说,网络报文由网络设备来进行接收。设备驱动程序从网络设备中读取报文,通过内核提供的网络接口函数,将报文传递到内核中的网络协议栈。报文经过协议栈的处理,或转发、或丢弃、或被传送给某个进程。  网络报文的发送与之相反,进程通过系统调用将数据送入网络协议栈,或者由网络协议栈自己发起报文的发送,然后协议栈通过调用网络接口函数来调度驱动程序,使其将报文传送给网络设备,从...

weixin_39581099的博客 352

Linux 报文队列

Linux 报文队列Linux 报文队列 一IPC 概述 二报文队列 1 报文队列简述 2 代码分析 21 msgget 创建报文队列 22 msgsnd 报文发送 221 相关数据结构 222 sys_msgsnd源码分析 3 msgrcv 报文接收 4 msgctl 报文控制与设置 一、IPC 概述早期的Unix系统进程件通信机制主要有管道和信号。管道开始只能在近亲之间通信,于是将pipe推广到

李兰溪的专栏 4612

[内核源码]Linux 发送报文过程简析及网络杂谈

sk_buff 数据结构 ip_output ip_forward Linux 邻居子系统 抓包程序层次 设备驱动前、后? 参考文章 https://www.cnblogs.com/newjiang/p/7428125.html https://blog.youkuaiyun.com/one_clouder/article/details/52674706 https...

blog 2467
上一篇: DPDK之PMD原理
下一篇: 为DPDK eal动态库添加新函数 ld不过的问题
废言Pro
博客等级 码龄16年 1093粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值