IP多路組播技術,英文爲IP Multicast, 就是英文文檔裏經常說到的BUM報文裏的大M。這是一門特別的技術,它從2層到3層協議mac地址到IP地址都自成一體。很多網工同行只在IE考試裏學習了一下,後來就不怎麼使用了,究其原因是該技術只在某些特定領域裏使用。使用(往往是大量使用)組播技術的領域有廣播行業或有IPTV業務的機構,據說央視就部署了很多組播設備。還有就是在金融行業,使用組播技術來達到同時向多個服務器下單的目的。
簡單描述一下什麼是組播,我們用微信來做個比喻:想象一下小A要同時向小B小C小D...小Z發一段語音,他會怎麼做?一,他可以向每個人發一段同樣的語音。二,他也可以拉一個羣把人都放進去,然後給羣裏發一段語音。後者的做法就是組播技術的原理,把消息發到一個羣裏也就是組播地址(multicast group IP), 所有羣成員都可以收到消息,這樣大大減少了信息源的工作不需要給每個羣成員單獨發消息。
組播技術的學習分兩部分,組播技術2層用的是IGMP協議,在3層用的是PIM協議,尤其PIM是學習難點。下文會簡要的講解一下這兩個協議 ,關於PIM今天我們只講PIM-SM。以下是本文的提綱。
- 基本原理
- 組播二層協議IGMP
- 組播三層協議三層PIM
- PIM-SM的工作流程
- 一個簡單的實驗
- 排錯清單
基本原理
組播的目的就是要讓一個終端能同時向多個終端發送數據報文。這些接收的終端都需要加入到一個IP組地址(multicast group IP)中,才能收到信息源發送的報文。IANA規定224.0.0.0/4 這個D類網段爲組播的IP地址段,這個網域包含從224.0.0.0 到 239.255.255.255 的所有地址,對應二進制地址中以1110開頭的所有地址。
在這些組播地址中還有預留給某些協議的專用地址。
224.0.0.0/24 | 子網內控制報文 |
224.0.1.0/24 | 不同網段的控制報文 |
224.0.0.1 | 網段內所有的主機 |
224.0.0.2 | 網段內所有的路由器 |
224.0.0.5 | 所有OSPF路由器 |
224.0.0.6 | OSPF中的指定路由器 (Designated Routers) |
224.0.0.9 | 所有RIPv2路由器 |
224.0.0.22 | IGMPv3協議 |
224.0.0.13 | 所有PIM路由器 |
224.0.1.1 | NTP設備 |
因爲羣組IP地址是一個共享地址所以對應的mac地址也是共享地址,所有羣成員(也就是加入羣組裏的接收端)都要讓自己偵聽這個地址。
組播MAC地址的前24位總是固定的以01:00:5E開頭, 並且組播MAC地址中的第25位總爲0,所剩下的23位就要用於匹配對應的組播IP地址。而前文說了組播的IP地址的前4位是不變的,這樣算下來組播MAC地址中可變的23位要就用來匹配組播IP中可變的28位,這就造成了組播MAC地址到組播IP地址的影射中有5位是不能一對一對應的 -- 不同的IP地址使用同一個MAC地址。因此在選擇組播IP地址時應避免同時使用239.0.x.y 和239.128.x.y這兩個區間的地址 [1]。(239.128.0.0 和239.0.0.0映射到同一個MAC地址,239.128.0.1則與 239.0.0.1使用同一個MAC地址如此類推。)
組播二層協議IGMP
終端是不會使用組播的MAC地址作爲發送報文的源地址的,所以交換機是不能通過mac learning學到組播的MAC地址,因而在這種情況下交換機只能把發給組播地址的報文向整個VLAN泛洪,這也是交換機一般的默認設置。對於要用作組播的網絡,把所有組播報文進行全網泛洪自然是不理想的,使用IGMP協議(RFC4541)即可以讓交換機選擇性地只把組播報文發送到加入到該組播地址組的端口。IGMP協議主要包含兩個部分(1)IGMP Snooping和(2)IGMP Querier。
IGMP Snooping能把組播MAC地址添加到交換機的MAC地址表中,這依賴於終端組員發送IGMP join報文來加入IGMP地址組,IGMP會把該地址加入到對應的地址表上,用命令show mac address-table multicast可查看當前交換機上有的組播MAC地址。 發送到一個組播地址的報文會被複制併發送到所有加入到該地址組的端口。用命令show ip igmp snooping groups可以查詢那些端口加入到IGMP Snooping的地址組中。
SW1#sh ip igmp snooping groups
Vlan Group Type Version Port-List
--------------------------------------------------------------------------------
900 239.20.20.20 Dynamic - Et1, Cpu
IGMP Snooping需要終端發送IGMP join的報文,在Linux中可以用這個命令sudo ip addr add <multicast group address>/32 dev eth1 autojoin來加入一個組播地址。例如加入239.20.20.20, 用sudo ip addr add 239.20.20.20/32 dev eth1 autojoin。
但是有些終端是不具備發送IGMP report的功能,這個情況下可以配置靜態關聯。
SW1(config)#interface et5
SW1(config-if-Et4)#ip igmp static-group 239.150.150.160
用命令show ip igmp member查看所有加入到igmp組播的成員,包括用靜態關聯加入的也會顯示。
#sh ip igmp membership
Interface----------------Group Address----IncludeSrc----------ExcludeSrc----------
Ethernet5 239.150.150.160 0.0.0.0
Vlan300 224.0.1.129 0.0.0.0
IGMP Querier會週期性地廣播發出queries報文到VLAN中,在該網段的終端通過回覆querier來表達要加入的組地址。在一個網段中如果有組播路由器,IGMP Querier的角色就由指定的(Designated)組播路由器來擔當,如果一個網段中有多個組播路由器,則通過選舉找出一個指定的路由器來擔當這個角色(一般看那一個的IP地址較小)。這裏組播路由器一般是指配置了PIM的路由器。在沒有組播路由器的情況下,交換機可以配置IGMP Snooping Querier來代替實現相同的功能。
找出在組播中的指定路由器(Designated Router), 用命令show ip pim interfaces。
SW1#show ip pim interfaces
Address Interface Mode Neighbor Hello DR DR Address PktsQed PktsDropped
Count Intvl Pri
70.0.0.1 Ethernet3 sparse 1 30 1 70.0.0.2 0 0
90.0.0.1 Vlan900 sparse 0 30 1 90.0.0.1 0 0
在這個連接裏[2]可以看到IGMP的抓包。
組播三層協議PIM
PIM是組播技術中使用的路由協議,讓組播報文能通過路由到達多個終端,這讓組播技術真正變得有價值。注意具備路由能力的交換機,當其配置了PIM的情況下,IGMP也會被自動開啓。
PIM有多個模式,其中PIM-SM模式應用最廣,本文中只講解PIM-SM。在這裏提一下的是PIM-DM這個模式,PIM-DM與PIM-SM的區別是PIM-DM不需要RP(下文會說什麼是RP),PIM-DM假設所有網段都加入到一個組播地址中,組播報文會被泛洪到所有路由器,不需要組播報文的終端需要發送prune消息來停止接收組播報文。另外還有一種PIM的模式爲PIM-SSM,這種模式下只有一個特定的組播源,不需要使用RP。因爲PIM-SM在組播源上沒有限制,所以也經常被叫作any source multicast, 意思就是任意組播源的組播協議。
要去理解PIM-SM,首先要搞清楚的就是它的術語。向一個組播地址發送報文的服務器就爲源端(source), 而使在該組播地址裏的組員即爲接收端。往源端方向的流爲上游(upstream), 往接收端方向爲下游(downstream)。下圖給出了在PIM-SM拓撲中幾個重要角色 -- FHR,RP,LHR--所處的位置,我做了一些簡化,假設FHR和LHR是具備路由功能的交換機,在現實中一般有多個FHR和LHR。下面來講解這些角色的功能。
- Mroute (Multicast Route): 組播路由表,與之對應的單播路由表就是我們平時常用的路由表。組播路由是爲流量驅動的,在有流量的情況下才會生成路由項,沒有流量路由表就爲空。在組播路由表中沒有BGP,OSPF這些用來傳遞路由的協議。
- FHR (First Hop Router): 如上圖,配置了PIM的連接組播源的第一跳路由器。
- LHR (LastHopRouter):如上圖,配置了PIM的連接接收端的第一跳的路由器。
- RP (Rendezvous Point): RP是PIM-SM的一個具有特殊角色的路由器,在FHR和LHR上配置的RP必須一致。RP是共享樹(RPT)的根。
- SPT (Shortest Path Tree): 從源端到接收端的最短路徑樹,根據單播路由表用RPF(Reserver Path Forwarding)算出來的。
- RPT(Rendezvous Point Tree): RP樹經常被稱之爲共享樹(share tree),從RP到接收端的路徑。
- (S, G): 用於標記SPT,在組播路由表中用來表示SPT去往接收端的下一跳,S表示source, G表示Group。
- (*,G): 用於標記RPT,在組播路由表中用來表示RPT去往接收端的下一跳,*表示任何地址,G表示Group。
爲了防止組播路由中出現環路,在組播中應用了RPF檢測這個規則。不論是從(S,G)路徑或是從(*,G)路徑發送的組播報文都必須通過RPF檢測才能夠往下發送[3]。RPF檢測就是在單播路由表上查詢出報文源地址對應的路徑所對應的出口,即爲RPF接口,如果組播報文進入到組播路由器時的入口與RPF接口不一致,該報文會被丟棄。
PIM-SM的工作流程
上面講了術語,估計不太好理解,下面講一下PIM-SM的工作流程,整個框架呈現出來以後就會好理解一點,其中理解這個流程的關鍵點是搞清報文發送的方向。
- FHR向RP註冊組播源。當組播源向一個組地址發送報文時,FHR會把這第一個報文封裝成PIM register報文,並把報文發送給RP去註冊這個組播源。
- RP給組播源完成註冊。當RP收到PIM register的報文後,假設在有RPT共享樹的情況下,RP會解封這個PIM register報文,並向接收端下發這個報文。同時RP會向FHR發送PIM join報文,在組播路由表中生成(S,G)路由,即去往組播源的路由,途徑的路由器都會生成對應的(S,G),SPT樹就建立了。(C)一旦SPT樹建立,RP會向FHR發PIM register stop報文。
- 組播源通過RPT路徑向接收端發報文。當第二步完成後,源端就可以向接收端發送報文,但這個時候發送的報文都要經過RP,所以可能不是發送報文的最優路徑。 注意這一步的前提條件是RP的組播路由表中有(*,G),也就是RPT共享樹已生成,這時Outgoing Interface List(OIL)上也會對應的接口,報文會從這些接口下發。在沒有(*,G)的情況下,RP會向FHR發PIM register stop報文,並不會向下傳輸組播報文。
- RPT路徑轉到(switchover)SPT路徑。當LHR接收到報文後,LHR就知道了組播源地址,LHR會向源端方向(即上游)發送PIM join報文,在組播路由表中生成(S,G),途徑的路由器也會生成(S,G),建立SPT樹。
- LHR剪除RPT樹。當LHR到FHR完成SPT樹的建立,也就是說途徑的路由器都有(S,G),那麼LHR會發送PIM prune報文給RP,告知RP不用再發組播報文,否則會收到重複的報文。在PIM的RFC7761中[5],這一步被表示爲(S,G,RPT), LHR發(S,G,RPT)報文來通知RP不要再轉發發來自該組播源的報文。
注意在上文第三步中說了RP在組播路由中有(*,G)時才向下發報文。(*,G)的生成由LHR驅動,LHR在有IGMP組員的情況下會向RP發PIM join,RP和中間路由器會對應地生成(*,G)。需要說明的一點是FHR是不用發PIM join報文的,只有LHR發PIM join報文。這裏我們假設LHR是其子網段中的DR,如果LHR不是DR,LHR則只負責在接到IGMP report後建立IGMP組員表,由DR發送PIM join。從PIM-SM上游到下游,如果沒有源端發報文,或沒有接收端發IGMP join報文,PIM-SM將不會有組播路由項也不會傳輸報文,所以PIM-SM被稱之爲流量驅動型的協議。
一個簡單的實驗
前文講解了什麼是PIM當中的FHR,RP,LHR,在實際拓撲中這些PIM協議中的角色通常會分佈在不同的路由器上,但我們也可以在同一個路由器上部署所有這些角色,換言之,這個路由器即是FHR同時也是RP和LHR。
在這個實驗中我們只需要兩臺設備,一臺作PIM路由器,一臺作打流機生成組播流量。這裏的PIM會被設置成同時擔當FHR,RP和LHR;打流器我們使用Arista的vEOS中自帶的軟件ethxmit,在我前面的博客裏介紹瞭如何在EVE-NG環境上導入vEOS,這是鏈接。下面是這個實驗的配置。
router pim sparse-mode
ipv4
rp address 5.5.5.5 <==== 使用loopback5作RPinterface Loopback5
ip address 5.5.5.5/32interface Ethernet1 <==== et1 作爲PIM組播源的入口, 連接到vEOS打流器上
no switchport
ip address 10.1.1.2/30
pim ipv4 sparse-modeinterface Vlan300
ip address 192.168.1.1/24
ip igmp version 2
ip igmp static-group 224.0.1.129 <==== 在vlan 300上配置igmp的靜態關聯,加入組地址224.0.1.129
pim ipv4 sparse-mode
在vEOS上用命令行bash進入Linux模式,用以下命令生成組播流量,用et1爲接口向組播224.0.1.129發流量。
# sudo ethxmit --ip-dst=224.0.1.129 --ip-src=10.1.1.1 --udp-dport=65000 --udp-sport=65000 et1
查看PIM-SM的數據流是否建立,主要就是看(S,G)是否生成。
# sh ip mroute | beg 224.0.1.129
224.0.1.129
0.0.0.0, 0:00:14, RP 5.5.5.5, flags: W
Incoming interface: Register
Outgoing interface list:
Vlan300
10.1.1.1, 0:00:03, flags: SLN <==== 這就是(S,G),S=10.1.1.1, G=224.0.1.129
Incoming interface: Ethernet1
RPF route: [U] 10.1.1.0/30 [0/1]
Outgoing interface list:
Vlan300
排錯清單
在排查組播路由時常見的問題有如下,
- 因MTU不足造成組播源到RP上的註冊失敗。上文的所述,當組播源開始發送報文時,FHR會封裝第一個報文發送到RP,封裝的報文會比原報文大,所以MTU不足會造成註冊失敗。
- FHR,LHR或任一組播路由器沒有去往RP的路徑,這裏指單播(unicast)的路徑。
- TTL問題。有一些組播源在發送的報文上設定TTL爲1,如需經過多箇中間的路由器,報文即無法到達接收端[3]。另一點是IGMP report報文的TTL也爲1。
- LHR中沒有IGMP組員導致報文不能下發。LHR沒有IGMP組員就不會給RP發PIM join, RP就不會向其轉發組播報文。造成這個的原因可能有多種,組員不具備發送IGMP report的功能,或者發送IGMP report的間隔太長。
- Switchover沒有發送。上文說了switchover的過程,簡單來說就是報文的轉發從RPT樹的路徑換到使用SPT樹的路徑,相應地組播路由表中的(*,G)會變成(S,G)。記住即使RP在最短路徑上,這個狀態的切換依然要發生,組播表中最終應該顯示的是(S,G)。如果不想讓switchover發生,需要把SPT threshold這個參數上設爲infinity。
在排錯組播問題常用的命令有:
show ip igmp snooping group | 查看IGMP組地址和組員 |
show ip pim interfaces | 查看配置了PIM的接口, 查看誰是DR |
show ip mroute <group ip> | 查看組播路由表 |
show ip pim neighbor | 查看PIM鄰居和其對應接口 |
show ip rpf <source ip> | 查組播源地址對應的RPF接口 |
clear ip mroute * | 清空當前的組播路由表 |
用show ip mroute來查看一個組播路由器是處與RPT樹狀態還是SPT樹狀態。
以下是組播路由器處於SPT樹狀態的輸出,10.0.0.10是組播源地址,239.10.10.10是組地址,即爲(S,G):
# show ip mroute
239.10.10.10
10.0.0.10, 0:00:51, flags: SL
Incoming interface: Ethernet1
RPF route: [U] 10.0.0.0/24 [0/1]
Outgoing interface list:
Ethernet3
以下是組播路由器處於RPT樹狀態的輸出,組播源地址爲0.0.0.0,表示爲任何地址對應(*,G)中的’*‘, 239.10.10.10是組地址,所以爲(*,G):
#show ip mroute
239.20.20.20
0.0.0.0, 0:00:28, RP 2.2.2.2, flags: W
Incoming interface: Register
Outgoing interface list:
Ethernet4
參考文獻
[1] Clusters from Scratch:https://clusterlabs.org/pacemaker/doc/en-US/Pacemaker/1.1/html/Clusters_from_Scratch/_notes_on_multicast_address_assignment.html
[2] IGMP Packets: https://packetlife.net/captures/protocol/igmp/
[3] Multicast with TTL of 1: https://forums.juniper.net/t5/Routing/Multicast-with-TTL-of-1-how-to-route-across-subnets-PIM-not/td-p/289032
[4] Cisco IP Multicast Troubleshooting Guide: https://www.cisco.com/c/en/us/support/docs/ip/ip-multicast/16450-mcastguide0.htm
[5] Protocol Independent Multicast - Sparse Mode, RFC7761, https://tools.ietf.org/html/rfc7761