我正在尝试 Linux 桥接器和 VLAN 过滤,但遇到了一些问题。
我有一个虚拟机,带有中继(标记帧),到达 ens19。我想要做的是将此端口连接到 Linux 网桥,并在该网桥上设置“虚拟”接口,这些接口标有我需要的 VLAN,后面有完整的 TCP/IP 堆栈(主机的堆栈)。
对于我的实验,我将自己限制在 vlan 3 和 5 上,但想法是它应该很容易扩展。用途似乎并不大,因为它可以被 ens19 的子接口替换。但后来我感兴趣的是,我将使用 gretap 接口连接 ens19 端口,以在隧道上循环多个 vlan。
我已经对虚拟接口和 tap 接口进行了测试,但在我看来,考虑到这些接口的性质,它不起作用。我使用 br0.3 子接口进行了测试,但在这里我的客户端收到了 ARP 回复,但 PING 从未收到 ICMP 回复...
ip link add name br0 type bridge vlan_filtering 1
ip link set dev br0 up
ip link add link br0 name br0.3 type vlan id 3
ip link set dev ens19 master br0
ip link set ens19 up
ip link set dev br0 up
ip link set dev br0.3 up
ip addr add 10.3.0.106/22 dev br0.3
答案1
哑桥
在当前设置下,没有流量通过:所有流量都由 VLAN 感知桥过滤,因为默认情况下,它在所有端口和桥自身接口上使用 VLAN 1。当具有 VLAN ID 3 的帧到达或发出时,由于它与过滤器不匹配,因此会被丢弃。
为了使当前实验正常运行,只需将桥设置为“哑”桥:
ip link set dev br0 type bridge vlan_filtering 0
现在,标记的流量ens19
将到达(标记)br0
(如果没有转发到其他地方),将取消标记br0.3
并到达路由堆栈(例如:类型 IPv4、ARP 或 IPv6)。非标记流量(如果有)也将到达路由堆叠br0
。任何其他带有 VLAN 标记的流量都将被丢弃,因为没有任何东西可以认领它:路由堆栈本身不理解 VLAN。
网桥将转发带有 VLAN 标记的帧,而不考虑 VLAN ID 的含义,如果在多个 VLAN 上使用相同的 MAC 地址,则会导致问题。这可能会混淆网桥上转发数据库的处理,或导致其他设备上出现重复或循环等。
因此,VLAN 感知桥确实是首选。
VLAN 感知桥接
如果桥接器必须发挥中立作用,并且目标是轻松创建新的每个 VLAN 端口,甚至更多,那么改变无需删除并重新创建接口(VLAN 子接口需要删除并重新创建接口),那么 VLAN 感知桥确实很有用。在此配置中,虽然仍然可以在 上使用 VLAN 子接口br0
,但可以避免这种情况。可以改用韦特每个这样的 VLAN 对应一对:一个作为桥接端口,一个作为与路由堆栈通信的接口(这是韦特完全不涉及网络命名空间)。
br0
它本身不必用于路由,除非在没有其他物理接口(而不是ens19
)可用的情况下将其用作管理。下面的设置从完全锁定任何添加的端口(包括br0
它自己)开始,同时设置vlan_default_pvid 0
(而不是为所有内容获取默认的端口 VLAN ID 1)。这还允许立即将桥接端口设置为 UP,而不会在配置过程中冒泄漏风险,因为默认情况下什么都无法通过。
在 VLAN 感知桥上配置 VLAN 使用bridge vlan
使用较新的命令rtnetlink(7)
内核 API。过时的brctl
命令无法执行此操作,因为较旧的内核 API(或/sys
)不提供此功能。
OP 的案例分为以下几个步骤:
创建和中继链路
应该为网桥分配一个自己独有的 MAC 地址,这样它就不会默认继承网桥端口上可用的最低 MAC 地址,这可能会随着时间的推移而改变:韦特下面的方法可能会使网桥在添加新 VLAN 时随时间更改 MAC 地址,这对于此方法来说不是真正的问题,但如果结合使用,可能会影响 VLAN 子接口方法,或者
br0
在本身具有 IP 地址时影响 的使用。在最近的基于 systemd 的系统中,这是已经完成systemd无论涉及哪个网络管理员,如果它检测到创建了一个新的虚拟以太网类接口而没有说明其 MAC 地址,即使这种行为是不受欢迎的。ip link add name br0 address 12:34:56:78:9a:bc up type bridge vlan_filtering 1 vlan_default_pvid 0 ip link set dev ens19 up master br0
可选:
br0
仍然使用 VLAN 1(untagged)通过ens19
(tagged)传输,例如用于管理:bridge vlan add vid 1 dev ens19 bridge vlan del vid 1 dev br0 self pvid untagged
桥接接口本身
self
在配置时需要附加关键字。添加 VLAN
ens19
(此处的 VLAN ID 为 3 和 5):bridge vlan add vid 3 dev ens19 bridge vlan add vid 5 dev ens19
或者如果要考虑 ens19这上行链路中继端口,只需在其上添加所有其他 VLAN:
bridge vlan add vid 2-4094 dev ens19
用来
-compressvlans
显示其内容或将显示 4093 行单个条目。bridge -compressvlans vlan show dev ens19
现在可以通过以下方式实现相同的总体结果:
顶部有一个 VLAN 子接口
br0
(此处使用 VLAN ID 3)如果桥接接口(此处)或桥接端口(下一个项目)没有添加 VLAN ID,则当桥接器设置为 VLAN 感知桥接器时,不会通过任何此类流量。
必须添加 VLAN ID(仍带标记)到
br0
:bridge vlan add vid 3 dev br0 self
如上所述,所有内容只需提前添加一次即可:
bridge vlan add vid 2-4094 dev br0 self
然后在其上添加常用的 VLAN 子接口:
ip link add link br0 name br0.3 up type vlan id 3 ip addr add 10.3.0.106/22 dev br0.3
更改与接口关联的 VLAN ID(在常见设置中为 IP LAN 10.3.0.0/22)需要删除子接口并重新创建具有不同 VLAN ID 的新接口:
type vlan
无法重新配置接口。或一对韦特接口(此处使用 VLAN ID 5)
pvid untagged
其作用与使用 VLAN 子接口相同:从网桥到端口取消标记,从端口到网桥添加标记。只有一个 VLAN ID 可以作为 PVID(此处使用的是单个 VLAN ID)。ip link add name vlan5 up type veth peer name br0vlan5 ip link set br0vlan5 up master br0 bridge vlan add vid 5 dev br0vlan5 pvid untagged ip addr add 10.3.4.106/22 dev vlan5
除了示例中选择的名称反映了 VLAN ID 因此会引起人们的混淆之外,关联的 VLAN ID 几乎可以动态更改(此处将其从 5 更改为 6):
bridge vlan del vid 5 dev br0vlan5 bridge vlan add vid 6 dev br0vlan5 pvid untagged
如果尚未配置所有 VLAN
ens19
,也请在那里进行更改:bridge vlan del vid 5 dev ens19 bridge vlan add vid 6 dev ens19