我在多台机器上的 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 的下一跳条目被用作默认路由,其中包含另外两个单独的条目,一个用于2602:fbbc:1:1::1
,一个用于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 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 中如何完成路由选择的角度来看,有人知道可能导致此问题的原因吗? (关于可以调整哪些参数来修复它的任何想法?)
答案1
这是一条多路径路由:两个网关均被使用,一个网关没有优先级,但对于特定目的地(和其他因素),将使用同一网关以避免干扰使用它的流量。因此,如果使用或测试的目的地很少,则一个网关可能会比另一个网关更受青睐。
可以直接使用“简单”语法来设置多路径路由,也可以使用和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
和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 tcp
上面ip route get
的命令会更改结果,选择udp
或ipv6-icmp
而不是tcp
再次更改它)。