如何設置首選 IPv6 介面
我有一個通過 IPv6 發送多播流量的程序。它從預設網路介面發送流量。它正常工作(流量消失
eth0
)但是如果我載入了 Docker,那麼它會將流量從docker0
介面發送出去,而不是eth0
因此不再在網路上看到流量。這方面的一個例子是,如果我執行命令
ping ff05::1
並且在執行時我tcpdump -n host ff05::1 -i XXX
使用XXX
as檢查介面,eth0
或者docker0
然後數據包並不總是eth0
按需要離開 via。現在我可以通過檢查我正在使用的每個程序並指定要綁定的介面(例如使用
-I
上面的 ping 選項)來解決這個問題,但是這是有問題的,因為我想在多台電腦之間共享相同的配置文件,但是我必須為每一個設置不同的 IPv6 地址和介面名稱,並記住在動態 IP 地址更改時更新它們。相反,我想了解Linux在綁定到套接字時如何選擇要使用的介面,希望我可以在每台機器上手動設置首選介面。然後我正在使用的程序將在正確的介面上發送和接收它們的多播流量,而無需任何特殊配置。
我嘗試為網路 (
ip -6 route add ff05::/16 dev eth0
) 添加路由,但這沒有任何區別。問題似乎是Linux選擇了一個要綁定的介面(在路由發生之前),然後使用該介面的IP地址作為傳出數據包的源地址,無論路由規則如何,都將其鎖定到該介面。那麼,以
ping
上面的命令為例,如何選擇預設的傳出介面(-I
不使用時)以及如何更改它?
注意:應該使用 FF05::2(站點本地所有路由器多播地址)或 FF02::1(鏈路本地所有節點多播地址,這可能應該使用介面範圍)因為 FF05::1(假設站點本地所有節點多播地址)未定義, 並且可能永遠不會得到答案(
ip -6 maddress
至少在任何 Linux 系統上都不會顯示它,而路由器確實顯示 ff05::2)。每次添加和啟動新介面時,在各種自動地址中,都會在本地表中添加一條 IPv6 多播路由…,因此在主路由表中不可見:
$ ip route get ff05::02 multicast ff05::2 from :: dev dummy0 table local proto kernel src fe80::8c5f:87ff:fe50:d08a metric 256 pref medium $ ip -6 route show type multicast table local multicast ff00::/8 dev dummy0 proto kernel metric 256 pref medium multicast ff00::/8 dev lxcbr0 proto kernel metric 256 pref medium multicast ff00::/8 dev eth0 proto kernel metric 256 pref medium ...
equals 之間的順序是相當隨機的,很難重現。每次介面關閉/啟動時,多播條目都會被刪除並重新添加,但順序可能會改變。只有核心可以像這樣添加“相等的路由”,不允許使用者這樣做(=>
RTNETLINK answers: File exists
)。在規則優先級(優先級 0)中,在任何其他表之前使用本地表,主表中的類似條目可能**無效:$ ip -6 rule 0: from all lookup local 32766: from all lookup main
反正。只需在本地表中手動添加一個具有較低度量的多播路由,即可確定地選擇哪個是“預設”多播路由:
# ip route add multicast ff00::/8 dev eth0 table local metric 100 $ ip route get ff05::02 multicast ff05::2 from :: dev eth0 table local src 2001:db8:123:4567:52fb:e94:d3b7:5ba8 metric 100 pref medium
當介面關閉(和啟動)時,此路由將消失,因此應在配置此介面的工具中添加。
注意:預設情況下,IPv4 沒有在任何地方定義任何多播路由(並遵循一些核心內置邏輯來了解地址是否為多播),因此多播路由遵循預設路由。如果想要留出一個多播塊(例如:使用一種生成多播流的工具,但不想用該流淹沒沒有 IGMP 偵聽功能的交換機的 LAN),可以做相反的事情並為這些添加多播類型路由在不同的(這裡是虛擬的)介面上流動。由於沒有本地表互動,所以主表就足夠了(但
table local
也可以添加):# ip route add multicast 239.255.16.0/20 dev dummy0 $ ip route get 239.255.16.2 multicast 239.255.16.2 dev dummy0 src 172.20.21.22 uid 0 cache <mc>