Linux-Kernel

意外的路由選擇

  • May 28, 2022

我在幾台機器上的 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和一個 for 2602: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 zebra2602: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 中如何完成路由選擇的角度來看,有沒有人知道可能導致這種情況的原因?(以及關於可以調整哪些參數來修復它的任何想法?)

這是一個多路徑路由:使用兩個網關,一個沒有優先於另一個,但是對於特定的目的地(和其他因素),將使用相同的網關來避免使用它的干擾流。因此,如果使用或測試的目的地很少,一個網關可能看起來比另一個更受青睞。

可以直接使用“簡單”語法設置多路徑路由,也可以使用andip 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 的預設路由的模型配置,一個循環(帶有bashand jq)給出了這個:

# 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 tcpip route get上面的命令會更改結果,選擇udpipv6-icmp代替tcp再次更改)。

引用自:https://unix.stackexchange.com/questions/704140