一、路由的基本概念
1、一条路由就是一组参数,这些参数存储了往一个给定目的地转发流量所需的信息,而一条路由所需的最少的参数集合为:(1)目的网络,(2)出口设备,(3)下一跳网关
2、路由中的相关术语:(1)对称路由:如果从主机A到主机B的路由与从主机B返回主机A的路由相同,这样的路由称为对称路由,(2)metric:是一条路由上配置的可选参数,不要与路由协议中的metric混淆,后者用于衡量一条路由的好坏,路由协议metric的例子有端到端延迟(end-to-end delay),跃点数(the number of hops),配置权值(weight)或开销(cost)等
3、IP地址的Scope:在Linux中,IP地址的scope表示该IP地址距离本地主机有多远。IP地址常用的scope:(1)、主机(host):当一个地址只用于主机自身的内部通信时,其scope为主机,在这个主机以外不知道该地址,并且不能被用于外部通信。(2)、链路(link):当一个地址只在一个局域网内有意义且只在局域网内使用时,该地址的scope为链路。(3)、全域(Universe):当一个地址可以在任何地方使用时,其scope为全域,这是大多数地址的默认scope。需要注意的是,scope不能反映不可路由(私有)与可路由(公开)地址之间的区别,两者都可以是链路或全域
4、路由的Scope:路由的scope表示到目的网络的距离,路由常用的scope:(1)、主机(host):当一条路由表示目的地址为本地主机时,其scope为主机,(2)、链路(link):当一条路由表示的目的地址为本地网络时,其scope为链路,(3)、全域(universe):当一条路由表示的目的地址超过下一跳时,其scope为全域
5、主地址与辅助地址:当在一个接口上配置一个IP地址时,同时需要提供一个子网掩码,否则系统将根据IP所属的类来自动选择一个默认的子网掩码只能有一个主地址,而对于不同的子网掩码,即使两个子网覆盖的地址有重叠,也会各自拥有一个主地址。注意:当主机为本地生成的流量选择源IP地址时,只考虑主地址
6、Linux中使用一张独立的、基于Hash的路由表,该表只存储本地地址,更准确的说,在这张路由表中存储所有监听到的地址,既包括本地配置的地址,也包括子网广播地址。在默认情况下,Linux使用两张路由表:一张表用于本地地址,从该表中查找成功表明封包要提交给主机自己,另一张用于其他所有的路由,其数据项可由用户手工配置或路由协议动态插入
7、路由查找:当根据最长前缀进行匹配时,如果有多条路由都满足,则根据查找搜索关键字中的服务类型(Type of Service, TOS)进行选择。若根据TOS也无法选择路由,则优先级更高(优先权值较低)的路由被选中。如果根据优先级也无法选出路由,内核就简单地选择第一条
二、Linux内核中路由相关的主要数据结构
在数据结构名称中的rt、fib与fn前缀分别表示路由(route),转发信息库(Forwarding Information Base)和功能(function)
- struct fib_result:对路由表查找后返回该结构,它的内容并不是简单的包含下一跳信息,而且包含其他特性,例如策略路由所需的更多参数。
- struct fib_rule:表示由策略路由在路由流量时选择路由表的规则
- struct fib_node:一条路由表项。例如,该数据结构用于存储由route add或ip route add命令添加一条路由时生成的信息。
- struct fn_zone:一个zone表示子网掩码长度相同的一组路由
- struct fib_table:表示一张路由表
- struct fib_info:不同路由表项之间可以共享一些参数,这些参数被存储在fib_info数据结构中,当一个新的路由表项所用的参数与一个已经存在的路由表项所用的参数匹配时,则重复使用已经存在的fib_info结构。一个引用技术用于跟踪该结构重复使用的次数
- struct fib_alias:达到相同网络的路由,因为其他一些参数而不同,例如TOS,不同的路由是通过fib_alias实例来区分的
- struct fib_nh:表示下一跳
- struct fn_hash:该结构包含指向33个fn_zone链表头的指针,以及一个链表。这个链表将活动的zone(active zone,即那些至少有一个元素的zone)链接在一起,链表中的元素按照子网掩码长度的降序排列
- struct fn_zone_list:非空的fn_zone bucket被链接在一起,该链表的头保存在fn_zone_list中
- struct fib_info_hash:所有fib_info结构被插入到这个hash表中,用fib_find_info函数来查找该表
- struct fib_info_laddrhash:只有在路由表项有一个首选源地址时,才将fib_info结构插入到这个表中。这个hash表主要是为了方便地删除由于删除了本地配置IP地址而影响的路由
- struct flowi:类似于访问控制列表(ACL):它是根据从L3与L4包头中选择的字段值,例如,IP地址、L4端口号等,来定义一个流量集,可以将它用来作为路由查找时的搜索关键字
路由缓存相关:
1、struct dst_entry:表示路由缓存项中与协议无关的部分(DST)。适用于任何L3协议的路由表缓存项字段被放在该结构内,在L3协议所用到的数据结构内,通常嵌入该结构来表示路由缓存项
2、struct dst_ops:表示DST核心代码使用虚函数(VFT),该表用于向三层协议通知特定的事件。每个三层协议各自提供一组函数,按照自己的方式来处理这些事件,并不是所有的协议都使用VFT的每一个字段
3、struct rtable:在IPv4中表示一条路由表缓存项的数据结构,在IPv6中使用struct rt6_info
每个单独的子网对应一个fib_node实例,用变量fn_key识别,它的值就表示该子网。例如,对于子网10.1.1.0/24,fn_key为10.1.1。目的子网相同的不同路由(即fn_key相同)共享同一个fib_node。每条路由有自己的fib_alias结构。每个fib_alias实例都与一个fib_info结构相关联,该结构保存着真实路由信息(即如何到达目的地)。