Open vSwitch中的datapath flow匹配过程
- 数据结构看不懂
- 匹配算法经过了多次演进,已经有点复杂了,看代码完全看不懂,我能怎么办,我也很绝望啊!


- 在创建一个vxlan型的vport时,会调用到vxlan_create来创建这个vport,这个函数做了两件事情

- 调用vxlan_tnl_create,alloc要创建的vport,并创建好vxlan设备
- 调用ovs_netdev_link,把上一步创建的vxlan设备与vport绑定起来,并且还注册了一个收包回调函数是为netdev_frame_hook,如下:

- netdev_frame_hook收到包后,把包转交给netdev_vport_receive,但由于不知道这个宏USE_UPSTREAM_TUNNEL功能是什么,所以到底转交的时候带不带第二个参数就搞不清楚了,如下

这里要注意的是,netdev_frame_hook及netdev_port_receive是标准的收包流程,所谓标准指的是,只要是发向OVS中port的包,无论port是什么类型,是VXLAN vport,还是netdev vport,还是gre vport,走的都是这个流程,这些vport类型的收包回调统一都是netdev_frame_hook - 无论什么vport类型,包都会走netdev_frame_hook->netdev_port_receive这个流程,然而在netdev_port_receive中就要分流了,如下:

在这个函数中,根据skb下挂的dev,找出该包所收包时所属于的vport,然后调用ovs_vport_receive - 接下来到了ovs_vport_receive函数中,这个函数主要就做了一件事情:把包中的标识信息(一二三四层外加conntrack信息)扒到一个sw_flow_key结构中,这个结构并不复杂,字段也比较容易理解,这个sw_flow_key结构就是后续datapath转发表匹配时很关键的一个东西。把这件事做完后,就把skb本身与扒出来的这个sw_flow_key一起送给ovs_dp_process_packet函数中进行进一步处理

- ovs_dp_process_packet如下

在这个函数中,将调用ovs_flow_tbl_lookup_stats()进行datapath转发表项的匹配工作
第一个参数是查询的转发表,这个表挂在datapath下,类型为flow_table,看上面的数据结构图
第二个参数是之前扒出来的sw_flow_key类型结构实例
第三个参数是调用Linux kernel函数对skb进行的一个哈希数值
第四个参数是一个出参,如果是megaflow匹配的话,这个出参将携带掩码匹配命中的字段数出来 - 至此,先停一下车,上面说的是包是怎么收进来的,接下来就要看包是怎么匹配的了,先停一下车
- 第一个层次,假设没有megaflow,即按位选择性匹配,datapath转发表项必须全12个字段精确匹配,你会怎么做?这种情况下,匹配就很简单,我们把包中的信息扒到sw_flow_key结构中,然后在OVS中设计一个哈希表,映射的就是[sw_flow_key <==> 如何转发],直接用这个哈希表按key查询,O(1)就能完成匹配。
做个不恰当的比喻,内核datapath中实现了一个类似于std::map的数据结构,当然这是一个哈希表,其中键是sw_flow_key类型的,值就是“要执行的动作”(也就是sw_flow类型)
当packet收上来时,直接把packet解压出来的key当成键,去查询它对应的“要执行的动作”。。查询成功,就走快转直接从内核转走。。查询失败,就是内核datapath转发表项匹配失败,给用户态上送upcall消息。用户态根据OpenFlow流表,走慢转,然后再把慢转的行为总结成datapath转发表里的“要执行的动作”,下发给内核,这样,下一次再来,就直接走快转了。
但是问题出现了,精确匹配的最大缺点就是datapath转发表项数量会爆炸膨胀,你想一下用户态OpenFlow流表中的安全组的实现,conjunctive,你再想一想这些安全组映射成datapath转发表项,表项数量得炸成什么样。
所以为了解决这个问题,就出现了megaflow式匹配,这个洋文名字的意思就是:选择性的匹配某些字段 - megaflow匹配就是第二个层次
- 入的包解压出来的sw_flow_key实例是所有字段都有的
- 匹配时只需要匹配部分的sw_flow_key中的字段,所以OVS设计了一个数据结构叫sw_flow_mask,sw_flow_mask中有两个很重要的字段:sw_flow_key_range与sw_flow_key,其中range就指定了匹配哪些字段。。
比如,比如,举个不严谨的例子,datapath中要支持两种匹配:
第一种:按MAC层src与dst及IP层src与dst的匹配
第二种:IP层src与dst的匹配
那么就需要做两个sw_flow_mask实例,假设macsrc/macdst/ipsrc/ipdst的编号分别是3、4、5、6,那么这两个sw_flow_mask的实例的示意大致如下:
sw_flow_mask first = {
range = [3,4]
key = {
...
macsrc=11:22:33:44:55:66
macdst=66:55:44:33:22:11
...
}
}
sw_flow_mask second = {
range = [3,6]
key = {
...
macsrc=22:22:22:33:33:33
macdst=33:33:33:22:22:22
ipsrc=1.2.3.4
ipdst=4.3.2.1
...
}
}
然后这两个实例放在哪里呢?在(datapath.table)->mask_array中,在旧版本的OVS实现中,这些sw_flow_mask的实例被组织成链表,在2.7版本中,直接组织成顺序表了
那么packet收上来是如何进行匹配的呢?
首先,要对(datapath.table)->mask_array中的所有sw_flow_mask进行遍历
然后,对于每个sw_flow_mask实例,这里称为mask,去比对mask.range范围内,mask.key中的值,
如果这些值与packet解压出来的key一致,那么就表示megaflow匹配成功
这个时候接下来怎么搞呢?和第一步一样,依然是要去查哈希表,查出一个sw_flow出来,但是哈希表是全字段匹配的呀。
比如包原先解压出来的sw_flow_key是为key,这个时候用key作键去查哈希表,结果并不是我们希望得到的megaflow匹配结果,而是全匹配结果(很有可能会miss)
所以不能用key去当键去查哈希表,而应该用匹配的sw_flow_mask实例里的"range + key"这两个信息结合起来,当成键,去查哈希表。
在这一版的匹配流程中,相较于上一版,解决了datapath转发表项数量爆炸的问题。
并且在实际实现中,对于sw_flow结构,还增加了一个用来表示mask的字段,是为sw_flow->mask,类型是为sw_flow_mask
- 上一版的匹配流程虽然改善了datapath转发表项的爆炸问题,但是又引入了一个新的问题(真他妈是聋子治成哑巴了):性能下降了!
第一版虽然很浪费内存空间,但是查找快啊!只查一次哈希表就世界太平了!顶多桶位上链表长度长一点撑死了!
第二版虽然节省了空间,但又浪费时间了啊!你看,先要遍历所有的mask_array中的sw_flow_mask实例,来看哪个实例与包的key能对上!
所以OVS这拨人又处心积虑的搞出了第三版匹配流程。
核心思想还是站在前人的工作上糊一层屎:既然遍历mask_array里的实例太浪费时间,那么就不要以“遍历”的形式去做这件事,来,老子的意大利散列函数呢??想办法干他娘的一炮!
在上一版的策略中,流程大概是:
第一层:遍历mask
第二层:根据masked_key查询flow
所以这一版的策略就改进了这一点,现在流程是这样的:
第一层:根据packet的key,查询masked_key
第二层:根据masked_key,查询flow
注意这两个层次的查询都是哈希表(字典)查询,所以总共实现了两个哈希表(字典):
第一个字典:键为packet的标识信息,值为mask的标识信息
第二个字典:键为masked_key,值为flow
大概逻辑就是这样,下面将讲第三版匹配流程的具体实现


- ufid_ti的用途?
- sw_flow结构中,每个table_instance都对应着两个链表字段,为什么?
- table_instance结构中的node_ver是什么用途?
body,td { font-family: Consolas; font-size: 10pt }
Open vSwitch中的datapath flow匹配过程的更多相关文章
- 绝对路径${pageContext.request.contextPath}用法及其与web.xml中Servlet的url-pattern匹配过程
以系统的一个“添加商品”的功能为例加以说明,系统页面为add.jsp,如图一所示: 图一 添加商品界面 系统的代码目录结构及add.jsp代码如图二所示: 图二 系统的代码目录结构及add.js ...
- (转)绝对路径${pageContext.request.contextPath}用法及其与web.xml中Servlet的url-pattern匹配过程
以系统的一个“添加商品”的功能为例加以说明,系统页面为add.jsp,如图一所示: 图一 添加商品界面 系统的代码目录结构及add.jsp代码如图二所示: 图二 系统的代码目录结构及add.js ...
- web.xml中的url-pattern写法规则及匹配过程
servlet和filter在javaEE开发中很常用,因此有必要知道web.xml文件映射的规则 1. 写法 ①完全匹配:以“/”开头,以字母(非“*”)结束 如:<url-patte ...
- 在Python中使用正则表达式同时匹配邮箱和电话并进行简单的分类
在Python使用正则表达式需要使用re(regular exprssion)模块,使用正则表达式的难点就在于如何写好p=re.compile(r' 正则表达式')的内容. 下面是在Python中使用 ...
- 【java规则引擎】模拟rete算法的网络节点以及匹配过程
转载请注明:http://www.cnblogs.com/shangxiaofei/p/6340655.html 本文只用于理解rete算法,通过一个规则的编译成的网络结构,以及匹配过程去理解rete ...
- Java中对象方法的调用过程&动态绑定(Dynamic Binding)
Java面向对象的最重要的一个特点就是多态, 而多态当中涉及到了一个重要的机制是动态绑定(Dynamic binding). 之前只有一个大概的概念, 没有深入去了解动态绑定的机理, 直到很多公司都问 ...
- Python妙用re.sub分析正则表达式匹配过程
声明:本文所使用方法为老猿自行研究并编码,相关代码版权为老猿所有,禁止转载文章,代码禁止用于商业用途! 在<第11.23节 Python 中re模块的搜索替换功能:sub及subn函数>介 ...
- Python正则表达式书写容易碰到的陷阱:\W*和\W*?匹配过程遇到的问题
老猿在分析<Python正则表达式\W+和\W*匹配过程的深入分析>中的问题时,想到一个问题,如果"re.split('(\W*)','Hello,world')"的处 ...
- Python正则表达式\W+和\W*匹配过程的深入分析
在学习re.split函数的处理过程中,发现执行如下语句及返回与老猿预想的不一致: >>> re.split('\W*','Hello,world') ['', 'H', 'e', ...
随机推荐
- PHP7中我们应该学习会用的新特性
PHP7于2015年11月正式发布,本次更新可谓是PHP的重要里程碑,它将带来显著的性能改进和新特性,并对之前版本的一些特性进行改进.本文小编将和大家一起来了解探讨PHP7中的新特性. 1. 标量类型 ...
- JS中substring与substr的区别
Substring: 该方法可以有一个参数也可以有两个参数. (1) 一个参数: 示例: var str=“Olive”: str.substring(3); 结果:“ve” 说明:当substri ...
- 【Tomcat源码学习】-3.应用管理
通过上一节我们完成了对容器进行了加载.初始化.启动,而对于应用的加载部分独立出来,本节进行单独的讲解 一.应用加载流程 1)应用识别,Context创建 在Host启动后,会调用Host的监听Ho ...
- 【Windows 10 应用开发】输入模拟
---恢复内容开始--- Input Injection 直译为:输入注入.通俗的译法为:模拟输入.此注入行为可以模拟以下几种输入行为: 1.键盘按键. 2.鼠标. 3.触控. 4.书写笔输入. 5. ...
- 《Effective C#》读书笔记-1.C# 语言习惯-2.使用运行时常量(readonly)而不是编译时常量(const)
概念 编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识 ...
- Laravel 5.2 教程 - 数据填充
一.简介 Laravel提供的填充类(seed),可以让大家很容易的实现填充测试数据到数据库.所有的填充类都位于database/seeds目录.填充类的类名完全由你自定义,但最好还是遵循一定的规则, ...
- iOS开发 - Swift使用JavaScriptCore与JS交互
一.前言 在这个提倡敏捷开发和H5横行的年代,原生App内嵌入一些H5页面已经成为一种流行的趋势.一套H5页面就可以适配复杂的iOS和Android页面,大量节省了开发和维护时间,如果本来就有移动端网 ...
- ASP.NET Web基本原理
ASP.NET Web基本原理 浏览器与服务器之间的交互 浏览器向服务器发送HTTP请求,具体如下: 1.浏览器向服务器发送TCP包,要求服务器打开连接 TCP包首部32位,占20字节,格式如图一: ...
- CSS vertical-align属性
之前也经常用到vertical-align进行垂直居中对齐,突然发现其中的一些属性值根本就没使用过,也不清楚效果,将今天的研究成果记录下. vertical-align 属性 下表是w3c上列举的属性 ...
- 你跟上技术趋势了么? 来看看这10场2017热门it技术会议!
2016年各类大会让人应接不暇,技术圈儿最不缺的就是各种大会小会,有的纯干货,有的纯广告.作为一名技术开发者,参加了几场大会,你是不是也开始思忖:究竟哪些会议才值得参加?下面活动家为你推荐几场2017 ...