OVS MAC、VLAN learning

vlan 字段解释

Posted by chochi on June 12, 2018

1 ovs mac+vlan learning 实验说明

  1. Ubuntu18.04 openvswitch2.9.0,oh-my-zsh
  2. vlan的数据字段。

1.1 VLAN 数据字段

1.vlan的匹配字段如果所示,low xx bits表示只有low xx bits可用,其他高位置0。 11

1.1.2 OpenFlow 1.2+ VLAN Field

  1. ID Field 12

 在下发流表的时候可以用vlan_vid来匹配该字段,该字段是十进制的,可任意掩码匹配,可读可写,在OXM中名为OXM_OF_VLAN_VID。只有后12位使用。P置1表示这是一个VLAN header。

  1. Priority Field 13

 VLAN的优先级,只有后三位使用,最大优先级为7。十进制,可读写,无法掩码匹配。只有当 vlan_vid使用掩码匹配,且vlan的优先级不为0的使用pcp字段才有匹配使用。

1.1.3 Open vSwitch Extension VLAN Field

5

 vlan_tci 是ovs所设定的字段,十六进制,任意掩码匹配,可读写, NXM_VLAN_TCI 字段就是将 vlan_pcp 和 vlan_vid 综合在一个字段里面。例如,当我需匹配 vlan_tci=0xf123 表示需匹配流的vlan标签为0x123且优先级为7。

实验场景

  1. 端口:
    • 端口p1, trunk
    • 端口p2, access,vlan20
    • 端口p3,p4, access,vlan30
  2. 流表处理逻辑
    • table0-admission control
    • table1-VLAN input proccessing
    • table2-Learn source MAC and VLAN for ingress port
    • table3-Look up learned port for destination MAC and VLAN
    • table4-Output processing

      setup

  3. 开启ovs-sandbox
  4. 创建网桥 chochi ,设置“fail-secure”,以确保流表创建的时候是空的。
  5. 为网桥添加四个端口,并以1,2,3,4编号。
#! /bin/sh -ve

ovs-vsctl add-br chochi -- set Bridg chochi fail-mode=secure

for i in 1 2 3 4; do
    ovs-vsctl add-port chochi p$i -- set Interface p$i ofport_request=$i
    ovs-ofctl mod-port chochi p$i up
done

1

table 0 : admission control

  1. 为表0添加流表项
#! /bin/sh -ve

ovs-ofctl add-flow chochi \
    "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
    #丢弃所有的广播包

ovs-ofctl add-flow chochi \
    "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"
    #丢弃所有生成树协议包
    
ovs-ofctl add-flow chochi "table=0, priority=0, actions=resubmit(,1)"
    #将合法需操作的流量转入1表

 dl_src匹配项=MAC地址/掩码,掩码就是想要匹配的位置为1,不匹配的置为0。

  1. 使用 ofproto/trace 来测试正确性,模拟发一个MAC目标地址01:80:c2:00:00:05的包
    ovs-appctl ofproto/trace chochi "in_port=1,dl_dst=01:80:c2:00:00:05"
    

    2

 可以看出发的数据包匹配到table0第二条流表项然后被drop了,因为我们下发第二条流表项时dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0,掩码的最后一位的0表示末尾的四个bit不用匹配,故01:80:c2:00:00:00~01:80:c2:00:00:09的数据包都会匹配到该流表项。

ovs-appctl ofproto/trace chochi "in_port=1,dl_dst=01:80:c2:00:00:10"

3

 01:80:c2:00:00:10匹配到最后一条流表,转发到table1。

table 1 : Vlan input processing

 Vlan是为access端口进来的数据包打上vlan header,table-miss的数据包丢弃。

  1. 为table1添加流表项。
#! /bin/sh -ve

ovs-ofctl add-flow chochi "table=1, priority=0, actions=drop"
    #table-miss packet 优先级最低
    
ovs-ofctl add-flow chochi \
    "table=1, priority=99, in_port=1, actions=resubmit(,2)"
    #trunk 端口进来的数据包直接丢入table2
    
ovs-ofctl add-flows chochi - <<'EOF'
    table=1, priority=99, in_port=2, vlan_tci=0, actions=mod_vlan_vid:20, resubmit(,2)
    table=1, priority=99, in_port=3, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
    table=1, priority=99, in_port=4, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
EOF
    #为每个aceess口进来的数据包打上vlan标签并丢入table2
    
  1. 模拟任一从acess端口进入的数据包和table-miss packet,查看匹配过程。
ovs-appctl ofproto/trace chochi in_port=2
ovs-appctl ofproto/trace chochi in_port=2,vlan_tci=5

4

table 2 : MAC + VLAN Learning for ingress Port

 该表使用学习动作。为表2添加如下流表项。

ovs-ofctl add-flow chochi \
        "table=2,actions=learn(table=10,NXM_OF_VLAN_TCI[0..11], \
                                NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
                                load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \
                                resubmit(,3)"

 该条流规则可以拆分成两个大动作来看,learn,resubmit,地一个动作将当前学习到的新的流规则安装在table10,并将当前流转发到table3。

  • learn
    • ovs的openflow扩展,根据当前正在处理的流的内容实时修改流表项。
  • table=10
    • 将table10认为定义为MAC学习表。
  • NXM_OF_VLAN_TCI[0..11]
    • 使我们添加到table10的流表项的 VLAN ID 和当前处理流的VLAN ID相同,NXM_OF_VLAN_TCI字段一共有16位,高3位是优先级,第四位是置1表示为vlan header,最后12位表示vlan id,故只使用最低的12位。
  • NXM_OF_ETH_DES[]=NXM_OF_ETH_SRC[]
    • 添加到table10的流规则的匹配项还有MAC目的地址,将当前流的MAC源地址复制给该字段。
  • load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]
    • 将当前流的入端口存放到寄存器0。
      6
  • 使用generate参数模拟真实流,假设流入口为1,vlan为20。
ovs-appctl ofproto/trace chochi \
    in_port=1,vlan_tci=0x0014,dl_src=50:00:00:00:00:01 -generate

7

  • 查看table10自动生成的流表项。 8

  • 假设流入口为2,无vlan标签。

ovs-appctl ofproto/trace chochi \
    in_port=2,vlan_tci=0x0014,dl_src=50:00:00:00:00:01 -generate

9

  • 查看table10. 10 可以看到寄存器的值被修改了。

table3 :Look Up Destination Port

 该表根据目标MAC和VLAN计算出我们应该发送数据包的端口。

ovs-ofctl add-flow chochi \
    "table=3 priority=50 actions=resubmit(,10),resubmit(,4)"
  • 首先将流丢如表10,若该流已经被学习过,这寄存器保存着该流的入端口,若该流没有被学习到,则寄存器保持着初始值0,我们将寄存器的值为0事作为泛洪数据包的标记。第二个动作是将数据包丢如表4,一变之后的pipeline操作。
ovs-ofctl add-flow chochi \
    "table=3 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,4)"
# 将目的地址标记为广播报地址的流丢如表4
  • 测试1:一个从1端口进入从f0:00:00:00:00:01地址发来的vlan标签为20的数据流。
ovs-appctl ofproto/trace chochi \
    in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01 -generate

111

  • 测试2: 从2端口进入,目的mac和源mac与上一条模拟流相反。
ovs-appctl ofproto/trace chochi \
    in_port=2,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01 -generate

222 可以看到在table10,匹配到由上一条流学习而生成的流表项,并把上一条的入端口 1 写入了寄存器0. 333


心态蹦了 - - 已经自己弄混了。。。以后再做吧。。。不 = = 希望有一个学弟继承我的意志!浮现