![Linux 路由错误?](https://linux22.com/image/567568/Linux%20%E8%B7%AF%E7%94%B1%E9%94%99%E8%AF%AF%EF%BC%9F.png)
一段时间以来,我一直在努力解决这个不容易重现的问题。我使用的是 Linux 内核 v3.1.0,有时无法路由到几个 IP 地址。似乎发生的是,内核没有将数据包发送到网关,而是将目标地址视为本地地址,并尝试通过 ARP 获取其 MAC 地址。
例如现在我的当前IP地址是172.16.1.104/24,网关是172.16.1.254:
# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:1B:63:97:FC:DC
inet addr:172.16.1.104 Bcast:172.16.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:230772 errors:0 dropped:0 overruns:0 frame:0
TX packets:171013 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:191879370 (182.9 Mb) TX bytes:47173253 (44.9 Mb)
Interrupt:17
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.1.254 0.0.0.0 UG 0 0 0 eth0
172.16.1.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
我可以 ping 几个地址,但不能 ping 172.16.0.59:
# ping -c1 172.16.1.254
PING 172.16.1.254 (172.16.1.254) 56(84) bytes of data.
64 bytes from 172.16.1.254: icmp_seq=1 ttl=64 time=0.383 ms
--- 172.16.1.254 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.383/0.383/0.383/0.000 ms
root@pozsybook:~# ping -c1 172.16.0.1
PING 172.16.0.1 (172.16.0.1) 56(84) bytes of data.
64 bytes from 172.16.0.1: icmp_seq=1 ttl=63 time=5.54 ms
--- 172.16.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.545/5.545/5.545/0.000 ms
root@pozsybook:~# ping -c1 172.16.0.2
PING 172.16.0.2 (172.16.0.2) 56(84) bytes of data.
64 bytes from 172.16.0.2: icmp_seq=1 ttl=62 time=7.92 ms
--- 172.16.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.925/7.925/7.925/0.000 ms
root@pozsybook:~# ping -c1 172.16.0.59
PING 172.16.0.59 (172.16.0.59) 56(84) bytes of data.
From 172.16.1.104 icmp_seq=1 Destination Host Unreachable
--- 172.16.0.59 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
当尝试 ping 172.16.0.59 时,我可以在 tcpdump 中看到已发送 ARP 请求:
# tcpdump -n -i eth0|grep ARP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
15:25:16.671217 ARP, Request who-has 172.16.0.59 tell 172.16.1.104, length 28
并且 /proc/net/arp 中 172.16.0.59 的条目不完整:
# grep 172.16.0.59 /proc/net/arp
172.16.0.59 0x1 0x0 00:00:00:00:00:00 * eth0
请注意,172.16.0.59是可从该 LAN 上的其他计算机访问。
有人知道发生了什么事吗?谢谢。
更新:回复以下评论:
- 除了 eth0 和 lo 之外没有其他接口
- ARP 请求在另一端是看不到的,但这就是它的工作原理。主要的问题是 ARP 请求根本不应该被发送
- 即使我使用命令“route add -host 172.16.0.59 gw 172.16.1.254 dev eth0”添加显式路由,问题仍然存在
答案1
这确实是 Linux 内核的一个错误,可能从 2.6.39 版开始。我已将问题发布到 lkml 和 netdev 列表(请参阅以下帖子https://lkml.org/lkml/2011/11/18/191),并且刚刚在另一个 netdev 线程中进行了讨论http://www.spinics.net/lists/netdev/msg179687.html
目前的解决方案是重新启动或刷新所有路由并等待 10 分钟,直到 icmp 重定向过期。为了防止这种情况再次发生,
echo 0 >/proc/sys/net/ipv4/conf/eth0/accept_redirects
有帮助。
答案2
172.16.XX 默认子网掩码为 255.255.0.0,您已将其重新配置为 255.255.255.0。因此,主机 172.16.0.x 和 172.16.1.x 位于不同的子网上。因此它将尝试通过默认网关进行路由。
将子网掩码更改为 255.255.0.0 将解决问题。
你能提供一张图吗?如果你不能画出网络,它就无法修复(老网络工程师的谚语...对我来说!)。
干杯,