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

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

linux安装、更新、卸载anaconda实践

《linux安装、更新、卸载anaconda实践》Anaconda是基于conda的科学计算环境,集成1400+包及依赖,安装需下载脚本、接受协议、设置路径、配置环境变量,更新与卸载通过conda命令... 目录随意找一个目录下载安装脚本检查许可证协议,ENTER就可以安装完毕之后激活anaconda安装更

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详