1.什么是IP路由
在一个IP网络中,路由(Routing)是个非常非常基本的概念。网络的基本功能,是使得处于网络中的两个IP节点能够互相通信,而通信实际上就是数据交互的过程,数据交互则需要网络设备帮助我们来将数据在两个通信节点之间进行传输。当路由器(或者其他三层设备)收到一个IP数据包,路由器会找出报文中的IP头里的目的IP地址,然后拿着目的IP地址到自己的路由表(Routing Table)中进行查找,找到“最匹配”的路由条目后,将数据包根据路由条目所指示的出接口或下一跳IP转发出去,这就是路由(Routing)。
而每台路由器都会在本地维护一个路由表,路由表中装载着路由器通过各种途径获知的路由条目(Routes),每一条路由条目由路由前缀(路由所关联的目的网络号及掩码长度)、路由信息来源、出接口或下一跳IP、优先级、开销等信息元素构成。路由器通过直连、静态的或者动态的方式获取路由条目并维护自己的路由表,路由表是每台支持路由功能的设备进行数据转发的依据和基础,是一个非常重要的概念,任何一台支持路由功能的设备要执行数据转发或路由的动作,就必须拥有及维护一张路由表。
2.IP路由表
任何一台支持路由功能的设备要执行数据转发或路由的动作,就必须拥有及维护一张路由表,路由表可以理解为将数据包转发到特定目的地所依据的一张“地图”。在我司三层设备(如路由器、防火墙、三层交换机等)上查看IP路由表的命令如下:
[Huawei] display ip routing-table
每个路由条目必须包括下面几个信息元素:
路由前缀: 这是路由条目所关联的目的网络号。一条完整的路由前缀由:网络号+前缀长度构成,两者缺一不可,例如192.168.1.0/24与192.168.1.0/25,虽然网络号相同,都是192.168.1.0,但是两者绝对是两条不同的路由、两个不同的路由前缀,因为他们的前缀长度不相同。
协议类型: 本条路由是通过什么途径学习到的,例如是直连的,或是静态的,或者是通过OSPF、IS-IS、EIGRP、BGP等动态路由学习到的。
优先级与协议类型对应,路由表中路由的获取来源有多种,每种协议类型对应不同的优先级,优先级值越小越优先。当一台路由器同时从两种不同的路由协议学习到去往同一个目的地的路由时,它将优选路由协议优先级小的那条路由。
开销Cost路由的度量值, 在许多书籍或文档中也使用metric来描述。直连及静态路由的cost为0。通过动态路由协议学习到的Cost则根据实际环境。
指向目标的指针: 指针不是指向路由器的直连目标网络就是指向直连网络内的另一台路由器地址,或者是到这个链路的本地接口。更接近目标网络一跳的路由器叫下一跳(next hop)路由器。
3.路由优先级(Preference)
路由器可以通过多种途径获知路由条目:如静态手工配置或通过各种动态路由协议学习等等。当路由器从两种不用的途径获知去往同一个目的地的两条下一跳不相同的路由,那么路由器会比较这两条路由的优先级(Preference),优选Pre值小的路由。如果Pre值相等,例如是同种路由协议获取到的,则进一步比较开销(Cost)值,当然,这其中还牵涉到不同的路由协议内在的工作机制问题,这就要针对不同的路由协议具体讨论了,我们这里暂时不涉及到这么深入。
如下图,R3与R1运行的是RIP协议,R3又通过OSPF与R2建立邻接关系。于是R3同时从RIP及OSPF学习到了去往目的地1.1.1.0/24的路由,这两条路由分别以R1和R2作为下一跳。R3最终选择OSPF的路由装载进路由表,也就是将R2作为实际去往1.1.1.0/24的下一跳,因为OSPF协议的优先级值比RIP要小、要更优。
针对不同的路由协议,对应的优先级见下表,这是个众所周知的约定(不同的厂家,可能有所不同,下表中罗列的是我司的产品特性):
路由协议或路由种类相应路由的优先级
4.静态路由
1) 关于静态路由
路由器的天职,就是维护路由表以及依据路由表进行数据转发。而路由表中包含通过各种途径学习到的路由表项或路由条目,主要有如下几种途径:
直连路由自动学习
使用静态路由的方式手工添加路由条目
使用动态路由协议使得设备之间能够进行路由信息的更新及学习,动态的维护路由表项
我们以下图为例:
PC1及PC2的IP地址如图所示,PC1的网关设置为172.16.1.254,也就是R1的GE0/0/0口IP;PC2的网关设置为172.16.2.254也就是R2的GE0/0/0口IP。路由器的各接口IP地址如图所示。那么在初始情况下,对于R1而言,当所有接口UP以后,路由器自动学习活跃的接口所在网络的网络号并且维护自己的路由表,例如R1的路由表,可能像下面这样(省略了无关信息):
R2的路由表类似,这里不再赘述。现在当PC1要访问PC2时,由于PC1的网关设置为R1的GE0/0/0口的IP地址,于是PC1将目的地址为172.16.2.1的IP数据包发送给它的网关。而当R1收到这个数据包时,R1发现这个数据包的目的地址是172.16.2.1,它就去查找自己的路由表,结果发现路由表中,并没有匹配172.16.2.1的条目,因此数据包被丢弃,自然到目前为止PC1是无法与PC2互访的。那么如何才能够使得R1正常的转发这个数据包呢?当然需要R1的路由表中有相关的条目来做指示。
最简单的一种方式是,为R1使用静态手工的方式来添加去往172.16.2.0/24网络的路由条目,这种方式添加的路由称为静态路由。这种方式最直接,可控性最高,配置也最简单。在小型的网络中,全网静态路由似乎没有什么问题,但是在一个大型网络中,如果纯用静态路由来做,工作量就非常大了,不仅仅工作量大,另外一个更重要的缺陷是静态路由无法根据网络拓扑结构的变更而做出动态的调整,因此,在大规模网络中,我们往往采用静态+动态路由协议的方式来完成路由的部署。
静态路由的配置的命令非常简单:
命令中的红色字体部分是这条路由的目的网络号(172.16.2.0)及掩码(24),也就是路由前缀;蓝色字体部分是去往这个目的地的“下一跳IP”。于是R1的路由表变成下面这个样子:
我们看到,R1的路由表里出现了一个新增的条目,路由前缀是172.16.2.0/24,协议类型为“静态”,优先级为60,出接口为GE0/0/1,去往目的地的下一跳IP是172.16.100.2。这样一来,当R1收到PC1发往172.16.2.1的数据包,它查看路由表,发现路由表中有一个条目匹配,于是R1将该数据包丢给该条路由指示的下一跳IP 172.16.100.2,这个数据包被传输到了R2,再由R2查它的路由表,发现数据包的目的地172.16.2.1在本地路由表中有路由条目匹配,而且是直连网络,因此R2将数据包根据路由条目所指示从GE0/0/0口发送出去,最终PC2收到了这个数据包。
现在问题来了,我们在R1上增加了这条静态路由后,PC1与PC2就能够正常通信了么?答案是否定的,为什么?因为两个节点之间的数据通信是双向的,有去得有回,在R1上增加去往172.16.2.0/24的静态路由后,PC1发往PC2的数据包是能够被转发到PC2的,但是如果此刻PC2要回送报文呢?PC2回送的数据包目的IP地址就是172.16.1.1,这个数据包首先被PC2发往自己的网关也就是R2,那么R2查看路由表,却没有发现匹配目的地172.16.1.1的路由,于是就丢包。
因此,为了使得PC1与PC2之间能够相互通信,我们还需要做一步动作,也就是在R2上也增加一条路由,路由的目的地是172.16.1.0/24网络,下一跳呢?当然就是172.16.100.1了。如此一来PC1及PC2互相通信就没有问题了。
2) 静态路由的配置
方法一:关联下一跳IP的方式:
红色字体部分为该路由条目的网络号
蓝色字体部分为该网络号的掩码或者前缀长度
绿色字体部分为去往该网络的下一跳IP
方法二:关联出接口的方式:
红色字体部分为该路由条目的网络号
蓝色字体部分为该网络号的掩码或者前缀长度
绿色字体部分为去往该网络的出接口,注意,在我司的路由器上,静态路由可关联出接口或下一跳IP,或两者都关联。但是如果出接口为广播多路访问型接口,例如以太网口,那么就必须关联下一跳。如果为点对点接口如serial接口,则可只关联出接口。例如 ip route-static 172.16.2.0 24 GigabitEthernet0/0/0 172.16.100.2
3 默认路由
我们看上图,对于R1而言,如果要到达R2所直连的172.16.1.0、2.0、3.0网络,就必须有路由。如果采用静态路由的方式为R1添加路由,三个目的网络就需要配置三条静态路由。这样不仅仅增加了配置工作量,另一方面,也增加了R1的负担,因为它需要维护更多的路由条目,而承载路由条目的路由表是需要占用设备内存资源的。因此从网络设计及优化的角度,我们往往在保证网络路由可达性的同时,尽量减少路由器路由表的条目数量。
在这个环境中,由于R1仅有一条出口线路,因此我们可以在R1上配置一条默认路由, 下一跳为R2,如此即可在保证R1到R2后方三个网络可达的同时,路由条目达到最简。具体的配置如下:
[R1] Ip route-static 0.0.0.0 0.0.0.0 172.16.100.2
或者简写成:
[R1] Ip route-static 0.0.0.0 0 172.16.100.2
默认路由的网络号和掩码都是全0,可匹配任意目的网络前缀,可作为路由器的“最后求助对象”使用。
4 浮动静态路由
我们看上面的例子,对于R3及其下挂的网络而言,要去往10.9.9.0/24网络,通过R1及R2都可达。那么如果在R3上,我们分别配置静态路由:
[R3] ip route-static 10.9.9.0 24 10.1.13.1
[R3] ip route-static 10.9.9.0 24 10.1.23.2
这样一来,由于这两条路由都是去往同一个目的地,分别采用不同的下一跳IP,同时这两条路由具备相同的优先级,以及相同的开销(cost,都为0),因此最终这两条去往10.9.9.0/24网络的路由被同时装载进了R3的路由表。这种现象我们称为路由的等价负载均衡。最终的一个结果是,R3转发去往10.9.9.0/24网络的流量,有可能会同时采用R1及R2作为下一跳。这种方法是存在一定的隐患的,例如有可能到达目的地的数据包是非顺序的。那么如果我希望R3去往10.9.9.0/24的流量始终先走单边(如R1),当R1宕机或R1-R3之间的互联链路出现故障时,R3能够自动将流量切换到R2呢?
这里我们就可以使用到浮动静态路由的概念。我们已经知道使用ip route-static命令可以为设备添加静态路由,在默认情况下,这条命令所添加的静态路由其优先级为60(在我司设备上,静态路由的优先级默认为60,其他设备厂商可能有所不同),这个静态路由的优先级事实上是可以自定义的,例如,在R3上配置修改为:
[R3] ip route-static 10.9.9.0 24 10.1.13.1#静态路由默认优先级为60
[R3] ip route-static 10.9.9.0 24 10.1.23.2 preference 80 #这条路由的优先级被设置为80
上述配置中,我们为R3添加了两条静态路由,目的网络号都是10.9.9.0/24,下一跳分别为10.1.13.1及10.1.23.2,留意到下一跳为R1的静态路由,我们并没有设置优先级,因此该条路由的优先级为默认的60,另一条静态路由,我们使用preference关键字指定了优先级80。那么这样一来,这两条路由,就会进行优先级的比较,优先级小的路由将最终被放进路由表并作为数据转发的依据,另一条优先级为80的路由,则“潜藏”起来,并不出现在路由表中。
当R1宕机,或者R1-R3之间的直连链路发生故障时,ip route-static 10.9.9.0 24 10.1.13.1这条静态路由失效,ip route-static 10.9.9.0 24 10.1.23.2 preference 80也就浮现出来了,因此这是一种不错的路径备份机制。