VLAN网桥配置过程中的DefaultPVID和tagged
续接上一篇文章,我们在第二种方法中提到了DefaultPVID参数,那么我们该如何理解DefaultPVID参数呢,它的作用是什么?
DefaultPVID的释意
在systemd.netdev (www.freedesktop.org)中可以看到DefaultPVID的解释:
DefaultPVID=
This specifies the default port VLAN ID of a newly attached bridge port. Set this to an integer in the range 1–4094 or "none" to disable the PVID.
这指定了新连接的桥接端口的默认端口 VLAN ID。将其设置为 1–4094 范围内的整数或“无”以禁用 PVID。
以上内容便说明了通过systemd方式配置网桥时,br0.netdev文件中DefaultPVID参数的作用就是给所有加入该网桥的网络端口配置一个PVID,包括网桥自己。
那么这个PVID和普通的VLAN ID有什么区别呢?暂时先保留这个疑问往下看。
pvid和untagged的作用
首先看一下bridge命令的选项说明:
bridge vlan { add | del } dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]
选项说明:
pvid:端口的默认vlan,所有从该端口输入的没有携带vlan的报文,会被打上该vlan标签,该选项只对输入报文有效。
untagged:端口的untag vlan,输出报文携带该vlan时,会被剥离。一般情况下pvid和untagged是同时使用的。
由上述说明可以看到,在bridge命令中,pvid和untagged参数是高度关联的。那么,这个tag又是什么东西呢?Tagged和Untagged又是什么?
接下来可以参照交换机的发送帧和接受帧时候对VLAN的处理来理解。
1、接收帧时:所有以太网帧在交换机中都是以Tagged的形式处理转发的,因此设备必须给接口收到的Untagged帧加上Tag。为了实现此目的,必须配置接口的缺省VLAN。当该接口收到Untagged帧时给它加上该接口缺省VLAN的VLAN Tag。
2、发送帧时:当该帧的VLAN ID与端口的PVID不同时,直接透传;当该帧的VLAN ID与端口的PVID相同时,则剥去Tag;(前提是看该VLAN ID在允许通过的VLAN ID列表中;如果在列表中,才会去比较PVID)。
※数据帧打不打Tag 与 允不允许带该Tag的数据帧通过 没有必然关系。
1、数据帧到达时:若不带VLAN Tag,无论如何会先打上缺省的VLAN ID,再看该缺省VLAN ID在不在允许通过的VLAN ID列表中。
2、数据帧发送时:先看该VLAN ID在允许通过的VLAN ID列表中;如果不在允许的列表中,直接丢弃;如果在列表中,才会去比较PVID,决定剥还是不剥Tag。
※只要数据帧的VLAN ID不在允许通过的VLAN ID列表里时(无论是接收时就带VLAN ID,还是接收后打上的缺省的VLAN ID),都会丢弃该报文。
简而言之:
1:对于trunk口
当收到的帧不带tag,先打PVID,再比较PVID是否在Allow VLAN,在——接收,不在——丢弃。
当收到的帧带tag,比较TAG是否在Allow VLAN,在—接收,不在-丢弃
2:端口默认时,会转发所有vlan1的数据。为了防止产生广播风暴,在接口下经常要配置undo vlan 1
3:因此trunk口在发送数据时:TAG属于Allow VLAN,比较TAG是否属于PVID,属于——剥离TAG;不属于——保持TAG
实际情况演示
下面我们实际看一下,以上一篇文章中的方法二为一个简单示例搭一个环境,
/etc/systemd/network/fm1-mac1.network
[Match]
Name=fm1-mac1
[Network]
Bridge=br0
[BridgeVLAN]
VLAN=100
[BridgeVLAN]
VLAN=200
/etc/systemd/network/fm1-mac9.network
[Match]
Name=fm1-mac9
[Network]
Bridge=br0
[BridgeVLAN]
VLAN=100
以下是/etc/systemd/network/br0.netdev不同配置时,bridge vlan show命令看到的情况
DefaultPVID=100:
/etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
DefaultPVID=100
VLANFiltering=true
STP=false
bridge vlan show
根据上图我们可以看到
port | vlan | ids | 说明 |
---|---|---|---|
fm1-mac1 | 100 | ||
200 | |||
fm1-mac9 | 100 | ||
br0 | 100 | PVID Egress Untagged | br0输出报文携带该vlan时,会被剥离 |
此时向fm1-mac9发送一个VLAN100的数据帧,在fm1-mac9可以看到:(此处看到的是发给fm1-mac9的帧)
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:07:27.515215 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac9收到了VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
br0会监听桥上所有流通的数据帧,并将某一个网卡发送的数据帧直接透传转发给所有网卡,所以对br0的抓包只是看到是否有帧通过,以及br0本身对数据帧的处理
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:42:39.071731 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype Unknown (0x88ba), length 337:
br0收到了fm1-mac9发送的VLAN100的数据帧之后,比较TAG是否需要进行Untagged,需要,则剥离TAG
在fm1-mac1可以看到:(此处看到的是fm1-mac1发送的帧)
root@localhost:~# tcpdump -i fm1-mac1 -vve
tcpdump: listening on fm1-mac1, link-type EN10MB (Ethernet), capture size 262144 bytes
12:42:55.192324 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac1收到了fm1-mac9发送的流经了br0的带有VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
DefaultPVID=none:
/etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
DefaultPVID=none
VLANFiltering=true
STP=false
bridge vlan show
根据上图我们可以看到
port | vlan | ids | 说明 |
---|---|---|---|
fm1-mac1 | 100 | ||
200 | |||
fm1-mac9 | 100 | ||
br0 | None |
此时向fm1-mac9发送一个VLAN100的数据帧,在fm1-mac9可以看到:(此处看到的是发给fm1-mac9的帧)
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:19:39.249789 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac9收到了VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:19:57.826871 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
br0收到了fm1-mac9发送的VLAN100的数据帧之后,比较TAG是否需要进行Untagged,不需要,则保持TAG
在fm1-mac1可以看到:
root@localhost:~# tcpdump -i fm1-mac1 -vve
tcpdump: listening on fm1-mac1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:20:14.850848 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac1收到了fm1-mac9发送的流经了br0的带有VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
DefaultPVID=111:
/etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
DefaultPVID=111
VLANFiltering=true
STP=false
bridge vlan show
根据上图我们可以看到
port | vlan | ids | 说明 |
---|---|---|---|
fm1-mac1 | 100 | ||
111 | PVID Egress Untagged | fm1-mac1输出报文携带该vlan时,会被剥离 | |
200 | |||
fm1-mac9 | 100 | ||
111 | PVID Egress Untagged | fm1-mac9输出报文携带该vlan时,会被剥离 | |
br0 | 111 | PVID Egress Untagged | br0输出报文携带该vlan时,会被剥离 |
向fm1-mac9发送一个VLAN100的数据帧
此时向fm1-mac9发送一个VLAN100的数据帧,在fm1-mac9可以看到:(此处看到的是发给fm1-mac9的帧)
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:22:37.590162 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac9收到了VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:22:58.590664 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
br0收到了fm1-mac9发送的VLAN100的数据帧之后,比较TAG是否需要进行Untagged,不需要,则保持TAG
在fm1-mac1可以看到:
root@localhost:~# tcpdump -i fm1-mac1 -vve
tcpdump: listening on fm1-mac1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:23:17.007224 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 100, p 4, ethertype 0x88ba,
fm1-mac1收到了fm1-mac9发送的流经了br0的带有VLAN100的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
向fm1-mac9发送一个VLAN111的数据帧
此时向fm1-mac9发送一个VLAN111的数据帧,在fm1-mac9可以看到:(此处看到的是发给fm1-mac9的帧)
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:24:26.305122 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 111, p 4, ethertype 0x88ba,
fm1-mac9收到了VLAN111的数据帧之后,比较TAG是否需要进行Untagged,需要,则剥离TAG然后发送。
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:26:34.613896 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype Unknown (0x88ba), length 337:
br0收到了fm1-mac9发送的Untagged数据帧之后,收到的帧不带TAG,先打PVID111的TAG,比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,需要,则剥离TAG
在fm1-mac1可以看到:
root@localhost:~# tcpdump -i fm1-mac1 -vve
tcpdump: listening on fm1-mac1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:27:03.750824 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype Unknown (0x88ba), length 337:
fm1-mac1收到了fm1-mac9发送的流经了br0的Untagged数据帧之后,收到的帧不带TAG,先打PVID111的TAG,比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,需要,则剥离TAG然后发送。
向fm1-mac9发送一个VLAN120的数据帧
此时向fm1-mac9发送一个VLAN120的数据帧,在fm1-mac9可以看到:(此处看到的是发给fm1-mac9的帧)
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:36:39.969915 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 120, p 4, ethertype 0x88ba,
fm1-mac9收到了VLAN120的数据帧之后,经过比较TAG不在Allow VLAN中,所以将帧丢弃。
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
br0没有监听到fm1-mac9发送的数据帧
在fm1-mac1可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
fm1-mac1没有数据帧发出
向fm1-mac1发送一个VLAN200的数据帧
此时向fm1-mac1发送一个VLAN200的数据帧,在fm1-mac1可以看到:(此处看到的是发给fm1-mac1的帧)
root@localhost:~# tcpdump -i fm1-mac1 -vve
tcpdump: listening on fm1-mac1, link-type EN10MB (Ethernet), capture size 262144 bytes
09:13:35.014019 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 200, p 4, ethertype 0x88ba,
fm1-mac1收到了VLAN200的数据帧之后,经过比较TAG在Allow VLAN中,所以将帧接收,然后比较TAG是否需要进行Untagged,不需要,则保持TAG然后发送。
在br0可以看到:
root@localhost:~# tcpdump -i br0 -vve
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:13:24.918034 4c:e1:73:42:30:7c (oui Unknown) > 01:0c:cd:04:40:01 (oui Unknown), ethertype 802.1Q (0x8100), length 341: vlan 200, p 4, ethertype 0x88ba,
br0收到了fm1-mac1发送的VLAN200的数据帧之后,比较TAG是否需要进行Untagged,不需要,则保持TAG
在fm1-mac9可以看到:
root@localhost:~# tcpdump -i fm1-mac9 -vve
tcpdump: listening on fm1-mac9, link-type EN10MB (Ethernet), capture size 262144 bytes
fm1-mac9收到了VLAN120的数据帧之后,经过比较TAG不在Allow VLAN中,所以将帧丢弃。fm1-mac9没有数据帧发出
我们验证了之前的解释:DefaultPVID参数的作用就是给所有加入该网桥的网络端口配置一个PVID,包括网桥自己。
同时也发现了一个点,那就是如果设置的PVID在VID中存在的话,那么这个VID是untagged的。
命令创建VLAN网桥示例
接下来我们举一些使用命令创建VLAN网桥示例,这些例子来源于networking - Bridged interfaces and VLAN tags - Unix & Linux Stack Exchange
首先是创建一个普通网桥的示例:
# 开启网卡eth0和tap1
ip link set eth0 up
ip link set tap1 up
# 创建一个普通网桥,名字为br0,以下行可以在创建网桥时直接包含附加参数 `vlan_filtering 1`
ip link add name br0 type bridge
# 将网卡eth0和tap1添加到网桥br0中
ip link set tap1 master br0
ip link set eth0 master br0
激活网桥br0的VLAN感知功能:
# 设置网桥附加参数 `vlan_filtering 1`
ip link set dev br0 type bridge vlan_filtering 1
# 删除在添加网卡到网桥的时候为网卡默认创建的vid 1配置
bridge vlan del dev tap1 vid 1
bridge vlan del dev eth0 vid 1
# 为网卡tap1添加vid 5
bridge vlan add dev tap1 vid 5
# 为网卡tap1添加vid 5,同时将其设置为pvid untagged,此处在命令的末尾省略了master参数
bridge vlan add dev eth0 vid 5 pvid untagged
# 开启网桥
ip link set br0 up
# 删除在创建网桥的时候默认创建的vid 1配置
bridge vlan del dev br0 vid 1 self
# 为网桥br0添加vid 5,同时将其设置为pvid untagged
bridge vlan add dev br0 vid 5 pvid untagged self