linux之网络子系统-本机发包到本机 实现

news2024/9/21 16:35:08

一、前言

在linux之网络子系统-网络协议栈 发包收包详解-CSDN博客 文章中,详细介绍了跨主机之间的数据包发送的源码流程。除了跨主机,还有本机发包到本机是如何实现的?就是 saddr ip地址为 127.0.0.1 .

二、发送数据包到 127.0.0.1

首先,127.0.0.1 就是指 lo (本地回环网络设备):

 这个lo设备是在 网络设备子系统 初始化时注册的:

static int __init net_dev_init(void)
{

.....
        if (register_pernet_device(&loopback_net_ops))
                goto out;
...

}

 接着看 loopback_net_ops:

/* Registered in net/core/dev.c */
struct pernet_operations __net_initdata loopback_net_ops = {
        .init = loopback_net_init,
};
 

接着  loopback_net_init:

/* Setup and register the loopback device. */
static __net_init int loopback_net_init(struct net *net)
{
        struct net_device *dev;
        int err;

        err = -ENOMEM;

//初始化 lo 网络设备
        dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup); 
        if (!dev)
                goto out;

        dev_net_set(dev, net);

//注册lo 网络设备
        err = register_netdev(dev);
        if (err)
                goto out_free_netdev;

        BUG_ON(dev->ifindex != LOOPBACK_IFINDEX);
        net->loopback_dev = dev;
        return 0;

out_free_netdev:
        free_netdev(dev);
out:
        if (net_eq(net, &init_net))
                panic("loopback: Failed to register netdevice: %d\n", err);
        return err;
}
 

 

上面是 网络设备子系统初始化完成,那么如何被调用到?

根据之前的文章中,描述了跨主机的发包过程:

 发包过程中,到达 网络设备子系统 dev_queue_xmit 时,会选择 lo 网络设备驱动的ndo_start_xmit 回调函数。这个驱动没有实际的硬件设备,纯属软件意义上的驱动。

lo 驱动是如何定义 ndo_start_xmit 回调函数?

函数调用链:

loopback_net_init ->

        loopback_setup->

                gen_lo_setup

 static void loopback_setup(struct net_device *dev)
{
        gen_lo_setup(dev, (64 * 1024), &loopback_ethtool_ops, &eth_header_ops,
                     &loopback_ops, loopback_dev_free);
}

 loopback_ops 定义如下:

static const struct net_device_ops loopback_ops = {
        .ndo_init        = loopback_dev_init,
        .ndo_start_xmit  = loopback_xmit,
        .ndo_get_stats64 = loopback_get_stats64,
        .ndo_set_mac_address = eth_mac_addr,
};
 

 本机发送数据包时,调用 loopback_xmit 函数:

/* The higher levels take care of making this non-reentrant (it's
 * called with bh's disabled).
 */
static netdev_tx_t loopback_xmit(struct sk_buff *skb,
                                 struct net_device *dev)
{
        int len;

        skb_tx_timestamp(skb);

        /* do not fool net_timestamp_check() with various clock bases */
        skb->tstamp = 0;

        skb_orphan(skb);

        /* Before queueing this packet to netif_rx(),
         * make sure dst is refcounted.
         */
        skb_dst_force(skb);

        skb->protocol = eth_type_trans(skb, dev);

        len = skb->len;
        if (likely(netif_rx(skb) == NET_RX_SUCCESS)) // lo 驱动中直接调用 接收数据包的软中断。
                dev_lstats_add(dev, len);

        return NETDEV_TX_OK;
}
 

 看到了驱动与网络设备子系统的接口函数netif_rx ,然后会触发软中断,接收数据包。

上面已经把主机发包到本机的流程已经分析完毕,和跨主机的流程基本一致,都是到驱动层。

本机网络 IO 需要进行 IP 分片吗?

因为和正常的网络层处理过程一样,如果 skb 大于 MTU 的话,仍然会进行分片。
只不过 lo 的 MTU 比 Ethernet 要大很多。
通过 ifconfig 命令就可以查到,普通网卡一般为 1500,而 lO 虚拟接口能有 65535。

在内核源码中, 65535 是用 (64*1024)表示的,单位是字节。


 

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

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

相关文章

Go语言编程 学习笔记整理 第2章 顺序编程 前半部分

前言:《Go语言编程》编著 许式伟 吕桂华 等 1.1 变量 var v1 int var v2 string var v3 [10]int // 数组 var v4 []int // 数组切片 var v5 struct { f int } var v6 *int // 指针 var v7 map[string]int // map,key为string类型,value为in…

神经网络理论(机器学习)

motivation 如果逻辑回归的特征有很多,会造出现一些列问题,比如: 线性假设的限制: 逻辑回归是基于线性假设的分类模型,即认为特征与输出之间的关系是线性的。如果特征非常多或者特征与输出之间的关系是非线性的&#…

职场新人必备神器:四款PDF转Word在线转换工具大比拼

关于PDF文件格式转换这件事,其实已经变成了职场人都要会的基础技能了,那么要如何才能够快速且完成的PDF转换为Word呢?今天就让我用自己的毕生所学给大家说说四款pdf转word在线转换免费的工具吧,下面一起来了解一下吧。 一、福昕PD…

【C++】流插入和流提取运算符重载

目录 前言ostream和istream自定义类型的流插入重载自定义类型的流提取重载解决私有问题日期类总接口 前言 我们在上一节实现日期类时,在输入和输出打印时,经常会调用两个函数: void Insert()//输入函数{cin >> _year;cin >> _mo…

ARDUINO 上传失败:上传错误:退出状态 2常见原因及解决方法Failed uploading: uploading error: exit status

前言: 串口监视器可显示各种ESP32打印信息 下述均为USB TYPEC 数据线正常的情况下的报错,如果数据线或串口有问题 原因1:无法连接到ESP32:串行数据流停止:可能存在串行噪音或损坏 解决方法:ESP32电路板是…

一文速览llama 3.1及其微调:长度终于到128K,故可让paper-review数据集直接微调

前言 llama3 刚出来时,其长度只有8K对于包括我司在内的大模型开发者是个小小的缺憾,好在很快,在7.23日,Meta发布了Llama 3.1,其意义在于 很明显,随着llama的影响力越来越大,Meta想让llama类似…

(雷达数据处理中的)跟踪算法(1) --- 整体目录

说明 目标跟踪是雷达数据处理中核心的步骤之一,基于雷达的各项应用往往需要跟踪模块所输出的结果。比如在车载雷达领域,目标跟踪位于点云聚类和ADAS功能实现之间(关于聚类,可以参考我之前的博文[1]:(毫米波雷达数据处理…

macOS 10.15中屏蔽Microsoft Edge浏览器的更新提示

文章目录 1.效果对比2.安装描述文件3.停用描述文件4.高级操作(可选)参考文献 最近在macOS10.15系统,打开Microsoft Edge浏览器,每次打开都有个烦人的提示“ 要获取将来的 microsoft edge 更新,需要 macos 10.15 或更高…

C#实战 | 天行健、上下而求索

本文介绍C#开发入门案例。 01、项目一:创建控制台应用“天行健,君子以自强不息” 项目说明: 奋斗是中华民族的底色,见山开山,遇水架桥,正是因为自强不息的奋斗,才有了辉煌灿烂的中华民族。今…

单向链表知识汇总

提示:本文章参考知乎大佬和一位博主大佬 单向链表 1.前置知识(部分最好记忆)1.1 链表组成1.2 链表插入分三种情况1.2.1头插1.2.2 中间插1.2.2 结尾插 1.3 链表的删除1.51.61.7 2.链表各种接口的实现2.1 链表的打印2.1 链表的节点的申请2.2 单链表节点增加2.2.1 单链…

【常微分方程】

框架 常微分方程的概念一阶微分方程可变离分量齐次方程一阶线性微分方程可降阶的高阶微分方程二阶常系数齐次线性微分方程二阶常系数非齐次线性微分方程 讲解 【1】 常微分方程:是微分方程的特殊情况; 阶:是方程未知函数的最高阶导数的阶数&…

关于pycharm上push项目到gitee失败原因

版权声明:本文为博主原创文章,如需转载请贴上原博文链接:https://blog.csdn.net/u011628215/article/details/140577821?spm1001.2014.3001.5502 前言:最近新建项目push上gitee都没有问题,但是当在gitee网站进行了一个…

【笔记:3D航路规划算法】二、RRT*

目录 一、RRT*于RRT的不同之处1、路径优化:2、成本计算:3、重连线步骤: 二、图解1、初始化2、路径搜索3、效果展示 3D路径规划是在三维空间中寻找从起点到终点的最短或最优路径的一种技术。它广泛应用于无人机导航、机器人运动规划、虚拟现实…

开源软件项目:趋势、参与经验与收获

在当今这个全球经济与科技日新月异的时代,开源软件项目(Open Source Software, OSS)正以前所未有的速度蓬勃发展,成为推动技术创新、促进产业合作、加速知识共享的重要力量。随着云计算、大数据、人工智能等技术的兴起&#xff0c…

C#入门与精通

C#精通 本文章主要是对于学习C#基础难点进行学习以及与java语言的不同点,详细学习可见官网:https://dotnet.microsoft.com/en-us/learn 文章目录 C#精通VSVS基本设置 C#是什么C#程序控制台输出变量内插占位符C#foreach循环类型转换操作数组内置方法格式设…

Java智慧养老养老护理帮忙代办陪诊陪护小程序系统源码

🌟智慧养老新风尚,护理代办陪诊小程序来帮忙✨ 🏡【开篇:关爱老人,从智慧养老开始】🏡 随着社会的进步,智慧养老已成为新时代孝心的体现。面对忙碌的生活节奏,如何更好地照顾家中长…

三、基础语法2(30小时精通C++和外挂实战)

三、基础语法2(30小时精通C和外挂实战) B-02内联函数B-04内联函数与宏B-05_constB-06引用B-07引用的本质B-08-汇编1-X86-X64汇编B-09-汇编2-内联汇编B-10-汇编3-MOV指令C-02-汇编5-其他常见指令C-05-汇编8-反汇编分析C-07-const引用、特点 B-02内联函数 …

智能时代的伦理困境:如何应对AI引发的社会问题

文章目录 每日一句正能量前言构建可靠的AI隐私保护机制1. **数据最小化原则**2. **数据匿名化和去标识化**3. **加密技术**4. **访问控制**5. **数据使用透明度**6. **用户控制权**7. **数据保护影响评估**8. **法规遵从性**9. **隐私设计**10. **安全意识教育和培训**11. **持…

C++自定义字典树结构

代码 #include <iostream> using namespace std;class TrieNode { public:char data;TrieNode* children[26];bool isTerminal;TrieNode(char ch){data ch;for (int i 0; i < 26; i){children[i] NULL;}isTerminal false;} }; class Trie { public:TrieNode* ro…

Transformer和预训练模型是什么

目前我们使用的OpenAI的ChatGPT是一种基于GPT-3.5或GPT-4的聊天机器人&#xff0c;能够实现人与机器之间的自然语言交互。那么GPT是什么呢&#xff1f; GPT是一种语言模型&#xff0c;它是由OpenAI实验室于2018年推出的基于Transformer架构的预训练语言模型&#xff0c;通过处理…