Linux 网桥支持LACP 透传的解决方法


IEEE 802.1D MAC网桥过滤MAC组地址

  LACP的协议是使用01-80-C2-00-00-0x范围内的MAC地址,这个范围在IEEE标准802.1D中定义为“MAC桥接过滤MAC组地址”。这是IEEE为使用链路本地组播与相邻设备通信的标准协议预留的范围。使用这些MAC地址的帧应该是显式链接本地的;引用IEEE标准组MAC地址教程:

IEEE 802.1D MAC Bridge Filtered MAC Group Addresses: 01-80-C2-00-00-00 to 01-80-C2-00-00-0F; MAC frames that have a destination MAC address within this range are not relayed by MAC bridges conforming to IEEE 802.1D.
IEEE 802.1D MAC网桥过滤MAC组地址:01-80- c2 -00-00至01-80-C2-00-00-0F;在此范围内具有目标MAC地址的MAC帧不会由符合IEEE 802.1的MAC桥接器中继。

IEEE维护了一个协议列表,如下列表:

MAC address Protocol
01-80-C2-00-00-00 Spanning Tree (STP/RSPT/MSTP)
01-80-C2-00-00-01 Ethernet Flow Control (pause frames)
01-80-C2-00-00-02 Link Aggregation Control Protocol (LACP)
01-80-C2-00-00-03 802.1X Port-Based Network Access Control
01-80-C2-00-00-08 Provider Bridge protocols (STP)
01-80-C2-00-00-0D Provider Bridge protocols (MVRP)
01-80-C2-00-00-0E 802.1AB Link Layer Discovery Protocol (LLDP)

实际应用中的问题

  任何符合IEEE 802.1的桥接都必须过滤这些帧:要么处理它们,要么删除它们。在任何情况下,都不允许将它们连同其他接收器一起转发。这在2000年那时候是有道理的,那时网桥是硬件。但在虚拟化时代,情况就不同了。
比如,我使用基于kvm的主机来模拟多个虚拟网络设备。我使用Linux网桥来连接这些设备,当然,我希望网桥尽可能像一根电线一样直接连接我的虚拟设备。不幸的是,Linux桥接器编写得很好,符合IEEE 802.1,它使用01-80-C2-00-00-0x范围内的目标地址过滤所有以太网帧。这意味着我不能使用我的虚拟环境来测试上表中的任何协议。悲剧!

解决方法

  可是我确实有需求在构建网络实验时测试LLDP、LACP、STP、802.1X,所以必须找到一个解决方案。显然,我不是第一个遇到这种情况的人,所以有一些解决方案。由于Linux内核2.6有一个设置,允许您通过在/sys/class/net/bridge-iface/bridge/group_fwd_mask中设置一个特定的位掩码,来控制从IEEE 802.1D中定义的桥接器应该转发的范围内的哪个本地帧。默认值0表示Linux桥接器不转发任何链接本地帧。例如,将这个值设置为16384将允许桥接转发LLDP帧(01-80-C2-00-00-0E):

echo 16384 > /sys/class/net/br0/bridge/group_fwd_mask

  有个问题是:在默认内核发行版中,前三个MAC地址(-00、-01和-02)的位掩码值是受限制的,这意味着我们仍然不能使用这个技巧在我们的实验环境中启用STP和LACP协议。要删除这个限制,就需要自己对内核进行补丁并编译,就像EVE-NG中的人员所做的那样。为了简便,所以我只是从EVE-NG存储库中获取编译后的内核。现在,我们可以将group_fwd_mask设置为我们喜欢的任何值。

group_fwd_mask 掩码值解析

  那么这个位掩码应该用什么值呢?位掩码是一个16位的数字,其中第1位代表MAC地址01-80- c2 -00-00,第16位代表01-80-C2-00-00-0F。默认值(所有位都是0)不转发任何链接本地帧。为了能够转发特定MAC地址的帧,我们需要将对应的位设置为1。例如,为了允许转发LLDP帧(01-80-C2-00-00-0E),我们需要将第15位设为1,其余的设为0:

MAC 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
MAC 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

  这意味着我们使用二进制数字0100 0000 0000作为位掩码,它翻译成十进制数字16384,就像我们在前面的示例中使用的一样。
如果我们想在mix中加入LACP (01-80-C2-00-00-02)和802.1X (01-80-C2-00-00-03),我们也会将第3位和第4位设为1:

MAC 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
MAC 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0

  这导致二进制数0100 0000 0000 1100,在小数中是16396。使用此方法,您现在可以完全控制转发或筛选哪种类型的帧。
  很简单对不对。对于我的实验环境,我只想允许尽可能多的协议,这样我就可以测试任何我想要的协议。所以我把所有的位都设为1:
  对于打过补丁的内核,我可以使用所有的位:1111 1111 1111 1111 = 65535
  对于未打补丁的内核,我不能使用前三位:1111 1111 1111 1000 = 65528
  换句话说:要使开箱即用的Linux桥接器能够转发所有经过IEEE 802.1D MAC桥接器过滤的MAC组地址(受限制的三种类型除外),请执行以下命令:

echo 65528 > /sys/class/net/br0/bridge/group_fwd_mask

最后注意

  在生产环境中,这可能不是最明智的做法,特别是使用修补过的内核泛洪STP BPDUs时。您最好只将其用于(虚拟)网络实验环境。祝你好运!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM