【C语言】linux内核dev_queue_xmit

一、中文注释

这两个函数是Linux内核网络子系统中负责发起网络包(sk_buff结构)传输的代码。下面我将用中文对这两个函数做一个简单的注释:

/**
 * __dev_queue_xmit - 发送一个buffer
 * @skb: 要发送的buffer
 * @sb_dev: 子设备,用于层2转发离线处理
 *
 * 将buffer排队以发送到网络设备。调用此函数之前,调用者必须设置好设备和优先级,并构建好buffer。
 * 这个函数可以在中断上下文中调用。
 *
 * 如果失败,则返回一个负的errno错误码。成功返回并不保证帧一定会被发送,因为可能会因为拥塞或流量整形而被丢弃。
 *
 * 注意,这个方法也可以返回队列规则(queue disciplines)的错误,
 * 包括NET_XMIT_DROP,它是一个正值。所以,错误也可能是正值。
 *
 * 不管返回的值是什么,skb都会被消耗,所以当前很难尝试重新发送到这个方法。
 * (如果你小心的话,在发送前,你可以增加引用计数以持有引用进行重试。)
 *
 * 调用此方法时,中断必须是启用的。这是因为BH(Bottom Half,底半部)启用代码必须在IRQ启用的情况下,
 * 不会造成死锁。
 */
static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
{
    // 省略代码中部分注释和实现...
  
    // 如果网络设备并没有队列(例如环回设备,隧道),则直接发送
    if (dev->flags & IFF_UP) {
        int cpu = smp_processor_id(); // 当前CPU编号

        // 如果还没有线程持有发送锁
        if (txq->xmit_lock_owner != cpu) {
            // 省略了关于递归发送检测和发送限制的代码...
            
            skb = validate_xmit_skb(skb, dev, &again);
            if (!skb)
                goto out;

            HARD_TX_LOCK(dev, txq, cpu); // 获取硬件发送锁

            // 如果可以发送(没有被停止)
            if (!netif_xmit_stopped(txq)) {
                // 尝试发送数据包
                skb = dev_hard_start_xmit(skb, dev, txq, &rc);
                // 如果发送完成
                if (dev_xmit_complete(rc)) {
                    HARD_TX_UNLOCK(dev, txq); // 解锁
                    goto out;
                }
            }
            HARD_TX_UNLOCK(dev, txq); // 解锁
            // 如果虚拟设备请求排队发送数据包,打印告警信息
        } else {
            // 如果检测到递归发送,打印告警信息
        }
    }

    rc = -ENETDOWN; // 网络设备不可用
    rcu_read_unlock_bh(); // 读解锁

    atomic_long_inc(&dev->tx_dropped); // 增加丢包计数
    kfree_skb_list(skb); // 释放skb
    return rc;
out:
    rcu_read_unlock_bh(); // 读解锁
    return rc;
}

/**
 * dev_queue_xmit - 发送一个buffer
 * @skb: 要发送的buffer
 *
 * 对__dev_queue_xmit函数的简单封装,不指定子设备。
 */
int dev_queue_xmit(struct sk_buff *skb)
{
    return __dev_queue_xmit(skb, NULL);
}
EXPORT_SYMBOL(dev_queue_xmit); // 导出符号,使得其他模块可以调用

这两个函数涉及到Linux内核网络发送路径的处理细节,包括选择设备队列、处理网络设备的发送锁、检查设备队列是否被停止、调用真正的发送函数、错误处理和资源清理等。它们体现了操作系统内核在网络通信方面的复杂逻辑和对并发控制的处理。

二、中文讲解

这两个函数是Linux内核网络堆栈中负责处理网络包发送的函数。

__dev_queue_xmit函数是一个静态函数,它的作用是将一个网络数据包(即socket buffer,简称skb)放入网络设备队列中以便传输出去。它的参数包括待发送的数据包`skb`和用于二层转发卸载的从属设备`sb_dev`。

函数内部步骤如下:

1. 通过`skb_reset_mac_header`重置数据包中的MAC头部信息。
2. 如果数据包需要软件时间戳,则添加这个时间戳。
3. 获取RCU读锁,这是因为可能会访问共享数据而不希望被其他CPU更改。
4. 更新数据包的优先级,并初始化包的传输长度信息。
5. 如果设置有特定的流量控制,会执行一些流量控制的处理。
6. 如果网络设备标志表明它不需要数据包的目的信息,则直接丢弃这部分信息。
7. 根据数据包和设备信息,选择合适的网络设备队列。
8. 如果设备有队列调度器,则尝试将数据包加入队列。
9. 如果设备不需要队列,比如是软件设备(例如回环设备或者隧道),则尝试直接传输数据包。
10. 若设备正常运作,使用硬启动传输函数`dev_hard_start_xmit`尝试传输数据包;如果设备已经关闭或发送失败,则将其丢弃,并增加丢包计数器。
11. 结束前释放之前获取的RCU读锁。

dev_queue_xmit函数是一个可导出的简单封装函数,用于调用`__dev_queue_xmit`函数。它只需要一个参数,即要发送的数据包`skb`,因为它默认不需要处理从属设备`sb_dev`。这个函数会被内核中其他模块调用,以此来发送网络数据。

注意的是,`__dev_queue_xmit`函数可以在中断上下文中调用,并且即使发送操作报告成功,也无法保证数据包一定会被传输出去,因为可能会因为网络拥堵或流量整形策略被丢弃。函数返回值可能是负的错误码,也可能是正的,例如`NET_XMIT_DROP`表示包被丢弃。一旦调用该函数发送数据包,数据包的内存就被消费了,即使发送失败也不会尝试重传。此外,在调用此函数时,必须保证中断是开启的,以避免死锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年最新整理腾讯云学生服务器价格、续费和购买流程

2024年腾讯云学生服务器优惠活动「云校园」,学生服务器优惠价格:轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年,轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年,CVM云服务器2核4G配置842.4元一年&…

Pytorch之神经网络最大池化层

池化层(Pooling layer)是深度学习神经网络中常用的一种层类型,它的作用是对输入数据进行降采样(downsampling)操作。池化层通过在输入数据的局部区域上进行聚合操作,将该区域的信息压缩成一个单一的值&…

面试题个人总结(面经)

自我介绍 你好,我叫XXX,是今天面试初级蓝队的人员,我毕业于XXXX,专业为网络空间安全,我曾经在XXXXX实习过,有过大概一年左右的工作经验,还有过一定的护网经验,去年在XXX厂商护过网,…

【计算机考研择校】四川大学vs电子科技大学哪个难度更大?

川大在文科,经管方面比科大强,医学在国内都很强。但工科方面特别是电子信息领域明显是科大强于川大。毕竟一个是综合大学,一个是工科大学不可同日而语。 就业上,电子科大在IT领域的社会声誉口碑不错。就业一向都很好。这个多问问…

Swin-UMamba—基于 Mamba 的 UNet 和基于 ImageNet 的预训练—论文精读和代码实践

Swin-UMamba 期刊分析摘要贡献方法Swin-UMamba整体框架1. 基于 Mamba 的 VSS 块2. 集成基于 ImageNet 的预训练3. Swin-UMamba解码器4. Swin-UMamba†:带有基于 Mamba 的解码器的 Swin-UMamba 实验代码实践 可借鉴参考 期刊分析 Swin-UMamba只是名字中含有swin&…

为什么不从独立服务器中转向云或其他方案呢?

传统的专用服务器,如香港服务器租赁、重庆服务器租赁等,是最强大、最稳定的业务托管类型之一。您将获得比任何其他托管计划更多的管理权限和卓越的性能,并且您可以控制整个服务器上的几乎所有内容。 当然,专用服务器也是在线业务…

HTML5:七天学会基础动画网页9

在进行接下来的了解之前我们先来看一下3d的xyz轴,下面图中中间的平面就相当于电脑屏幕,z轴上是一个近大远小的效果。 3d转换属性 transform 2D或3D转换 transform-origin 改变旋转点位置 transform-style 嵌套元素在3D空间如何显 …

Eclipse调试技巧 条件断点 监视

实验代码 import java.util.Scanner;public class Test {// 判断n是否为质数public static boolean isPrime(int n){if (n < 2)return false;for (int i 2; i < n; i){if (n % i 0)return false;}return true;}public static void main(String[] args){Scanner scanne…

类初步认识与对象

一&#xff0c;对于面向对象的认识 Java是一门面向对象的语言&#xff0c;一切都可以称为对象。将一个大象装进冰箱&#xff0c;甭管步骤多复杂&#xff0c;大象便是对象&#xff1b;将牛奶放进冰箱&#xff0c;牛奶便是对象&#xff1b;你我均是对像。 再比如洗一个衣服&…

JavaScript——流程控制(程序结构)

JavaScript——流程控制&#xff08;程序结构&#xff09; 流程控制就是来控制我们的代码按照什么结构顺序来执行。更倾向于一种思想结构。 流程控制分为三大结构&#xff1a;顺序结构、分支结构、循环结构 1、顺序结构 ​ 代码从上往下依次执行&#xff0c;从A到B执行&#x…

Java毕业设计 基于SpringBoot vue 疫苗咨询与预约系统

Java毕业设计 基于SpringBoot vue 疫苗咨询与预约系统 SpringBoot vue 疫苗咨询与预约系统 功能介绍 用户前端&#xff1a;首页 图片轮播 疫苗信息 条件查询 疫苗详情 点我收藏 评论 接种疫苗 疫情资讯 资讯详情 资讯评论 论坛交流 发布帖子 公告信息 公告详情 留言反馈 登录…

arm架构服务器使用Virtual Machine Manager安装的kylin v10虚拟机

本文中使用Virtual Machine Manager安装kylin v10的虚拟机 新建虚拟机 新建虚拟机 选择镜像&#xff0c;下一步 设置内存和CPU&#xff0c;下一步 选择或创建自定义存储&#xff08;默认存储位置的磁盘空间可能不够用&#xff09; 点击管理&#xff0c;打开选择存储卷页…

[linux]shell脚本语言:变量、测试、控制语句以及函数的全面详解

一、shell的概述 1、shell本质是脚本文件&#xff1a;完成批处理。 shell脚本是一种脚本语言&#xff0c;我们只需使用任意文本编辑器&#xff0c;按照语法编写相应程序&#xff0c;增加可执行权限&#xff0c;即可在安装shell命令解释器的环境下执行。shell 脚本主要用于帮助开…

【软件测试】如何申请专利?

一、专利类型 在软件测试领域&#xff0c;可以申请发明专利、实用新型专利和外观设计专利。其中&#xff0c;发明专利是最常见的专利类型&#xff0c;它保护的是软件测试方法、系统和装置等技术方案。 二、申请专利的条件 申请专利需要满足新颖性、创造性和实用性三个条件。…

饮料换购 刷题笔记

直接开个计数器mask 每当饮料现存数-1&#xff1b; cnt;且mask; 一旦mask达到3 饮料现存数 计数器清零3 代码 #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int main(){ int n; …

【AIGC】如何提高Prompt准确度

前言 随着人工智能的迅猛进展&#xff0c;AIGC&#xff08;通用人工智能聊天工具&#xff09;已成为多个行业中不可或缺的自然语言处理技术。Prompt作为AIGC系统的一项关键功能&#xff0c;在工具的有效运作中发挥了举足轻重的作用。本篇文章将深入探讨Prompt与AIGC之间的紧密…

迭代器失效问题(C++)

迭代器失效就是迭代器指向的位置已经不是原来的含义了&#xff0c;或者是指向的位置是非法的。以下是失效的几种情况&#xff1a; 删除元素&#xff1a; 此处发生了迭代器的失效&#xff0c;因为erase返回的是下一个元素的位置的迭代器&#xff0c;所以在删除1这个元素的时候&…

SAP Parallel Accounting(平行分类账业务)配置及操作手册(超详细的说明和测试)

SAP Parallel Accounting(平行分类账业务)配置及操作手册 1、Overview 为了适应不同的会计准则&#xff0c;SAP在新总账中启用了多分类账&#xff0c;&#xff08;其作用简单来说就是&#xff0c;同时一笔记账&#xff0c;会产生多个账套的凭证。&#xff09;分类账可以对应一…

Python之Web开发中级教程----搭建SSH环境

Python之Web开发中级教程----搭建SSH环境 SSH 的全称是 “安全的 Shell(Secure Shell)”&#xff0c;它功能强大、效率高&#xff0c;这个主流的网络协议用于在两个远程终端之间建立连接。让我们不要忘记它名称的“安全”部分&#xff0c;SSH 会加密所有的通信流量&#xff0c…

C语言从入门到精通 第十二章(程序的编译及链接)

写在前面&#xff1a; 本系列专栏主要介绍C语言的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C语言教材&#xff0c;笔者认为重要的部分大多都会用粗体标注&#xf…