Linux 内核源码阅读——ipv4

news2025/3/25 22:13:24

Linux 内核源码阅读——ipv4

综述

在 Linux 内核中,IPv4 协议的实现主要分布在 net/ipv4/ 目录下。以下是一些关键的源文件及其作用:

1. 协议栈核心

  • net/ipv4/ip_input.c:处理接收到的 IPv4 数据包(输入路径)。
  • net/ipv4/ip_output.c:处理 IPv4 数据包的发送(输出路径)。
  • net/ipv4/ip_forward.c:实现 IP 数据包的转发逻辑。

2. 地址管理

  • net/ipv4/devinet.c:管理 IPv4 地址,包括添加、删除和查询接口地址。
  • net/ipv4/af_inet.c:实现 IPv4 协议族的 socket 操作,如 socket()bind()connect() 等。

3. 路由子系统

  • net/ipv4/route.c:核心的路由查找和管理逻辑。
  • net/ipv4/fib_frontend.cfib_trie.c:实现基于前缀树(Trie)的 FIB(Forwarding Information Base)路由表。

4. 传输层交互

  • net/ipv4/tcp_ipv4.c:IPv4 版本的 TCP 处理。
  • net/ipv4/udp.c:IPv4 版本的 UDP 处理。
  • net/ipv4/raw.c:处理 IPv4 原始套接字(Raw Sockets)。

5. 其他重要模块

  • net/ipv4/ip_fragment.c:处理 IP 数据包的分片和重组。
  • net/ipv4/icmp.c:实现 ICMP(Internet Control Message Protocol)。
  • net/ipv4/igmp.c:实现 IGMP(Internet Group Management Protocol)。
  • net/ipv4/netfilter/ 目录:Linux 内核 Netfilter(防火墙和 NAT)相关代码。

收发包

关键数据结构

iphdr
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	__u8	ihl:4,      // IP头长度 (单位:4字节)
		version:4;       // IP版本(例如 IPv4)
#elif defined (__BIG_ENDIAN_BITFIELD)
	__u8	version:4,   // IP版本(例如 IPv4)
  		ihl:4;          // IP头长度 (单位:4字节)
#else
#error	"Please fix <asm/byteorder.h>"  // 如果没有定义大小端模式,编译时会报错
#endif
	__u8	tos;          // 服务类型(Type of Service,TOS),用于指定数据包的优先级和路由
	__u16	tot_len;      // 总长度(包括头部和数据部分),单位字节
	__u16	id;           // 标识符,用于标识分片的所有部分
	__u16	frag_off;     // 分片偏移和标志,指示是否是分片,以及分片的位置
	__u8	ttl;          // 生存时间(Time To Live),指定数据包能在网络上生存的最大跳数
	__u8	protocol;     // 上层协议类型(例如 ICMP、TCP、UDP 等)
	__u16	check;        // 校验和,用于错误检查
	__u32	saddr;        // 源 IP 地址
	__u32	daddr;        // 目标 IP 地址
	/*The options start here. */
};

收包主要接口ip_rcv

/**
 * ip_rcv - 处理接收到的 IPv4 数据包
 * @skb: 指向 socket buffer 的指针,包含接收到的数据包
 * @dev: 指向接收到数据包的网络设备的指针
 * @pt: 指向 packet_type 结构体的指针,描述数据包类型
 *
 * 该函数用于接收并处理从网络设备接收到的 IPv4 数据包。它解析 IP 头部,
 * 检查数据包的有效性,并根据协议类型(如 TCP、UDP 或 ICMP)将数据包
 * 传递给相应的协议栈进行处理。如果数据包不可达或格式无效,返回错误。
 * 如果数据包处理成功,返回 0。
 *
 * 返回值:
 *   - 0:表示数据包处理成功,已传递给适当的协议处理函数
 *   - 负值:表示错误,例如数据包格式无效或目标不可达
 */
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
@startuml

start
:网络数据包到达;
:调用 ip_rcv 函数;
:调用 ip_rcv_finish 完成处理;
:调用 ip_route_input 查找路由;
if (路由(缓存)查找成功?) then (是)
  if (是本地包?) then (是)
    :调用 ip_local_deliver 处理本地包;
    :将数据包交给本地协议栈处理;
  else (否)
    if (是多播包?) then (是)
      :调用 ip_route_input_mc 处理多播包;
      :处理多播包;
    else (否)
      :调用 ip_route_input_slow 进行慢路径处理;
      :处理路由查找未命中的情况;
        note right
	  插入缓存表rt_hash_table
      end note
    endif
  endif
else (否)
  :调用 ip_route_input_slow 进行慢路径处理;
  :处理路由查找未命中的情况;
  note right
	插入缓存表rt_hash_table
  end note
endif
stop

@enduml

在这里插入图片描述

本机包:ip_local_deliver

其他包,进行转发:ip_forward

发包主要接口ip_output

该函数的主要任务是:

  • 处理 IP 头部(如检查和更新校验和)
  • 执行 IP 选项 处理
  • 可能需要进行 分片
  • 最终调用 底层链路层接口 进行发送
int ip_output(struct sk_buff *skb)
主要流程
@startuml
start
:调用 ip_output(skb);
if (需要分片?) then (是)
    :调用 ip_fragment(skb);
    :对每个分片调用 ip_finish_output(skb);
else (否)
    :调用 ip_finish_output(skb);
endif

:进入 ip_finish_output2;
:添加链路层头部(如以太网头部);

if (存在 hh 缓存?) then (否)
    :发送 ARP 请求;
    :等待 ARP 响应;
    :缓存邻居信息;
endif

:调用 hh->hh_output(skb);
stop
@enduml

在这里插入图片描述

设备管理

事件通知处理函数——inetdev_event

处理什么事件?

NETDEV_REGISTER ——注册接口

NETDEV_UP —— 接口UP

NETDEV_DOWN —— 接口DOWN

NETDEV_CHANGEMTU —— 改变MTU

NETDEV_UNREGISTER ——注销接口

NETDEV_CHANGENAME —— 更改接口名

接口UP处理

分为普通接口和环回口处理

  1. MTU 检查
  2. 环回设备的特殊处理
  3. 启动多播(Multicast)功能

RTNetlink 消息

RTNetlink 是 Linux 内核用于网络配置和管理的接口,它通过 Netlink sockets 向用户空间传递网络相关的信息。

关键结构

static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
	 [4] = { .doit	 = inet_rtm_newaddr,  }, /* 处理新的 IP 地址添加消息 */
	 [5] = { .doit	 = inet_rtm_deladdr,  }, /* 处理删除 IP 地址的消息 */
	 [6] = { .dumpit = inet_dump_ifaddr,  }, /* 处理获取 IP 地址的消息 */
	 [8] = { .doit	 = inet_rtm_newroute, }, /* 处理新的路由添加消息 */
	 [9] = { .doit	 = inet_rtm_delroute, }, /* 处理删除路由的消息*/
	[10] = { .doit	 = inet_rtm_getroute, .dumpit = inet_dump_fib, },
#ifdef CONFIG_IP_MULTIPLE_TABLES /* 多个路由表支持 */
	[16] = { .doit	 = inet_rtm_newrule, },
	[17] = { .doit	 = inet_rtm_delrule, },
	[18] = { .dumpit = inet_dump_rules,  },
#endif
};

主要流程

在这里插入图片描述

@startuml

start
:module_init(inet_init);
floating note left:  module_init内核模块的初始化入口点
:inet_init;
note right
初始化网络协议栈中与 IP 协议相关
end note
:ip_init;
note right
初始化 IPv4 协议栈
end note
:ip_rt_init;
:devinet_init;
note right
初始化与设备相关的网络功能
end note
:rtnetlink_links[PF_INET] = inet_rtnetlink_table;
note left
注册 IPv4 相关的 Netlink 消息处理表
end note
stop


@enduml 
/**
 * module_init() - driver initialization entry point
 * @x: function to be run at kernel boot time or module insertion
 * 
 * module_init() will either be called during do_initcalls (if
 * builtin) or at module insertion time (if a module).  There can only
 * be one per module.
 */
#define module_init(x)	__initcall(x);

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

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

相关文章

宝塔平替!轻量级开源 Linux 管理面板 mdserver-web

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 想必很多人刚接触 Linux 云服务器的时候都听过或者用过宝塔面板&#xff0c;对于小白来说&#xff0c;使用面板大大降低了服务器运维的难度&#xff0c;一键安装 LNMP 环境就可以建站了&#xff0c;像是 N…

基于springboot+vue的网络海鲜市场

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

QT开发(6)--信号和槽

这里写目录标题 1. 信号和槽概述信号的本质槽的本质 2. 信号和槽的使用2.1 连接信号和槽2.2 文档查询 3.自定义信号和槽3.1 自定义槽3.2 自定义信号3.3 带参数的信号和槽 4. 信号和槽的断开 1. 信号和槽概述 在Qt中&#xff0c;⽤⼾和控件的每次交互过程称为⼀个事件。⽐如&quo…

Linux部署DHCP服务脚本

#!/bin/bash #部署DHCP服务 #userli 20250319#检查是否为root用户 if[ "$USER" ! "root" ] thenecho "错误&#xff1a;非root用户&#xff0c;权限不足&#xff01;"exit 0 fi#配置网络环境 read -ep "请给本机配置一个IP地址(不…

Dervy数据库

Derby 和 Sqlite 数据库都是无需安装的数据库 Derby 和 Sqlite 数据库的配置与使用_derby sqlite-CSDN博客 Derby数据库简明教程_原味吐司-腾讯云---开发者社区 下载 对于jdk1.8及以上 Apache Derby 10.14.2.0 Release 进入bin 找到 启动服务端 进入bin目录 实际上是启…

Pythonic编程设计风格解析

Python 作为一种“优雅”、“简洁”、“明确”的编程语言&#xff0c;自诞生以来便以其极强的可读性和简洁的语法风靡全球。然而&#xff0c;真正掌握 Python 并不仅仅是会写 Python 代码&#xff0c;更在于是否写出了Pythonic 风格的代码。什么是 Pythonic&#xff1f;Guido v…

Json的应用实例——cad 二次开发c#

以下是一个使用AutoCAD C#.NET API实现你需求的示例代码&#xff0c;代码实现了提示用户选择一个实体&#xff0c;将一些字符串变量及其对应的值组成JSON格式数据存储到实体的扩展数据&#xff08;XData&#xff09;中&#xff0c;并在弹出窗口中显示该实体的所有扩展数据信息。…

免费送源码:Java+springboot+MySQL 房屋租赁系统小程序的设计与实现 计算机毕业设计原创定制

目 录 摘要 1 1 绪论 1 1.1选题意义 1 1.2开发现状 1 1.3springboot框架介绍 1 1.4论文结构与章节安排 1 2 房屋租赁系统小程序系统分析 3 2.1 可行性分析 3 2.1.1 技术可行性分析 3 2.1.2 经济可行性分析 3 2.1.3 法律可行性分析 3 2.2 系统功能分析 3 2.2.1 功…

个人学习编程(3-22) leetcode刷题

连续子数组&#xff1a;&#xff08;难&#xff09; 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。 示例 2: 输入: nums [0,1,0] 输出: 2 说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。 需要理解的知识&a…

基于python+django的酒店预定网站-酒店管理系统源码+运行步骤+课程学习

该系统是基于pythondjango开发的酒店预定管理系统。适用场景&#xff1a;大学生、课程作业、毕业设计。学习过程中&#xff0c;如遇问题可在github给作者留言。共同学习技术 演示地址 前台地址&#xff1a; http://hotel.gitapp.cn 后台地址&#xff1a; http://hotel.gitapp…

Spring 6: 3容器-Ioc

3、容器&#xff1a;IoC IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;是一个重要的面向对象编程法则&#xff0c;能够指导我们如何设计出松耦合、更优良的程序。 Spring 通过 IoC 容…

【漫话机器学习系列】154.岭回归(Ridge Regression)

岭回归&#xff08;Ridge Regression&#xff09;详解 1. 引言 岭回归&#xff08;Ridge Regression&#xff09;是一种改进的线性回归方法&#xff0c;它通过引入正则化项来解决普通最小二乘法&#xff08;OLS, Ordinary Least Squares&#xff09;可能遇到的多重共线性问题…

wsl2配置xv6全解(包括22.04Jammy)

文章目录 获取xv6源代码Ubuntu20.04 Version安装指令成功测试参考MIT2021年官方文档 24.04 Version安装指令成功测试参考MIT2024年官方文档 Ubuntu 22.04没有官方文档&#xff1f; 配置大体流程1. 卸载原本qemu&#xff08;如果之前安装了&#xff09;2. clone qemu官方源代码&…

并查集——108. 冗余连接

108. 冗余连接 题目描述 有一个图,它是一棵树,他是拥有 n 个节点(节点编号1到n)和 n - 1 条边的连通无环无向图(其实就是一个线形图),如图: 现在在这棵树上的基础上,添加一条边(依然是n个节点,但有n条边),使这个图变成了有环图,如图: 先请你找出冗余边,删除后…

初识XXL-JOB分布式任务调度

XXL-JOB架构分析 设计思想 将调度行为抽象形成"调度中心"公共平台&#xff0c;而平台自身并不承担业务逻辑&#xff0c;"调度中心"负责发起调度请求。 将任务抽象成分散的JobHandler&#xff0c;交由"执行器"统一管理&#xff0c;"执行器…

【数据结构进阶】位图

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 一、位图的概念与结构 二、位图的实现 1. 结构定义 2. 构造函数 3. 三大接口实现 set unset test 总代码 4. 测试 三、 标准库的…

[极客大挑战 2019]BabySQL—3.20BUUCTF练习day4(3)

[极客大挑战 2019]BabySQL-3.20BUUCTF练习day4(3) 做题过程 打开是以下页面&#xff08;前几天有它的第一版和第二版出现&#xff09;输入1’ 回显以下内容&#xff08;还是字符型以单引号闭合&#xff0c;因为有报错信息回显&#xff09; 输入1 order by 4%23回显成这个 被过…

JVM 学习前置知识

JVM 学习前置知识 Java 开发环境层次结构解析 下图展示了 Java 开发环境的层级关系及其核心组件&#xff0c;从底层操作系统到上层开发工具&#xff0c;逐步构建完整的开发与运行环境&#xff1a; 1. 操作系统&#xff08;Windows, MacOS, Linux, Solaris&#xff09; 作用&…

数智读书笔记系列021《大数据医疗》:探索医疗行业的智能变革

一、书籍介绍 《大数据医疗》由徐曼、沈江、余海燕合著&#xff0c;由机械工业出版社出版 。徐曼是南开大学商学院副教授&#xff0c;在大数据驱动的智能决策研究领域颇有建树&#xff0c;尤其在大数据驱动的医疗与健康决策方面有着深入研究&#xff0c;曾获天津优秀博士论文、…

解决python配置文件类configparser.ConfigParser,插入、读取数据,自动转为小写的问题

配置类 [Section1] Key_AAA Value[Section2] AnotherKey Value默认情况下&#xff0c;ConfigParser会将ini配置文件中的KEY&#xff0c;转为小写。 重载后配置类&#xff1a; 继承类从configparser.ConfigParser改为configparser.RawConfigParser重载方法optionxform&#…