我有两台通过交换机连接的 Linux 机器。
两台机器都运行 Linux RHEL 7.3 内核 3.10.0-327.el7.x86_64
其中一台机器通过两个端口连接到交换机,另一台机器通过一个端口连接到交换机。
两个端口共享同一子网。
ifconfig machine 1
ens3f1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 6.6.6.2 netmask 255.255.255.0 broadcast 6.6.6.255
ether 34:9a:17:aa:28:1b txqueuelen 1000 (Ethernet)
ifconfig machine 2
ens1f1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 6.6.6.11 netmask 255.255.255.0 broadcast 6.6.6.255
ether 34:9a:17:65:55:5d txqueuelen 1000 (Ethernet)
ens3f1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 6.6.6.12 netmask 255.255.255.0 broadcast 6.6.6.255
ether 34:9a:17:aa:26:1b txqueuelen 1000 (Ethernet)
我使用以下方法刷新了 arp 表
ip -s neigh flush
然后我在机器 1(带有一个端口)上运行一个 tcp 服务器,并在机器 2 上运行一个绑定到特定设备(设备 ens3f1,ip 为 6.6.6.12)的 tcp 客户端。我在服务器(机器 1)的 arp 表中看到了这一点
ip neigh show
6.6.6.12 dev ens3f1 lladdr 34:9a:17:65:55:5d REACHABLE
10.224.12.254 dev eno1 lladdr 00:00:5e:00:01:01 REACHABLE
6.6.6.11 dev ens3f1 FAILED
正如你在 arp 表中看到的,我看到 ip 6.6.6.12 和 mac 34:9a:17:65:55:5d 之间存在连接,但在 ifconfig 中你看到这个数据不正确。再次运行客户端并将其绑定到另一个端口 (6.6.6.11) 后,我看到这个 arp 表
6.6.6.12 dev ens3f1 lladdr 34:9a:17:65:55:5d REACHABLE
10.224.12.254 dev eno1 lladdr 00:00:5e:00:01:01 REACHABLE
6.6.6.11 dev ens3f1 lladdr 34:9a:17:65:55:5d REACHABLE
在这里你可以看到两个 ip 都有相同的 mac!有人知道如何解决这个问题吗?这是两台机器中的 tcpdump
tcpdump: listening on ens1f1, link-type EN10MB (Ethernet), capture size 65535 bytes
17:36:39.309925 34:9a:17:aa:28:1b (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has ***** (Broadcast) tell 6.6.6.2, length 46
17:36:39.309931 34:9a:17:65:55:5d (oui Unknown) > 34:9a:17:aa:28:1b (oui Unknown), ethertype ARP (0x0806), length 42: Ethernet (len 6), IPv4 (len 4), Reply ****** is-at 34:9a:17:65:65:5d (oui Unknown), length 28
tcpdump -i ens3f1 -e -vv
tcpdump: listening on ens3f1, link-type EN10MB (Ethernet), capture size 65535 bytes
17:36:39.309941 34:9a:17:aa:28:1b (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has r-aa-nitro01.rdmz.labs.
谢谢!!
答案1
这是由于网络堆栈中选项的默认配置所致arp_filter
。可能的值记录在https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt:
arp_filter - 布尔值
1 - 允许您在同一子网上拥有多个网络接口,并根据内核是否将数据包从 ARP 的 IP 路由出该接口来回答每个接口的 ARP(因此您必须使用基于源的路由才能使其工作)。换句话说,它允许控制哪些卡(通常是 1 个)将响应 arp 请求。
0 -(默认值)内核可以使用来自其他接口的地址来响应 arp 请求。这看起来可能不对,但通常是有道理的,因为它增加了成功通信的机会。在 Linux 上,IP 地址归整个主机所有,而不是由特定接口所有。只有对于更复杂的设置(如负载平衡),这种行为才会导致问题。
如果 conf/{all,interface}/arp_filter 中至少有一个设置为 TRUE,则将启用该接口的 arp_filter,否则将禁用该接口的 arp_filter
也与arp_ignore
此相关:
arp_ignore - INTEGER 定义响应收到的解析本地目标 IP 地址的 ARP 请求发送回复的不同模式:
0 - (默认值):回复任何本地目标 IP 地址,配置在任何接口上
1 - 仅当目标 IP 地址是传入接口上配置的本地地址时才回复
2 - 仅当目标 IP 地址是传入接口上配置的本地地址,并且与发送方的 IP 地址都属于此接口上的同一子网时才回复
因此,设置arp_filter
为 1 和arp_ignore
2 后,您应该会得到想要的行为。
答案2
最后我做了这个设置
$ sysctl -w net.ipv4.conf.[DEVICE].arp_announce=1
$ sysctl -w net.ipv4.conf.[DEVICE].arp_ignore=2
$ sysctl -w net.ipv4.conf.[DEVICE].rp_filter=0
$ sysctl -w net.ipv4.conf.[DEVICE].arp_filter=0
我从 http://jefflane.org/v2/technology/multiple-nics-on-the-same-subnet-avoiding-arp-flux/