Linux 路由选择不遵循预期规则

Linux 路由选择不遵循预期规则

我有以下路由规则(使用显示route -n):

Kernel IP routing table
Destination  Gateway    Genmask         Flags Metric Ref Use Iface
0.0.0.0      10.0.2.1   0.0.0.0         UG    100    0     0 enp0s3
10.0.2.0     0.0.0.0    255.255.255.192 U     100    0     0 enp0s3.100
10.0.2.0     0.0.0.0    255.255.255.0   U     100    0     0 enp0s3
169.254.0.0  0.0.0.0    255.255.0.0     U     1000   0     0 enp0s3

该接口enp0s3.100是VLAN id 100的接口。

如果我尝试获取 10.0.2.70 的路由,我希望它使用 VLAN 接口,但事实并非如此:

# ip route get 10.0.2.70
10.0.2.70 dev enp0s3  src 10.0.2.11 
    cache

有谁知道为什么这里不使用最长前缀匹配?

答案1

首先,最好只使用命令ip,因此您应该使用ip route show(或ip r简称)来列出路由表。

在这种情况下,VPN 上的路由为 10.0.2.0/255.255.255.192 或 10.0.2.0/26。该子网为 0 - 63。您的示例目标 10.0.2.70 属于外部在此范围内,因此它不会通过 VPN 进行路由,而是使用 enp0s3 上的下一个更具体的路由 10.0.2.0/24。

你提到“最长的前缀匹配”,我通常听到“最具体的匹配”,即范围最小的地方,这确实意味着最长的前缀。然而,如上所述,您正在测试的 IP 地址并不属于您认为的前缀范围。

在 Debian(及其衍生版本)上有一个非常有用的实用程序netmask,它可以帮助使事情变得更清晰:

$ netmask -r 10.0.2.0/255.255.255.192
       10.0.2.0-10.0.2.63       (64)

请注意,这ip route show并没有显示全部情况,基于策略的路由可能正在发挥作用。您还需要列出所有路由规则,这是正常输出:

$ ip rule show
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 

然后,您可以通过这种方式列出给定表中的路由条目,此处为“本地”表:

$ ip route show table local

这称为基于策略的路由。通常您不会使用此功能(例如,如果您有多个互联网连接,则您会使用此功能),但在对非您自己配置的系统上排除路由问题时了解这一点会有所帮助。

相关内容