[转帖]网络包的内核漂流记 Part 1 - 图解网络包接收流程

网络,内核,漂流记,part,图解,接收,流程 · 浏览次数 : 0

小编点评

## 目录目录《网络包的内核漂流记》系列介绍 **目录结构清晰明了,页面之间链接合理,文章内容易懂。** **风格独特,富有想象力:** 作者通过一系列清晰的步骤和图像,将网络包接收流程与内核代码的各个环节逐个解析,为读者呈现出网络数据处理背后的奥秘。 **交互阅读方式:** 作者使用rozumful 的语言描述网络流程,并结合图像和代码片段,让读者直观地理解每个步骤的功能。 **其他细节:** 文章开头引用了其他文章,并建议读者阅读相关内容,为阅读深度加深。 **总结:** 该文章为网络安全领域中的 SRE/DevOps 或 Performance Engineer 的读者提供了一个深入理解网络包接收流程的重要参考。

正文

https://blog.mygraphql.com/zh/notes/low-tec/network/kernel-net-stack/

 

目录

《网络包的内核漂流记》系列介绍

大家知道,网络数据来源于网线、光纤、无线电波上的比特(bit),然后到网卡,到内核,最后到应用进程 socket。事情好像很简单。但如果是 SRE/DevOps 或是 Performance Engineer ,需要做细致的监控和优化时,这些显然是不够的。引用本文主要参考作者的原话:

Optimizing and monitoring the network stack is impossible unless you carefully read and understand how it works. You cannot monitor code you don’t understand at a deep level.
除非您仔细阅读并了解其工作原理,否则无法优化和监控网络堆栈。 您无法深入监控您不理解的代码。
—— Joe Damato

《网络包的内核漂流记》尝试分析和跟踪一个网络包在内核各子系统间的流转和触发的协作。

开始前先做个预告,《网络包的内核漂流记》 系统包括:

为免吓跑人,还是老套路,多图少代码。不过有的图有点点复杂。🚜

本文主要参考:Monitoring and Tuning the Linux Networking Stack: Receiving Data 。是的,这是篇被转载、参考到泛滥的文章。几乎你能在网上找到的所有讲 Linux 网卡和网络栈收发的文章,都会参考它。但有句话是:

一千个人眼中就有一千个 “哈姆雷特”。 —— 无名高人

风格、样式、本文的交互阅读方式 📖

虽然不是写书,不过还是说明一下吧:

  1. 我不打算像八股文的 Linux 内核文章一样,贴一堆源码,让文章看起来内容很丰满但无趣。我用交互 SVG 图片的的方法去引用源码 😎 。
  2. https://blog.mygraphql.com/zh/notes/low-tec/network/kernel-net-stack/ 的原文是 SVG 图片。如果你是在其它地方看到本文,请转回原文。
  3. 正确浏览 SVG 图片的姿势是浏览器中图片处右键,选择 “新 Tab 中打开图片” 。
  4. SVG 图片可以点击链接,直接跳转到相应内核源码网页,精确到源码行。 是的,你不需要 git clone那大陀源码 🤠 ,只需要一个浏览器就可以。如果你在电脑前开双屏,结合源码和图看,相信我,内核源码不是什么天书,你能看懂大部分的。
  5. 浏览内核源码我用 https://elixir.bootlin.com/linux/v5.4/source 。这个是很好的内核源码浏览网站,内置源码引用跳转和搜索功能。

ISO 网络模型

我并不太学院派,但回顾一下基础知识还是必须的:

OSI 基本参考模型和 TCP/IP 堆栈之间的逻辑映射

图:OSI 基本参考模型和 TCP/IP 堆栈之间的逻辑映射,来自这里

下文把第 n 层缩写为 Ln,如 TRANSPORT 层是第 4 层,缩写为 L4

网络包接收流程概述

图:网络包接收流程概述

上面是我画的图,网上有一图也比较形像:

packet_reception.png

networkmap.png

网络包接收步骤

从代码细节看,网络包接收步骤比较多。下面划分为 4 步来叙述:

  1. 初始化与配置
  2. IRQ 处理
  3. SoftIRQ 中加载网络包到内存
  4. SoftIRQ 中推送网络包到上层

初始化与配置

首先说说,内核启动时,网络子系统的初始化流程。

图:初始化与配置

  1. 创建 ksoftirqd 内核线程(每个 CPU 一个)
  2. ksoftirqd 线程开始在 run_ksoftirqd 函数中执行它们的处理循环。
  3. 接下来,为每个 CPU 创建一个专用的 softnet_data 对象。。这些对象又引用了其它处理网络数据的重要对象。其中之一是下文会提到 poll_list(轮询列表)。 程序通过调用 napi_schedule()函数或来自设备驱动程序的其他 NAPI API 来添加 NAPI 到 poll_list中 。
  4. 然后,net_dev_init() 通过调用 open_softirq() 向 softirq 系统注册 NET_RX_SOFTIRQ 软中断。注册的处理函数称为“net_rx_action()”。这是softirq内核线程将执行以处理数据包的函数。

不要心急,第 4 步以后的步骤,将在下文继续。因需要铺垫一下其它内容。

IRQ 处理

下面,从网卡在网络上接收到数据开始,说说前期的包处理过程。

网络包到达网卡触发 IRQ,IRQ 处理程序完成网络包处理前半部分,并触发 SoftIRQ

  1. 网卡从网络接收数据。
  2. NIC 使用 DMA 将网络数据写入 RAM。
  3. NIC 拉起 IRQ 位。
  4. 设备驱动之前注册的IRQ处理程序被执行。
  5. 清除网卡上的 IRQ,以便它可以为新的数据包到达生成 IRQ。
  6. 通过调用 napi_schedule() 函数,异步触发 NAPI softIRQ 轮询循环。

有了以上铺垫知识后,我们回头看看上节的「初始化与配置」中未讲解的步骤:

5. 驱动中对napi_schedule()的调用将驱动的NAPI poll对象添加到当前CPU的poll_list中。
6. 标记 softirq 拉起位,以便这个 CPU 上的 ksoftirqd 进程知道有数据包要处理。
7. run_ksoftirqd() 函数被调用(由ksoftirq 内核线程循环运行)执行。
8. __do_softirq() 被调用检查softirq 拉起位,看到一个 softIRQ 拉起, 并调用拉起位相关的softIRQ注册的处理程序:net_rx_action(),后续的网络接收数据所有重要的工作将在这个函数中完成。

SoftIRQ 中加载网络包到内存

图:SoftIRQ 中加载网络包到内存

这个图比较简单,不多说。

SoftIRQ 中推送网络包到上层

图:SoftIRQ 中推送网络包到上层

Receive Packet Steering(RPS)被禁用的情况流程为:

1. netif_receive_skb() 将数据传递给 __netif_receive_core()
6. __netif_receive_core() 将数据传送到 TAP(监听模块) (如 PCAP)。
7. __netif_receive_core() 将数据传递给已注册的协议层处理程序。在大多数情况下,是 IPv4 协议栈注册的 ip_rcv 函数。

使用Receive Packet Steering(RPS)的情况流程,这里不说了,我暂时未分析到。

如果你心急,想了解 Receive Packet Steering(RPS) 是什么鬼,那么:

结尾

没太多好说的,好好学习,天天向上。笨人做笨事,做最好的自己。

相关

如果你关注云原生,也使用到 Calico,那么以下这篇兄弟文章你可能喜欢:

与[转帖]网络包的内核漂流记 Part 1 - 图解网络包接收流程相似的内容:

[转帖]网络包的内核漂流记 Part 1 - 图解网络包接收流程

https://blog.mygraphql.com/zh/notes/low-tec/network/kernel-net-stack/ 目录 目录 《网络包的内核漂流记》系列介绍 风格、样式、本文的交互阅读方式 📖 ISO 网络模型 网络包接收流程概述 网络包接收步骤 初始化与配置 IRQ 处

[转帖]网络包的内核漂流记 Part 2 - BPF 跟踪 epoll/Envoy 事件与调度

https://blog.mygraphql.com/zh/notes/low-tec/network/bpf-trace-net-stack/ 为何 现代人好像都很忙,忙着跟遥远的人社交,却很容易忽视眼前的人事,更别提那些不直接体现出价值的基础认知了。要花时间认真看一编文章前,都要问一个问题:WH

[转帖]使用eBPF&BCC提取内核网络流量信息

前言 本文将分享从0开始编写自己的bcc程序。那么开始编写bcc之前,自己一定要明确,我们要用bcc提取什么数据。本文的实例是统计内核网络中的流量,我要提取的数据关键字段为进程的PID,进程的名字,进程的收包实时流量、发包实时流量,收包流量总和,发包流量总和,总的收发流量等。 我们知道bcc是eBP

[转帖]国内常用镜像加速源分享

国内常用镜像加速源分享 我们经常在下载一些 Python 或 Java等包的时候总是会访问国外的资源站,但是墙内访问国外的网络一般都比较卡。这里作者搜集了一些常用的国内镜像源,涵盖一些互联网大厂和知名高校的repo, 用得上的可以收藏备用哦~ Python相关镜像 (1) pip使用说明 对于Pyt

【转帖】【ethtool】ethtool 网卡诊断、调整工具、网卡性能优化| 解决丢包严重

目录 即看即用 详细信息 软件简介 安装 ethtool的使用 输出详解 其他指令 将 ethtool 设置永久保存 如何使用 ethtool 优化 Linux 虚拟机网卡性能 ethtool 解决网卡丢包严重和网卡原理 即看即用 查看: ethtool ethx 查看eth0网卡的基本设置 内容包

[转帖]制作本地epel镜像仓库(reposync下载、createrepo制作、httpd发布)

记录:310 场景:在CentOS 7.9操作系统上,使用reposync从开源镜像站下载epel镜像仓库的rpm包;使用createrepo制作本地epel镜像仓库;使用httpd发布服务。解决内网中使用yum命令安装软件时,缺少依赖包的需求。 版本: 操作系统:CentOS 7.9 名词: EP

[转帖]Kafka-Kraft 模式架构部署

news文章来源: Kafka-Kraft 模式架构部署 Kafka网址:https://kafka.apache.org/ PS:因环境原因此文档内端口都有修改! 1.去官网下载二进制包 PS:3.4.0是目前最新的版本!需要jdk1.8及以上版本启动。 [root@k8s-node1 ~]# w

[转帖]制作本地docker-ce镜像仓库(使用reposync、createrepo、httpd)

记录:330 场景:在CentOS 7.9操作系统上,使用reposync从开源镜像站下载docker-ce镜像仓库的rpm包;使用createrepo制作本地docker-ce镜像仓库;使用httpd发布服务。解决内网中使用yum命令安装docker-ce的需求。 版本: 操作系统:CentOS

[转帖]k8s之udp丢包问题

https://www.jianshu.com/p/6a5faee4cc65 image.png 测试仪发送某种类型的报文进行性能测试,报文目的mac为VF的mac。对于发出去的每个报文,必须在3s内收到响应,否则认为丢包,会重新发送一次,此时会有retransmit的统计。 pod A有两个网卡,

[转帖]macvlan 网络模式实现跨主机 Docker 通信

https://www.jianshu.com/p/cc481870236b macvlan 网络模式概念 macvlan 本身是 linux 内核的模块,本质上是一种网卡虚拟化的技术,其功能是允许在同一个物理网卡上虚拟出多个网卡,通过不同的 MAC 地址在数据链路层进行网络数据的转发。 一块网卡上