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命令之firewalld的用法

《Linux命令之firewalld的用法》:本文主要介绍Linux命令之firewalld的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux命令之firewalld1、程序包2、启动firewalld3、配置文件4、firewalld规则定义的九大

Linux之计划任务和调度命令at/cron详解

《Linux之计划任务和调度命令at/cron详解》:本文主要介绍Linux之计划任务和调度命令at/cron的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux计划任务和调度命令at/cron一、计划任务二、命令{at}介绍三、命令语法及功能 :at

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1