Open vSwitch VLAN相关字段详解(dl_vlan、dl_vlan_pcp、vlan_vid、vlan_pcp、vlan_tci)

时间:2024-04-08 09:34:20

字段概览

字段名 长度 格式 Masking 前置项 访问权限 OpenFlow 1.0 OpenFlow 1.1 NXM/OXM Support 描述
dl_vlan 16位 (仅用到后12位) 十进制 not maskable Ethernet 读/写 VLAN ID相关
dl_vlan_pcp 8位 (仅用到后3位) 十进制 not maskable Ethernet 读/写 和802.1Q报文的优先级相关
vlan_vid 16位( 仅用到后13位) 十进制 支持任意位掩码 Ethernet 读/写 exact match only exact match only OF 1.2+ and OVS 1.7+ VLAN ID相关
vlan_pcp 8位 (仅用到后3位) 十进制 not maskable VLAN VID 读/写 exact match only exact match only OF 1.2+ and OVS 1.7+ 和802.1Q报文的优先级相关
vlan_tci 16位 十六进制 支持任意位俺码 Ethernet 读/写 exact match only exact match only OVS 1.1+ 覆盖了VLAN ID和优先级的匹配

字段详解

VLAN相关字段主要是对802.1Q VLAN header进行解析得到,该header的格式如下:
Open vSwitch VLAN相关字段详解(dl_vlan、dl_vlan_pcp、vlan_vid、vlan_pcp、vlan_tci)
该报文头包括了2个16bit的部分,这两个部分分别被称为TPID(Tag Protocol IDentifier)和TCI(Tag Control Information),对于OVS来说,只支持0x8100的Ethertype,所以前面16位TPID是固定的。剩下的TCI又包括3部分:

  • PCP (Priority Control Point):3位大小的优先级,即0~7(从低到高)。当交换机/路由器发生传输拥塞时,优先发送优先级高的数据帧。
  • CFI(Canonical Format Indicator):长度为1bit,表示MAC地址是否是经典格式。CFI为0说明是经典格式,CFI为1表示为非经典格式。该字段用于区分以太网帧、FDDI帧和令牌环网帧,在以太网帧中,CFI取值为0。而实际上在OVS和OpenFlow中,都不会匹配这个位,直接忽略。
  • VID(VLAN ID):长度为12bit,取值范围是0~4095,其中0表示该帧不属于任何一个VLAN,而4095是保留值,不能给用户使用,所以实际可用的VLAN ID一共为4094个(1 ~ 4094)。

vlan_tci

为什么叫vlan_tci呢,顾名思义,就是和802.1Q VLAN报文头的TCI相关的字段啦。我们来仔细看看这个OVS的字段:
Open vSwitch VLAN相关字段详解(dl_vlan、dl_vlan_pcp、vlan_vid、vlan_pcp、vlan_tci)
NXM(Nicira Extended Match)是Open vSwitch 1.1中对OpenFlow 1.0引入的扩展。这个字段比其他几个VLAN字段(如dl_vlan、dl_vlan_pcp)提供了更强大的匹配能力。当数据包没有802.1Q报文头时,这个字段的值是0;当数据包带有802.1Q报文头时,这个字段的P位为1。以下用几个例子来做示例:

  • vlan_tci=0:表示匹配不带802.1Q报文头的数据包
  • vlan_tci=0x1000/0x1000:0x1000展开就是0001 0000 0000 0000,P位是1表示匹配带有802.1Q报文头的数据包,掩码0x1000表示忽略PCP和VID,因此该条件表示匹配带有802.1Q报文头,任意优先级和任意VLAN ID的数据包
  • vlan_tci=0xf123:0xf123展开就是1111 0001 0010 0011,111=7、0001 0010 0011=291,故该条件表示匹配优先级为7,VLAN ID为291的数据包

vlan_vid

该字段和802.1Q报文头的CFI和VID相关。格式如下:
Open vSwitch VLAN相关字段详解(dl_vlan、dl_vlan_pcp、vlan_vid、vlan_pcp、vlan_tci)
当P为0时,表示匹配不带802.1Q报文头的数据包,否则后12位表示匹配数据包的VLAN ID。仅用到后13位,前3位固定为0。以下用几个例子来作为示例:

  • vlan_vid=*:表示匹配所有不带802.1Q报文头和带802.1Q报文头的数据包,此时vlan_pcp字段无效
  • vlan_vid=0x0000/0xffff:匹配不带802.1Q报文头的数据包
  • vlan_vid=0x1000/0x1000:匹配所有带802.1Q报文头,且任意VLAN ID的数据包
  • vlan_vid=0x1009:匹配带802.1Q报文头,且VLAN ID为9的数据包

vlan_pcp

该字段和802.1Q VLAN报文头的PCP相关,表示该数据包的优先级。vlan_pcp的格式如下:
Open vSwitch VLAN相关字段详解(dl_vlan、dl_vlan_pcp、vlan_vid、vlan_pcp、vlan_tci)
vlan_pcp占用一个字节(8位),但只使用到后3位,前5位固定为0。该字段只在vlan_vid不为通配符和0时有效。

dl_vlan/dl_vlan_pcp

这两个字段是在OpenFlow 1.0开始就存在的(其它几个都是在1.0之后定义的),dl_vlan表示VLAN ID,dl_vlan_pcp表示优先级。这两个字段的定义非常迷,在OpenFlow 1.0中,有以下规则:

  • 这两个字段都为通配符时,匹配所有不带802.1Q报文头和带802.1Q报文头的数据包
  • dl_vlan=0xffff时,匹配不带802.1Q报文头的数据包,此时dl_vlan_pcp应该为*,因为不带802.1Q报文头的数据包没有PCP,但OpenFlow没有强制它这么做,也没有说明当dl_vlan_pcp不为*时要怎样,所以Open vSwitch就直接把dl_vlan_pcp忽略了
  • 如果不是以上两种情况,则匹配带有802.1Q报文头的数据包。
    dl_vlan只会用到16位中的后12位,dl_vlan_pcp只会用到8位中的后3位,但OpenFlow没有说明不用的哪些位的值要怎么设置,Open vSwitch则直接把这些位忽略。

在OpenFlow 1.1时,对这两个字段进行了改进,当dl_vlan=0xfffe匹配带802.1Q报文头的任意VLAN ID的数据包。(在OpenFlow 1,0中匹配不了这种场景,但此时VLAN ID 4094就不能用了)
我们可以看到这两个字段用起来真的是很复杂,也许这就是为什么在之后又出现了其它3个字段。看完这些字段,你会发现vlan_tci真的是简单好用啊╮(・o・)╭

参考资料:

  1. ovs-fields
  2. 802.1Q帧格式