Linux 路由 (1)

路由,在网络技术中扮演着核心且任务繁重的角色,由于调用频繁,所以它的性能非常重要,再加上它为每一个数据包指明了前进的道路。如同我们写信一样,只要指明了目的地址,那么根据这个信息,邮件就会被尽力送达,数据包也是如果,当我们指定了目的 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 来决定下一步动作,而每个策略都会指定一个路由表,即是我们将使用的路由表。

(未完待续)

时间: 2024-07-30 14:08:56

Linux 路由 (1)的相关文章

linux路由服务

本文介绍如何使用linux创建一台简单的路由服务器.主要包括几个参数的设置:ip_forward和rp_filter. 1.开启IP forwarding # 重启后失效 $ echo "1" > /proc/sys/net/ipv4/ip_forward 或者 编辑/etc/sysctl.conf,做如下修改 net.ipv4.ip_forward = 1 # sysctl用于在内核工作时直接修改内核参数 $ sysctl -p 2. 关闭rp_filter echo &quo

linux 路由转发实验(软路由)

一.实验网络拓扑 (R1,R2由 Linux 虚拟机添加双网卡做软路由实现) 二.环境准备: (虚拟机网卡需要设置为桥接模式) 1. 关闭NetworkManager: service NetworkNanager stop 禁止开机自启动: chkconfig NetworkNanager off 清空iptables 条目: iptables -F 开启路由转发功能:(0 :禁用, 1:启用) echo 1 > /proc/sys/net/ipv4/ip_forward 检查路由转发功能开启

Linux 路由 (2)

上篇我们讲到了,如何匹配策略,得到一个路由表,其实在 rib_rule 里,存的是该策略所使用的路由表的索引,这里顺便解释一下 FIB (Forward Infomation Base), 即转发信息数据库,即相当于路由表. 得到所使用的路由表的索引后,就可以从 current->nsproxy->net_ns.ipv4.fib_table_hash 表中,得到路由表的指针,路由表是使用 fib_table 表示的(见上一往篇的图).在 fib_table 结构中,它会指定查找该表的方法,这里

利用systemtap学习Linux路由代码

http://bbs.chinaunix.net/thread-4090162-1-1.html 一.为什么要这样做读kernel route子系统代码,当我弄懂了数据结构之间的关系以及控制流程后,心里还是不妥贴,总有一种“纸上得来终觉浅,绝知此事要躬行”的感觉.此时,systemtap能起大作用. 二.准备工作安装systemtap, kernel, kernel-debuginfo, kernel-debuginfo-common等.uname -r2.6.38.6-26.rc1.fc15.

网络基础~linux路由与网关、路由命令

Linux的路由与网关: 路由(Routing):路由是指从一个设备(一般指路由器)的接口上接收到数据包,依据设备所既定的某些规则,将数据包转发到其它接口的 "过程".路由工作在OSI参考模型第三层--网络层的数据包转发设备.路由器通过转发数据包来实现网络互连 路由器(Router):路由器是用于连接多个逻辑上分开的网络,所谓逻辑网络是代表一个单独的网络或者一个子网.当数据从一个子网传输到另一个子网时,可通过路由器的路由功能来完成.因此,路由器具有判断网络地址和选择IP路径的功能,它能

Linux路由实验

一    实验背景:路由器的功能是将不同网段的主机建立通信,本次试验是在使用linux主机当作路由器,完成主机间通信.如下图所示 二.实验环境:主机A和B为CentOS7.2,主机C和D为CentOS6.8,且C和D上分别都有两块网卡 三.实验步骤 注意:为避免干扰项,需将每台主机的防火墙关闭     1.主机A配置 # 配置IP地址 #配置默认网关 2.主机B配置 #配置B的IP地址(vi  /etc/sysconfig/network-scripts/ifcfg-eth#) #关闭Netwo

Linux路由转发简介

要求: 需要让Linux01通过Linux02访问Linux03,把Linux02转换成一个路由器. 实施步骤: (1)  准备环境:Linux01(ip:10.0.0.10)Linux02(双网卡eth0:10.0.0.11  eth1:10.0.1.11)Linux03(ip:10.0.1.10) (2)  配置Linux01,添加路由:route add -net 10.0.1.0/24 gw10.0.0.11 (3)  配置Linux02,开启路由转发功能:echo "1" &

linux路由

在默认路由表添加路由ip route add 网络 via 网关 dev 网卡 在指定路由表添加路由ip route add 网络 via 网关 dev 网卡 table 路由表 查看默认路由表路由ip route 查看指定路由表路由ip route show table 路由表ip route list table 路由表 策略路由ip rule add from IP table 100 查看策略路由ip rule 建立特殊路由表vi /etc/iproute2/rt_tables 例子:i

峰回路转 哪来回哪去 LINUX 路由脚本   ERIKXUE

[[email protected] Desktop]# ip ru sh 0: from all lookup local 32766: from all lookup main 32767: from all lookup default [[email protected] Desktop]# 实现流量从哪个网卡来,就从哪个网卡回去 [[email protected] Desktop]# [[email protected] Desktop]# for i in `ip addr  |