背景技术
现有技术中,网络路由器中的IP查找通常使用控制前缀扩充CPE(control prefix expansion)方法。CPE方法是由Srinivasan提出的一种快速查找方法,论文名称为“Faster IP Lookups usingControlled Prefix Expansion”(出自proc.ACM sigmetrics′98conf.,madison,WI,第1-11页),该方法利用分段压缩的思想减少方法的时间复杂度,使得查找速度大大增加,根据不同的配置,可以在3~32步之间查找完成。下面简单介绍CPE方法。
自从1993年采用CIDR(无类域间路由协议)协议以来,IP路由就包含两个部分<IP前缀,前缀的长度>,前缀的长度范围在0~32之间。对于每一个输入包,IP查找引擎需要查找出匹配的IP前缀集合,并从匹配的前缀集合中查找出最长匹配的前缀。最长匹配的前缀所指示的地址就是查找出来的下一跳的地址。关于CIDR的详细内容可见:RFC1519 Classless Inter-Domain Routing(CIDR):anAddress Assinment and Aggregation Strategy.V.Fuller,T.Li,J.Yu,& K.Varadhan.September 1993.以及RFC1817 CIDR安定Classful Routing.Y.Rekhter.August 1995。
路由表中的规则可以表示为前缀的形式,前缀的长度在8位和32位之间变化,IP查找方法即找出最长匹配的前缀,由于前缀长度的多样性,是造成查找方法时间复杂度高的一个重要因素。对于前缀最大长度为W,NetBSD(一种标准的unix操作***,该操作***实现了TCP/IP协议栈,其中包含IP查找的实现)中的二叉树的方法复杂度为O(W),如果前缀最大长度减少为L(L<W),则方法复杂度将减少为O(L)。显而易见,减少前缀的最大长度将提高方法的速度。控制前缀扩充方法的基本思想是通过减少前缀长度的多样性来增加方法的步长,从而减少了方法的复杂度,达到快速查找的目的。
任何前缀,可以扩充为指定长度的前缀集合,如对于前缀10*,可以扩充为长度为4的前缀集合{1000*,1001*,1010*,1011*},通过扩充前缀到指定的长度,可以归一化前缀的长度,从而减少了前缀长度的多样性。扩充前缀方法可以把扩充后归一化的前缀长度分为几级,每一级前缀的长度是一样的,通过数组索引就可以找到该级别的节点。
扩充前缀tries树把原来的1-比特树的32级结果压缩为3级结构,查找次数缩短为3次,方法的时间复杂度为O(3)。从而达到快速查找的目的。假设P5=0*,P1=10*,P2=111*,P3=11001*,P4=1*,P6=1000*,P7=100000*,P8=1000000*,则典型的扩充前缀树的结构如图1所示。
但是,在CPE方法中,当进行路由修改时,需要借助如图2所示的辅助1-比特树来判断原有前缀和修改前缀的长度,当***一个前缀项时,如果原有前缀长度大于***的前缀长度,该前缀不能覆盖原有的前缀,如果原有前缀长度小于现有前缀长度,则需要覆盖该前缀。
而且,辅助1-比特树需要占用内存,在4万个路由项时,大约需要占用1.5M的空间。另外,在采用辅助1-比特树的方式进行路由修改时需要复杂的遍历和读写操作,从而需要浪费大量的内存带宽。
具体实施方式
在描述本发明的实施例前,先说明一下本发明中的两个术语的差别。一个是级别长度,一个级的长度。在本说明书中,级别长度指的是该级的第一比特和最后一比特之间的距离,而级的长度是该级的最后一比特与第一级的开始比特之间的距离。
图2是包含6个前缀的辅助1-比特树。参照图2,(1)~(6)表示1-比特树中的前缀。为了说明的方便,假定前缀的***顺序与序号(1)~(6)一致。在图2的辅助1-比特树中,具有前缀的节点用实心点表示,没有前缀的节点用空心点表示。1-比特树的左节点表示0,右节点表示1,对于前缀(3),用1-比特树表示其前缀为11001*。图2中的1-比特树分为2级,其中级别1包含2个比特,级别2包含3个比特。为了便于说明本发明的原理,我们将本发明中的分级与辅助1-比特进行对应。在本发明的优选实施例中,分级指的是CPE方法中的分级,并在图2中假设将前缀分为2级。参照图2可看出,级别1中的前缀总是不能覆盖级别2中的前缀,反之,级别2中的前缀总是能覆盖级别1中的前缀,因为级别1中的前缀的长度比级别2的前缀的长度短。这样,在本发明中要解决的就是如何判读同一级别中的前缀的覆盖关系。注意,这里只是为了便于说明本发明的原理而引用了辅助1-比特树,在实际中实现本发明是不需要借助1-比特树的。
图3是根据本发明的优选实施方式的前缀掩码的一种实现方式-网络地址掩码级别码。在本发明的一种实施例中,前缀掩码的表示方式是前缀的长度,例如,对于前缀(3),总共包括5位二进制数,其长度为5,所以其用长度表示的前缀掩码值为5。同理,前缀(6)的前缀掩码为3。因为,前缀(6)的长度比前缀(3)的长度短,所以在***(6)这个节点时,就不能够覆盖(6)的下级节点(3)所在的单元。总之,如果要***的前缀的长度比原来的长,则覆盖;比原来的短或一样长,则不覆盖。
在本发明的另一个实施例中,用前缀的相对长度来表示前缀掩码。前缀的相对长度即前缀在当前级别中的长度,也就是把前缀长度减去上一级别的长度,例如,对于前缀(6)来说,其在级别2中的相对长度为3-2=1;前缀(3)在级别2中的相对长度为5-2=3,同样可以得出前缀(6)的长度比前缀(3)的长度短。可见,前缀的相对长度并不改变前缀长度之间的相对关系。采用前缀的相对长度,可以减少前缀掩码占用的空间,从而达到降低内存占用的目的。同上一个实施例一个,如果要***的前缀的相对长度比原来的长或一样长,则覆盖;比原来的短,则不覆盖。
路由器中的前缀通常用“网络地址”和“网络地址掩码”来表示,如果要计算前缀的长度,一种计算前缀长度的方法是对前缀的网络地址掩码进行左移位,然后每移一次将一个计数器加1,当到达第一个零时结束。计数器中的值就是前缀的长度。前缀的相对长度也可以用类似的办法来计算。本领域中的普通技术人员很容易设计出计算长度的其他方法。
在本发明的另外优选实施例中,通过从网络地址掩码中截取一定长度的数据来表示前缀掩码,并通过比较前缀掩码的大小来判断覆盖关系。
如本说明书前面所述,只需要在同一级别中判断前缀的覆盖关系,所以截取的长度只要能大于或等于前缀在相应级别的长度就行。因此,最长的一种形式是截取整个网络地址掩码的长度,即直接用网络地址掩码来表示前缀掩码。然后通过将在判断覆盖关系时对前缀掩码的大小进行比较。例如,根据该方法,前缀(3)的前缀掩码为11111000…,前缀(6)的前缀掩码为111000,显然前缀(6)的前缀掩码小于前缀(3)的前缀掩码,所以不能覆盖。但由于直接用网络地址掩码来表示显然太长,占用内存太多,所以在在其它截取方式中,我们对网络地址掩码进行截短。一种截短方式是采用固定前缀长度的方式,即所有前缀掩码的长度一样,根据前面的原理,显然只要截取的长度大于或等于最长的级别长度就行。在优选实施例中,选择前缀掩码的长度等于最长级别的长度。另一种方式是采用变长的前缀长度的方式,即前缀掩码的长度对不同级别的前缀的的长度是不一样的,根据本发明的原理,只要前缀掩码的长度大于或等于该前缀在相应级别的长度就行。在本发明中,选择前缀掩码的长度等于前缀在相应级别的长度,并称这种形式的前缀掩码为“网络地址掩码级别码”。例如,对于图1中的前缀(3),它的前缀值为11001*,其网络地址掩码为11111000…,前缀(3)在级别2上,可以截取网络地址掩码在级别2所对应的值作为前缀掩码,即“111”作为前缀掩码。如图3所示。同样,可以得出前缀(6)的前缀掩码为“100”。这样,就可以通过“111”和“100”的大小的比较来判断覆盖关系。100显然比111小,所以前缀(6)不能覆盖前缀(3)。
上面的实施方式中,关于长度和相对长度表示的前缀掩码如何生成本领域的技术人员都很熟悉,这里就不再详细描述。直接用网络地址掩码表示的也很简单,下面描述一下当用网络地址掩码来生成前缀掩码时的优选实施方式。
第一种方式是通过先左移后右移来产生。假设前缀分为L级,要取出前缀在第M级别的长度,则可以先左移,左移的长度为级M-1的长度,然后右移,右移的长度为级L的长度减去级别M的级别长度。例如,L为3,总长为8,级别长度分别为2,3,3(对应级的长度为2,5,8)。假设前缀的网络地址掩码为1111000,则前缀掩码的获得过程如下:
|
级别1 |
级别2 |
级别3 |
网络地址掩码 |
11 |
111 |
000 |
左移2位后 |
11 100 00000 000 111 |
右移5位 |
移位操作显然比较花时间,为此可以通过用与一个掩码值进行“位与”然后右移位的方法来进行。可以先为不同的级别定义不同的掩码值,对于级别M,掩码值F(M)的构成为“对应相应级别的位为1,其余位为0”。这样,在如上例子中,F(1)=11000000,F(2)=00111000,F(3)=00000111。
这样可以将前缀的网络地址掩码与级别的掩码值相与然后进行右移来得到前缀掩码,右移的位数为最后一级的长度减去当前级的长度。例如,计算过程如下所示:
|
级别1 |
级别2 |
级别3 |
网络地址掩码 |
11 |
111 |
000 |
掩码值 |
00 111 00000 111 000 |
相与后 |
移位后 |
00 000 111 |
网络地址掩码级别码的生成方式还有很多,基本原理与上面描述的是一样的。例如,还可以直接取前缀在相应级别中的值并在前面加“1”来形成前缀掩码。例如,在图2中的前缀3的情况下,其前缀掩码将为“1+001”=“1001”。对于前缀6,前缀掩码将为“10”。
图4是前缀覆盖码的***操作流程。有了以上介绍的各种前缀掩码后,在进行前缀修改时,可以通过判断前缀掩码来决定是否可以进行前缀的覆盖操作,这样可以去掉原有的数据结构“辅助1-比特树”,以及复杂的判断覆盖的操作。
在使用前缀掩码时,需要在CPE的数据结构中增加保存前缀掩码的空间,CPE的数据结构是以节点为基础的。每个节点表示一个路由项,每个节点都需要增加保存前缀掩码的空间。在实际处理时,可以把节点与前缀掩码的数据结构放在一起,也可以分开,当分开处理时,需要节点与前缀掩码的数据结构保持一一对应的索引关系。在本发明的优选实施例中,前缀掩码与节点的数据结构放在一起。并且,在下面的描述中,假设前缀掩码是网络地址掩码级别码。
图4的流程从方框401开始,到达方框402计算要***的前缀的前缀掩码。计算前缀掩码的方法如上所述,包括长度、相对长度以及网络地址掩码级别码等。例如假如在图1中要***的前缀是P9=1111*,则用网络地址掩码级别码表示的前缀掩码为“110”。计算出前缀掩码后流程进行到方框403,查找前缀***的开始位置。根据本领域技术人员所熟知的方法,找到前缀的***的开始位置为节点S中的“110”。接着流程到达方框404,计算出前缀***结束位置。前缀的结束位置是这样来计算的,即前缀的开始位置加2K,其中K是前缀在该级别中的剩余长度,因为前缀P9在级别2中的剩余长度为1,所以K=1,则结束位置等于110+001=111。接着流程到达方框405开始将前缀循环***扩充前缀节点。循环的开始流程显然不会结束,所以流程到达方框406取当前节点的前缀掩码,并在方框407时对所要***的前缀P9的掩码与所取的当前节点的前缀掩码进行比较,当前节点是P2,其前缀掩码是“100”,因为110大于100,所以P2被P9覆盖。接着流程到达方框408***扩充前缀,即写入P9。接着,流程到达方框409修改当前节点的前缀掩码为“110”。同理,在下一次循环时将111位置处的P2替换为P9,并将当前节点的前缀掩码修改为110。到第三次循环时,在方框405判断出循环完毕,则流程到达方框410退出。总之,在判断前缀的覆盖关系时,如果原来节点的为空(即前缀掩码为000),则可以直接***;如果原来节点的前缀掩码值比现在的小或相等,则直接覆盖;如果原来的节点掩码值比现在的大,则保留原来的节点。
另外,本领域的技术人员将能够理解,***前缀的开始位置和结束位置在实际中可以在进行前缀扩充的时候自然形成。例如前缀P9经扩充后为11110*和11111*,所以能自然得到开始和结束位置分别为110和111。当然,本领域技术人员也可以使用获得开始和结束位置的其它方法。
从图4的前缀***流程图中可以看出,前缀的***操作很简单,只需要判断一下前缀掩码的大小,就可以决定是否可以***,避免了原有前缀***需要通过1-比特树的情形。通过前缀掩码,大大减少了前缀***的计算复杂度。
图5是根据本发明的优选实施例的路由删除操作的流程图。
前缀的删除时同样可以通过判断前缀掩码来决定是否删除当前节点,但是删除当前节点后,需要回嗍找到上一个相邻的前缀,填充到删除的节点处。这个相邻前缀通过原有的结构是无法获得的,前缀掩码中也无法得到这个前缀。这是删除操作的一个关键问题。
在路由器中,往往有一个路由协议处理单元,路由协议处理单元产生需要修改的前缀,路由协议处理单元往往与转发处理单元独立。路由协议处理单元中保留一个类似于1-比特树的结构,所以路由协议处理单元在生成需要修改的前缀时,是能够回嗍得到上一个相邻的前缀。所以这里借鉴这个结构,在发起前缀删除操作时,需要同时带上相邻前缀的结构。删除前缀的数据结构如下所示:
struct DEL_ROUTE
{
Prefix cur_prefix;
Prefix up_prefix;
};
在实际路由器设计中,也可以采用一个1-比特树来产生这个DEL_R0UTE结构,DEL_ROUTE结构可以在主控板,接口板,网管平台等地方生成,也可以采用其他的类1-比特树或者类协议处理单元的数据结构的方式产生。
DEL_ROUTE结构中Prefix是前缀的数据结构,包括前缀的值,网络地址掩码的值,以及路由信息。cur_prefix表示需要删除的前缀,up_prefix是删除cur_prefix后,需要填充的上一个相邻前缀。例如,11*的上一个相邻前缀是1*,1110*的上一个相邻前缀是111*。这个结构是路由协议处理单元产生一个删除路由消息时产生的,有了这个结构后,结合前缀掩码的概念,可以方便的完成路由的删除操作,路由删除操作的流程图如图5所示。
图5的流程从方框501开始。接着在方框502计算要删除的前缀的前缀掩码。假设现在要删除的是在上面针对图4的描述中***的P9,P9的前缀掩码是“110”。从过来的数据结构DEL_ROUTE中的信息可知前缀P9的up_prefix是P2。所以流程在方框503中计算出up_prefix的前缀是“100”。接着,流程在方框504计算前缀删除起始位置。与图4中描述的同样原理,计算出起始位置为110。同理,在方框505计算出结束位置为111。接着到达方框506判断是否进入循环体。显然,当前的判断结果为不退出循环,所以接着在方框507取当前节点的前缀掩码。取出为“110”。然后在方框508比较两个前缀掩码,结果为相同,所以删除。接着在方框509将P9改为P2,并接着在方框510将当前节点的前缀掩码改为“100”。在方框508,若经判断发现不用删除当前节点,则流程回到方框506。若在方框506经判断循环完毕,则退出循环后在方框511结束。
从前缀删除流程图中可以看出,增加DEL_ROUTE结构后,前缀的删除操作也是及其简单的,其中比较两者的前缀掩码值,指的是比较删除前缀的前缀掩码值和当前节点前缀的前缀掩码值的大小。如果删除前缀的前缀掩码值要等于当前节点的前缀掩码值,则删除当前节点。否则不删除当前节点。如果删除当前节点,其实就是把上一个相邻前缀(up_prefix)***到当前节点,并修改当前节点的前缀掩码为up_prefix的前缀掩码。如果up_prefix为空,则置当前节点和前缀掩码为0。
当删除前缀节点时,需要获得上一个相邻前缀的值,这里借用路由协议处理单元的结果,在路由协议处理单元生成前缀时,产生上一个相邻前缀的值,在删除节点时,采用DEL_ROUTE的结构,解决了删除节点的问题,使得节点删除操作与节点***操作同样简单,可以满足高速路由器的处理要求。
上面参照本发明的优选实施方式描述了本发明,显然,在本发明的所公开的原理和实质范围内,可以对所公开的实施例作各种替换、变换或等效。另外,本发明可以与其它节省内存的方法共同使用,例如叶子下移(LeafPush)技术,该技术主要是把叶子节点下移到根节点,加快查找的速度。