在OSPF的标准文档RFC2328中,附录E描述了OSPF在某种特定的环境下会产生路由计算错误,从而给组网应用带来隐患,我们以下图为例来具体阐述这个问题:
图1 OSPF协议附录E演示组网图
如图1,路由器Rtr A、Rtr B都运行OSPF协议,且所有接口都在区域0。对于上图所示的网络,一种常见的配置步骤可能是:
1、在路由器Rtr A上配置OSPF协议引入静态路由,以通过OSPF协议将路由信息传递给路由器Rtr B。
2、路由器Rtr A上配置静态路由20.20.0.0/24,下一跳指向该网络的出口路由器Rtr C;
3、路由器Rtr A上配置静态路由20.20.0.0/16,下一跳指向该网络的出口路由器Rtr D;
这样的配置看起来十分完美,会不会隐藏着什么隐患呢?
实际的效果是:通过路由器Rtr B转发的去往目的地为20.20.1.0/24~20.20.4.0/24四个网段的流量将在Rtr B上全部被丢弃!
为什么会这样呢?
我们知道,OSPF协议是一种基于链路状态的路由协议,其路由计算是基于LSA的。当路由器引入静态路由时,通过生成相应的第5类LSA进行洪泛,以此向其他路由器传递拓扑信息。第5类LSA是以对应网段的IP地址来标识的,并协同产生该LSA的路由器ID、LSA的序列号等三个信息的组合作为其关键值进行唯一性标识,也就是说:不关心路由的掩码信息!
上述组网中,在路由器Rtr A上配置第一条静态路由20.20.0.0/24时,生成了一条第5类LSA往Rtr B洪泛;当再配置第二条静态路由20.20.0.0/16时,由于网段IP地址相同,不再生成重复的LSA。于是导致了路由器Rtr B只知道20.20.0.0/24的网段信息,而不知道Rtr D所在的网络的网段信息。
上述情形不只针对OSPF的第5类LSA,其第3、7类LSA由于对网络信息描述的关键值不包含网段的掩码信息,也存在相同的问题。
在RFC2328的附录E中同时推荐了一种改进的方法。
在OSPF协议中,关于其他区域网段和外部引入网段的计算主要依靠第3类LSA和第5、7类LSA来实现;这三类LSA分别承载OSPF区域间路由、OSPF外部路由以及OSPF的NSSA区域外部路由的信息。
由于OSPF的这三类LSA的ID是以这些网段的IP地址来标识的,每一类型的LSA是以产生该LSA的路由器ID、LSA的序列号以及被描述网段的IP地址这三个信息的组合作为关键值进行区分的。所以,同一台路由器产生的或者引入外部路由而生成的这些LSA,对于那些网段地址一样、而掩码信息不同的路由,将不能进行区分。例如,上面例子中的路由器Rtr A对于静态路由20.20.0.0/16和20.20.0.0/24的引入将只会生成一个LSA,其中必有一条路由因无法描述而被丢弃。
在讲述OSPF RFC2328附录E中的解决方案之前,我们先来深入分析下此类组网,收集下解决这类问题的一些相关要点。
首先,OSPF路由器本地必须能够区分对相同网段IP、不同掩码的多条路由的描述,这是保证解决办法有效的基础条件。
其次,对于需要的路由信息的描述必须使用网络地址,这是OSPF协议路由计算方法的根本,不应该改变,否则会涉及协议的大修改。
再次,当存在相同网段IP、不同掩码的路由时,只要保证最短掩码的那条路由传播出去,就可以解决问题。所以,合适的解决方案必须保证最短掩码的路由能够被其他路由器学习到。
最后,这类情形的发生是由于路由器本地无法对网段IP相同而掩码不同的多条路由进行描述而导致的,不涉及与其他OSPF路由器的互操作问题。所以,每台OSPF路由器可以自己选择实施合适的解决方案。
OSPF的RFC2328附录E推荐的一种改进的方法,就是本着上面四个原则进行处理的。下面以第5类外部LSA的处理为例进行介绍,相同的处理方法也同样适用于其他两类LSA。
OSPF路由器欲引入一个外部路由,网段IP地址为NA,掩码为NM_new,我们以[NA,NM_new]进行标记。该路由器的处理过程如下:
(1)查找链路状态数据库,判断是否已经存在对应IP地址为NA的路由的第5类LSA,如果没有,就产生一个第5类LSA,其ID为NA,处理结束。
(2)如果已经存在,则从已有的第5类LSA中提取该网段的掩码NM_old,分两种情况进行处理:
如果NM_new的长度大于NM_old,也就是说,将要引入的路由的掩码比原先的那条更长,这时只需要再产生一条新的第5类LSA即可:将新的外部路由网段的主机位全部置1,子网广播地址作为新的第5类LSA的ID。例如,原先的外部路由网段是10.10.0.0/16,其LSA的ID是10.10.0.0,新的将要引入的网段是10.10.0.0/24,产生的LSA的ID就是10.10.0.255。
如果NM_new的长度小于NM_old,则需要立即替除原来的第5类LSA,并产生两条新的第5类LSA。一条LSA的ID为NA,其序列号为原来被替掉的LSA的序列号加1,花费值对应新路由的花费值;对于另一条LSA,将原路由[NA,NM_old]的主机位全部置1,用子网广播地址作为其LSA的ID。例如,原先的路由10.10.0.0/24以花费值10引入,序列号为100;新的路由10.10.0.0/16以花费值20引入。于是按上面的处理,OSPF路由器先替掉原来的LSA,并生成两条新的LSA,一个LSA的ID为10.10.0.0,花费值为20,序列号为101;另一条LSA的ID为10.10.0.255,花费值为10,序列号为1。
附录E所推荐的方法也有一定的局限性,其实施的前提是:
l 所有的掩码都是连续的;
l 不存在一条外部路由的网络IP刚好与上述处理后的子网广播地址相同。
l 只有基于上述两个前提,这种解决办法才能保证每次产生的LSA的ID都是唯一的。