两个接口共享同一子网,出现奇怪的 arp 问题

两个接口共享同一子网,出现奇怪的 arp 问题

我有两台通过交换机连接的 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_ignore2 后,您应该会得到想要的行为。

答案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/

相关内容