OpenvSwitch系列之flow_mod
来源:互联网 发布:java面试项目介绍范文 编辑:程序博客网 时间:2024/05/17 22:36
最近两周一直在研究flow_mod这个消息,flow_mod这个消息是openflow中最重要的消息,没有之一,所以花在它的时间上比较多,而且里面涉及的内容也比较复杂。社区有一篇博文对我帮助还是很大。因此这边可能和他的文章有一部分冲突,但是对于学习和总结无所谓啦!!
我们在上一篇中有介绍了,OpenvSwitch是如何进行不同openflow协议版本的控制的,也知道了入口函数是handle_openflow__,本文的主题是flow_mod消息,因此我们直接进入flow_mod处理函数。
众所周知,flow_mod是用于下发流表的。可以简单理解为一个flow_mod就是就是一个流表项。如果有谁不是很了解flow_mod,请自行阅读openflow协议。
通过入口函数openflow_handle__可以知道flow_mod处理函数是,为了描述相对清晰,我会在代码中直接进行注释,除了需要特别指出或者着重描写才在博文中单独写出来。
上面是flow_mod函数处理框架,下面我们进行逐个分析,我们进行分析时候会结构flow_mod消息,因此有具体的消息内容,我们在分析代码的时候不至于那么抽象。
下面报文就是我抓取的,比较有针对性,控制器下发的流表是从host1到host2,出端口是交换机的2。具体报文和网络拓扑如下:
注:红色线就是打通的通道。
由于函数ofputil_decode_flow_mod相对较长,因此采用分段描述,层层深入方式进行剖析。
上面内容相对简单,也不用多说些。下面是我们进行着重分析的。由于我们基于openflow1.3进行连接的,因此raw实际值是OFPRAW_OFPT11_FLOW_MOD。(opeflow1.1之后版本flow_mod没有变化。)在这里就有if-else判断,所以我们会着重分析if分支。
一般情况下,flow_mod消息主要是由openflow固定字段,match字段,instruction字段(可以没有),然而match字段中可以包含多个oxm字段(可以没有oxm),instruction字段中可以包含多个action字段。其中oxm格式是TLV(Type-Length-Value)。针对上面的报文来说,oxm有两个,action只有一个。所以我们能够预测if分支中主要是针对这些字段进行解析。
以上就是flow_mod解析函数大体框架,下面我们来看一下match、instruction这两个解析函数。首先我们来看一下函数调用关系图:
根据关系图,从函数3、函数4内容都比较短小,函数也比较容易理解,我们从函数5开始进行分析,分析如下:
在介绍nx_pull_raw函数之前,我们先看来看一下这个全局数组const struct mf_field mf_fields[MFF_N_IDS](在文件meta-flow.c),这个数组在下面的函数会用到mf_from_nxm_header。所先把分析一下。
这个虽然数组很长,但是里面的注释对于理解还是有帮助的,数组中是按照网络层次进行划分的,主要是metadata, L2, L2 .5,L3, L4, L5。也就是说根据报文中match字段可得出位于数组的哪层。例如上面报文,是针对物理地址(源/宿mac)那么我们可以推断出是位于数组的L2,如下面代码所示:
我们来看一下蓝色字体,这个宏定义
枚举:
通过上面代码罗列可得知,OXM_HEADER是用于构造报文OXM头部的宏,而OXM是以TLV格式进行封装的。针对上面报文和宏定义就有如下对应(图片蓝色下划线):
经过函数nxm_do_init处理,会把这个数组中成员挂在全局变量all_fields,这个变量是一个hmap结构,至于这里具体存储关系是怎么关联的,这里不进行详细解析(可以参考函数nxm_do_init)。如果有不理解hmap的网友可以去看一下我之前文章。下面我们继续分析nx_pull_raw函数。
上面分析比较混乱,这里进行一下总结:
1、通过上面这个函数处理(核心代码是for循环),就会把报文中两个oxm字段解析成功并且保存在入参match里面。
2、我们知道oxm表现形式是一个tlv格式,OpenvSwitch会把value字段赋值到match结构体中的,struct flow(flow.h)结构体。flow这个结构体和mf_fields是有关联关系的。
3、通过上面解析后,flow中字段数据时这样的(实际内存中没有冒号):
flow.dl_dst[6] = 00:00:00:00:00:02
flow.dl_src[6] = 00:00:00:00:00:01
其他字段是默认值,大部分是0。
通过上面的一系列分析,openflow中的match字段就结束了。现在我们返回到函数ofputil_decode_flow_mod中,下面应该解析instructions。
基于目前OpenvSwitch实现主要支持这6中actions,分别是:openflow1.3中meter表,openflow1.1中apply_action,openflow1.1中clear_action,openflow1.1中write_action,openflow1.1中write_metadata,openflow1.1中goto_table。针对当前的flowmod中action是apply_action,如下图所示:
在介绍函数之前,我们先来看一下函数中即将用到指针数组,const struct ofp11_instruction *insts[N_OVS_INSTRUCTIONS],通过查看宏定义可知, N_OVS_INSTRUCTIONS=6
默认指针数组中保存地址是null,经过处理后会把其中某个数组存储单元修改为有效地址。针对上面那个报文,instructions的类型是apply_actions,因此经过函数decode_openflow11_instructions会把数组下标为OVSINST_OFPIT11_APPLY_ACTIONS的值修改为有效地址(即上图中红色字体)。
现在我们来看一下这个函数代码,下面红色字体就是那6种action:
我们现在来分析一下这两个函数:decode_openflow11_instructions(解析instructions函数)和ofpacts_from_openflow(解析actions函数)。
函数decode_openflow11_instructions主要是循环遍历,不断解析instructions,内部最终处理函数是decode_openflow11_instruction,对于这个函数,比较难看懂,主要是因为里面switch-case子句是通过宏定义的,这样不便于理解。然而我们可以借助编译器(GCC),让它帮我们展开宏定义。由于展开后代码变得非常庞大,因此我只相关代码展示出来:
我们再来看一下actions解析函数,上面已经说过了,对于openflow1.3的actions报文,最终会进入这个ofpact_from_openflow11函数,函数主体代码如下:
flow mod操作主要是有五类操作,增加、修改、严格修改、删除、严格删除。代码如下,对于上面报文是添加操作:
我们现在来看一下add_flow这个函数,这个函数比较大,需要我们耐心分析。这个函数主要是对解析成功match、instructions再次进行抽象,抽象成openvswitch中rule。
虽然add_flow这个函数比较长,但是函数逻辑还是比较清晰:如果已经存在rule则进行修改操作,否则创建(这个是openflow标准)。针对我们这个flow_mod,显然是创建,所以只需要关心创建流程即可,其他流程可以以后再进行详细分析。
以上这些操作,对于我们分析代码流程不是很关键,我们只需要知道,通过报文中的table_id字段,能够获取OpenvSwitch中定义的table对象即可,其他内容无需深入研究。下面这部分代码,主要是用于修改操作,即如果存在rule则进行修改,修改完成后直接退出函数。
针对我们的报文来说,肯定是不存在rule,所以不会进入这个修改分支。因此不进行深入分析,而且修改操作是基于添加后进行,所以个人认为,如果把添加流程搞清楚后,修改操作也会非常简单。
通过上面的分析,已经完成对fm进一步抽象,现在我们回到函数handle_flow_mod__,看一下此rule执行操作,即下发到datapath。我们知道用户态vswitchd和内核态datapath是通过netlink进行通信,我们在函数run_rule_executes中,将会看到netlink应用。
通过上面代码可知,最终调用函数是rule_execute,函数调用关系如下:
这些函数就不分析了,主要原因是我对netlink不熟悉,而且我们的目的是,知道是什么样的流程下发到datapath即可。
上面有一个函数我们分析,这里单独分析一下:do_add_flow。这个插入rule的流程比较繁琐,主要原因是规则很多。这里函数里面会调用到函数oftable_insert_rule,
其实对于上面这多插入规则,只能从代码中理解表面意思,至于为什么这样做,还不是很理解。从文章篇幅可知,flow_mod这个消息是最复杂的消息,这里写的只是个人观点,有些地方可能理解不到位或者描述不到位,希望读者能够指点出来,以便进行修改。今天突然下载了github中最新代码,发现很多函数都没有了,所以这里指出,文章分析的函数是以ovs-2.3.2版本为准。终于结束,写这篇博客断断续续用了一周的时间,希望能够帮助大家理解。
作者简介:
徐小冰:毕业于河北大学,主要从事嵌入式软件开发,虚拟化,SDN。目前基于ODL和Open vSwitch进行二次开发,希望与广大网友一起探讨学习。作者系OpenDaylihgt群(194240432)资深活跃用户,@IT难人。
- OpenvSwitch系列之flow_mod
- openvswitch
- OpenvSwitch
- 虚拟化技术系列--openvswitch介绍
- Openvswitch之Qos rate-limiting原理
- openVswitch(OVS)源代码分析之简介
- openVswitch(OVS)源代码分析之数据结构
- 【OpenVswitch源码分析之二】架构
- openVswitch(OVS)源代码分析之简介
- openVswitch(OVS)源代码分析之数据结构
- openVswitch(OVS)实现之源代码分析之数据结构
- openVswitch(OVS)实现之源代码分析之工作流程
- openVswitch(OVS)源代码之linux RCU锁机制分析
- SDN启蒙3:openVswitch(OVS)源代码分析之简介
- OpenStack网络实战系列一:通过Openvswitch实践了解交换机的基本概念和操作
- Openvswitch使用
- openvswitch configuration
- openvswitch架构
- 原子变量 atomic_set 类型为何在int外嵌套结构体
- CAS服务器端搭建配置
- log4j简单配置解释
- sierdun
- IOS的学习笔记之Objective-C style guide.
- OpenvSwitch系列之flow_mod
- ubuntu配置swoole开发环境
- DispatcherServlet与ContextLoaderListener的对比
- 在sqlserver中查询注释的函数
- java web QQ(六)
- oracle中的行列转换(一 列转行 pivot)
- 数据库设计三大范式
- Java多线程模拟实现消费者生产者问题
- 游戏开发 博客