从物理或虚拟接口进入OvS-DPDK的包,根据其报头字段计算出一个唯一标识符或hash值,然后将其与“精确匹配缓存(EMC)”、“数据路径分类器(dpcls)”、"ofproto分类器"这三个主要交换表中的条目进行匹配。包的标识符将依次遍历这三个表,直到找到一条匹配,接下来,将执行表中的匹配规则指示的适当操作,并在完成所有操作后将包转发出交换机。
microflow在ovs+dpdk代码中,又被称为EMC(exact match cache)。(精确匹配)
megaflow在ovs+dpdk代码中,又被称为dpcls(datapath classifer)。(模糊匹配)
从网卡接收到报文后,首先查找EMC表项,如果命中则直接执行action,如果miss则查找dpcls。如果查找dpcls命中,则将规则插入EMC,并且执行action。还是miss的话,就查找openflow流表。如果查找openflow命中,则将规则插入dpcls和EMC,并且执行action。还是miss的话,就丢包或者发给controller。
对包进行分类后,可对包执行多种不同的动作,比如将包转发至一个确定的端口,增加VLAN tag,丢包亦或者将包发送至连接跟踪模块。
(1)一二级流表的数据结构:
struct dp_netdev
代表一个datapath。在ovs+dpdk下,datapath也位于用户空间,所有netdev类型的网桥共享同一个datapath。
ports: 用于保存datapath下的所有端口,包括网桥的所有物理端口(不包含patch口)。
poll_threads: 用于保存datapath下的所有pmd线程相关信息。
struct dp_netdev_pmd_thread
表示一个pmd线程相关信息。
flow_cache: 这个就是EMC流表,每个pmd线程有一个EMC。
stats: 用来统计EMC和dpcls的命中和miss情况。
struct cmap classifiers:
用来保存dpcls。每个port都对应一个dpcls。
struct emc_cache
用来保存8k个emc表项。
flow: 类型struct dp_netdev_flow,主要包含流表的action。
key: 类型struct netdev_flow_key,主要包含匹配项。key是从报文提取出来的内容,精确表示一条数据流。
struct dpcls
表示一个datapath分类器,使用TSS查找算法,将相同mask的流表插入同一个subtable。
in_port: 此分类器所属端口。
subtables: subtable数组,用于查找时遍历subtable。
struct dpcls_subtable
具体相同mask的流表集合。
rules: 保存流表。
mask: 类型struct netdev_flow_key,subtable的mask。
struct dpcls_rule
表示一个dpcls流表的匹配域。
struct dp_netdev_flow
表示一条datapath流表,包含匹配域和动作。
actions: 指向此流表的动作。
cr: 指向struct dpcls_rule,表示此流表的匹配域。
batch: 类型struct packet_batch_per_flow,将匹配的此流表的报文插入batch,用于批量处理报文,这也是dpcls的一个优化。
(2)查找过程:
入口在lib/dpif-netdev.c,查询的缓存分为两层:一个是DFC,一个是dpcls,相当于microflow和megaflow,DFC由两部分组成,DFC(datapath flow cache):EMC(Exact match cache)+SMC(Signature match cache),另一部分就是dpcls(datapath classifer),在紫金ovs优化设计方案中EMC查找已关闭
收到包后,包头将被提取存入miniflow中,miniflow是struct flow的稀疏表示
EMC查找的函数调用过程如下图(有些过时),暂不做深入了解
在EMC中,包将在以下几个结构体中进行处理:
fast_processing传了in_port参数,以确定查哪个dpcls
dpcls函数调用:
通配符匹配:
在每个subtable中,使用每一个包提取的miniflow与subtable mask生成一个search key来用于dpcls_lookup中的匹配,匹配过程见下图:
此时在插入一条匹配规则并匹配(网络掩码该是16):
每个dp_packet拥有自己对应的dp_netdev_flow(miniflow),每个dp_netdev_flow拥有自己对应的rules(匹配规则),下图为dpcls调用关系图
拥有相同流信息的包将入队至一个相同组(batch),而该组将根据流动作对包进行处理。为了提升包转发性能,将对同一组内的包同时处理。
根据分组将对包执行特定的动作,以下是动作将包转发至出口的流程:
netdev_send->netdev_dpdk_send__->netdev_dpdk_eth_tx_burst->rte_eth_tx_burst进行发包