在 Windows 中,如果我们在 Hyper-V 管理器中创建一个外部虚拟交换机,它将具有所连接到的 NIC 的 MAC 地址。
所以我想在 Linux 中使用 systemd-networkd 做类似的事情。我的配置如下:
[tom@localhost ~]$ ls /etc/systemd/network/
br0.netdev br0.network enp3s0.network
[tom@localhost ~]$ cat /etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
MACAddress=ac:22:0b:29:e6:0c
[tom@localhost ~]$ cat /etc/systemd/network/br0.network
[Match]
Name=br0
[Network]
DHCP=ipv4
IPv6AcceptRouterAdvertisements=no
[tom@localhost ~]$ cat /etc/systemd/network/enp3s0.network
[Match]
Name=enp3s0
[Network]
Bridge=br0
IPv6AcceptRouterAdvertisements=no
其中ac:22:0b:29:e6:0c
是系统中唯一 NIC(作为 的从属设备br0
)的 MAC 地址。
结果如下:
[tom@localhost ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether ac:22:0b:29:e6:0c brd ff:ff:ff:ff:ff:ff
inet6 fe80::ae22:bff:fe29:e60c/64 scope link
valid_lft forever preferred_lft forever
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ac:22:0b:29:e6:0c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.111/24 brd 192.168.1.255 scope global dynamic br0
valid_lft 85622sec preferred_lft 85622sec
inet6 fe80::ae22:bff:fe29:e60c/64 scope link
valid_lft forever preferred_lft forever
如您所见,现在enp3s0
和br0
具有相同的link/ether
和inet6
(链路本地地址)。
到目前为止,它似乎运行良好。使用 qemu/kvm 创建的虚拟机具有可用的桥接网络(使用-net bridge -net nic
,它利用qemu-bridge-helper
)。主机和客户机都可以正常连接到互联网。
但是,我有点怀疑这种配置在某些情况下是否会引起冲突。所以我的问题是,这是正确的做法吗?或者这是一种糟糕/丑陋的做法?如果有的话,可能存在哪些问题?
编辑enp3s0
:如果我禁用链路本地地址和/或br0
接受 IPv6 路由器通告,会有什么区别吗?
[tom@localhost ~]$ ls /etc/systemd/network/
br0.netdev br0.network enp3s0.network
[tom@localhost ~]$ cat /etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
MACAddress=ac:22:0b:29:e6:0c
[tom@localhost ~]$ cat /etc/systemd/network/br0.network
[Match]
Name=br0
[Network]
DHCP=ipv4
[tom@localhost ~]$ cat /etc/systemd/network/enp3s0.network
[Match]
Name=enp3s0
[Network]
LinkLocalAddressing=no
IPv6AcceptRouterAdvertisements=no
Bridge=br0
[tom@localhost ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether ac:22:0b:29:e6:0c brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ac:22:0b:29:e6:0c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.111/24 brd 192.168.1.255 scope global dynamic br0
valid_lft 86357sec preferred_lft 86357sec
inet6 2404:c805:e00:5300:ae22:bff:fe29:e60c/64 scope global mngtmpaddr noprefixroute dynamic
valid_lft 1756sec preferred_lft 1756sec
inet6 fe80::ae22:bff:fe29:e60c/64 scope link
valid_lft forever preferred_lft forever
答案1
由于该配置,它将生成大量 ARP 流量和可能的路由错误。TCP/IP 非常强大,通常需要出现严重性能下降才会被用户(即个人或通信过程)注意到。
ARP 是以太网堆栈中位于 IP 之下的协议。它代表地址解析协议,其作用是将 IP 地址与 MAC 地址关联起来。毫无疑问,它的性能有所下降,但根据设计,即使存在歧义,它也会路由数据包;使用上次收到的值。IP 是临时的软件分配,可以几乎立即分配给不同的远程设备 - MAC 旨在锁定到硬件,ARP 使用它来确定下一个获取数据包的网关。
所以答案是它已经降低了你的网络质量。有几种方法可以证明这一点。有一种叫做 arpping 的东西——使用 arp 层进行 ping。它会丢弃数据包。从外部源以高速率向两个不同的 iface 发送 arping 并查看指标。
启动 wireshark 并查看执行此操作时的 ARP 流量以及一般情况。
然后修复 MAC。sudo ip link set dev interface address XX:XX:XX:XX:XX:XX
希望新地址是唯一的;如果不是唯一的,则不是本地的。在 Linux 上,您可以查看 proc 文件系统中的 ARP 缓存。最低限度的检查是该 mac 未被您的系统缓存。
您还可以使用 iperf3 之类的工具来测试吞吐量。在此实验室中设置多个客户端和/或多个服务器,通过该网桥和网卡进行路由,然后查看差异。如果您这样做了,请发布结果,只是好奇。
重新运行相同的测试并查看差异。如果您执行了所有这些操作并且数据表明没有差异,我很乐意亲自查看。
我认为,最糟糕的情况是同一 WAN 段上有两台相同的 Mac,因为这种混乱会混入足够多的非确定性延迟,从而导致出现一些近乎死锁的情况。这显然只是猜测。
除此之外,您还违反了 802.3 的基本规则 - MAC 地址是唯一的。它们不应该是唯一的,或者如果是唯一就好了,但从定义上讲它们就是唯一的。您怎么能心安理得呢?
当然,在嵌入式系统中,这种情况总是会发生;但当有或可能存在可路由的路径时就不会发生。