OpenDaylight开发学习笔记基础篇

一 、摘要

本文主要针对 Openflowjava 部分进行实例简述,初学者需要对 java 了解一些,总结一些我自己的学习收获,不足之处请指正。

Openflowjava工程作为 Opendaylight 南向接口的协议栈存在,与openflowplugin 工程及外部的 netty.io 网络库紧密联系。其主要作用是接受南向接口上报的消息、解码、将其交给 Openflowplugin以便进一步上报以及接收Openflowplugin传达的发送消息的指令并将其编码为字节流从南向接口中发出。结构上与功能相关的是Openflow-protocol-api及Openflow-protocol-impl两个文件夹下的代码。 前者中用一系列yang文件定义了控制器支持的Openflow消息结构及对应的收、发行为,后者包含了消息的解码、编码及上报、下发的功能逻辑。

netty.io网络库在Opendaylight中负责处理控制器与switch间的TCP连接。控制器接收上报的Openflow消息时,消息的二进制字节流会被装入netty的Bytebuf类对象中传递给Openflowjava来提供解码,发送消息时,消息相关的数据在编码序列化后被封装进Bytebuf类中交给netty完成发送。Openflowplugin作为opendaylight处理openflow消息的外挂组件进一步负责解码后消息的分类、处理、上传以及发送消息时控制器指令数据的分发、消息体数据的组织与打包。Openflowplugin控制着openflow消息收发的流程和逻辑,openflowjava作为其末端动作的执行者存在。

二 、Openflow-protocol-api部分开发

openflow-protocol-api 文 件 夹 下 的 代 码 主 要 是 openflow-protocol-api/src/main/yang 路径下的一系列 yang 文件,yang 是一种表示结构与属性的语言,同时也是一个 RFC 标准(RFC6020) 。Opendaylight 使用这种语言来定义其所支持的 openflow 消息结构以及消息的收发动作。在项目编译阶段,maven 会调用 opendaylight 的 yangtools 工具根据 yang 文件生成一系列 java 文件,包括各openflow 消息的容器类、 容器类的构造器以及侦听并接收这些容器类的接口。 通过 yang 文件,我们可以简单清晰地定义我们需要的消息类型以及其上传/下发管道。

在上述路径下最为重要的是openflow-protocol.yang及openflow-types.yang两个文件,前者定义了 openflow 消息和动作,后者包含了自定义、非 yang 语言内置的特殊数据类型。此目录下我们主要进行 yang 文件的改写,将一些协议的字段写成 yang 的形式,主要进行 openflow-protocol.yang 与 openflow-types.yang 两个 model 中的协议添加。

在 openflow-protocol.yang 文件中,grouping 语句用于定义一个数据结构块,uses 语句可将其他 grouping 结构块复用进当前结构块。通过这种方法可定义对应于所有 openflow 消息的数据结构块。但这些结构快并非对 openflow 消息中所有字段的映射。如果这是一个从南向接口接受的消息,则结构快中只需要包含希望从消息获取并进一步上报的字段。如果是发送的消息,其结构快中只需要包含那些来自于控制器指令的数据。而 length、padding 等字段则不需要包括。也就是说,yang 文件中消息的定义是对实际的openflow 消息中有用数据的一种抽象。下面是 yang 文件中对 flow-stats 消息的数据结构块定义。

在定义了消息结构后,还需要在同一 yang 文件内定义消息的行为。相关的语句是 notification 和 rpc。notification 用于定义控制器被动等待收取的消息的收取行为。rpc 用于定义控制器主动发送的消息的发送行为以及可能的switch 应答消息的收取行为。如使用 notification 定义的 hello 消息的收取行为是:

其中 uses hello 是复用了之前定义的 hello 消息结构块(hello 命名的grouping) 。而使用 rpc 定义的有应答的 echo 消息的发送和收取行为是:

其中 input 语句块是发送的定义,output 语句块是收取的定义,uses 语句后的是之前定义的对应消息的结构块。利用上述的 yang 语法我们就可以定义各个 openflow 消息的结构和行为了。在 openflow-protocol-api 目录或 openflowjava 根目录下用 maven 完成项目编译后在 openflow-protocol-api/target/generated-sources/sal 路径下可以找到 yang 文件生成的消息结构相关的 java 文件。他们将会在编解码中被用到。Yang 和 java 之间的对应生成关系详见 opendaylight 的如下wiki页面。

三 、 Openflow- - protocol- - impl 部分

该文件夹下的开发主要针对消息的编解码模块以及上报/下发逻辑。先讲解码模块及逻辑流程。解码模块位于路径Openflow protocolimpl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization

TypeToClassMapInitializer.java 和 MessageDeserializerInitializer.java两个文件。它们初始化两张表,前者包含了 openflow 消息 type 值到消息类型的映射关系, 后者包含了消息 type 值、 消息类型和对应的解码模块间的映射关系。

根据这两张表,可以将 netty 传递来的包含了 openflow 消息二进制字节流的Bytebuf 对象传递给对应消息类型的解码模块。如果对 opendaylight 的消息有增删修改的话, 需要相应地调整这两张表, 同事 import 语句也需要做相应调整。解码模块位于路径openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories下,每一个java文件对应一种消息。文件中的java类继承 OFDeserializer和DeserializerRegistryInjector两个类,解码过程由其中的deserialize方法实现。这个方法接受 netty 传来的一个Bytebuf类实例rawmessage作为参数,在内部使用 yang 文件生成的该类型消息的的构造器及消息子结构的构造器(xxbuilder)以及 Bytebuf 类的方法进行解码。具体来说,使用 Bytebuf 的一系列 read 方法线性地将 rawmessage 中存储的二进制字节流中的各消息字段读出来,然后使用消息构造器或消息子结构构造器的 set 函数写入到消息构造器的各实例域中。每调用一次 rawmessage 的 read 方法,rawmessage 中指示读取位置的一个游标就会向后移动相应位数,以便下次调用时读取下一个字段。读取和写入的顺序按照消息中字段的顺序。 如此将一条消息中所有有用的字段都读取并赋给消息的构造器(xxbuilder) ,最终构造器使用自己的 build 方法返回作为解码结果的类实例。这个类的定义同样是由 yang 文件编译生成的。Hello 消息的示例代码如下:

解码的结果——一个类实例将被传递给 connectionadapter 模块, 该模块的实现位于

openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java 文件中, 其中一系列以 Future<RpcResult<>>为返回值的函数是 yang 中使用 rpc 定义的消息动作的收发实现,而 consume 方法是 notification 定义的消息动作的实现。先看 consume 方法,解码的结果——一个类实例作为参数 message 传递进来,在方法内部使用一系列 if 语句判断该 message 属于何种消息的类, 一旦匹配则传递给 messageListener 类中相应的on方法(这些 on 方法是根据 yang 文件中的notification语句生成的),之后message 就被传递到 openflowplugin 中去了。示例如下:

编码模块位于路径openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization 下,其中的MessageFactoryInitializer.java 用于初始化一张表,表示将要发送的消息类型与其编码模块间的映射关系。Openflowjava 得到openflowplugin 传递来的消息类实例调用 connectionadapterimpl 中的那些以Future<RpcResult<>>为返回值的函数并通过这张表找到需要的编码模块。实际的编码工作在路径openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories 下的 java 文件中展开。这些类继承 OFSerializer<>类,其中的 serialize 方法以 openflowplugin 传递来的 xxinput 类实例 message 和Bytebuf 类实例 outBuffer 为参数。将 message 中的实例域提取出来传递给

outBuffer,调用 outBuffer 的一系列 write 方法将其以二进制字节流形式写入outBuffer 中,写入的顺序按照 openflow 消息的定义,其中也可能包括消息子结构的编码,类似于解码中的子结构解码。除了 message 中包含的字段外,还需要根据情况填写 length、 padding 等字段。填写完毕后 outBuffer 由 netty 完成对外发送,编码的流程就此结束。至此 openflowjava 工程中的工作结束。

四 、 总结

以上是关于 openflowjava 部分的开发文档简述, 具体的消息类型或协议可以自行进行添加和修改,本人知识水平有限,不足之处还请谅解。

本篇文章由OpenDaylight群(194240432)@北邮-Kobe提供,欢迎共同探讨。

时间: 2024-10-12 20:38:29

OpenDaylight开发学习笔记基础篇的相关文章

iOS开发学习笔记:基础篇

iOS开发需要一台Mac电脑.Xcode以及iOS SDK.因为苹果设备都具有自己封闭的环境,所以iOS程序的开发必须在Mac设备上完成(当然,黑苹果应该也是可以的,但就需要花很多的精力去折腾基础环境),Xcode是一个集成开发环境,包括了编辑器.调试.模拟器等等一系列方便开发和部署的工具,iOS SDK则是开发应用所必需,不同的SDK分别对应不同的iOS版本或设备,通常我们需要下载多个iOS SDK以确保我们开发的程序能够在不同版本的iOS上正常运行. 创建新工程 Xcode提供了很多种工程模

渗透学习笔记--基础篇--sql注入(字符型)

环境:dvwa1.7数据库:mysql前置知识:sql语句(Click me)      在进行sql注入前,我们先熟悉熟悉select语句.一.打开我们的sql终端 二.进入之后可以看到有mysql>我们输入sql语句,即可返回我们想要的结果,注意分号哟!我们使用的dvwa,在我们前几章设置的时候,会在数据库中生成一个dvwa的database:这里我们使用它来进行我们的select 语句:(1)使用dvwa数据库use dvwa;(2)在users表里查询用户名为'admin'的所有信息se

Python学习笔记基础篇——总览

Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列表.字典.主文件判断.对象 Python学习笔记——基础篇1[第三周]——set集合 Python学习笔记——基础篇2[第三周]——计数器.有序字典.元组.单(双)向队列.深浅拷贝.函数.装饰器 Python学习笔记——基础篇[第四周]——迭代器&生成器.装饰器.递归.算法.正则表达式 Python

Python学习笔记——基础篇【第六周】——面向对象

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 面向对象编程(Object-Oriented Programming )介绍 对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,大家虽然都按老师讲的都知道OOP的三大特性是继承.封装.多态,并且大家也 都知道了如何定义类.方法等面向对象的常用语法,但是一到真正写程序的时候,还是很多人喜欢用函数式编程来写代码,特别是初学者,很容易陷入一

Python学习笔记——基础篇【第四周】

本节大纲 1.迭代器&生成器 2.装饰器 a.基本装饰器 b.多参数装饰器 3.递归 4.算法基础:二分查找.二维数组转换 5.正则表达式 6.常用模块学习 7.作业:计算器开发 a.实现加减成熟及括号优先级解析 b.用户输入1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

Python学习笔记——基础篇【第一周】(未完待续)

学习Python目的: 1.学完之后,可以做开发运维监控.自动化软件.聊天软件.BBS.博客和网站. 2.投资自己,结识更多的朋友,变更更优秀的人 Python第一周笔记 Python语言介绍 python创始人Guido,荷兰人,Python源自他所挚爱的电视剧Monty Python's Flying Circus.Python编译器使用C语言实现,能够调用C语言库文件.1991年初,Python发布了第一个公开发行版. Python版本: Python1.0   1994年 python2

thymeleaf 学习笔记-基础篇(中文教程)

转自: http://www.cnblogs.com/vinphy/p/4674247.html (一)Thymeleaf 是个什么? 简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果.这是由于它支持 html 原型,然后在 h

IOS 开发学习笔记-基础 UI(10)九宫格布局,块动画,字典转模型,Xib使用

大概如下图示:九个应用图标的样子 功能分析 (1)以九宫格的形式展示应用信息 (2)点击下载按钮后,做出相应的操作 步骤分析 (1)加载应用信息 (2)根据应用的个数创建对应的view (3)监听下载按钮点击 思路整理 要在支持文件夹里,放入 plist 文件,且拖拽素材到 supporting files,注意勾选的项目的区别: 大多数情况,往项目中拖拽素材时,通常选择 Destination, Folders:选择第一项:创建组,这样 xcode 导航显式的是黄色文件夹,要知道,Xcode中

渗透学习笔记--基础篇--sql注入(数字型)

环境:dvwa 1.7数据库:mysql dvwa的安全等级:medium 一.分析和查找注入点(1)知识点回顾如果上一篇有好好读过的同学应该知道,我们上一篇遇到的字符型注入.也即是通过Get或者Post方式传进去的数据被单引号或者双引号包裹住.如果我们想要注入自己的payload(有效载荷)的话,则我们必须先闭合前面的单引号或者双引号,否则我们的数据始终会被当做成字符串来处理. 这种类型的注入点称为字符型注入点. (2)这次我们的把防御等级提升了一个层次,来逐步加强我们手工注入的能力以及开更多