目錄
前文列表
《IPv6 — 網際協議第 6 版》
《IPv6 — 地址格式與尋址模式》
《IPv6 — 協議頭》
IPv6 的通信方式
在 IPv4 中,主機之間的通信是建立在 IP 協議和 ARP 協議之上的,主機通過 ARP 廣播得知 IP 地址所對應的主機網卡的 MAC 地址,進而在子網中進行數據報文的傳送。但 IPv6 是沒有廣播尋址模式的,所以啟用 IPv6 的主機並不是必須要通過 DHCP 自動獲取或手動配置 IP 地址的,主機可以自動配置自己的 IP 地址。在 IPv6 中 ARP 已被 ICMPv6 的鄰居發現協議替代。
NDP(Neighbor Discovery Protocol,鄰居發現協議)
IPv6 引入了相鄰節點搜索協議,該協議使用消息傳遞作為處理相鄰節點間的交互的方式。相鄰節點是指在同一鏈路上的 IPv6 節點。例如,通過發出與相鄰節點搜索相關的消息,節點可以獲知相鄰節點的鏈路本地地址。相鄰節點搜索控制 IPv6 本地鏈路上的以下主要活動:
- 路由器搜索-幫助主機查找本地鏈路上的路由器。
- 地址自動配置-使節點能夠為其接口自動配置 IPv6 地址。
- 前綴搜索-使節點能夠搜索已分配給鏈路的已知子網前綴。節點使用前綴來區分位於本地鏈路上的目標和那些只能通過路由器來訪問的目標。
- 地址解析-幫助節點確定相鄰節點的鏈路本地地址(如果只給定目標的 IP 地址)。
- 確定下一個躍點-使用某種算法來確定本地鏈路之外的包接受者的躍點的 IP 地址。下一個躍點可以是路由器或目標節點。
- 相鄰節點無法訪問檢測-幫助節點確定相鄰節點是否不再可以訪問。對於路由器和主機,可以重復進行地址解析。
- 重復地址檢測-使節點能夠確定其要使用的地址是否尚未被使用。
- 重定向-使路由器能夠通知主機要用於到達特定目標的較好的第一個躍點節點。
相鄰節點搜索使用下列類型的 ICMP 消息在鏈路上的節點之間進行通信:
- 相鄰節點請求
- 相鄰節點通告
- 路由器請求
- 路由器通告
- 重定向
IPv6 主機能夠使用唯一的鏈路本地地址來自動配置自身的 IPv6 地址,一旦主機獲得了 IPv6 地址,它就加入了多個組播組。與該段相關的所有通信僅在那些組播地址上發生。
- 鄰居請求:通過 DHCP 自動獲取或手動配置 IPv6 地址之后,主機向其所有 IPv6 地址的 FF02 :: 1/16 多播地址發送鄰居請求消息,以此來確定沒有 IPv6 地址沖突。
- DAD(重復地址檢測):當主機不偵聽來自段中關於其鄰居請求消息的任何內容時,假定段上沒有重復地址。
- 鄰居通告:在將地址分配給其接口並使其啟動和運行后,主機再次發出鄰居通告消息,通知該段上的所有其他主機,它已分配這些 IPv6 地址其接口,其他的主機就不要再繼續重復分配了。
一旦主機完成了其 IPv6 地址的配置,它會執行以下操作:
- 路由器請求:主機在其段上發送路由器請求 FF02 :: 2/16 組播數據包,以了解此段上所有存在的路由器。它幫助主機將路由器配置為其默認網關。如果其默認網關路由器關閉,主機可以切換到新的路由器,並使其成為默認網關。
- 路由器通告:當路由器接收到路由器請求消息時,它回應主機,通告它在該鏈路上的存在。
- 重定向:路由器收到了主機發出的路由器請求,但它知道自己並不是該主機的最佳網關。在這種情況下,路由器會響應一個重定向消息,告訴主機有一個更好的 “下一跳” 路由器可用。
NDP 替代了 IPv4 的 ARP(Address Resolution Protocol,地址解析協議)。ARP 報文封裝在 L2 報文中,可視為 2.5 層協議。而 NDP 基於 ICMPv6(Internet Control Message Protocol,網絡控制消息協議)實現,ICMPv6 報文(作為 IPv6 擴展頭部)封裝在 L3 報文中,可視為 3 層協議。NDP 在 L3 實現,優點是:可利用 L3 安全特性;可對不同介質的 L2 使用同一種地址解析協議;可使用組播替代廣播,減輕 L2 網絡壓力。
NDP 定義了 5 種 ICMPv6 報文,分別是 NS(Neighbor Solicitation,鄰居請求)、NA(Neighbor Advertisement,鄰居通告)、RS(Router Solicitation,路由器請求)、RA(Router Advertisement,路由器通告)和 Redirect(重定向)。
前面已經提到,主機如何由 MAC 地址轉換得到接口 ID(MAC-to-EUI-64),以及如何由接口 ID 構成鏈路本地地址(fe80:: + 接口 ID)。主機應進行重復地址檢測,確認同一鏈路上沒有其他接口使用同一地址,再將這個地址分配給接口。
這看起來似乎有些多余,由 MAC 地址轉換得到的接口 ID 應是全球唯一的,構成的鏈路本地地址也應是全球唯一的。實際上,並不是所有類型的 L2 地址(鏈路層地址)都可提取出全球唯一的標識,重復地址檢測是必要的。
假設主機 1 構成的鏈路本地地址為 IP A。主機 1 大喊一聲:誰在用 IP A,答應我一聲。如果等了一陣子,主機 1 沒聽到回應,就表示沒人在用,可以將 IP A 分配給接口;相反,如果主機 1 聽到回應,只能停止 Stateless 自動配置,轉為手工配置。
無論哪種單播地址,在將 IP 占為己有之前,主機應將其標記為 Tentative(臨時)狀態,重復地址檢測通過后再標記為 Valid(合法)狀態。如果主機正在請求某個 IP(Tentative 狀態),收到其他主機對同一 IP 的請求(NS),或已使用同一 IP 的通告(NA),主機應放棄這個 IP。極端情況是,每個請求主機都收到其他主機的請求而同時放棄這個 IP。
假設主機 1 請求 IP 為 IP A=fe80::1,主機 1 發送 NS 報文向其他節點詢問,源地址為 ::(即未指定地址,請求 IP 還是 Tentative 狀態,主機 1 不能用來做源地址),目的地址為 IP A 對應的 Solicited-Node 組播地址 FF02::1:FF00:1(固定前綴為 FF02::1:FF00::,低 48 位和 IP A 相同)。ICMP 報文類型為 135,Option 包含目標地址為 IP A(Target Address=FE80::1,注意區分目標地址和目的地址,這里是 ICMP 報文中的 Target Address,不是 IP 報文中的 Destination Address)。
加入同一 Solicited-Node 組的節點(即 IP 低 48 位和 IP A 相同的節點),比如說主機 2,收到 NS 報文后應查看 Option 包含的目標地址(IP A),如果主機 2 也在請求 IP A(Tentative 狀態),應放棄 IP A,且不返回任何報文,如果主機 2 已在使用 IP A(Valid 狀態),應發送 NA 報文向所有節點通告:源地址為 IP A,目的地址為組播地址 ff02::1,即同一鏈路上的所有節點。ICMP 報文類型為 136,Option 包含目標地址為 IP A。
主機如果想和同一鏈路的其他節點通信,需先獲得對方的本地鏈路地址,進行地址解析,以獲得對方的鏈路層地址(L2)。地址解析和重復地址檢測過程有些相似,不同的是,NS 報文中詢問的目標地址是別人的地址(而不是自己的地址),收到 NS 報文的節點應查看 Option 包含的目標地址,如果和自身地址相同,應返回NA報文通告自己的鏈路層地址。
NS 和 NA 報文都包含發送方的 IP 地址和鏈路層地址,通過上述過程雙方均獲得對方 IP 地址和鏈路層地址的綁定關系,並記錄到鄰居表中並進行維護。鄰居狀態包括 Empty、Incomplete、Reachable、Stale、Delay 和 Probe。簡單的說,重復地址檢測 NS 報文詢問目標是自己的地址,不希望收到 NA 報文;地址解析 NS 報文詢問目標是別人的地址,希望收到 NA 報文。
經過以上步驟,接口 ID 有了,就差前綴了。前綴從哪兒來呢,從路由器來。即使主機不主動找路由器,路由器也會周期性發送 RA 報文,向鏈路上所有節點通告前綴,這稱為 Unsolicited RA。如果主機不想等,也可主動發送 RS 報文,催促路由器發送 RA 報文,這稱為 Solicited RA。即使發送 RS 報文前就收到 RA 報文,主機也應至少發送一次 RS 報文,因為 Solicited RA 可能比 Unsolicited RA 報文包含更豐富的信息。
為了避免造成網絡擁塞,主機不會在獲得鏈路本地地址后立即發送 RS 報文,而是延遲一段隨機時間后再發送,在大面積故障恢復(如停電結束)后鏈路不會同時涌入大量 RS 報文。同樣道理,路由器的周期性 RA 報文也不是嚴格按照周期發送的,避免同一鏈路上的多個路由器同時發送 RA 報文。
假設主機鏈路本地地址為 IP A,路由器鏈路本地地址為 IP B。主機向同一鏈路所有路由器發送 RS 報文,請求路由器發送 RA 報文:源地址為 IP A,目的地址為 ff02::2,即同一鏈路所有路由器的組播地址,ICMP 報文類型為 133。
路由器收到 RS 報文后,向同一鏈路所有節點發送 RA 報文:源地址為 IP B,目的地址為 IPA(如果是 Unsolicited 通告則目的地址為 ff02::1,即同一鏈路所有節點的組播地址),ICMP 報文類型為 134。
RA 報文除了包含前綴(Prefix),還包含 MTU(最大傳輸單元)、Hop Limit(最大跳數)、Route(路由)、Router Lifetime(路由器生存期)、ReachableTime(可達性確認時間)和 RetransTimer(NS 重發時間間隔)等。路由器還會告訴主機使用 Stateless 還是 DHCPv6 獲得全球唯一地址,以及如果使用 Stateless,上述其他信息是否通過 DHCPv6 獲得。
經過第二步,接口 ID 有了,前綴也有了,主機將前綴和接口 ID 組合,就獲得全球唯一地址。全球唯一地址是單播地址,主機應先進行重復地址檢測,再將這個地址分配給接口。實際上,不管地址是通過 Stateless 配置的,還是通過 DHCPv6 配置的,甚至是手工配置的,都應進行重復地址檢測。(某些廠家只檢測鏈路本地地址,不檢測全球唯一地址,是基於兩者由相同接口 ID 構成的前提。實際上,這個前提並不成立,同一接口的多個單播地址不一定使用相同的接口 ID 構成)。
IPv6 地址自動配置
IPv6 的一個主要特征就是允許主機自動配置接口。通過相鄰節點搜索,主機可以在本地鏈路上查找 IPv6 路由器並請求站點前綴。在自動配置過程中,主機將執行以下操作:
- 為每個接口創建鏈路本地地址,該操作不要求鏈路上有路由器。
- 檢驗地址在鏈路上是否唯一,該操作不要求鏈路上有路由器。
- 確定全局地址是應通過無狀態機制、有狀態機制還是這兩種機制來獲取。(要求鏈路上有路由器。)
無狀態自動配置概述
無狀態自動配置不需要手動配置主機,只需對路由器進行很少的配置(如果需要的話),而且不需要其他服務器。無狀態機制允許主機生成其本身的地址。無狀態機制使用本地信息以及由路由器通告的非本地信息來生成地址。
可以為接口實現臨時地址,臨時地址也是自動配置的。可以為主機上的一個或多個接口啟用臨時地址標記。但是,與自動配置的標准 IPv6 地址不同,臨時地址由站點前綴和一個隨機生成的 64 位數字組成。這個隨機數將成為 IPv6 地址的接口 ID 部分。臨時地址作為接口 ID 時,不會生成鏈路本地地址。
路由器將通告鏈路上已指定的所有前綴。IPv6 主機使用相鄰節點搜索從本地路由器獲取子網前綴。主機通過合並子網前綴和從接口的 MAC 地址生成的接口 ID 來自動生成 IPv6 地址。如果沒有路由器,主機可以只生成鏈路本地地址。鏈路本地地址只能用於和同一鏈路上的節點進行通信。