静态路由是一种傻瓜化的手动路由配置方法,虽然配置简单,但是在实际工程中是非常有用的路由配置方法。在小型网络,以及配置缺省网关等方面,静态路由显得尤为突出。首先它不用跑路由协议,节省路由器资源,其次路由条目稳定。但缺点也是有的,那就是麻烦,而且很不人性化,如果网络大规模改动,那么就要辛苦咋们这些网络管理员了。

 

配置静态路由

命令基本格式:ip route[目标前缀] [目标前缀掩码] [转发地址/出接口/转发地址 出接口][管理距离]

上面是静态路由的基本框架,它的很多拓展命令其实也是很多的。但是最少要满足目标网络、目标网络掩码、下一跳或者出接口这三项。除此之外,要记住一点,当我们指出接口时,链路必须是双UP状态;当我们指下一跳时,下一条必须可达,否则路由条目是不会被加表的。静态路由的参考度量值是管理距离,默认是1,这样即使配置网络的下一跳为出接口,也不回比直连路由条目(标记C的路由)优先,因为默认直连的管理距离是0.

例子: ip route 1.1.1.0 255.255.255.0 s1/0 

看一个例子吧,拓扑如下:

静态路由-成长便签

在R1上创建环回口1.1.1.1,我们在R1上创建去往1.1.1.0网段的静态路由,命令如下:

  ip route 1.1.1.0 255.255.255.0 s1/0 

这是一个去往1.1.1.0网段的静态路由,目的是指向了出接口,接着我们看看R2的路由表,如下:

静态路由-成长便签

  静态路由已经成功配置了,这里我们看到如果直接跟出接口,路由表会显示这条路由是直连路由,但是标记S的直连路由管理距离是1。接着我们在指下一跳地址看看,命令如下:

   ip route 1.1.1.0 255.255.255.0 12.1.1.1

效果如下:

静态路由-成长便签

  这里出现负载了,这也证明了标记S的直连路由条目的管理距离是1,因为如果配置下一跳位地址的话我们看到的管理距离也是1。上面的效果也是静态路由负载的配置方法,这里就不多说了,两条管理距离值一样的静态路由可以同时加表。

 

下一跳和出接口

静态路由还可同时配置出接口和下一跳地址,但是要注意的是,这种配法并不是为了实现路由下一跳冗余的。在共享网络(比如以太网)中,如果我们只指出接口,那么路由表上就会出现去目标网络的直连类型静态路由。路由器就会认为该网络是自己的直连网络,而该直连网络是以太网的话,去目标网络的数据首先会向目标地址发送ARP请求报,并且去往该网段的所有数据第一次都回请求ARP,这样就会造成广播风暴。还有一点,目标网络其实并非自己直连网络,于是ARP到达对端路由器后对端路由器会进行代理ARP处理,如果对端路由器没有开启代理ARP功能,那么ARP就没有响应了。如果我们指了下一跳地址,那么路由器会认为该网络不是直连的,于是便会请求下一跳地址的Mac地址,而且只请求一次,这样即不用代理ARP,又没有广播风暴,很好的节省了资源。

下面我们来做实验看看是不是如我们所说的那样,R1和R2的配置分别如下:

R1:

  ip route 10.1.1.0 255.255.255.0 FastEthernet0/0

R2:

interface Loopback1

 ip address 10.1.1.1 255.255.255.255

interface Loopback2

 ip address 10.1.1.2 255.255.255.255

interface Loopback3

 ip address 10.1.1.3 255.255.255.255

接着我们ping测试一下,如下:

静态路由-成长便签

  通是没问题的,接着我们看看R1的ARP表,如下:

静态路由-成长便签

  正如我们所预料的那样,R1把10网段认为是直连网络了,而且每一个目标地址都发送一次ARP,从图上我们可以看到10网段所解析到的MAC地址都是一样的,也就是R2以太网的MAC地址,这里就用了ARP代理。接着我们在R2的F0/0口上关闭ARP代理功能,接着看看效果,配置如下:

interface FastEthernet0/0

 ip address 100.1.1.2 255.255.255.0

 no ip proxy-arp

效果如下:

静态路由-成长便签

  R1已经Ping不通10网段了,原因就是MAC地址无法解析,和我们所分析的一样。接着我们在R1上删掉刚才那个静态路由,然后指下一跳再试试,配置如下:

no ip route 10.1.1.0 255.255.255.0 FastEthernet0/0

ip route 10.1.1.0 255.255.255.0 100.1.1.2

接着我们再Ping一下试试,效果如下:

静态路由-成长便签

  ping通了,这里我们是已经关掉代理ARP的,从上图我们也可以看到我们ping 10网段解析的也是100.1.1.2的MAC地址,和我们分析的一样。看来以太网最好是指下一跳比较好。那同时配置两种呢,如果同时配置了两种那么路由器即知道了出接口,又知道下一跳地址,那么只用查一次表就可以讲数据转发出去,这是递归查找的结果,后面会说到。

 

配置静态汇总路由

路由汇总,其实就是把具有相同网络位的路由条目进行分组聚合。目的就是为了减少路由条目,实现路由快速查表。命令和静态路由的配置配有什么区别,我们主要来看看汇总的方法。首先汇总我们要确定一个网络号,这个网络号的确定是由所汇路由决定的。我们看个例子把,192.168.65.1 和192.168.97.1进行汇总。首先我们要把两个地址转换成二进制:

192.168.65.1   ←→   11000000.10101000.01000001.00000001

192.168.97.1   ←→   11000000.10101000.01100001.00000001

然后我们在二进制中找连续相同的部分,也就是 11000000.10101000.01******.******** 这就是我们要找的网络号,10进制就是192.168.64.0。掩码的确定也是先找连续相同的部分,然后把连续相同的部分进行与运算,最后把后面的位都置0.结果就是255.255.192.0

汇总命令最后如下:

命令: ip route 192.168.64.0 255.255.192.0 [下一跳地址/ 出接口]

 

最长匹配原则

路由器查表遵循一个最长匹原则,也就是说,如果路由表匹配的越长,那么数据就会按此路由发出去。我们来看个例子,如下:

静态路由-成长便签

  R1有两条去往10.1.1.0网络的路由,一条掩码是25位的,另一条掩码是24的,那么路由器会选择掩码位25的进行路由,我们来追踪一下就知道了,如下:

静态路由-成长便签

  追踪结果就是R1去10.1.1.0网段的数据从掩码为25的路由条目走了,这就是最长匹配原则了。

 

静态浮动路由

静态浮动路由一般用来实现路由冗余用的。当去同一网络有两个下一跳时,我们可以修改某一条的管理距离(也就是静态路由的metric)来实现一条路由优先加表,而另一条路由作为备份。配置很简单就是将备份路由的管理距离改大,就可以了。假如我们现在要去R1的1.1.1.0网段实现冗余,串口主用,以太口备用,那么命令如下:

  ip route 1.1.1.0 255.255.255.0 12.1.1.1

  ip route 1.1.1.0 255.255.255.0 100.1.1.1 2

R2路由表如下:

静态路由-成长便签

R2现在去R1的1.1.1.0网段走的是串口,接着我shutdown掉R2的S1/0口,接着看看R2的路由表,如下:

静态路由-成长便签

  现在走串口的路由配置还在,但是因为S1/0 shutdown掉了,所以路由条目也被动态移除了,Debug信息如下:

*Mar  1 00:09:17.379: is_up: 0 state: 6 sub state: 1 line: 0 has_route: True

*Mar  1 00:09:17.383: RT: interface Serial1/0 removed from routing table

*Mar  1 00:09:17.387: RT: del 12.1.1.0/24 via 0.0.0.0, connected metric [0/0]

*Mar  1 00:09:17.391: RT: delete subnet route to 12.1.1.0/24

*Mar  1 00:09:17.391: RT: NET-RED 12.1.1.0/24

*Mar  1 00:09:17.395: RT: delete network route to 12.0.0.0

*Mar  1 00:09:17.399: RT: NET-RED 12.0.0.0/8

*Mar  1 00:09:17.643: %SYS-5-CONFIG_I: Configured from console by console

*Mar  1 00:09:18.399: RT: del 1.1.1.0/24 via 12.1.1.1, static metric [1/0]

*Mar  1 00:09:18.403: RT: delete subnet route to 1.1.1.0/24

*Mar  1 00:09:18.403: RT: NET-RED 1.1.1.0/24

*Mar  1 00:09:18.407: RT: SET_LAST_RDB for 1.1.1.0/24NEW rdb: via 100.1.1.1

*Mar  1 00:09:18.411: RT: add 1.1.1.0/24 via 100.1.1.1, static metric [2/0]

*Mar  1 00:09:18.415: RT: NET-RED 1.1.1.0/24

*Mar  1 00:09:19.347: %LINK-5-CHANGED: Interface Serial1/0, changed state to administratively down

*Mar  1 00:09:20.407: %LINEPROTO-5-UPDOWN: Line protocol on Interface Serial1/0, changed state to down

上面就是动态切换的全部过程了,我们可以用 debug ip routing 来抓到如上信息。这里要注意的是,如果我们用以太网接口做主用路由,那么要考虑两个路由设备是否直连,如果中间接了2层交换机,那么本端以太网接口Down对端是不回Down的。也就是说如果对方接口出了问题,我们即使配置了浮动路由,路由器也不会自动切换。

 

递归查询

递归查询,静态路由允许目标不是直连网段,但是该网段必须可达,才能实现路由加表。我们看看如下的例子,拓扑如下:

静态路由-成长便签

  在上面的拓扑中,R1有一个环回口1.1.1.1,现在我们能看看R3的路由表是如何到达R1的:

静态路由-成长便签

  首先我们在R3上看到去往1.1.1.0这个网段的下一条是12.1.1.1,然后路由器会继续查询一遍路由表,看12.1.1.0这个网段如何到达。接着路由器会查到最下面的那条静态路由,发现去12.1.1.0是通过23.1.1.1,紧接着路由最后一次查表,发现23.1.1.0是直连网络,于是变从直连接口s1/0丢出去,这样数据就被发出去了。上面的过程一共查了三次表,我个人认为,路由器一般会查到直连接口才会转发数据,这也就是说,如果一个静态路由的下一跳指向了出接口,那么在不受其他路由条目的影响下,路由器只用查一次表,这也就是将路由指向出接口的好处之一。

从上面我们发现递归表是个配置麻烦、查表麻烦的东西,但是递归查询也有它的好处。现在假如上面的拓扑发生变化,R2将报废停止使用,R3将通过其他路由去往12.1.1.0网段,这时,如果我当初的静态路由都指向了R2的23.1.1.1或者S1/0口,而且这个接口和网络将不再被使用,那就意味着我们的每条链路都要重新更改下一跳地址或者出接口。现在网络只有一个路由条目,如果路由条目多的话,那将是很大的工程量。但是如果我们当初的下一跳设置的是12.1.1.0网段的地址,那么我们只需更改去往12.1.1.0的下一条或者出接口就可以实现其他陆游条目可达了,这里就显示了递归表查询的好处了。

 

静态路由负载

静态路由的基本配置方法其实很简单,但是其中还另有玄机。我们来用下面的拓扑来实现负载:

静态路由-成长便签

  R2去网R1的环回口可以走s1/0口也可以走f0/0口,我们开看看路由表吧,如下:

静态路由-成长便签

  现在从路由表上看,貌似已将实现所谓的负载了,但是我们来Debug看是什么情况,如下:

*Mar  1 00:23:54.607: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:23:54.611: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:23:54.623: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:23:54.627: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:23:54.635: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:23:54.639: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:23:54.659: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:23:54.663: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:23:54.679: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:23:54.683: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:23:54.695: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:23:54.699: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:23:54.707: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:23:54.707: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:23:54.763: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:23:54.767: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:23:54.775: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:23:54.779: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:23:54.799: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:23:54.803: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

我们会发现我们抓到的两个ping包都是经过查询FIB表后从相同的接口丢出去,我们所理解的负载并非这样,正常的负载应该是从不同的接口交替转发的,为什么会出现从一个接口发包的情况?FIB表又是什么东西?FIB全称 Forwarding Information Base 叫做转发信息数据库,它是CEF的一个数据库。CEF全称 Cisco Express Forwarding(思科快速转发),CEF是思科IOS软件版本11.1(17)以后新加入的一种新的转发机制。CEF采用一个4级每级256条通道结构的转发表来指明转发条目的位置,转发表有next hop等信息,涵盖了整个IPv4的地址范围,并有指针指向另一个邻接表。转发条目(MAC地址之类)都存储在一个单独的邻接表上。这两个表包括了所有的转发信息,而这些转发信息是根据路由表和ARP来构造的。

CEF简化了查询的步骤,提高了单位时间的工作效率。而且从整体上来看,路由信息和转发信息是分离的,数据包的转发只根据转发信息而不用参照路由信息,可以充分利用专用硬件的功能来达到线速转发,而不受路由变化或者其他因素的干扰,保证了转发的高速高效。

CEF转发提供3张表

1>FIB:从路由选择表中拷贝过来的转发信息,包括路由选择表中用于转发路由分组所必须的最少信息。

2>邻接表:维护一个邻接节点以及他们相关的2层MAC重写或下一跳信息数据库

3>NetFlow Table:用于统计网络数据等

我们说了这么多CEF这和我的负载有什么关系吗?答案是肯定的。我们首先来看个信息:

静态路由-成长便签

  这个命令查看某网段CEF的的详细信息,上面有一条是 per-destination sharing ,这个用来设置转发方式,默认是基于目的的。所谓基于目的,就是只要数据是发往同一地点的,都会从相同的接口发出去,这也就是我们的数据都从一个包发出的原因了。这里还有一个原因和思科设备的转发机制有关,我们来看看下面的转发组合

静态路由-成长便签

  思科默认是开启CEF的,而CEF的默认转发方式又是基于目的的,所以我们配置了静态负载路由以后路由器并不会从两个接口分别发送数据。上面提到一个快速和一个过程,快速就是快速交换,这也是思科IOS特性,该特性和CEF和相似,不过快速只有一种发送数据的方式,那就是基于目的去发。而过程就是最基本的发包方式,每个数据包都会查表选接口,也就是所谓的基于包去转发。

上面我们想看到数据走不同的接口的效果,由于CEF的原因我们没有实现,现在我们知道了原理,就可以很轻松的实现基于包转发。首先一种直接的方法就是直接关掉CEF功能,命令就是在在全局下 no ip cef,这样路由器就会老老实实的查路由表。另一种可行的方法是将CEF的转发方式改成基于包的,命令是在接口下配置 ip load-sharing per-packet 。在上面的转发组合中,我们发现最后一条,当入站是快速,出站是过程的时候,我们的转发过程也会变成过程,这也就是第三种方法。在接口下用 ip route-cache 可以配置接口的转发方式。

下面我们把R1和R2的串口和以太网口都改成基于包转发,然后看看Debug效果,配置如下:

R1:

interface FastEthernet0/0

 ip address 100.1.1.1 255.255.255.0

 ip load-sharing per-packet

interface Serial1/1

 ip address 12.1.1.1 255.255.255.0

 ip load-sharing per-packet

R2:

interface FastEthernet0/0

 ip address 100.1.1.2 255.255.255.0

 ip load-sharing per-packet

interface Serial1/0

 ip address 12.1.1.2 255.255.255.0

 ip load-sharing per-packet

Debug效果如下:

*Mar  1 00:31:17.795: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:31:17.799: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:31:17.835: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:31:17.839: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:31:17.851: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (Serial1/0), routed via FIB

*Mar  1 00:31:17.851: IP: s=12.1.1.2 (local), d=1.1.1.1 (Serial1/0), len 100, sending

*Mar  1 00:31:17.859: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:31:17.863: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:31:17.875: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:31:17.875: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:31:17.915: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:31:17.919: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:31:17.927: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (Serial1/0), routed via FIB

*Mar  1 00:31:17.927: IP: s=12.1.1.2 (local), d=1.1.1.1 (Serial1/0), len 100, sending

*Mar  1 00:31:17.963: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:31:17.967: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

*Mar  1 00:31:17.975: IP: tableid=0, s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), routed via FIB

*Mar  1 00:31:17.975: IP: s=12.1.1.2 (local), d=1.1.1.1 (FastEthernet0/0), len 100, sending

*Mar  1 00:31:17.999: IP: tableid=0, s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), routed via RIB

*Mar  1 00:31:17.999: IP: s=1.1.1.1 (Serial1/0), d=12.1.1.2 (Serial1/0), len 100, rcvd 3

从上面我们可以看到已经从不同的接口交替发送数据包了。

 

静态路由的扩展命令

我们在配置静态路由的时候,发现除了可以配置管理距离以外,还有三个扩展参数,分别是:name、permanent和tag。

首先我们来看这个name参数,该参数是为了给静态路由命名的,也就是起到标识的作用。

  例子:ip route 1.1.1.0 255.255.255.0 12.1.1.1 name GotoR1

这时我们show run 的时候就能看到标识了,如下:

R2#sho run | include ip route

ip route 1.1.1.0 255.255.255.0 12.1.1.1 name GotoR1

ip route 1.1.1.0 255.255.255.0 100.1.1.1

“GotoR1”只是一个标识,并没有实际意义,当有很多路由条目的时候,为了在show run下迅速找到自己想要的结果,最后好加上name参数以标识。

接下来看permanent这个参数,permanent中文意思是永久的意思,也就是说加上该参数后路由不会因为链路Down而消失。

例子:ip route 1.1.1.0 255.255.255.0 12.1.1.1 permanent

接着我们看看效果,如下:

静态路由-成长便签

  除非clear ip route,否则路由会一直存在。

最后一个是tag命令,tag就是给路由打标记,对于路由的批量分组管理很有用。

例子:ip route 1.1.1.0 255.255.255.0 12.1.1.1 tag 1

效果如下:

静态路由-成长便签

  上面的Tag表示后面的数字就是我们所打的标记了,静态路由的扩展参数就这些了。