第三十二章:路由:Linux的实现

路由相关的内核选项:

路由选项可以分为两类:一类是永远支持的,只需要用户通过比如/proc来配置或开启;一类是编译内核时可以添加或删除的选项。

基本选项:略

高级选项:略

    

主要的数据结构:

在数据结构名称中的rt,fib,fn前缀分别表示路由,转发信息库,功能。

struct ip_rt_acct:该结构被基于路由表的分类器使用。

struct rt_cache_stat:存储路由查找的统计信息。

struct inet_peer:维护远程ip端点的长期信息。

struct fib_result:对路由表查找后返回该结构。

struct fib_rule:表示策略路由在路由流量时选择路由表的规则。

struct flowi:从某种程度上来说类似访问控制列表,它是根据从L3与L4包头中选择的字段值,如ip地址,L4端口号等来定义一个流量集。

下面这些结构用于构造路由表:

struct fib_node:一条路由表项。

struct fn_zone:一个zone表示子网掩码长度相同的一组路由。

struct fib_table:表示一张路由表。

struct fib_info:不同路由表项之间可以共享一些参数,这些参数被存在该结构内。

struct fib_alias:到达相同网路的路由,因为一些其他参数而不同,比如tos,不同的路由是通过fib_alias来区分的。

struct fib_nh:表示下一跳。

struct fn_hash:该结构包含指向33个fn_zone链表头的指针,以及一个链表,这个链表将那些至少有一个元素的zone链接在一起。

下面这些结构用于协议有关的路由缓存代码和协议无关的路由缓存代码(DST):

struct dst_entry:表示路由表缓存项中与协议无关的部分,适用于任何L3协议的路由表缓存项字段被放在该结构内。

struct dst_ops:表示DST核心代码使用虚函数表(VFT),用于向L3通知特定的事件。

struct rtable:在ipv4中表示一条路由表缓存项的结构。

下面的数据结构通常用于路由配置:

struct kern_rta:当内核收到添加或删除一条路由请求时,这个请求来自用户空间的一条IPROUTE2命令,内核就解析请求并保存到该结构内。

struct rtentry:当使用route命令向内核发送添加或删除路由表向的请求时所用的结构。

struct fib_iter_state:当遍历一张路由表的数据结构实例时,用该结构存储上下文信息。

下面的结构用于多路径缓存特性:

struct ip_mp_alg_ops:表示多路径缓存算法。

struct multipath_device:在设备循环缓存算法中用于跟踪设备信息

struct multipath_candidate:

struct multipath_dest:

struct multipath_bucket:

struct multipath_route:这几个结构都是加权随机算法中用于算法所需的状态信息。

下面是两个通用的数据结构链表与hash表:

hlist_head:

hlist_node:hash表是用这两种数据结构实现的。

路由scope和地址scope:

路由scope被保存在fib_alias的说一句结构内的fa_scope字段,下面是ipv4路由代码中的主要scope:

    RT_SCOPE_NOWHERE:非法scope,意味着没有到达目的地的路由。

    RT_SCOPE_HOST:scope为主机host

    RT_SCOPE_LINK:scope为链路。

    RT_SCOPE_UNIVERSE:scope为全域。

地址scope被保存在in_ifaddr结构内(该结构见十九章)的ifa_scope字段。

当路由查找返回socpe为RT_SCOPE_HOST的路由项,主机直接将封包提交至本地。

当路由查找返回scope为RT_SCOPE_LINK的路由项,主机可以使用二层协议直接向目的地址发送包。

路由子系统初始化:

ipv4路由代码的初始化从ip_rt_init开始,在这个函数中,ipv4路由代码初始化其数据结构和全局变量,另外还完成了下列功能:

    根据可用的内存确定路由缓存的容量。

    创建用于分配路由缓存元素的内存池。    

    初始化路由缓存。

    确定垃圾回收算法使用的gc_thresh阈值。(参见三十三章)

    启动rt_periodic_timer定时器。(参见三十三章)

    启动rt_secret_timer定时器。(参见三十三章)

    添加一些文件到/proc。

ip_fib_init函数用于初始化默认路由表,用两个通知链(netdev_chain和inetaddr_chain)注册两个处理函数。

devinet_init函数使用通知链netdev_chain注册另一个处理函数,用Netlink套接字和路由命令(ip route和route)注册处理函数。

外部事件:

路由子系统对两类事件感兴趣:网路设备状态的变化和网路设备山ip地址的变化。为此,在netdev_chain和inetaddr_chain分别注册了fib_netdev_event和fib_inetaddr_event两个处理函数:

fib_netdev_event和fib_inetaddr_event函数会调用的一些辅助函数:

    void rt_cache_flush(int delay):延迟一段指定的时间后,刷新一次路由缓存。

    int fib_sync_down(u32 local,struct net_device *dev,int force):当一个设备被关闭或删除一个本地地址时跟新路由表。其其中,local表示被删除的ip,dev表示被关闭的设备,force为0,表示一个ip被删除,为1表示一个设备被关闭,为2表示一个设备被注销。

    int fib_sync_up(struct net_device *dev):内核支持多路径路由时使用该函数,其主要工作是在路由的某些下一跳为alive时,更新fib_info结构内该路由的一些参数。

    void fib_flush(void):扫描ip_fib_main_table和ip_fib_local_table,删除所有的设置有RTNH_F_DEADA标识的fib_info结构以及相关联的fib_alias结构。

    static void fib_disable_ip(struct net_device *dev,int force):该函数调用fib_sync_down来禁止输入参数dev设备上的ip协议。

当设备上有了一个新地址时,fib_add_addr函数用来添加相关路由项:

当设备上删除一个ip地址时,路由子系统得到通知,fib_del_addr函数用来清理路由表和路由缓存:

设备状态改变:

路由子系统向netdev_chain通知链注册三个不同的处理函数来处理设备状态的变化:

    fib_netdev_event更新路由表。

    当使用策略性路由时,fib_rules_event更新策略数据库。

    ip_netdev_event更新设备的ip配置。

下面介绍路由子系统收到netdev_chain收到下面这些通知时,会做什么处理:

    NETDEV_UNREGISTER:当一个设备注销时,对路由表来说,删除使用该设备的所有路由,对ip配置来说,禁用该设备上的ip协议。

    NETDEV_DOWN:关闭一个设备时,对路由表来说,删除使用该设备的所有路由,对ip配置来说,关闭多播配置(如果有的话)。

    NETDEV_UP:启动一个设备时,必须将与该设备上所有ip地址有关的路由表项添加到路由表ip_fib_local_table中,激活多播配置。

另外,当一个设备被注销时,所有与其相关的策略(即fib)标记为不可用(调用fib_rules_attach),当设备注册时,如果有与该设备相关的未激活策略,重新激活(调用fib_rules_attach)。

与其他子系统的交互:

    Netlink通知:当创建和删除一条路由时,利用函数组rtmsg_fib向Netlink组RTMGRP_IPV4_ROUTE发送一个通知。

    策略路由与基于防火墙的分类器:策略路由可以使用一个由防火墙代码初始化的标签tag来决定对入口流量和出口流量应该使用那一张路由表。基于防火墙标签的路由需要在内核编译时添加支持。    

    路由协议守护进程:

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值