如果你有一个大规模的路由器,你可能不得不同时满足不同用户对于路由的不同需求。路由策略数据库可以帮助你通过多路由表技术来实现。如果你想使用这个特性,请确认你的内核配置中带有"IP:advancedrouter"和"IP:policyrouting"两项。当内核需要做出路由选择时,它会找出应该参考哪一张路由表。除了"ip"命令之外,以前的"route"命令也能修改main和local表。缺省规则:[ahu@homeahu]$iprulelist0:fromalllookuplocal32766:fromalllookupmain32767:fromalllookupdefault上面列出了规则的优先顺序。我们看到,所有的规则都应用到了所有的包上(“fromall”)。我们前面已经看到了"main"表,就是“iproutels”命令的输出,但是“local”和“default”是初次见到。如果我们想做点有趣的事情,就可以生成一些指向不同路由表的规则,取代系统中的路由规则。对于内核如何处理一个IP包匹配多个规则的精确意义。4.1.简单的源策略路由让我们再来一个真实的例子。我有两个CableModem,连接到了一个Linux的NAT(“伪装”)路由器上。这里的室友们向我付费使用Internet。假如我其中的一个室友因为只想访问hotmail而希望少付一些钱。对我来说这没有问题,他们肯定只能使用那个比较次的CableModem。那个比较快的cablemodem的IP地址是212.64.94.251,PPP链路,对端IP是212.64.94.1。而那个比较慢的cablemodem的IP地址是212.64.78.148,对端是195.96.98.253。local表:[ahu@homeahu]$iproutelisttablelocalbroadcast127.255.255.255devloprotokernelscopelinksrc127.0.0.1local10.0.0.1deveth0protokernelscopehostsrc10.0.0.1broadcast10.0.0.0deveth0protokernelscopelinksrc10.0.0.1local212.64.94.251devppp0protokernelscopehostsrc212.64.94.251broadcast10.255.255.255deveth0protokernelscopelinksrc10.0.0.1broadcast127.0.0.0devloprotokernelscopelinksrc127.0.0.1local212.64.78.148devppp2protokernelscopehostsrc212.64.78.148local127.0.0.1devloprotokernelscopehostsrc127.0.0.1local127.0.0.0/8devloprotokernelscopehostsrc127.0.0.1有很多明显的事实,其实可能还需要进一步说明。好了,这样就行了。“default”表为空。让我们看看“main”路由表:[ahu@homeahu]$iproutelisttablemain195.96.98.253devppp2protokernelscopelinksrc212.64.78.148212.64.94.1devppp0protokernelscopelinksrc212.64.94.25110.0.0.0/8deveth0protokernelscopelinksrc10.0.0.1127.0.0.0/8devloscopelinkdefaultvia212.64.94.1devppp0我们现在为我们的朋友创建了一个叫做“John”的规则。其实我们完全可以使用纯数字表示规则,但是不方便。我们可以向/etc/iproute2/rt_tables文件中添加数字与名字的关联:#echo200John>>/etc/iproute2/rt_tables#ipruleaddfrom10.0.0.10tableJohn#iprulels0:fromalllookuplocal32765:from10.0.0.10lookupJohn32766:fromalllookupmain32767:fromalllookupdefault现在,剩下的事情就是为John的路由表创建路由项了。别忘了刷新路由缓存:#iprouteadddefaultvia195.96.98.253devppp2tableJohn#iprouteflushcache这样就做好了。至于如何在ip-up阶段实现就留给读者自己去研究吧。4.2.多重上连ISP的路由下图是很常见的配置,同一个局域网(甚至是同一台计算机)通过两个ISP连接到互联网上。________+------------+/|||+-------------+ISP1+-------__|||/12___/\_+------+-------++------------+|_/\__|if1|//\||||局域网-----+Linux路由器||国际互联网\___/|||\____/|if2|\\___/+------+-------++------------+||||\+-------------+ISP2+-------|||+------------+\________这种情况下通常会出现两个问题。4.2.1.流量分割首先是如何保证:回应来自某一个ISP的数据包时,仍然使用相同的ISP。让我们先定义一些符号。令第一块网卡(上图的if1)的名字叫$IF1,而第二块网卡叫做$IF2。然后设置$IF1的IP地址为$IP1,$IF2的IP地址为$IP2。并且,令ISP1的网关地址为$P1,ISP2的网关地址为$P2。最后,令$P1的网络地址为$P1_NET,令$P2的网络地址为$P2_NET。额外创建两个路由表,T1和T2。加入到/etc/iproute2/rt_tables中。然后如下设置两个路由表中的路由:iprouteadd$P1_NETdev$IF1src$IP1tableT1iprouteadddefaultvia$P1tableT1iprouteadd$P2_NETdev$IF2src$IP2tableT2iprouteadddefaultvia$P2tableT2没什么大不了的,不过是建立了通向该网关的一条路由,并使之成为默认网关,分别负责一个单独的上行流,并且为这两个ISP都作这样的配置。要指出的是,那条网络路由是必要条件,因为它能够让我们找到那个子网内的主机,也包括上述那台网关。下一步,我们设置“main”路由表。把包通过网卡直接路由到与网卡相连的局域网上不失为一个好办法。要注意“src”参数,他们能够保证选择正确的出口IP地址。iprouteadd$P1_NETdev$IF1src$IP1iprouteadd$P2_NETdev$IF2src$IP2然后,设置你的缺省路由:iprouteadddefaultvia$P1接着,设置路由规则。这实际上在选择用什么路由表进行路由。你需要确认当你从一个给定接口路由出数据包时,是否已经有了相应的源地址:你需要保证的就是如果你已经有了相应的源地址,就应该把数据包从相应的网卡路由出去:ipruleaddfrom$IP1tableT1ipruleaddfrom$IP2tableT2以上命令保证了所有的回应数据都会从他们来的那块网卡原路返回。现在,完成了非常基本的配置。这将对于所有运行在路由器上所有的进程起作用,实现IP伪装以后,对本地局域网也将起作用。如果不进行伪装,那么你要么拥有两个ISP的地址空间,要么你想对两个ISP中的一个进行伪装。无论哪种情况,你都要添加规则,基于发包的主机在局域网内的IP地址,选择从哪个ISP路由出去。4.2.2.负载均衡第二个问题是如何对于通过两个ISP流出的数据进行负载均衡。如果你已经成功地实现了流量分割,这件事并不难。与选择两个ISP中的一个作为缺省路由不同,这次是设置缺省路由为多路路由。在缺省内核中,这会均衡两个ISP的路由。象下面这样做(基于前面的流量分割实验):iprouteadddefaultscopeglobalnexthopvia$P1dev$IF1weight1\nexthopvia$P2dev$IF2weight1这样就可以均衡两个ISP的路由。通过调整“weight”参数我们可以指定其中一个ISP的优先权高于另一个。应该指出,由于均衡是基于路由进行的,而路由是经过缓冲的,所以这样的均衡并不是100%精确。也就是说,对于一个经常访问的站点,总是会使用同一个ISP。进而,如果你对此不满意,你可能需要参考以下JulianAnastasov的内核补丁:http://www.linuxvirtualserver.org/~julian/#routesJulian的路由补丁会弥补上述缺陷。
上一篇:GRE和其他隧道_网络技术
下一篇:生成树的介绍_网络技术