IP層轉發分組的流程
這篇文章我們一起來學習下IP層轉發分組的流程。
首先用一個簡單的例子來說明路由器是怎樣轉發分組的,如下圖所示:
有4個A類網絡通過三個路由器連接在一起,每一個網絡上都可能有成千上萬台主機。若路由表指出每一台主機應怎樣轉發,則路由表就會過於龐大(假設每一個網絡有一萬台主機,四個網絡就有4萬台主機,因而每一個路由表就有4萬行),但若路由表指出到某個網絡應如何轉發,則每個路由器中的路由表就只包含4行,一行對應一個網絡。以路由器R2的路由表為例,由於R2同時連接在網絡2和網絡3上,因此只要目的主機在網絡2或網絡3上,都可通過接口0或1由路由器R2直接交付(還要利用ARP協議找到主機硬件地址)。若目的主機在網絡1中,則下一跳路由器應為R1,其IP地址為20.0.0.7。路由器R2和R1由於同時連接在網絡2上,因此路由器R2把分組轉發到路由器R1是很容易的。同理,若目的主機在網絡4中,則路由器R2應把分組轉發給IP地址為30.0.0.1的路由器R3(注意:每一個路由器都有2個不同的IP地址)。
可以把整個的網絡拓撲簡化為下圖所示:
網絡變成了一條鏈路,但每一個路由器都注明其IP地址。使用這樣的簡化圖,可以使我們不必關心某個網絡內部的具體拓撲以及連接在該網絡上有多少台主機,這樣的圖強調了在互聯網上轉發分組時,是從一個路由器轉發到下一個路由器。
在路由表中,每一條路由最主要的是以下兩個信息:
- 目的網絡地址
- 下一跳地址
根據目的網絡地址來確定下一跳路由器,這樣做可得到以下的結果:
- IP數據報最終一定可以找到目的主機所在網絡上的路由器
- 只有到達最后一個路由器時,才試圖向目的主機進行直接交付
在IP數據報的首部中,沒有地方可以用來指明“下一跳路由器的IP地址”,在IP數據報的首部寫上的IP地址是源IP地址和目的IP地址,而沒有中間經過的路由器的IP地址。既然IP數據報中沒有下一跳路由器的IP地址,那么待轉發的數據報又怎樣能夠找到下一跳路由器呢?當路由器收到一個待轉發的數據報,從路由表得出下一跳路由器的IP地址后,不是把這個地址填入IP數據報,而是送交數據鏈路層的網絡接口軟件。網絡接口軟件負責把下一跳路由器的IP地址轉換成硬件地址(使用ARP協議),並將此硬件地址放在鏈路層的MAC幀的首部,然后根據這個硬件地址找到下一跳路由器。由此可見,當發送一連串的數據報時,上述的這種查找路由表、用ARP得到硬件地址、把硬件地址寫入MAC幀的首部等過程,將不斷重復進行。
下面總結下分組轉發算法:
- 從數據報的首部提取出目的主機的IP地址D,得出目的網絡地址為N
- 若N就是與此路由器直接相連的某個網絡地址,則直接交付,即不需要再經過其它的路由器,直接把數據報交付目的主機(把目的主機地址D轉換為硬件地址,把數據報封裝為MAC幀,再發送此幀);否則就間接交付,執行下一步
- 若路由表中有目的地址為D的特定主機路由,則把數據報傳送給路由表中所指明的下一跳路由器,否則,執行下一步
- 若路由表中有到達網絡N的路由,則把數據報傳送給路由表中所指明的下一跳路由器,否則,執行下一步
- 若路由表中有一個默認路由,則把數據報傳送給路由表中所指明的默認路由器,否則,執行下一步
- 報告轉發分組錯誤
路由表並沒有給分組指明到某個網絡的完整路徑,即先經過哪一個路由器,然后再經過哪一個路由器等等。路由表指出,到某個網絡應當先到某個路由器,在到達下一跳路由器后,繼續查找路由表,知道下一步應當到哪一個路由器。這樣一步一步的查找下去,直到最后到達目的網絡。就好比我們去某個目的地,但沒有地圖,只能在每個岔路問路,路人僅指出下一段路如何走,到了下一個岔路,我們繼續問路,如此往復。即使沒有地圖,但最終一定可以到達目的地。
在進一步討論路由選擇之前,我們還要先介紹划分子網和構造超網這兩個非常重要的概念。
划分子網
三級IP地址
今天來看,在ARPANET的早期,IP地址的設計不夠合理:
-
IP地址空間的利用率有時很低
每一個A類地址網絡可連接的主機數超過1000萬,而每一個B類地址網絡可連接的主機數也超過6萬。有的單位申請到了一個B類地址網絡,但所連接的主機數並不多,又不願意申請一個足夠使用的C類地址。IP地址的浪費,還會使IP地址空間資源過早被用完。 -
給每一個物理網絡分配一個網絡號會使路由表變的太大而使網絡性能變壞
每一個路由器都應當能夠從路由表查出應怎樣到達其它網絡的下一跳路由器,當互聯網中的網絡數越多,路由器的路由表的項目數也就越多。這樣,即使我們擁有足夠多的IP地址資源可以給每一個物理網絡分配一個網絡號,也會導致路由器的路由表中的項目數過多。這不僅增加了路由器的成本(更多存儲空間),而且查找路由會耗費更多的時間,同時也使路由器之間定期交換的路由信息急劇增加,因而使得路由器和互聯網的性能下降。 -
兩級IP地址不夠靈活
有時情況緊急,一個單位需要在新的地點馬上開通一個新的網絡。但是在申請到一個新的IP地址之前,新增加的網絡是不可能連接到互聯網上工作的。
為了解決以上問題,從1985年起,IP地址中增加了一個“子網號字段”,使兩級IP地址變成三級IP地址。這種做法叫做划分子網,它的基本思路如下:
(1)一個擁有許多物理網絡的單位,可將所屬的物理網絡划分為若干個子網(subnet)。划分子網純屬一個單位內部的事情,本單位以外的網絡看不見這個網絡是由多少個子網組成,因為這個單位對外仍然表現為一個網絡。
(2)划分子網的方法是從網絡的主機號借用若干位作為子網號(subnet-id),當然主機號也就相應減少了同樣的位數。
(3)凡是從其它網絡發送給本單位某台主機的IP數據報,仍然是根據IP數據報的目的網絡號找到連接在本單位網絡上的路由器。但此路由器在收到IP數據報后,再按目的網絡號和子網號找到目的子網,把IP數據報交付目的主機。
下面用例子說明划分子網的概念:
某單位擁有一個B類IP地址,網絡地址是145.13.0.0(網絡號是145.13)。凡目的地址為145.13.x.x的數據報都被送到這個網絡上的路由器R1。
現在把上圖所示的網絡划分為三個子網,假定子網號占用8位,那么此時主機號就只有8位。所划分的三個子網分別是145.13.3.0、145.13.7.0、145.13.21.0。在划分子網后,整個網絡對外部仍表現為一個網絡,其網絡地址為145.13.0.0,但網絡145.13.0.0上的路由器R1在收到外來的數據報后,再根據數據報的目的地址把它轉發到相應的子網。
子網掩碼
假定有一個數據報已經到達了路由器R1(145.13.3.10),那么這個路由器如何把它轉發到子網145.13.3.0呢?
從IP數據報的首部無法看出源主機或目的主機所連接的網絡是否進行了子網划分。因為IP地址本身及數據報的首部都沒有包含任何有關子網划分的信息,必須另外想辦法,這就是子網掩碼。如下圖所示:
為了使路由器R1能夠很方便的從數據報中的目的IP地址中提取出所要找的子網的網絡地址,路由器R1就要使用三級IP地址的子網掩碼。將數據報的目的IP地址和子網掩碼進行“與”運算,就可得到子網的網絡地址。從網絡外面看,這就是一個普通的B類網絡,但進入到這個網絡后(進入路由器R1),就看到了還有許多網絡(子網)。
現在的互聯網標准規定:所有的網絡都必須使用子網掩碼,同時在路由器的路由表中也必須有子網掩碼這一欄。如果一個網絡不划分子網,那么該網絡的子網掩碼就使用默認子網掩碼,如下:
- A類地址默認子網掩碼:255.0.0.0
- B類地址默認子網掩碼:255.255.0.0
- C類地址默認子網掩碼:255.255.255.0
子網掩碼是一個網絡或一個子網的重要屬性,路由器在和相鄰路由器交換路由信息時,必須把自己所在網絡(或子網)的子網掩碼告訴相鄰路由器。在路由器的路由表中的每一個項目,除了要給出目的網絡地址外,還必須同時給出該網絡的子網掩碼。若一個路由器連接在兩個子網上,就擁有兩個網絡地址和兩個子網掩碼。
划分子網增加了靈活性,但卻減少了能夠連接在網絡上的主機數。
使用子網時分組的轉發
在划分子網后,分組轉發的算法必須做相應的改動。
使用子網划分后,路由表必須包含以下三項內容:目的網絡地址、子網掩碼、下一跳地址,此時轉發分組算法如下:
- 從收到的數據報的首部提取目的IP地址D
- 判斷是否直接交付,對路由器直接相連的網絡逐個進行檢查:用各網絡的子網掩碼和D進行“與”運算,看結果是否和網絡地址匹配。若匹配,則直接交付分組(把D轉換為物理地址,把數據報封裝成幀發送出去),否則間接交付,執行下一步
- 若路由表有目的地址為D的特定主機路由,則把數據報傳送給路由表中所指明的下一跳路由器,否則執行下一步
- 對路由表中的每一行,用其中的子網掩碼和D進行“與”運算,其結果為N。若N與該行的目的網絡地址匹配,則把數據報傳送給該行指明的下一跳路由器,否則執行下一步
- 若路由表中有一個默認路由,則把數據報傳送給路由表所指明的默認路由器,否則執行下一步
- 報告轉發分組出錯
無分類編址CIDR(構造超網)
划分子網在一定程度上緩解了互聯網在發展中遇到的困難,然而在1992年,互聯網仍然面臨三個必須盡早解決的問題,這就是:
(1)B類地址在1992年已分配了一半,眼看很快就將全部分配完畢
(2)互聯網主干網上的路由表中的項目數急劇增長(從幾千個增長到幾萬個)
(3)整個IPv4的地址空間最終將全部耗盡(2011年2月3日,IANA宣布IPv4地址耗盡)
IETF研究出無分類編址的方法來解決前兩個問題,它的正式名字是無分類域間路由選擇CIDR(Classless Inter-Domain Routing),有兩個主要的特點:
(1)它消除了傳統的A類、B類、C類地址以及划分子網的概念。它把32位的IP地址划分為前后兩個部分,前面部分是網絡前綴,用來指明網絡,后面部分用來主機。因此,CIDR使IP地址從三級編址又回到了兩級編址,它使用斜線記法,在IP地址后面加上斜線“/”,寫上網絡前綴所占的位數。
(2)CIDR把網絡前綴都相同的連續的IP地址組成一個“CIDR地址塊”,只要知道CIDR地址塊中的任何一個地址,就可以知道這個地址塊的起始地址(最小地址),最大地址,以及地址塊中的地址數。
當然,主機號全0和全1的地址,一般並不使用。為了方便進行路由選擇,CIDR使用32位的地址掩碼,它由一串1和一串0組成,1的個數就是網絡前綴的長度。雖然CIDR不使用子網,但由於目前仍有一些網絡還使用子網划分和子網掩碼,因此CIDR使用的地址掩碼也可繼續稱為子網掩碼。CIDR不使用子網的的意思是:CIDR並沒有在32位地址中指明若干位作為子網字段,但分配到一個CIDR地址塊的單位,仍然可以在本單位內根據需要划分出一些子網。這些子網也都只有一個網絡前綴和主機號字段,但子網的網絡前綴比整個單位的網絡前綴要長些。例如,某單位分配到地址塊/20,就可以再繼續划分為8個子網(從主機號借用3位來划分子網)。這時每一個子網的網絡前綴就變成23位。
由於一個CIDR地址塊有很多地址,所以在路由表中就利用CIDR地址塊來查找目的網絡。這種地址的聚合常稱為路由聚合,它使得路由表中的一個項目可以表示原來傳統分類地址的很多個路由,減少了路由器之間路由選擇信息的交換,提高了互聯網的性能。路由聚合也稱為構成超網。
最長路徑匹配
在使用CIDR時,路由器中的每一行由“網絡前綴”和“下一跳地址”組成。但是,在查找路由表時可能會得到不止一個匹配結果,這樣就帶來一個問題:應當從匹配的結果中選擇哪一條路由呢?答案是:選擇具有最長網絡前綴的路由,這叫做最長前綴匹配,因為網絡前綴越長,地址塊就越小,路由就越具體。
使用二叉線索查找路由表
因為要尋找最長前綴的路由,所以使得路由表的查找過程變得更加復雜了。當路由表的項目數很大時,怎樣設法減小路由表的查找時間就成為一個非常重要的問題,路由表中必須使用很好的數據結構以及先進的快速查找算法。
對於無分類編址的路由表的最簡單的查找算法是:對所有可能的前綴進行循環查找。例如:給定一個目的地址D,對每一個可能的網絡前綴長度M,路由器從D中提取出M個位的網絡前綴,查找路由表中的網絡前綴,所找到的最長匹配就對應於要查找的路由。這種算法的明顯缺點是查找的次數太多。為了進行更加有效的查找,通常是把無分類編址的路由表存放在一種層次的數據結構中,然后自上而下的按層次進行查找,最常用的就是二叉線索。下面用一個例子說明二叉線索的結構。
為了簡化二叉線索的結構,可以先找出對應於每一個IP地址的唯一前綴。所謂唯一前綴就是:在表中所有的IP地址中,該前綴是唯一的。在進行查找時,只要能夠和唯一前綴相匹配就行了。從二叉線索的根節點自頂向下的深度最多有32層,每一層對應於IP地址中的一位。一個IP地址存入二叉線索的規則很簡單,先檢查IP地址左邊的第一位,如為0,則第一層的節點就在根節點的左下方,如為1,則在右下方,再檢查地址的第二位,構造出第二層的節點,依次類推,直到唯一前綴的最后一位。