对openflow 1.0协议的扩展
通过这几天对openvswitch代码的分析,以及项目的须要,须要对openflow 1.0进行一定的扩展,发现网上没有这方面的教程,尽管在搞懂ovs代码架构,floodlight controller中利用的事件驱动模型之后,会认为并非难事,可是对于刚入门SDN的同学来说,须要一番折腾,这里简单记录一下,希望帮助到其它人。
环境配置:2host + 1 OVS + floodlight
软件版本号: openvswitch 1.9.0 , floodlight0.85
在尝试对ovs中的openflow协议进行扩展之前至少应该理清的是,ovs怎样与SDN controller进行通信,收发of msg的过程,处理of action的流程,特别是怎样解析来自controller的消息;此外由于Floodlight利用的是netty框架,所以还要理解netty事件驱动的原理。接下来添加一个简单的openflow message以及相应的action ,然后看ovs能否成功接收来自controller的消息。
1.在 include/openflow/openflow-1.0.h中扩展of协议,添加我们的消息类型。(里面的字段依据自己的业务逻辑须要而设置)
struct ofp10_action_fp_update {
ovs_be16 type;
ovs_be16 len;
ovs_be32 vector;
};
OFP_ASSERT(sizeof(struct ofp10_action_fp_update) == 8);
struct ofp_fp_update{
ovs_be32 buffer_id; /* ID assigned by datapath or UINT32_MAX. */
ovs_be16 in_port; /* Packet's input port (OFPP_NONE if none). */
ovs_be16 other; /* other fields reserved. */
struct ofp_action_header actions[0]; /* The action length is inferred
from the length field in the
header. */
};
OFP_ASSERT(sizeof(struct ofp_fp_update) == 8);
2.在 lib/ofp-msg.h 更新ofpraw这个结构体(非常重要,由于当ovs收到来自controller的消息之后就会利用ofpraw里面格式化的定义来验证消息的有效性,从而进行兴许处理)和ofptype枚举体。须要注意的是对ofpraw的更改一定要遵循固定的格式,凝视中讲的非常清楚。
enum ofpraw {
/* Immutable standard messages.
*
* The OpenFlow standard promises to preserve these messages and their numbers
* in future versions, so we mark them as <all>, which covers every OpenFlow
* version numbered 0x01...0xff, rather than as OF1.0+, which covers only
* OpenFlow versions that we otherwise implement.
* Without <all> here, then we would fail to decode "hello" messages that
* announce a version higher than we understand, even though there still could
* be a version in common with the peer that we do understand. The <all>
* keyword is less useful for the other messages, because our OpenFlow channels
* accept only OpenFlow messages with a previously negotiated version.
*/
....................................................
/* OFPT 1.0 (13): struct ofp_packet_out, uint8_t[]. */
OFPRAW_OFPT10_PACKET_OUT,
/* OFPT 1.1+ (13): struct ofp11_packet_out, uint8_t[]. */
OFPRAW_OFPT11_PACKET_OUT,
/* OFPT 1.0 (20): struct ofp_fp_update, struct ofp_action_header[]. */
OFPRAW_OFPT10_FP_UPDATE,
};
enum ofptype {
/* Immutable messages. */
OFPTYPE_HELLO, /* OFPRAW_OFPT_HELLO. */
OFPTYPE_ERROR, /* OFPRAW_OFPT_ERROR. */
......................................
/* Controller command messages. */
OFPTYPE_PACKET_OUT, /* OFPRAW_OFPT10_PACKET_OUT.
* OFPRAW_OFPT11_PACKET_OUT. */
OFPTYPE_FLOW_MOD, /* OFPRAW_OFPT10_FLOW_MOD.
* OFPRAW_OFPT11_FLOW_MOD.
* OFPRAW_NXT_FLOW_MOD. */
OFPTYPE_PORT_MOD, /* OFPRAW_OFPT10_PORT_MOD.
* OFPRAW_OFPT11_PORT_MOD. */
OFPTYPE_FP_UPDATE, /* OFPRAW_OFPT10_FP_UPDATE. */
};
3. 在lib/ofp-util.h 中加入对应的数据结构代表对应的通用类型结构,由于ovs用户空间在解码对应的消息的时候须要针对详细的类型运行对应的动作,所以也要更新 ofp-actions.h
// ofp-util.h
struct ofputil_fp_update {
struct ofpact *ofpacts; /* Actions. */
size_t ofpacts_len; /* Size of ofpacts in bytes. */
};
// 对这个消息编解码辅助函数
enum ofperr ofputil_decode_fp_update(struct ofputil_fp_update *,
const struct ofp_header *,
struct ofpbuf *ofpacts);
struct ofpbuf *ofputil_encode_fp_update(const struct ofputil_fp_update *,
enum ofputil_protocol protocol);
// ofp-actions.h
struct ofpact_fp_update {
struct ofpact ofpact;
uint32_t vector; /* 自己定义*/
};
4. 在 ofproto/ofproto.c (3790)- handle_openflow_() 函数中加入处理该消息的分支,
static enum ofperr
3793 handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
3794 {
3795 const struct ofp_header *oh = msg->data;
3796 enum ofptype type;
3797 enum ofperr error;
3798
3799 error = ofptype_decode(&type, oh);
3800 if (error) {
3801 return error;
3802 }
3803
3804 switch (type) {
3805 /* OpenFlow requests. */
3806 case OFPTYPE_ECHO_REQUEST:
3807 return handle_echo_request(ofconn, oh);
3808
3809 case OFPTYPE_FEATURES_REQUEST:
3810 return handle_features_request(ofconn, oh);
3811
3812 case OFPTYPE_GET_CONFIG_REQUEST:
3813 return handle_get_config_request(ofconn, oh);
3814
3815 case OFPTYPE_SET_CONFIG:
3816 return handle_set_config(ofconn, oh);
3817
3818 case OFPTYPE_PACKET_OUT:
3819 return handle_packet_out(ofconn, oh);
3820 case OFPTYPE_FP_UPDATE:
3821 return handle_fp_update(ofconn, oh);
...............................................
}
处理函数自己依据须要来实现,这里只打印日志信息。
static enum ofperr
handle_fp_update(struct ofconn *ofconn, const struct ofp_header *oh)
{
//TODO
VLOG_INFO("=====I GOT FP FROM CONTROLLER ========");
return 0;
}
以上就是ovs上须要考虑的地方,细节处要注意。接下来是Floodlight上面通过构造一个该消息,而后当接收到packet in 后就将其发送到这个SW上。
5. 在org.openflow.protocol 包中添加我们的消息类,以及对应的方法。
public class OFFPUpdate extends OFMessage implements OFActionFactoryAware{
public static int MINIMUM_LENGTH = 16;
public static int BUFFER_ID_NONE = 0xffffffff;
protected OFActionFactory actionFactory;
protected int bufferId;
protected short inPort = 0x0000; // not used yet
protected short other;
protected List<OFAction> actions;
public OFFPUpdate(){
super();
this.type = OFType.FP_UPDATE;
this.length = U16.t(MINIMUM_LENGTH);
}
....................................
}
6.然后再OFType中标示这个新增的消息类。
public enum OFType {
HELLO (0, OFHello.class, new Instantiable<OFMessage>() {
@Override
public OFMessage instantiate() {
return new OFHello();
}}),
...........................................................
FP_UPDATE (20, OFFPUpdate.class, new Instantiable<OFMessage>() {
@Override
public OFMessage instantiate() {
return new OFFPUpdate();
}});
}
7. 在org.openflow.protocol.action中新增相应的action类,由于每次从SDN controller发送控制类消息时都会设置它的action list。
public class OFActionFPUpdate extends OFAction implements Cloneable {
public static int MINIMUM_LENGTH = 8;
protected int vector;
public OFActionFPUpdate() {
super.setType(OFActionType.FP_UPDATE);
super.setLength((short) MINIMUM_LENGTH);
}
public OFActionFPUpdate(int vector) {
super();
super.setType(OFActionType.FP_UPDATE);
super.setLength((short) MINIMUM_LENGTH);
this.vector = vector;
}
...................................
}
8. 最后写一个简单的module 来測试。这里的思路是当收到某个SW发来的packetin消息时,我们就给这个交换机下发一个FPUpdate的消息。主要代码:
OFFPUpdate fu =
(OFFPUpdate) floodlightProvider.getOFMessageFactory()
.getMessage(OFType.FP_UPDATE);
OFActionFPUpdate action = new OFActionFPUpdate();
action.setVector(0xffffffff); // just for testing
List<OFAction> actions = new ArrayList<OFAction>();
actions.add(action);
fu.setBufferId(OFFPUpdate.BUFFER_ID_NONE)
.setInPort((short)0)
.setActions(actions)
.setLengthU(OFFPUpdate.MINIMUM_LENGTH+OFActionFPUpdate.MINIMUM_LENGTH);
try {
sw.write(fu, cntx);
} catch (IOException e) {
logger.error("Failure writing fp update", e);
}
通过简单的測试,整个流程是正确的。
转载请注明出处:点击打开链接
对openflow 1.0协议的扩展的更多相关文章
- 深入理解OAuth2.0协议
1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...
- 帮你深入理解OAuth2.0协议
1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...
- OpenID Connect:OAuth 2.0协议之上的简单身份层
OpenID Connect是什么?OpenID Connect(目前版本是1.0)是OAuth 2.0协议(可参考本人此篇:OAuth 2.0 / RCF6749 协议解读)之上的简单身份层,用 A ...
- (转)帮你深入理解OAuth2.0协议
1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...
- 问题:OAuth2.0;结果:帮你深入理解OAuth2.0协议
1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题. 豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒 ...
- 对OAuth2.0协议的理解和测试demo
1. 什么是OAuth OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容. OAuth ...
- 硕盟 TYPE C转HDMI+VGA+USB3.0+PD3.0四口扩展坞
硕盟SM-T54是一款USB-C 四合一多功能扩展坞,支持四口同时使用,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显示器.电视机或其他显示设备.产品可以接入硬盘. ...
- USB2.0协议笔记
1.概述 USB(Universal Serial Bus)具有传输速率快,可热插拔等显著特点,应用已经十分广泛,目前的相当多的设备已经支持最新的USB3.0协议.理论上USB1.1的传输速度 ...
- Swift - 2 (?和!、结构体、类、协议、扩展、闭包)
1> 可选类型(?)和强制解包(!) 在swift中,可选类型(?) 其根源是一个 枚举型,里面有 None 和 Some 两种类型.其实所谓的 nil 就是 Optional.None , 非 ...
随机推荐
- Java枚举类型理解
Enum格式理解 Enum的格式可以看做跟class关键字一样 class的定义格式如下: public class abc{ } enum的定义格式如下: Public enum abc { } 引 ...
- 实现textarea限制输入字数
实现textarea限制输入字数(包含中文只能输入10个,全ASCII码能够输入20个) textarea称文本域,又称文本区,即有滚动条的多行文本输入控件,在网页的提交表单中经常用到.与单行文本框t ...
- Configuration ReportNG with TestNG
下载 Reporter.jar,velocity-dep-1.4.jar 和 Guice.jar: 配置项目属性:Properties ->TestNG ->Disable Default ...
- 理解O/R Mapping
本文的目的是以最精炼的语言,理解什么是O/R Mapping,为什么要O/R Mapping,和如何进行O/R Mapping. 什么是O/R Mapping? 广义上,ORM指的是面向对象的对象模型 ...
- sql server2008附加数据库5120错误
解决方法: 附加数据库时,显示错误,错误信息为 一种解决方法为,设置mdf文件所在文件夹的权限(有些资料说只设置mdf文件的权限就好,但我试了不管用),在文件夹上右击——属性——安全,如图所示: 选择 ...
- 无法为数据库 XXX 中的对象XXX 分配空间,因为 'PRIMARY' 文件组已满。请删除不需要的文件、删除文件组中的对象、将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘空间。
无法为数据库 XXX 中的对象XXX 分配空间,因为 'PRIMARY' 文件组已满.请删除不需要的文件.删除文件组中的对象.将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘 ...
- JS 单击复制,复制后变为已复制
这段代码是在新浪网站上找到的.先放出CSS代码: .focus a.arrow,.card_con4 li i,.cm1_menu_wrap a.cm1_menu_box,.cm1_img span, ...
- python模块之json序列化
31.序列化: 1.json实现序列化,json.dumps()和json.loads(). >>> s1 = {'k1':'v1','k2':'v2' ...
- 大脑皮层是如何工作的 《人工智能的未来》(<On intelligence>)读书笔记
PS:今年寒假的读书笔记,挖下的坑已无力再填...不过有关智能和人工智能的书还是要继续读的~ 正文: 我觉得书名翻译不是很确切,全书讨论的核心应该更是在“真”智能:讨论对人脑智能的理解,可以怎样帮助我 ...
- Java中String、StringBuffer、StringBuilder和toString的介绍
作为一个刚接触java的小白,觉得字符串是个比较大的知识点,所以我把自己整理的一点笔记写成随笔,与园友一起分享,也请园友多多指出意见. 一.String类 1.字符串长度——length() Stri ...