Linux:网桥、VLAN 和 RSTP

Linux:网桥、VLAN 和 RSTP

我试图弄清楚如何在涉及 VLAN 和网桥的 Linux 上设置 RSTP,但现在我完全糊涂了。

我正在尝试桥接三个接口,其中两个接口应该用作中继(hdlc0 和 hdlc1),一个接口应该用作访问端口(eth0)。我还需要在桥接中包含的每个接口上启用 RSTP,但使用下面列出的配置,RSTP 数据包通过标记的 hdlc0 和 hdlc1 发送(!),因此其他设备会拒绝它们。由于 Linux 没有“本机 VLAN”的概念,我不知道如何修复它。

这是我的配置:

ifconfig eth0 up


ifconfig hdlc0 up
ifconfig hdlc1 up

vconfig add hdlc0 42
vconfig add hdlc1 42
ifconfig hdlc0.42 up
ifconfig hdlc1.42 up


brctl addbr br1
brctl addif br1 eth0
brctl addif br1 hdlc0.42
brctl addif br1 hdlc1.42

ifconfig br1 up
brctl stp br1 on

另一个问题:我还想知道在有多个网桥的情况下如何配置 RSTP:假设 eth0 是允许 vlan 42-42 的 trunk,vlan 42 应该通过 hdlc0 传递,vlan 43 应该通过 hdlc1 传递,所以我有两个网桥。如果我在两个网桥上都启用 RSTP,它(可能)会在每个网桥上独立运行,所以我很快就会遇到问题?

答案1

在 Linux 中,VLAN 和网桥是完全独立的构造,并且 Linux 网桥不是“VLAN 感知”的。

当您创建 VLAN 接口时,Linux 会在该接口上标记/取消标记数据包,然后再将它们传递到底层物理(“中继”)接口或从底层物理(“中继”)接口传出。但是,您仍然可以使用底层物理接口发送未标记(“本机 VLAN”)数据包。

当您创建网桥时,Linux 会在相关接口之间交换数据包,而不考虑数据包上的 VLAN 标记(或缺少标记)。如果您将中继接口连接到网桥,网桥将很乐意交换 VLAN 标记数据包,而不考虑标记。当您在网桥上启用 STP 时,Linux 会生成未标记的 STP 数据包并将其丢弃在网桥上。

当网桥连接到还具有关联 VLAN 接口的物理接口时,这些 VLAN 接口将不再看到任何不是发往物理接口的 MAC 地址的流量。此行为是由于桥接和 VLAN 标记的处理顺序造成的,可以使用 ebtables 进行更改,如中所述http://blog.rackspace.com/vms-vlans-and-bridges-oh-my-part-2但是,就生成树而言,将网桥连接到物理接口和关联的 VLAN 接口只有在使用 PVST+ 时才会正常工作(因为每个网桥的 STP 端口阻塞都是独立管理的),所以这里并不真正相关。

但是您也可以在传递 VLAN 标记数据包的网桥上创建 VLAN 接口,然后将这些 VLAN 接口添加到其他网桥。

因此,为了实现您的目标,请尝试:

ip link set dev hdlc0 up
ip link set dev hdlc1 up

brctl addbr br_native
brctl addif br_native hdlc0
brctl addif br_native hdlc1
brctl stp br_native on
ip link set dev br_native up

ip link add link br_native name br_native.42 type vlan id 42
ip link set dev br_native.42 up
ip link set dev eth0 up

brctl addbr br_42
brctl addif br_42 br_native.42
brctl addif br_42 eth0
ip link set dev br_42 up

请注意,Linux 内核桥接代码仅原生支持传统 802.1D STP。要添加对 RSTP 和 PVST+ 的支持,请使用https://github.com/mstpd/mstpd(有关 mstpd 的一些相关文档也可以在以下网址找到:https://docs.cumulusnetworks.com/display/DOCS/Spanning+Tree+and+Rapid+Spanning+Tree)。mstpd 也能够使用 MSTP,但由于 Linux 实现其 FIB 的方式,目前无法将 MSTP 拓扑映射到 Linux 网桥上,因此 MSTP 实际上不起作用。

回答你的第二个问题,我认为不可能(在任何交换机上,不仅仅是在使用 Linux 时)使用 STP 或 RSTP 将单个中继上的两个不同 VLAN 分别引导到其他两个中继。这只能使用 PVST+ 或 MSTP 来实现,尽管如上所述,Linux 不支持 MSTP。

答案2

从 Linux 内核 3.0 左右开始,Linux 网桥“不支持 VLAN”的情况已不再存在。https://linux-blog.anracom.com/2017/10/30/fun-with-veth-devices-in-unnamed-linux-network-namespaces-i/后续文章也给出了相当好的解释,但总结一下:

您可以使用该bridge(8)工具来操纵网桥-VLAN 交互,其方式与大多数管理型交换机类似。

根据你的情况,你可以尝试以下方法:

# ip link set br0 type bridge vlan_filtering 1 vlan_default_pvid 1 stp_state 1 priority 32768 nf_call_iptables 1 nf_call_arptables 1
# bridge vlan add vid 1 pvid untagged dev eth0
bridge vlan add vid 19 dev eth0

ip link set up dev eth0
ip link set up dev hdlc0
ip link set up dev hdlc1

# if you only want to bridge VLAN42, you don't need these, but here's how you'd create them:
# ip link add link hdlc0 name hdlc0.42 type vlan protocol 802.1q id 1 reorder_hdr on gvrp on mvrp on loose_binding off
# ip link add link hdlc1 name hdlc1.42 type vlan protocol 802.1q id 1 reorder_hdr on gvrp on mvrp on loose_binding off
# ip link set up dev hdlc0.42
# ip link set up dev hdlc1.42

# now for the actual bridging:
brctl addbr br1
brctl addif br1 eth0
brctl addif br1 hdlc0
brctl addif br1 hdlc1

# port eth0 is an untagged port; assuming it should be in VLAN42:
bridge vlan add vid 42 dev eth0 pvid untagged
# hdlc0 is a trunk interface that forwards vlan42 in a tagged manner:
bridge vlan add vid 42 dev hdlc0
# hdlc1 carries vlan42 and vlan43, both with tagging:
bridge vlan add vid 42 dev hdlc1
bridge vlan add vid 43 dev hdlc1

brctl stp br1 on
ip link set up dev br1

您还可以将 VLAN 接口添加到网桥,然后它会执行合乎逻辑的操作(如果您仔细想想的话):网桥生成以太网帧并将其传递到端口,然后端口将其发送出去。由于所讨论的端口是 VLAN 接口,它会在发送帧之前添加 VLAN 标记。我相信这样做有有效的用途,但目前我想不出任何用途。:)

相关内容