OVS添加自定义action
版本及环境
ovs 2.13.7
ubuntu 18.04
与前一篇ovs安装的环境一致,里面所提及的脚本本篇也会用到
看这篇需要有一定的OVS基础,基本概念必须要了解。
基本概念
-
这里讲的action并不是openflow action, 而是数据平面的执行action
-
OVS中流主要从两个部分转发:内核空间和用户空间
内核空间主要是通过缓存的流表转发流,若在缓存流表中未找到,则到用户空间的完整流表中找。
用户空间对于匹配的流会添加一份缓存到内核空间的流表中;
若用户空间的完整流表也没有匹配的,就把这个数据包的相关信息发到控制器。
-
一个OpenFlow flow有两部分的组成:match, action
match用于匹配到达的数据包,action是对匹配到的数据包执行相应的动作
下面这个图是流表的例子
下图为已有的一些action
- 为什么需要自定义action: 当然是已有的满足不了需求了!!!
基本步骤
-
先在OVS社区进行讨论(挺难找的)
-
在ofp-action.c中添加新的action代码
-
添加parse/encode/decode代码,这是为了使ovs-ofctl和控制器使用新加的action
-
在内核datapath部分实现新加的action
-
在ovs-vswitchd中添加action的用户层面实现
-
将action翻译到datapath
流表的添加过程概述
对于下面这个流表
它的添加过程为:
控制平面(控制器,还有在mininet中的操作命令行中)
- 我们的流表字符串会被先编码为ofpacts
- 再将ofpacts编码为OpenFlow actions
- 将flow_mod 消息发送到ovs-vswitchd
数据平面:
- 将OpenFlow actions 解码为 ofpacts
- 把flow放到交换机的规则分类器中(这里要表达的意思其实是:把转换后的ofpacts放到流表中,当有数据包来了后就会进行流表匹配)
自定义action代码实现
一、添加 action 定义(OpenFlow)
lib/ofp-actions.c中添加代码
这里添加我们自定义action的名字,这个名字是OpenFlow action的名字,它并不是OVS action的名字。OpenFlow action 需要解码才可转换为 OVS action。
|
|
这里的注释 * OF1.0+(30): uint32_t. * 是必要的,它声明了OF消息的类型,序号以及构造OF消息所需要的参数,ovs会根据这里声明的类型在编译时会在/lib/ofp-actions.inc2这个文件里按put_OFAT_##ENUM的形式自动生成函数,这里生成的函数名为put_OFAT_PVL, 这个函数的第一个参数是 ofpbuf *, 其他的参数为注释中指定的参数(指定为void时则只有一个参数),因此未按指定格式注释会出错.
include/openvswitch/ofp-actions.h 中添加定义
|
|
找到文件中代码对应的位置,添加一行我们自定义的pvl
结合/include/openvswitch/ofp-actions.h 中关于`#define OFPACTS` 的宏定义看,每添加一行OFPACT编译器会根据宏定义添加大量的处理函数;结合/include/openvswitch/ofp-actionsh.h中关于enum OVS_PACKED_ENUM ofpact_type来看,每添加一行OFPACT会给这个枚举类型添加一项.
因为C中没有类这个概念,当新添加一个行为是,对应的行为属性其实是通过宏定义这个方式来实现的。
include/openvswitch/ofp-actions.h 中添加代码
|
|
这里面其实定义了新action中所需要的参数。
datapath/linux/compat/include/linux/openvswitch.h:中添加代码:
|
|
这里需要对新添加的类型定义显式的值,否则可能会出错
这部份代码是内核层的定义,这个枚举类型里有所有的action,当datapath要执行哪个action时,会有for循环轮每个action, 再用switch case语句直接跳到对应的action中进行执行.
二、parse,encode和decode
这步的目的是为了ovs-ofctl和控制器能够使用我们新添加的action
如果这篇文章帮到了你, 那就赞助我一瓶水吧, 这可以让我有动力去写更多的文章
Sponsor