意外的路由選擇
我在幾台機器上的 Debian Linux 上使用 FRR 執行 BGP。我的問題最終可能與 FRR/BGP 配置中的某些內容有關,但我試圖在更基本的層面上理解為什麼會發生特定的 IPv6 路由選擇(來自 Linux 核心)。
我有一台機器“a3”,它與“a1”和“a2”對等。“a1”和“a2”是路由反射器,都為 a3 提供預設網關。這裡可以看到a3的IPv6路由表:
root@a3:~# ip -6 route ::1 dev lo proto kernel metric 256 pref medium 2602:fbbc:0:2::/64 dev vxbr2 proto kernel metric 256 pref medium 2602:fbbc:0:65::/64 dev vxbr101 proto kernel metric 256 pref medium 2602:fbbc:1:1::/64 dev 000_bridge proto kernel metric 256 pref medium fe80::/64 dev 000_bridge proto kernel metric 256 pref medium fe80::/64 dev vnet7 proto kernel metric 256 pref medium fe80::/64 dev vxbr101 proto kernel metric 256 pref medium fe80::/64 dev vxbr2 proto kernel metric 256 pref medium fe80::/64 dev vnet40 proto kernel metric 256 pref medium fe80::/64 dev vnet43 proto kernel metric 256 pref medium fe80::/64 dev vnet46 proto kernel metric 256 pref medium fe80::/64 dev vnet47 proto kernel metric 256 pref medium fe80::/64 dev vnet54 proto kernel metric 256 pref medium fe80::/64 dev vnet57 proto kernel metric 256 pref medium fe80::/64 dev vnet58 proto kernel metric 256 pref medium fe80::/64 dev vnet63 proto kernel metric 256 pref medium fe80::/64 dev 001_bridge proto kernel metric 256 pref medium default nhid 36 proto bgp metric 20 pref medium nexthop via 2602:fbbc:1:1::1 dev 000_bridge weight 1 nexthop via 2602:fbbc:1:1::2 dev 000_bridge weight 1
據我了解,底部讀數附近的行
default nhid 36 proto bgp metric 20 pref medium
表明編號為 36 的 nexthop 條目被用作預設路由,其中包含另外兩個單獨的條目,一個 for2602:fbbc:1:1::1
和一個 for2602:fbbc:1:1::2
。這是下一跳表:
root@a3:~# ip nexthop id 15 dev 001_bridge scope host proto zebra id 16 dev 000_bridge scope link proto zebra id 26 dev vxbr2 scope link proto zebra id 27 dev vxbr101 scope link proto zebra id 31 via 2602:fbbc:1:1::1 dev 000_bridge scope link proto zebra id 32 via 10.1.0.1 dev 001_bridge scope link proto zebra id 36 group 31/37 proto zebra id 37 via 2602:fbbc:1:1::2 dev 000_bridge scope link proto zebra
所以我認為,由於這裡的序列(它在下一跳列表中較早,編號降低並且在 序列中的第一個
id 36 group 31/37 proto zebra
)2602:fbbc:1:1::1
將被選為預設網關,但事實並非如此。查找任何隨機公共 IPv6 地址給出:root@a3:~# ip -6 route get 2001:4860:4860::8888 2001:4860:4860::8888 from :: via 2602:fbbc:1:1::2 dev 000_bridge proto bgp src 2602:fbbc:1:1::a3 metric 20 pref medium
我可以通過 traceroute6 和任何其他可用工具確認2602:fbbc:1:1::2 肯定被選為網關,而不是 2602:fbbc:1:1::1。我不知道為什麼。
此外,
ip -6 route show cache
沒有輸出,ip -6 route flush cache
也沒有效果,所以它似乎與路由記憶體無關。似乎也沒有配置任何自定義規則:root@a3:~# ip -6 rule show 0: from all lookup local 32766: from all lookup main
我確信我將在 BGP 配置上進行更多調整以解決此問題,但僅從 Linux 中如何完成路由選擇的角度來看,有沒有人知道可能導致這種情況的原因?(以及關於可以調整哪些參數來修復它的任何想法?)
這是一個多路徑路由:使用兩個網關,一個沒有優先於另一個,但是對於特定的目的地(和其他因素),將使用相同的網關來避免使用它的干擾流。因此,如果使用或測試的目的地很少,一個網關可能看起來比另一個更受青睞。
可以直接使用“簡單”語法設置多路徑路由,也可以使用and
ip route add ... nexthop ... nexthop ...
使用更新且功能更豐富的語法設置多路徑路由。ip nexthop add id XXX ...``ip route add ... nhid XXX
這裡,路由 nhid 36 選擇 nexthop id 36,它是 id 31 和 id 37 的 nexthop 組。它們在組中具有平等的參與度(因為沒有設置特定的權重)。
算法選擇用於特定目標的網關:預設值是雜湊門檻值算法,如備用(彈性)算法和RFC 2992的文件中所述。該算法確保平均使用兩個網關,但對於特定目的地,始終使用相同的網關。
可以通過比較多個不同目標地址的路由來驗證這一點。例如,使用模擬 OP 的預設路由的模型配置,一個循環(帶有
bash
andjq
)給出了這個:# for i in 2001:db8::{{0..9},{a..f}}; do ip -6 -json route get $i; done | jq -j '.[] | .dst, " via ", .gateway, "\n"' 2001:db8:: via 2602:fbbc:1:1::1 2001:db8::1 via 2602:fbbc:1:1::2 2001:db8::2 via 2602:fbbc:1:1::2 2001:db8::3 via 2602:fbbc:1:1::2 2001:db8::4 via 2602:fbbc:1:1::2 2001:db8::5 via 2602:fbbc:1:1::1 2001:db8::6 via 2602:fbbc:1:1::1 2001:db8::7 via 2602:fbbc:1:1::1 2001:db8::8 via 2602:fbbc:1:1::2 2001:db8::9 via 2602:fbbc:1:1::1 2001:db8::a via 2602:fbbc:1:1::1 2001:db8::b via 2602:fbbc:1:1::1 2001:db8::c via 2602:fbbc:1:1::2 2001:db8::d via 2602:fbbc:1:1::2 2001:db8::e via 2602:fbbc:1:1::2 2001:db8::f via 2602:fbbc:1:1::1
其他系統上的結果可能會有所不同,但總體而言,兩個網關將被均勻使用,每個目的地只有一個網關以最大程度地減少流量中斷(例如:路徑中的防火牆應該看到整個流量,而不是只看到其中的一部分)。
雜湊實際上不僅基於目標,還可能使用源、協議和可能的其他屬性(例如:添加
ipproto tcp
到ip route get
上面的命令會更改結果,選擇udp
或ipv6-icmp
代替tcp
再次更改)。