1,OVS组件构成
1.1,组件列表
1.2,组件关系
1.3,数据库表
1.4,组件互动
1.5,目录结构
2,总体框架
3,数据结构
4,数据包转发流程
为了兼顾性能与功能,当前OVS被设计成3级转发路径,从快到慢依次为:EMC,Megaflow,openflow。
EMC转发:
包进入的第一个转发路径称为EMC,即用包中所有字段作为key去查找精确匹配缓存,若找到则得到一条flow,其中包含转发需要的所有信息。EMC设计为开放地址的hash表,它用memcpy()进行报文全字段比较,因为不进行额外的判断,因而比较快。
Megaflow转发:
当EMC路径找不到匹配的flow时进入第二级转发路径fast path简称dpcls,每一个端口有一个dpcls。在dpcls中每一种元组分配了一个hash表,一种元组可以认为是一种匹配类型或一个掩码,比如(source IP/24, destination IP/24)是一种元组,(src IP/24, dest IP/24,src port,dest port)是另一种元组。注意(source IP/24, destination IP/24)和(source IP/32, destination IP/32)是两种元组。每个dpcls的hash表有自己的hash算法。找到对应的桶之后进行wildcard匹配即只匹配掩码中为1的字段。fast path实际上也很快,但由于要进行掩码匹配,它比EMC稍慢。
openflow转发:
当fast path也找不到匹配的flow时进入第三级转发路径upcall。upcall首先会进入openflow协议层查找其内部的流表,若找得到则执行其中的动作。openflow协议层内的流表查找也是基于掩码的查找,因为它是openflow协议的全面实现,包含了table,group,meter等EMC, fast path所不包含的元素,所以会比较慢。如果在openflow协议层内还找不到匹配的flow则需要把包发送给远程的controller,以期它在收到packet in消息后添加一条flow到本地openflow switch。同时controller也应该用packet out消息把包发回到本地openflow switch基于更新后的流表进行再转发。upcall路径因为涉及到远程消息交换,因而是最慢的。
在这3层转发路径中,在慢路径找到flow时会在快路径插入一条新流,以在下一次走快路径。比如在openflow路径找到流时会将流插入megaflow和EMC,在megaflow找到流时会将流插入到EMC。
5,流表生成
我们假设ofproto层有一条规则:将源IP在子网192.168.1.0/24内的包送往3号端口我们假设ofproto层有一条规则:将源IP在子网192.168.1.0/24内的包送往3号端口。初始时EMC和dpcls均为空。
- 1->2->3 : 此时收到一个源IP为192.168.1.1的包,因为EMC和dpcls均为空,故走到upcall流程,上ofproto层。此时会命中openflow层的规则。
- 4: upcall 流程走完后会在dpcls里添加一个dpcls entry,其中的flow取自于包的全部信息,可见dpcls->flow.ip_src=192.168.1.1。action取自于ofproto层返回的action。dpcls->cr.mask取自于ofproto层返回的mask。dpcls->cr.flow是dpcls->flow与dpcls->cr.mask互与的结果,因此是192.168.1.0。
- 5:在dpcls添加条目的同时也会在EMC添加一个条目,EMC条目的flow指向了上面新创建的dpcls entry,而key则是取自于包的全部信息,因此ip src=192.168.1.1。
- 6:第一个包完成所有动作,从3号口发出去。
- 7->8:此时再收到一个源IP为192.168.1.2的包,虽然此时EMC不为空,但EMC条目的key是ip src=192.168.1.1,所以它并不匹配第二个包,因此继续走到dpcls进行fast path查找。
- 9:虽然第二个包的源IP 192.168.1.2并不匹