Rust的eBFP框架Aya(一) - Linux内核网络基础

前言

在我的Rust入门及实战系列文章中已经说明, Rust是一门内存安全的高性能编程语言,从它的这些优秀特性来看,就是一门专为系统开发而诞生的语言。至于很多使用Rust来进行web开发的行为,不能说它们不好,只能说是杀鸡焉用牛刀耳。

本系列的文章旨在为大家介绍一个新的专用于开发eBPF程序的Rust框架:Aya。Aya 是 Rust 中的一个 eBPF(Extended Berkeley Packet Filter)库,提供了用 Rust 语言编写、加载和运行 eBPF 程序的能力。eBPF 是一种强大的技术,用于在 Linux 内核中安全地运行沙盒程序,常用于网络编程、性能监控和安全增强。我们在后面的文章中将对eBPF进行更加详细和深入的介绍。

Linux内核网络基础

如果你还不了解什么是eBPF, 那么其实从它的名称中便可见一斑,从Packet Filter可以看出,这显然是用于包的处理的一门技术。它通过在Linux的内核中的不同挂载点,加入一个隔离可控的二进制程序,来达到我们想要为内核增加功能处理网络包的目的。既然是在内核的网络处理流程中动手脚,那么在开始之前,我们有必要对Linux内核原本的网络处理流程有基本的认知, 否则,如果直接开始eBPF的编写,那么我们很可能会变成狗拿刺猬,无从下手。

网络模型概览

众所周知,网络模型的的划分有不同的方法, 最流行的莫过于经典的OSI七层网络模型, TCP/IP四层网络模型,还有综合两者而成的五层网络模型。从理解内核网络工作原理的角度出发,我们选择五层网络模型进行接下来的探究:
请添加图片描述

注: 在Linux系统中,内核源码的位置位于/usr/src/目录下的对应内核命名的目录下,例如我使用的azure虚拟机上,内核代码的目录为/usr/src/linux-headers-5.15.0-1052-azure。 后文提到的内核代码相关的目录都是以此为根的相对路径。

Linux内核在收到一个网络数据包后,首先会由网卡驱动程序(相关内核代码位于drivers/net/ethernet中)先进行处理, 然后回交由内核中处理协议栈相关的代码进行处理(相关内核代码位于kernel/net/中),处理完成后的结果,再由socket提供接口,供用户空间的应用层程序访问。

网络中断处理原理

那么从网卡收到数据包,是怎么传递给内核进行处理的呢,这里就要谈到中断处理了。 从硬件的角度来看,当一个网卡收到数据包时, 它会进行以下两件事情:

  • 将数据包以DMA(Direct Memory Access)的方式, 将收到的数据帧存放到内存的环形缓冲区中(Buffer Ring);
  • 向CPU的引脚施加一个电压变化,向CPU表明现在有一个数据来了,需要处理。

上述这种通过向CPU引脚施加电压的硬件操作,被称为硬中断。那么CPU此时就会对收到的数据包进行处理,那么如何处理呢?网络包如果一直不停的到来,而对网络包的处理往往又是复杂和耗时的,如果CPU每收到一个数据包都对它进行处理完成后再干别的工作,就会导致CPU的占用率过高,而无法对其他的硬中断进行响应了,比如鼠标键盘等设备发起的硬中断请求。

软中断注册

因此,当CPU收到一个网卡发来的硬中断时,它会告诉网卡驱动程序: “你先去内存登记一下待办事项吧”,于是网卡驱动程序会在内存中标记一个变量,表示这里有一个网络包需要人手来处理了。这个在内存中设置标志的操作,就被称为软中断。

上述过程的图示如下:
请添加图片描述

软中断处理

内核驱动程序处理

在我们的Linux启动后,内核中会运行一个进程ksoftirqd, 它的职责就是检测内存中是否有软中断需要处理, 一旦检测到这是一个网络驱动注册的软中断,就会调用网卡驱动中的poll函数,从内存的环形缓冲区中将网络数据包收下来并进行处理, 这个过程的图示如下:
请添加图片描述
其中, 网卡驱动程序中的igb_poll()函数会从内存的环形缓冲区中将完整的网络数据包取出来,然后调用igb_clean_rx_irq()函数进行处理,这些处理包括:

  • 校验收到的数据格式是否是一个合法的网络包;
  • 将收到的数据包格式化成skb,解析timestamp, VLAN id, protocol等字段信息
内核协议栈处理

在驱动程序对数据包进行处理后,处理完的数据将被发送到内核的协议栈进行处理,在进入协议栈之前,内核中存在一个GRO引擎,它的作用是把一些小的网络包合成一个大的网络包,一次性发给协议栈进行处理,目的是减少传送给协议栈的包数量,这有助于减少 CPU 的使用量。
请添加图片描述
如上图所示,在数据包进入协议栈后:

  • 首先会调用netif_receive_skb()函数,其中会辨别数据包的网络层协议,根据网络层协议调用不同的函数;
  • 例如判断得到这个数据包是个IP包,则会接下来调用ip_rcv()函数,在其中又会判断它的传输层协议,根据其是TCP还是UDP而调用不同的函数;
  • 例如判断得到这是一个TCP包,那么将继续调用tcp_rcv()函数对数据进行处理;
  • 处理完成后的数据可以供用户通过socket访问;

小结

网络模块在Linux内核中及其复杂,上面的介绍以尽可能简单明了的方式描述了一个数据包从网卡收到它开始,如何被内核进行处理的整个过程。其中包含了CPU硬中断,ksoftiqrd线程,软中断处理,网卡驱动对数据包的处理,skb的创建, 网络协议栈对数据包的处理等过程。

本文没有涉及用户空间应用程序从socket取包的过程,这涉及到recvfrom系统调用,也是一个比较复杂的话题。本系列文章旨在介绍Rust开发eBPF程序,只关注内核对网络包的处理流程,因此用户空间取包不在我们的关注范围内。在了解了网络包在内核中的处理流程之后,对于后需eBPF程序的挂载点,我们应当会有更清晰的认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/206761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2017下半年软工(桥接模式)

题目——桥接模式(抽象调用实现部分) package org.example.桥接模式;/*** 桥接模式的核心思想是将抽象部分与它的实现部分分离,使它们可以独立变化,就是说你在实现部分:WinImp、LinuxImp基础上还能加上RedHatImp&#…

uniapp 输入框输入时,会将内容顶上去的解决方案

// 设置页面最小高度 export const setPageMinHeight () > {return {position: relative,min-height: uni.getSystemInfoSync().windowHeight px} }页面使用: import {setPageMinHeight} from "/utils/uniUtil";data() {return {minHeight: setPag…

Unity 状态系统

状态系统 原理食用方法Demo 原理 #mermaid-svg-lUbxJ8eMP3KqrEhY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lUbxJ8eMP3KqrEhY .error-icon{fill:#552222;}#mermaid-svg-lUbxJ8eMP3KqrEhY .error-text{fill:#55…

官方officevisio在线安装包

在线安装包,在线就是要有网络环境,你能搜到这篇博客,就初步具备网络环境 visio在线安装包.zip官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 在线安装包如下,双击执行安装即可,可供选择的64/32位 软件的激活与…

【扩散模型】ControlNet从原理到实战

ControlNet从原理到实战 ControlNet原理ControlNet应用于大型预训练扩散模型ControlNet训练过程ControlNet示例1 ControlNet与Canny Edge2. ControlNet与Depth3. ControlNet与M-LSD Lines4. ControlNet与HED Boundary ControlNet实战Canny Edge实战Open Pose 小结参考资料 Cont…

Linux系统上RabbitMQ安装教程

一、安装前环境准备 Linux:CentOS 7.9 RabbitMQ Erlang 1、系统内须有C等基本工具 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c kernel-devel m4 ncurses-devel tk tc xz socat2、下载安装包 1)首先&a…

[linux] kaggle 数据集用linux下载

你可以通过以下步骤获取Kaggle的下载链接并在Linux中进行下载: 首先,确保你已经安装了Python和Kaggle API。如果没有安装,你可以通过以下命令安装: pip install kaggle 接着,你需要在Kaggle网站上获取API Token。登录…

【PyTorch】 暂退法(dropout)

文章目录 1. 理论介绍2. 实例解析2.1. 实例描述2.2. 代码实现2.2.1. 主要代码2.2.2. 完整代码2.2.3. 输出结果 1. 理论介绍 线性模型泛化的可靠性是有代价的,因为线性模型没有考虑到特征之间的交互作用,由此模型灵活性受限。泛化性和灵活性之间的基本权…

Docker构建自定义镜像

创建一个docker-demo的文件夹,放入需要构建的文件 主要是配置Dockerfile文件 第一种配置方法 # 指定基础镜像 FROM ubuntu:16.04 # 配置环境变量,JDK的安装目录 ENV JAVA_DIR/usr/local# 拷贝jdk和java项目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo…

Java基础50题: 21.实现一个方法printArray, 以数组为参数,循环访问数组中的每个元素,打印每个元素的值.

概述 实现一个方法printArray, 以数组为参数,循环访问数组中的每个元素,打印每个元素的值. 代码 public static void printArray(int[] array) {for (int i 0; i < array.length; i) {System.out.println(array[i] " ");}System.out.println();}public static…

【日常总结】mybatis-plus WHERE BINARY 中文查不出来

目录 一、场景 二、问题 三、原因 四、解决方案 五、拓展&#xff08;全表全字段修改字符集一键更改&#xff09; 准备工作&#xff1a;做好整个库备份 1. 全表一键修改 Stage 1&#xff1a;运行如下查询 Stage 2&#xff1a;复制sql语句 Stage 3&#xff1a;执行即可…

100. 相同的树(Java)

目录 解法&#xff1a; 官方解法&#xff1a; 方法一&#xff1a;深度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 方法二&#xff1a;广度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 给你两棵二叉树的根节点 p 和…

L1-028:判断素数

题目描述 本题的目标很简单&#xff0c;就是判断一个给定的正整数是否素数。 输入格式&#xff1a; 输入在第一行给出一个正整数N&#xff08;≤ 10&#xff09;&#xff0c;随后N行&#xff0c;每行给出一个小于231的需要判断的正整数。 输出格式&#xff1a; 对每个需要判断的…

Kotlin(十五) 高阶函数详解

高阶函数的定义 高阶函数和Lambda的关系是密不可分的。在之前的文章中&#xff0c;我们熟悉了Lambda编程的基础知识&#xff0c;并且掌握了一些与集合相关的函数式API的用法&#xff0c;如map、filter函数等。另外&#xff0c;我们也了解了Kotlin的标准函数&#xff0c;如run、…

vuepress-----22、其他评论方案

vuepress 支持评论 本文讲述 vuepress 站点如何集成评论系统&#xff0c;选型是 valineleancloud, 支持匿名评论&#xff0c;缺点是数据没有存储在自己手里。市面上也有其他的方案, 如 gitalk,vssue 等, 但需要用户登录 github 才能发表评论, 但 github 经常无法连接,导致体验…

[wp]“古剑山”第一届全国大学生网络攻防大赛 Web部分wp

“古剑山”第一届全国大学生网络攻防大赛 群友说是原题杯 哈哈哈哈 我也不懂 我比赛打的少 Web Web | unse 源码&#xff1a; <?phpinclude("./test.php");if(isset($_GET[fun])){if(justafun($_GET[fun])){include($_GET[fun]);}}else{unserialize($_GET[…

使用cmake构建的工程的编译方法

1、克隆项目工程 2、进入到工程目录 3、执行 mkdir build && cd build 4、执行 cmake .. 5、执行 make 执行以上步骤即可完成对cmake编写的工程进行编译 &#xff0c;后面只需执行你的编译结果即可 $ git clone 你想要克隆的代码路径 $ cd 代码文件夹 $ mkdir bu…

vmware安装centos7总结

vmware安装centos7总结 文章目录 vmware安装centos7总结一、配置网络&#xff08;桥接模式&#xff09;二、配置yum源&#xff08;连网配置&#xff09;三、可视化界面四、安装Docker五、安装DockerUI 一、配置网络&#xff08;桥接模式&#xff09; 网络连接模式选择桥接模式…

Ubuntu安装nvidia GPU显卡驱动教程

Ubuntu安装nvidia显卡驱动 1.安装前安装必要的依赖 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官网下载对应驱动 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸载原有驱动 sudo apt-get remove --purge nvidi…

深度学习:注意力机制(Attention Mechanism)

1 注意力机制概述 1.1 定义 注意力机制&#xff08;Attention Mechanism&#xff09;是深度学习领域中的一种重要技术&#xff0c;特别是在序列模型如自然语言处理&#xff08;NLP&#xff09;和计算机视觉中。它使模型能够聚焦于输入数据的重要部分&#xff0c;从而提高整体…