1. 标准转发
图1 标准L2转发
下面描述的内容都以上图1为例进行展开描述。
在展开描述之前,先提下虚拟机和br-int之间为什么还需要接入一个linux bridge桥。接入这个linux bridge桥主要是为了实现安全组功能。对于采用openvswitch组网,实现安全组有两种方式:ovs+iptables+connection track;ovs+openflow+connection track。后者的性能较好但是稳定性还有待验证
1.1 br-int
br-int上采用多级流表,这里先暂时跳过一些高级流表,如DVR、防火墙。下表列出了常规的几个流表及其作用。
表号 作用
table=0 LOCAL_SWITCHING,本地交换
table=23 CANARY_TABLE,用于检测OVS是否重启
table=24 ARP_SPOOF_TABLE,用于防范ARP欺骗
table=25 MAC_SPOOF_TABLE,用于防范MAC地址欺骗
table=60 TRANSIENT_TABLE,用于传统交换
上述这些流表的流程(涉及的ICMPv6暂时忽略)如下图所示:
图2 br-int流表匹配流程图(标准转发)
Node2
如下图3所示,br-int上的流表(只保留了相关的,去掉了ICMPv6)和上图2所示的流程是一致的,这里不再分析了。
如下图3所示,br-int上的流表(只保留了相关的,去掉了ICMPv6)和上图2所示的流程是一致的,这里不再分析了。
图3 Node2上的br-int流表
Node1
如下图4所示,br-int上的流表(只保留了相关的,去掉了ICMPv6)和上图2所示的流程是一致的,这里不再分析了。
如下图4所示,br-int上的流表(只保留了相关的,去掉了ICMPv6)和上图2所示的流程是一致的,这里不再分析了。
图4 Node1上的br-int流表
1.2 br-tun
br-tun上采用多级流表,这里先暂时跳过DVR相关的流表项。
表号 作用
table=0 LOCAL_SWITCHING,本地交换
table=2 PATCH_LV_TO_TUN,标识从patch-int端口进来的数据包
table=3 GRE_TUN_TO_LV,标识从gre隧道端口进来的数据包
table=4 VXLAN_TUN_TO_LV,标识从vxlan隧道端口进来的数据包
table=6 GENEVE_TUN_TO_LV,标识从geneve隧道端口进来的数据包(这个表在这里先不分析)
table=10 LEARN_FROM_TUN,自学习表,用来学习从gre、vxlan、geneve隧道口进来的数据包
table=20 UCAST_TO_TUN,单播表
table=21 ARP_RESPONDER, arp代答
table=22 FLOOD_TO_TUN,BUM表(组播、广播、未知名单播)
上述这些流表的匹配流程如下图5所示:
图5 br-tun流表匹配流程图
Node2
如下图6所示,br-tun上的流表(只保留了相关的,对于Arp Responder这里先不给出流表,下文会详细描述这个功能,同时只给出VXLAN相关的,对于GRE和GENEVE隧道没有给出,原理和VXLAN是一样的)和上图5所示的流程是一致的,这里不再分析了。
如下图6所示,br-tun上的流表(只保留了相关的,对于Arp Responder这里先不给出流表,下文会详细描述这个功能,同时只给出VXLAN相关的,对于GRE和GENEVE隧道没有给出,原理和VXLAN是一样的)和上图5所示的流程是一致的,这里不再分析了。
图6 Node2上的br-tun流表
Node1
如下图7所示,br-tun上的流表(只保留了相关的,对于Arp Responder这里先不给出流表,下文会详细描述这个功能,同时只给出VXLAN相关的,对于GRE和GENEVE隧道没有给出,原理和VXLAN是一样的)和上图5所示的流程是一致的,这里不再分析了。
如下图7所示,br-tun上的流表(只保留了相关的,对于Arp Responder这里先不给出流表,下文会详细描述这个功能,同时只给出VXLAN相关的,对于GRE和GENEVE隧道没有给出,原理和VXLAN是一样的)和上图5所示的流程是一致的,这里不再分析了。
图7 Node1上的br-tun流表
根据上面的描述,table=10是用来完成自学习功能的。首先来说下为什么需要这种自学习功能,考虑下图8的部署情况:三台计算节点,各部署了三个虚拟机VM1、VM2、VM3,都处于同一个VXLAN网络(VNI=10)。Openstack Neutron会在每个计算节点上创建两个VTEP端口用于两两计算节点间的连接。假设没有自学习这个功能,VM1要和VM2通信,数据包到达br-tun桥时无法知道目标虚拟机VM2在哪个VTEP上,因此,VM1从br-tun出来的数据包只能从VTEP1和VTEP2端口泛洪发送出去。同理,VM2要和其他计算节点上的虚拟机VM1或VM3通信时也是要从VTEP3和VTEP4端口泛洪出去。当我们的计算节点、租户网络规模比较大时,这种通过泛洪进行通信的机制是非常浪费带宽、降低性能的。为了解决这个问题,Neutron在br-tun桥上引入了table=10自学习功能。同样如下图8所示,VM1要和VM2通信,从VTEP1和VTEP2端口泛洪发送报文后,VM2从VTEP4接收到报文后,通过自学习学到了VM1在VTEP1上,接着VM2发出的回应报文不在泛洪了,而是单播从VTEP4端口出去,报文送到VTEP1后,学习到VM2在VTEP2上,因此后面再发送报文给VM2就不需要再泛洪了,直接单播从VTEP1出去了。
图8 自学习功能示意图
对于自学习的流表,有必要介绍下是如何实现的,具体如下图9所示。
图9 自学习流表项table=10
通过匹配上述的table=10后,会自动生成table=20的流表项(如上图6和7中红色标注的流表项)。自动生成的table=20是有一个超时时间的,默认为hard_timeout=300,即:300s。超过这个时间没更新,该流表项就会被删除,后续只能通过自学习再生成。