linux网络协议栈(五)网络层 (4)路由表

2024-05-09 22:32

本文主要是介绍linux网络协议栈(五)网络层 (4)路由表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5.3.3、路由表:

5.3.3.1、路由表的组成结构:
5.3.3.1.1、路由表基本组成:

路由表是一个很庞大的组织,导致关于它的相关操作也非常繁琐,所以必须深入理解路由表的组成结构。注意,基本上作为路由器网关编译的linux内核,默认都会支持策略路由,所以本文也已支持策略路由的方式描述。

Linux内核可以有最多256个路由表,一般情况下如2.10方案是2个路由表,一个用于发送给本机一个用于转发;

每个路由表首先根据子网掩码长度划分,所谓子网掩码长度就是子网掩码的二进制值中1的个数,子网掩码是多少和局域网划分相关,后面会举个例子,根据子网掩码这个32bit数可以划分为0-32共33个区,这是每个路由表的第一层划分,即按子网掩码长度划分为33个区(zone);

每个区还可以根据IP地址及其所处的子网划分为不同的网段,比如IP地址10.1.1.10/24,即掩码长度为24,对应的子网掩码为255.255.255.0,那么它的网段就是10.1.1网段,这样一来每个区可以被划分为不同的网段(node),这是对每个路由表的第二次划分;

这时就可以加入路由条目(alias)了,但还需要划分,当每个路由条目要加在路由表A的B区的C网段时,在每个网段,路由条目是按照tos大小依递增顺序排列,如果tos相同则按路由条目优先级(路由条目字段之一)的递增顺序再寻找位置,如果依然相同则把旧条目删除;注意这一步依然是一种划分,是按照tos和路由条目优先级的划分;

事实上上一步的路由条目依然是路由条目实质内容(info)的抽象,实质内容包括路由协议类型、路由标志、路由优先级、首选源IP、跃点设置、下一跳(出接口、网关、下一跳范围等,对于多路径路由会有多个下一跳),这是最终的路由条目了,强调一点一定理解这里的实质内容(info)才是真正有实质意义的路由信息,前面的一级一级的划分都是为了提高检索效率,先后根据子网掩码长度、网段、tos和路由条目优先级划分路由表,下图仅描述正常情况下路由表条目的创建,可以直观的感受下路由表的组成结构:


从数据结构来看,路由表的划分如下:


上面描述了路由表之下的组成关系,那么路由表自身是怎么回事?前面已提到在不考虑策略路由的情况下,linux内核会默认创建两个路由表,一个用于给本机,一个用于转发,若考虑策略路由,则会由用户创建路由表,不过路由表个数是编译时确定的(由宏FIB_TABLE_HASHSZ确定),最大可为256个,一般情况下为2个,2.10方案就是2个;对路由表的操作首先要明确是操作哪一个路由表。

5.3.3.1.2、路由条目详解:
了解了路由表基本的结构组成,现在要着重分析下路由表条目都包括什么内容,也就是实质内容,路由条目实际由用户配置,典型如zebra工具,通过把要配置的内容通过netlink告诉内核,涉及内容包括目的IP、下一跳网关、出接口、tos、路由协议、路由表id、路由条目优先级、路由条目控制标志、路由条目范围、多路径路由内容,在初始化时会加载内核的路由netlink的路由表操作接口,分别是添加一个路由条目(RTM_NEWROUTE)、删除一个路由条目(RTM_DELROUTE)、显示当前路由条目(RTM_GETROUTE),如下图:


典型观察路由条目的添加,首先解析用户的配置值,用户关于配置路由条目的数据结构为struct rtmsg,这是非常重要的一个数据结构,它里边就是路由条目的实质内容,在busybox和zebra工具中看到对它的使用,在内核中首先要解析它,并把它翻译成内核用于配置路由条目实质内容的数据结构struct fib_config,这些功能由函数rtm_to_fib_config完成,如下图:


现在就由用户配置值获知了要配置的包括目的IP、下一跳网关、出接口、tos、路由协议、路由表id、路由条目优先级、路由条目控制标志、路由条目范围、多路径路由内容的全部内容,下一步就是将该条目加入对应的路由表,在支持策略路由情况下,内核对路由表的操作包括定位、创建(fib_get_table函数、fib_new_table函数),这是因为用户有可能会新创建路由表,所以这里首先由获知的所操作的路由表确定内核里的路由表,如果存在定位即可,否则需创建,如下图:


接下来就是在这个路由表(tb)中加入新的路由条目了,这里就需要详细的描述下路由表自身的结构,它由结构体struct fib_table描述,它包括两方面内容,一方面是用于内核对它的操作,包括查找路由条目、插入路由条目、删除路由条目、显示(获取)路由条目、清除全部路由条目等等,路由表id范围是0-255,可标识最多的256个路由表,路由表和路由表之间以hash表链接;另一方面是它的路由条目内容(tb_data),实际上指向它底下33个区(zone)中第一个区,事实上相当于对于它底下的区(zone)的封装,如下图:


需要注意的是,路由条目在linux中可以有两种方式存储,一种是通过hash表的方式,另一种是trie方式,后者适用于特大型路由器效率更高,一般情况都使用hash表方式。

Linux内核对于插入路由条目的方法即路由表的tb_insert方法为函数fn_hash_insert,它首先根据用户配置的目的IP掩码长度(就是X.X.X.X/Y中的Y)确定区(zone),区(zone)在内核中由数据结构struct fn_zone模式,对于它无需细究,在这里首先要获取这个区,判断路由表的这个区是否创建过,如果没有需创建,如下图:


获得区之后(fz),再确定网段,一个区只能标识子网掩码长度,之下可以有很多不同的网段,如目的IP为3.4.5.6/24,那么网段值为3.4.5,再如目的IP为3.4.6.7/24,那么网段值为3.4.6,注意网段值是一个无符号整数,区(fz)的掩码和目的IP做与运算后的结果即网段,如下图:


定位到网段后,这里要先停下来,把实质内容的内核配置结构体struct fib_config翻译成路由子系统的实质内容描述结构体struct fib_info,由前面已经知道涉及内容包括路由协议类型、路由标志、路由优先级、首选源IP、跃点设置、下一跳(出接口、下一跳网关、下一跳范围等),如下图:


下一跳由结构体struct fib_nh描述,重点是下一跳网关、本地出接口、下一跳范围,还有一些路由算法相关内容可暂不关注,如下图:


可见对于路由表,其路由条目真正关注的实质内容是出接口、下一跳网关、下一跳范围,因为它们决定了报文应该从哪个接口出去并且发向何方;

这里需要注意的是多路径路由的情况,所谓多路径路由是指这个路由条目中,含有多个去向的选择(fib_nhs值大于1),每个去向的出接口、下一跳网关、跃点是可以不同的,其他字段相同;

多路径路由的意义,实现了报文在同一个路由表的同一个路由条目下,可以有不止一种路由结果,可以有不同的出接口、下一跳网关、下一跳范围;

一定注意多路径路由和策略路由的区别,策略路由给予报文走向不同路由表的相关条目的选择,但多路径路由是在同一路由表的同一路由条目中可以有不同的路由结果,这是本质上的不同。

至此,涵盖下一跳的路由条目实质内存fib_info翻译完毕,涉及内容包括路由协议类型、路由标志、路由优先级、首选源IP、跃点设置、下一跳(出接口、下一跳网关、下一跳范围等),接下来依据之前计算而得的网段值确定该网段(fib_node)是否创建,如下图:


如果网段已存在,则进一步查看该网段下的路由条目(fib_alias)创建情况,由之前已知网段下的每个路由条目(fib_alias)按tos字段递增排列,如tos相同则按照路由条目优先级(fib_priority)字段递增排列,若也相同则删除旧条目;如果还没有创建路由条目则必须创建路由条目(fib_alias);

如果网段不存在,则说明之前一直没有过该网段的路由条目内容,所以网段下也不存在任何路由条目,同样需要创建,网段和路由条目的创建都是由slab分配,在初始化时就已把它们各自的结构体大小注册进slab分配器;创建后分别插入各自的上一层结构体,需要注意对于路由条目fib_alias,它不仅要挂接路由实质内容fib_info(包含下一跳内容),自身也记录路由条目的tos、路由类型、下一跳范围。

至此,完成了一个路由条目在一个路由表的注册,每个路由表根据子网掩码长度划分为33个区(fz_zone),每个区(fz_zone)可以有很多的网段(fib_node),每个网段下有一个个的路由条目(fib_alias),每个路由条目(fib_alias)包含了路由实质内容(fib_info),路由实质内容(fib_info)中记录了路由条目的tos、路由类型、下一跳范围和下一跳(fib_nh),下一跳(fib_nh)是路由实质内容的核心,记录了出接口、下一跳网关、下一跳范围,需要注意不同的路由条目(fib_alias)可以共用一个路由实质内容fib_info),如路由条目(fib_alias)的tos不同,但它们都指向同一个路由实质内容fib_info);下图是一个细致的描述图:



这篇关于linux网络协议栈(五)网络层 (4)路由表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974688

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面