这篇文档是基于 x86 体系结构和转发 IP 分组的。

数据包在 Linux 内核链路层路径 接收分组

1 接收中断

如果网卡收到一个和自己 MAC 地址匹配或链路层广播的以太网帧,它就会产生一个中断。此网卡的驱动程序会处理此中断:

从 DMA/PIO 或其他得到分组数据,写到内存里去;

接着,会分配一个新的套接字缓冲区 skb ,并调用与协议无关的、网络设备均支持的通用网络接收处理函数 netif_rx(skb)。 netif_rx() 函数让内核准备进一步处理 skb 。

然后, skb 会进入到达队列以便 CPU 处理(对于多核 CPU 而言,每个 CPU 维护一个队列)。如果 FIFO 队列已满,就会丢弃此分组。在 skb 排队后,调用 __cpu_raise_softirq() 标记 NET_RX_SOFTIRQ 软中断,等待 CPU 执行。

至此, netif_rx() 函数调用结束,返回调用者状况信息(成功还是失败等)。此时,中断上下文进程完成任务,数据分组继续被上层协议栈处理。

2 softirq 和 bottom half

内核 2.4 以后,整个协议栈不再使用 bottom half (下半文,没找到好的翻译),而是被软中断 softirq 取代。软中断softirq 优势明显,可以同时在多个 CPU 上执行;而 bottom half 一次只能在一个 CPU 上执行,即在多个 CPU 执行时严格保持串行。

中断服务程序往往都是在 CPU 关中断的条件下执行的,以避免中断嵌套而使控制复杂化。但是 CPU 关中断的时间不能太长,否则容易丢失中断信号。为此, Linux 将中断服务程序一分为二,各称作“ Top Half ”和“ Bottom Half ”。前者通常对时间要求较为严格,必须在中断请求发生后立即或至少在一定的时间限制内完成。因此为了保证这种处理能原子地完成, Top Half 通常是在 CPU 关中断的条件下执行的。具体地说, Top Half 的范围包括:从在 IDT 中登记的中断入口函数一直到驱动程序注册在中断服务队列中的 ISR 。而 Bottom Half 则是 Top Half 根据需要来调度执行的,这些操作允许延迟到稍后执行,它的时间要求并不严格,因此它通常是在 CPU 开中断的条件下执行的,比如网络底层操作就是这样,由于某些原因,中断并没有立刻响应,而是先记录下来,等到可以处理这些中断的时候就一块处理了。但是, Linux 的这种 Bottom Half (以下简称 BH )机制有两个缺点,也即:

( 1 )在任意一时刻,系统只能有一个 CPU 可以执行 Bottom Half 代码,以防止两个或多个 CPU 同时来执行 Bottom Half 函数而相互干扰。因此 BH 代码的执行是严格“串行化”的。

( 2 ) BH 函数不允许嵌套。

这两个缺点在单 CPU 系统中是无关紧要的,但在 SMP 系统中却是非常致命的。因为 BH 机制的严格串行化执行显然没有充分利用 SMP 系统的多 CPU 特点。为此, Linux2.4 内核在 BH 机制的基础上进行了扩展,这就是所谓的“软中断请求”( softirq )机制。 Linux 的 softirq 机制是与 SMP 紧密不可分的。为此,整个 softirq 机制的设计与实现中自始自终都贯彻了一个思想:“谁触发,谁执行 ”( Who marks , Who runs ),也即触发软中断的那个 CPU 负责执行它所触发的软中断,而且每个 CPU 都由它自己的软中断触发与控制机制。这个设计思想也使得 softirq 机制充分利用了 SMP 系统的性能和特点。

3 NET_RX_SOFTIRQ 网络接收软中断

这一阶段会根据协议的不同来处理数据分组。 CPU 开始处理软中断 do_softirq() ,,接着 net_rx_action() 处理前面标记的 NET_RX_SOFTIRQ ,把出对列的 skb 送入相应列表处理(根据协议不同到不同的列表)。比如, IP 分组交给 ip_rcv()处理, ARP 分组交给 arp_rcv() 处理等。

4 处理 IPv4 分组

下面以 IPv4 为例,讲解 IPv4 分组在高层的处理。

linux 内核协议栈之网络层

ip_rcv() 函数验证 IP 分组,比如目的地址是否本机地址,校验和是否正确等。若正确,则交给 netfilter 的NF_IP_PRE_ROUTING 钩子(关于netfilter细节可以参考 Hacking the Linux Kernel Network Stack );否则,丢弃。到了 ip_rcv_finish() 函数,数据包就要根据 skb 结构的目的或路由信息各奔东西了。

ip_local_deliver() 处理到本机的数据分组;

ip_forward() 处理需要转发的数据分组;

ip_mr_input() 转发组播数据包

至此,数据分组的接受和处理工作就告一段落了,至于于此相对的数据分组的发送,我就贴个图吧,具体细节可参考 The Linux® Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel Prentice Hall August 01, 2004

dev_queue_xmit() 处理发送分组

附一张 Linux 2.4 核的 netfilter 框架下分组的走向图:

总结下:

1.中断处理函数中:

网卡收到一帧------------------------〉

引发中断-------------------〉

cpu调用相应的中断处理函数(指向此网卡驱动中的相应的处理函数)(把此packet读到ram中)--------------------〉

呼叫netif_rx函数来打上timestamp,并把此skb放入到cpu设置的队列中-----------------〉

标记软中断(__cpu_raise_softirq)---------------------〉中断完成。

2.当软中断被调用时(一共在三个地方调用),呼叫NET_RX_SOFTIRQ(其实就是net_rx_action()函数)来处理网络方面的软中断。-----------------〉

net_rx_action()根据数据包的协议类型在数组ptype_base[16]里找到相应的协议,并从中知道了接收的处理函数,然后把数据包交给处理函数,这样就交给了上层处理,实际调用处理函数是通过net_rx_action()里的pt_prev- func()这一句。例如如果数据包是IP协议的话,ptype_base[ETH_P_IP]- func()(ip_rcv()),这样就把数据包交给了IP协议。根据包的类型,查找系统中注册了的相应的包处理函数,对于ipv4的ip包,呼叫ip_rcv-------------〉

NF_IP_PRE_ROUTING--------------〉

ip_rcv_finish(进行对此包的路由操作)---------------------〉

根据路由的结果,呼叫ip_local_deliver(给本机的包)/ip_forwardd(要转发的包)/ip_error()(出现错误的包)/ip_mr_input()(多播包的处理)ip_forward:要进行转发的包,check ttl, mtu, call NF_IP_FORWARDS,--------------〉

ip_forwmard_finish(check other ip options for forwardd!)-------------------〉

ip_send(如果需要分片,则调用ip_fragment,否则调用ip_finish_output()(call NF_IP_POST_ROUTING,然后时ip_finish_output2(填充链路层头部到skb结构中)--------------〉

hh- hh_output/dsr- neighbour- output

linux网络协议栈之数据包处理过程,Linux网络协议栈之数据包处理过程相关推荐

  1. 网络协议 一 路由的概念、简述数据包的传输过程、网络常见概念、公网、私网、NAT(私网转公网)

    目录 路由 实践1 - 让4台主机之间可以互相通信 实践2 - 让4台主机之间可以互相通信 数据包的传输过程(简) 第一个包的丢失 网络 (Network).互联网 (internet).因特网 (I ...

  2. linux 虚拟机大量udp请求失败_理解 Linux 网络栈:Linux 网络协议栈简单总结分析...

    1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的.Linu ...

  3. 网络数据包收发流程(四):协议栈之packet_type

    进入函数netif_receive_skb()后,skb正式开始协议栈之旅. 先上图,协议栈大致过程如下所示: 跟OSI七层模型不同,linux根据包结构对网络进行分层. 比如,arp头和ip头都是紧 ...

  4. 数据包分析技术与网络基础

    1,数据包分析与数据包嗅探器 数据包分析,通常也被称为数据包嗅探或协议分析,指的是捕获和解析网络上在线传输数据的过程. 数据包分析过程通常由数据包嗅探器来执行,而数据包嗅探器则是一种用来在网络媒介上捕 ...

  5. 数据包是如何在网络中传输的

    我们电脑上的数据,是如何"走"到远端的另一台电脑的呢?这是个最基础的问题,可能很多人回答不上来,尽管我们每天都在使用网络.这里我们以一个最简单的"ping"命令 ...

  6. linux数据包注释,关于 linux中TCP数据包(SKB)序列号的小笔记

    关于  SKB序列号的小笔记 为了修改TCP协议,现在遇到了要改动tcp分组的序列号,但是只是在tcp_sendmsg函数中找到了SKB的end_seq  一直没有找到seq 不清楚在那里初始化了,就 ...

  7. linux 网络命令 dns,[LN_03] Linux网络环境查看(网卡|路由|DNS|IP)、网络测试命令(端口探测|路由跟踪|抓包|ssh连接)...

    一.Linux网络环境查看命令 1. 查看&临时配置网络状态命令 # 查看IP.MAC.Mask ifconfig # 临时设置指定网卡的网络配置 ifconfig eht0 192.168. ...

  8. 数据丢包怎么修复_网络丢包率如何解决

    网络丢包率如何解决 网络丢包是我们在使用 ping (检测某个系统能否正 常运行) 对目站进行询问时, 数据包由于各 种原因在信道中丢失的现象. ping 使用了 ICMP 回送请求与回送回答报文. ...

  9. 局域网数据包通过外网发送到另一局域网的过程

    局域网A中主机A产生的数据包是如何发送至局域网B中的主机B的.下图展示了数据包从主机A中应用程序生成到转发到主机B的过程. 主机A的应用程序先生成应用层数据,应用层数据达到传输层后,传输层根据应用层协 ...

最新文章

  1. Facebook 的AI翻身之战!
  2. 等比数列和的快速求法
  3. 求n的阶乘的算法框图_单片机常用的14个C语言算法
  4. MySQL外键创建失败1005原因总结
  5. C# Task 循环任务_taroco-scheduler 分布式定时任务调度
  6. JSP脚本元素(声明 %! 表达式 %= 脚本 %)
  7. uniapp——获取退出登录
  8. 武汉大学计算机学院朱晓薇,基于SDN的TDMA体制星间网络架构设计
  9. PowerMILL 2018四五轴编程后处理宏制作视频教程
  10. L2CAP数据发送和接收
  11. android监控app被杀死,Android App前后台监控
  12. 为什么没有Realtek面板?
  13. 195. 中文小说出海资料整理
  14. 华为笔记本软件商店_华为要消灭流氓软件?干净的电脑应用商店来了!
  15. Linux—DNS域名解析服务
  16. 从一款芯片架构来看ip公司和soc公司是什么?
  17. PHP搭建织梦网站,dedeCMS+PHPStudy帮助新手实现在本地搭建织梦网站
  18. 全球的生活服务型机器人产业发展得比较迅猛
  19. win10任务管理器cpu占用率显示不准的问题
  20. 循序渐进学运维-服务篇V1版更新完毕

热门文章

  1. telnet 22正常 ssh无法连接_Telnet咋就不安全了呢?带你来看用户名和密码
  2. python爬火车票_python爬取12306火车余票程序(一)
  3. matlab cell转double_MATLAB处理数据,掌握这7个小技巧就够了
  4. Ontology的研究和应用
  5. zabbix监控mysql的哪些参数_Centos6.3下zabbix监控mysql数据库参数
  6. 用python爬取淘宝用户数据的单位是_国内有没有数据爬取方面的公司?
  7. js样式会覆盖html样式,js实现html节点、CSS样式、事件的动态添加以及html覆盖层的添加...
  8. tar:文件打包归档
  9. Appium定位方式总结
  10. C++primer 13.1.6节练习