Linux 路由 (1)
先来解释下,一个数据包如何能一步步到达目的主机的。那么首先就要明白一点,在一个局域网内,网卡的传递数据包的时候是不需要 IP 的,只需要知道目的 MAC 地址,即如果目的主机在相同的局域网中,只需要查到它的 IP 对应的 MAC,就可以把数据包发给它。即要想发送一个数据包给一个目的主机,只需要把包发到它的局域网就行了,而局域网与局域网之间的连接,往往需要有一个接口,我们就叫它网关。当要发送一个数据包时,这里往往就是一个 IP 包,会给它指定一个目的 IP,网络协议栈会根据自己的路由,判断目的主机是不是在自己的局域网中,即一个子网中,如果在,那么很简单,直接按前面提到的方法传送,如果不在,那么本地路由表应该指出,该数据包应该由哪个网卡发送,应该发给的下一台主机是谁,由下一台主机继续决定如何处理这个数据包。这样,数据包就可以进入下一个子网,如果目的主机不在下一个子网,那么继续路由,直到到达目的地
,或者不能够决策而丢弃。
其实上面就提到了路由的几个重要的概念,子网,下一跳的地址,从自己的哪个网卡发包。
而 Linux 在此基础上又进行了进一步的扩展,产生了一种叫做策略路由的机制,即存在多张路由表,具体如何选择这些路由表,是由一些策略决定的。也就是当发一个数据包时,根据该数据包的一些特性,如源地址,目的地址,tos 等信息,去检查是否和制定的一些规则匹配,如果匹配成功,则根据该规则指定的路由表将被使用。下图就是策略路由的框架:
从图中我们可以看出,当进行路由查找时,先去按顺序搜索规则链表,去进行匹配。我们以代码来理解 linux 下的策略路由的实现,笔者的 linux 版本号为 2.6.27.62。
上图是以 IP v4 为例,具体的数据结构图,路由策略都是被以连接到 fib4_rules_ops_template->rules_list 的单链表中。ip v4 的策略是由 fib4_rules_ops_template 来表示的,它指定了策略链表的位置,以及策略的匹配规则,以及,匹配成功后的操作。我们以 udp 的发包为例讲解,上述的结构如何应用到策略路由中。
udp 的发包是在 udp_sendmsg 中完成的,当需要路由时,它会传入 源地址,源端口,目的地址,目的端口,tos 等信息,然后调用,ip_route_output_flow 来查找路由,查找路由过程中为了加快速度,会先查找 cache 中的内容,这里我们略过,直接看查找一个不在 cache 中的路由的过程,这更具有意义一些,它会依次调用 __ip_route_output_key, ip_route_output_slow,从而通过 fib_lookup 来查找路由表,这里是调用 net/ipv4/fib_fules.c
里的 fib_lookup。它会继续调用 fib_rules_lookup 来遍历策略表,即 fib4_rules_ops_template->rules_list。代码如下:
int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, int flags, struct fib_lookup_arg *arg) { struct fib_rule *rule; int err; rcu_read_lock(); list_for_each_entry_rcu(rule, &ops->rules_list, list) { jumped: if (!fib_rule_match(rule, ops, fl, flags)) continue; if (rule->action == FR_ACT_GOTO) { struct fib_rule *target; target = rcu_dereference(rule->ctarget); if (target == NULL) { continue; } else { rule = target; goto jumped; } } else if (rule->action == FR_ACT_NOP) continue; else err = ops->action(rule, fl, flags, arg); if (err != -EAGAIN) { fib_rule_get(rule); arg->rule = rule; goto out; } } err = -ESRCH; out: rcu_read_unlock(); return err; }
这就是策略路由中策略的核心所在,由于策略添加时是有顺序的,所以在匹配策略时是按照,本地策略,自定义策略,主策略,默认策略来搜索。匹配方法是由 fib4_rule_match 来实现,根据策略定义的 action 来决定下一步动作,而每个策略都会指定一个路由表,即是我们将使用的路由表。
(未完待续)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。