在图片案例 1 中,所有网络节点都能够互相 ping 通,添加另一个节点(如图 2 所示)后,我开始遇到问题
- 机器 h1 具有两张以太网卡,充当路由器的角色。
- h1 通过交换机连接到 h2,
- h1 通过以太网端口用交叉电缆直接连接到机器 h3,并且
- h3通过开关连接到h4。
h1上的设置是
#ip addr add 172.16.192.1/22 dev eth0
#ip addr add 172.16.131.254/25 dev eth1
#ip forwarding is set to 1 in /etc/sysctl.conf
h2 上的设置是
#ip addr add 172.16.192.2/22 dev eth0
#ip route add 172.16.131.128/25 via 172.16.192.1
h3 上的设置是
#ip addr add 172.16.131.130/25 dev eth1
#ip addr add 172.16.131.129/25 dev eth0
#ip route add 172.16.192.0/22 via 172.16.131.254
h4上的设置是
#ip addr add 172.16.131.131/25 dev eth0
#ip route add 172.16.192.0/22 via 172.16.131.254
如果看一下案例 1 和案例 2 的图片,就会注意到,在案例 2 中添加了节点 h4 后,机器 h2 就无法再 ping 通机器 h3,但在案例 1 中可以 ping 通。
现在请不要告诉我要改变网络拓扑。它必须完全像这样..并且条件是不能使用桥接!
我想知道是否存在某种循环,因为在 h3 的路由表中,它通过 eth0 和 eth1 有两个到它自己的子网的条目。
无论如何,我怎样才能让 h4 能够 ping h2?使用完全相同的设置?
答案1
没有循环,恰恰相反。
当路由器位于子网“中间”时,第一个问题是其邻近设备无法通过它发送 ARP 查询。在您的例子中,h1 认为 h4 的 IP 地址在 eth1 上是“本地”的(因为子网掩码是这样的),并对其发出 ARP 查询,但 ARP 查询无法跨越路由器 - 即使可以,结果也是不可用的,因为发往 h4 的 MAC 的数据包也无法跨越路由器。
(而如果他们可以穿过路由器,那么它就不再是路由器了:它将成为一座桥梁。你说你不想要一座桥梁。
通常,为了解决这个问题,h1–h3 和 h3–sw–h4 连接需要是不同的子网。
为了在不更改子网的情况下解决这个问题,您需要在中间的路由器 h3 上启用“代理 ARP”。它将使用以下地址回答 h1 发给 h4 的 ARP 查询:它自己的MAC 地址(并将对 h4 针对 h1 的 ARP 查询执行相同操作)。
Proxy-ARP 是一个内置内核功能,但如果它太有限或不够灵活,它也可以由用户空间守护进程(parpd、parprouted)来执行。
第二个问题是,当同一子网有两条路由时,操作系统不知道哪个使用的路由 – 无论设备位于哪个接口后面,它总是选择相同的路由。就您而言,ping 回复很可能总是通过 eth0,即使通往 h2 的网关位于 eth1 上。
如果您预先知道哪些设备在哪一侧,则可以为它们添加更具体的静态路由(并删除除一个子网路由之外的所有子网路由):
# ip route del 172.16.131.128/25 dev eth0
# ip route add 172.16.131.131/32 dev eth0
(您可以通过直接将 eth0 IP 地址配置为 /32 而不是 /25 来简化此过程。)
为了自动化此操作,您还可以使用“parprouted”之类的守护进程,它执行 ARP 代理并自动添加与 ARP 响应相对应的主机路由。