码迷,mamicode.com
首页 > 系统相关 > 详细

Linux 路由 (1)

时间:2015-02-06 16:46:50      阅读:312      评论:0      收藏:0      [点我收藏+]

标签:linux route   策略路由   policy routing   fib   

        路由,在网络技术中扮演着核心且任务繁重的角色,由于调用频繁,所以它的性能非常重要,再加上它为每一个数据包指明了前进的道路。如同我们写信一样,只要指明了目的地址,那么根据这个信息,邮件就会被尽力送达,数据包也是如果,当我们指定了目的 IP,那么就需要有一种强有力的机制来保证它会被送达,来确保这一目的的机制就是路由。
        先来解释下,一个数据包如何能一步步到达目的主机的。那么首先就要明白一点,在一个局域网内,网卡的传递数据包的时候是不需要 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 来决定下一步动作,而每个策略都会指定一个路由表,即是我们将使用的路由表。
        (未完待续)

Linux 路由 (1)

标签:linux route   策略路由   policy routing   fib   

原文地址:http://blog.csdn.net/henzox/article/details/43565369

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!