【C语言】linux内核netif_receive_skb

news2024/12/23 12:58:57

一、中文注释

/**
 * netif_receive_skb - 从网络处理接收缓冲区
 * @skb: 要处理的缓冲区
 *
 * netif_receive_skb() 是主要的数据接收处理函数。
 * 它总是成功的。由于拥塞控制或协议层的原因,缓冲区可能在处理过程中被丢弃。
 *
 * 这个函数只能在软中断(softirq)上下文中调用,并且应该启用中断。
 *
 * 返回值(通常被忽略):
 * NET_RX_SUCCESS: 无拥塞
 * NET_RX_DROP: 数据包被丢弃
 */
int netif_receive_skb(struct sk_buff *skb)
{
    trace_netif_receive_skb_entry(skb);

    return netif_receive_skb_internal(skb);
}
EXPORT_SYMBOL(netif_receive_skb);

static int netif_receive_skb_internal(struct sk_buff *skb)
{
    int ret;

    net_timestamp_check(netdev_tstamp_prequeue, skb);

    if (skb_defer_rx_timestamp(skb))
        return NET_RX_SUCCESS;

    if (static_branch_unlikely(&generic_xdp_needed_key)) {
        int ret;

        preempt_disable();
        rcu_read_lock();
        ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
        rcu_read_unlock();
        preempt_enable();

        if (ret != XDP_PASS)
            return NET_RX_DROP;
    }

    rcu_read_lock();
#ifdef CONFIG_RPS
    // RPS (接收包处理软中断) 配置,用于多核系统的性能优化
    if (static_key_false(&rps_needed)) {
        struct rps_dev_flow voidflow, *rflow = &voidflow;
        int cpu = get_rps_cpu(skb->dev, skb, &rflow);

        if (cpu >= 0) {
            ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
            rcu_read_unlock();
            return ret;
        }
    }
#endif
    ret = __netif_receive_skb(skb);
    rcu_read_unlock();
    return ret;
}

这段代码包含了两个函数,`netif_receive_skb` 和 netif_receive_skb_internal。
netif_receive_skb 是公开的API,用于处理从网络接收到的数据包。这个函数的作用是将收到的数据包传入内核网络栈进行进一步处理。它定义了一个跟踪点(tracepoint)来记录数据包接收事件,然后调用 netif_receive_skb_internal 来执行实际的处理。
netif_receive_skb_internal 是实际处理数据包的内部函数。该函数开始时通过对数据包进行时间戳检查来确定是否需要进一步处理。如果启用了泛型XDP,并且XDP程序对数据包的处理结果不是通过(XDP_PASS),则会直接返回并丢弃数据包(NET_RX_DROP),不再进一步处理。
如果启用了接收包处理软中断(RPS)配置,这是一个为多核处理系统设计的性能优化机制,它会尝试将数据包分发到合适的CPU上的后备队列中。如果没有启用RPS或者相关的处理不适用,会直接调用 __netif_receive_skb 函数来进行通常的数据包接收处理。
注意这些函数通常在软中断上下文中调用,这意味着它们不能被长时间阻塞,并且不能睡眠。因此它们通常都是快速执行的,并且需要注意并发和RPS等高级特性以获得最优的性能。在多核处理器系统中,处理网络数据包的性能至关重要,所以这些函数的设计考虑到了多核调度和效率。

二、讲解

这两个函数是Linux内核网络子系统中的一部分,它们负责处理接收到的网络数据包。

netif_receive_skb 函数

netif_receive_skb 函数是网络设备驱动收到数据包后的主要处理函数。当网络数据包(由`struct sk_buff`结构体表示)准备好从网络设备接收时,此函数被调用。
这个函数只能在软中断(softirq)上下文中被调用,并且在调用时应当开启中断。
函数返回的值通常会被忽略,但可能是以下几种:
- NET_RX_SUCCESS:代表数据包被成功处理,没有拥塞发生。
- NET_RX_DROP:代表数据包由于拥塞控制或协议层的原因被丢弃。
此函数简单地记录数据包接收事件(trace_netif_receive_skb_entry),并调用`netif_receive_skb_internal`函数来进行实际的数据包处理。

netif_receive_skb_internal 函数

netif_receive_skb_internal 是`netif_receive_skb`的内部实现,它执行实际的数据包接收处理操作。
1. 首先,检查是否需要记录时间戳(net_timestamp_check),如果需要的话,就对数据包时间戳进行处理。
2. 接着,检查是否需要进行接收路径时间戳的推迟处理(skb_defer_rx_timestamp)。如果是,将返回`NET_RX_SUCCESS`并退出。
3. 然后,如果全局性的XDP(eXpress Data Path)功能被需要,它会尝试执行XDP处理程序。XDP是一个高性能且灵活的数据包处理路径,可以运行eBPF程序来进行数据包的处理。如果XDP处理结果不是通过(XDP_PASS),则数据包将被丢弃,函数返回`NET_RX_DROP`。
4. 如果启用了接收包路由(RPS,接收包流量控制),则会尝试根据RPS逻辑确定合适的CPU来处理此数据包,如果找到,则将数据包入队到相应CPU的后端(backlog)中,接着返回相应的处理结果。
5. 如果没有应用RPS或者XDP处理结果是通过,函数会调用`__netif_receive_skb`来进行标准的网络数据包接收处理。这个过程涉及到网络协议栈的各个层级,处理如路由决策、协议分发(例如,IPv4、IPv6、ARP)等任务。
6. 最后,返回处理结果,它可能显示数据包被成功处理或者被丢弃。
以上描述的函数是网络接收路径中的关键部分,负责确保数据包被正确地从网络设备收集并按照配置的网络策略进行处理。

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

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

相关文章

MATLAB知识点:while-end循环语句

​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自​第4章:MATLAB程序流程控制 除了for-end语…

S5---FPGA-K7板级电源硬件实战

视频链接 FPGA-K7板级电源硬件实战01_哔哩哔哩_bilibili FPGA-K7板级电源硬件实战 基于K7 板级的系统框图 2、基于K7 板级的电源设计细则 2.1、K7 FPGA功耗评估 KINTEX-7 FPGA电源有数字电源VCCINT, VCCBRAM, VCCAUX, VCCAUX_IO ,VCCO和模拟电源VMGTAVCC ,VMGTAV…

uniapp 项目 浏览器chrome使用vue devtool 识别不了 in not detect

问题 uniapp的项目,vue2, chrome 分析 添加了运行时,指定模板h5.html 指定的h5.html重置了运行根目录,导致了vue dev tool在运行时,chrome上识别不了。 解决: 方法1: 只能调试的时候,不加sati…

AI EARTH——1972-2019全球不透水面30米分辨率产品(GISA-2.0)

1972-2019全球不透水面30米分辨率产品(GISA-2.0) 武汉大学Landsat全球地物识别年度产品前言 – 人工智能教程 时相: 1972-2019 范围: 全球 数据来源: 武汉大学(黄昕教授团队) 引用代码: dataset …

CRMCHAT修复获取客户ip信息,地区信息

CRMCHAT修复获取客户ip信息,地区信息-TP源码网原因: 因pv.sohu.com/cityjson?ieutf-8接口已无法正确获取ip信息,导致后台站点统计无法正确获取用户ip信息,无法获取地区信息 修改 注释掉无用接口地址 修复ip信息 也可以使用&…

C++惯用法之RAII思想: 资源管理

C编程技巧专栏:http://t.csdnimg.cn/eolY7 目录 1.概述 2.RAII的应用 2.1.智能指针 2.2.文件句柄管理 2.3.互斥锁 3.注意事项 3.1.禁止复制 3.2.对底层资源使用引用计数法 3.3.复制底部资源(深拷贝)或者转移资源管理权(移动语义) 4.RAII的优势和挑战 5.总…

XUbuntu22.04之如何找到.so库所在的软件包?(二百一十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

Jupyter Notebook的安装和使用(windows环境)

一、jupyter notebook 安装 前提条件:安装python环境 安装python环境步骤: 1.下载官方python解释器 2.安装python 3.命令行窗口敲击命令pip install jupyter 4.安装jupyter之后,直接启动命令jupyter notebook,在默认浏览器中打开jupyte…

C/C++ 乘积尾零问题(蓝桥杯)

如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零? 5650,4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 9937 1173 6866 3397 4759 7557 3070 2287 1453 9899…

stressapptest源码剖析:主函数main解析和sat类头文件分析

主函数main解析和sat类头文件分析 一、简介二、入口函数main.cc剖析三、SAT压力测试对象接口和数据结构总结 一、简介 stressapptest(简称SAT)是一种用于在Linux系统上测试系统稳定性和可靠性的工具,通过产生CPU、内存、磁盘等各种负载来测试…

web小游戏,蜘蛛纸牌

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的订阅后,私信本人,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、贪吃蛇、飞机大战、坦克大战、开心消消乐、扑鱼达人、扫雷、打地鼠、斗地主等等。 <!DOCTYPE h…

智能驾驶规划控制理论学习06-基于优化的规划方法之数值优化基础

目录 一、优化概念 1、一般优化问题 2、全局最优和局部最优 二、无约束优化 1、无约束优化概述 2、梯度方法 通用框架 线性搜索 回溯搜索 3、梯度下降 基本思想 实现流程 ​4、牛顿法 基本思想 实现流程 5、高斯牛顿法 6、LM法&#xff08;Le…

甲类,乙类,甲乙类,D类功放

功率放大器&#xff1a; 简称功放,分为甲类&#xff0c;已类&#xff0c;甲乙类和D类。 首先要认识三极管&#xff0c;三极管最简单的理解为B极向E极流过一个较小的电流的时候&#xff0c;C极可以向E极流过一个较大的电流&#xff0c;而且两个电流之间呈现倍数关系&#xff0…

STM32启动过程及反汇编

STM32从Flash启动的过程&#xff0c;主要是从上电复位到main函数的过程&#xff0c;主要有以下步骤&#xff1a; 1.初始化堆栈指针 SP_initial_sp&#xff0c;初始化 PC 指针Reset_Handler 2.初始化中断向量表 3.配置系统时钟 4.调用 C 库函数_main 初始化用户堆栈&#xf…

Linux网络编程 ——UDP 通信

Linux网络编程 ——UDP 通信 1. UDP1.1 UDP 通信1.2 广播1.3 组播&#xff08;多播&#xff09; 2. 本地套接字 1. UDP 1.1 UDP 通信 输入 man 2 sendto 查看说明文档 #include <sys/types.h> #include <sys/socket.h>ssize_t sendto(int sockfd, const void *buf…

内存安全的编程语言

美国政府新颁布《回归基础构件&#xff1a;通往安全软件之路》 《回归基础构件&#xff1a;通往安全软件之路》中&#xff0c;白宫国家网络主任办公室&#xff08;ONCD&#xff09;呼吁开发者使用「内存安全的编程语言」 内存安全的编程语言 根据NSA的建议&#xff0c;内存…

线程的同步互斥机制3月4日

题目&#xff1a; 代码&#xff1a; #include <stdio.h> #include <pthread.h> #include <string.h> #include <semaphore.h> #include <unistd.h>sem_t sem1,sem2;void* callback1(void*arg) {while(1){if(sem_wait(&sem1)<0) //等待…

keycloak-操作keycloak数据库添加用户及密码

一、环境描述 keycloak连接本地数据库的方法&#xff1a;keycloak-连接本地数据库-CSDN博客 连接数据库后&#xff0c; 用户数据表&#xff1a;user_entity 密码数据表&#xff1a;credential keycloak版本&#xff1a;23.0.7 二、开始干活 1、插入数据到用户表(user_entit…

使用 gulp-cleanwxss 清除小程序无用样式代码

小程序在迭代中&#xff0c;因没有及时清理无用样式&#xff0c;造成包体积越来越大。而通过人工判断清除工作量大&#xff0c;因而使用 gulp-cleanwxss 实现脚本清除。 一、Demo 演示 二、实现步骤 1、全局安装 gulp 命令行工具 yarn global add gulp-cli2、局部安装依赖 gu…

【Linux-shell系列】多脚本同时启动

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…