前言
在云网络环境中,VxLAN作为一种常见的租户隔离机制,使用24比特的VNI来区分不同的租户;在传统的物理网元设备中,仅能够支持VLAN或者双层VLAN(QinQ)。VLAN使用12bit的VID来做区分,QinQ有两个VLAN头,刚好能够组合成24比特,理论上就能够实现VxLAN 与QinQ 进行相互转换, 实现老旧设备的兼容。 本文将验证VxLAN 与QinQ的相互转换功能,仅从理论角度进行验证,不保证在实际生产环境完全无修改即可良好应用。
网络拓扑
为了简化流程,使用单机部署的方式进行验证,两个client和两个server,server 部署相同的服务。
虚拟机使用virsh创建,xml 示例如下
<domain type="kvm"> <interface type='bridge'> <serial/> |
OvS 流表设计
OvS流表使用多级pipeline设计:
- table0 : ingress 表,数据流入
- table8:分流表, 根据业务进行流表分发
- table90: egress表,数据输出
- table200:业务流表,实现VxLAN 转 VLAN
- group100: ECMP 业务输出
- bucket1: 模拟本地路径,直接跳转到output表
- bucket2: 模拟源端路径,跳转table200(省去了vxlan相关)
基本连通性配置
由于存在默认的流表规则,因此VM 能够正常通信:
VxLAN 转VLAN 验证
为了进行简化,在table200 实现VxLAN 转VLAN,然后直接在table 90 实现output
# basic ECMP test ovs-ofctl add-flow br-int "table=0,priority=100 actions=resubmit(,8)" ovs-ofctl -O openflow15 add-flow br-int "table=200,priority=10,arp,nw_src=192.168.1.1 actions=push_vlan:0x8100,mod_vlan_vid:1234,push_vlan:0x8100,mod_vlan_vid:567,resubmit(,90)" ovs-ofctl add-flow br-int "table=90,priority=10,arp,nw_dst=192.168.1.101 actions=output:3" |
打流进行抓包
从客户端收到的报文来看,192.168.1.1 发送的包走到了table 200, 在table 200里面打上了两层VLAN然后再在table90 将报文发送到了虚拟机。
QinQ 转VxLAN 验证
由于guest 不能直接发送双层VLAN的报文,因此使用scapy工具来构造数据包,guest里面直接采用最新的scapy-2.5.0 版本,构造报文如下:
sendp(Ether(dst='52:54:00:e4:51:5a', src='fa:16:3e:5b:af:3d')/Dot1Q(vlan=567,id=3,prio=2)/Dot1Q(vlan=1234,id=3,prio=2)/IP(dst='192.168.1.1',src='192.168.1.101')/ICMP(), iface='ens3', inter=1, loop=1) |
构造了一个192.168.1.101 到192.168.1.1 的ICMP request报文,只是与普通ICMP报文不同的是打上了两层VLAN头,ID分别为567(外层)和1234(内层),发送端抓包如下图:
在br-int 构造两级pipeline, 第一级匹配外层VLAN, 匹配到过后剥掉VLAN头,然后跳转到第二级,第二级匹配内层VLAN, 匹配后剥离VLAN头后发送到目的端
ovs-ofctl add-flow br-int "table=0,in_port=3,dl_vlan=567 actions=strip_vlan,goto_table:1" ovs-ofctl add-flow br-int "table=1,dl_vlan=1234 actions=strip_vlan,output:1" |
然后查看流表比配情况
ovs-ofctl dump-flows br-int cookie=0x0, duration=1045.855s, table=0, n_packets=1016, n_bytes=50800, in_port=vnet3,dl_vlan=567 actions=strip_vlan,resubmit(,1) cookie=0x0, duration=842.843s, table=1, n_packets=840, n_bytes=42000, dl_vlan=1234 actions=strip_vlan,output:vnet1 |
在192.168.1.1 所在虚机内抓包
结论
通过上面的验证,在OvS 通过设计合理的流表pipeline, 能够实现VxLAN到QinQ的相互转换,这样能够有效的兼容老设备而不丢失租户信息。