前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ODL源码分析之OpenFlowjava框架分析及hello消息流程

ODL源码分析之OpenFlowjava框架分析及hello消息流程

作者头像
SDNLAB
发布2018-04-02 16:13:13
1.1K0
发布2018-04-02 16:13:13
举报
文章被收录于专栏:SDNLABSDNLAB

基于ODL开发已经有一段时间了,对于一个全新的平台,总是喜欢每隔一段时间就总结一番,本篇算是第一篇吧。下面会介绍以下内容:

1.openflow服务注册

2.netty服务创建

3.序列化、反序列化工作原理

4.从hello到of-session

一、前提

Openflowjava是基于netty进行的开发,在阅读Openflowjava的源码的时候需要简单了解一下netty原理。 Openflowjava是一个独立的线程,功能入口函数是SwitchConnectionProviderImpl.java中startup函数。因此以类SwitchConnectionProviderImpl为起点进行展开分析。

二、Openflow服务注册

openflowjava使用了多种设计模式,例如生产者-消费者、工厂模式等。通过类名SwitchConnectionProviderImpl便知,连接管理服务使用的生产者-消费者模式(openflowjava是生成者,openflowplugin是消费者)。我们先看一下构造函数:

通过成员变量名称知道,序列化和反序列化采用工厂模式,由于openflow消息很多,因此采用工厂模式即可针对不同的消息,实例化不同的对象,以达到统一处理。下面是消息注册的整体组织架构图:

由此结构图可知,序列化和反序列化工厂注册消息结构类似,里面的消息类型基本是对应的,如:hellorequest和helloreply,barrierrequest和barrierreply等。

上面这个结构图信息来自serializerRegistry.init()和deserializerRegistry.init();方法,在进行展开说明。这里想说一下,大多数都基于odl进行二次开发,因此很多时候需要扩展openflow消息,通过上面结构图,如果扩展openflow消息,则需要在openflow message type增加对应代码,如果扩展flowmod则需要在match entry增加对应代码。

通过上图我们能做到,当我们扩展openflow协议的时候,在哪里增加代码即可,内部代码实现需要我们自己去深入分析。 三、 netty服务创建

上面已经分析过,startup是openflowjava入口函数,此函数比较简单,如下所示:

方法createAndConfigureServer主要流程图框架,如下图所示:

我们在来看一下代码,这部分需要有一定的netty框架的基础知识:

上面这些内容,大部分都是基于netty接口实现的,本人也只是了解一点netty,这不能做深入分析。我们接下来看一下上面提到的run方法,其实run方法很简单,里面只是调用了set方法:

这个地方的channelInitializer是主要作用是注册业务处理,即当接收到一个网络数据包时应该如何对其进行解析。在查看类TcpChannelInitializer的具体实现时候主要看方法initChannel,这个方法是一个接口,主要用于netty框架调用。先简单介绍一下netty处理报文机制:

Netty中的所有handler都实现自ChannelHandler接口,按照输入输出方向来划分,可分为ChannelInboundHandler、ChannelOutboundHandler两大类。

ChannelInboundHandler对从客户端发往服务器的报文进行处理,一般用来执行解码、读取客户端数据、进行业务处理等;

ChannelOutboundHandler对从服务器发往客户端的报文进行处理,一般用来进行编码、发送报文到客户端。

inbound 的处理顺序是与 add 顺序一致的, 而 outbound 的处理顺序是跟 add 顺序相反的。

有两点需要特别说明:

1)inbound格式的数据流处理完成后不会进入outbound处理流程。也就是说一个流要么进入inbound要进入outbound。

2)进入流水线之后,上一个处理流程的输出结果,可能会作为下一个处理流程的输入。注意是可能而不是必须。

我们来看一下代码:

假如控制器收到交换机的一个消息,那么会经过OF_FRAME_DECODER、OF_VERSION_DETECTOR、OF_DECODER处理。其中在OF_VERSION_DETECTOR确定openflow版本号(1.0还是1.3等),OF_DECODER是针对某个特定消息处理,如packet-in消息。

经过这个函数里之后,仅仅代表tcp建立成功,openflow会话还未建立。即没有处理hello消息,下面我们会分析hello处理流程。

四、序列化、反序列化工作原理

反序列化类是OFDecoder,这个只有三个方法,其中最重要的方法是decode。该方法是由上层调用,后面会在进行分析的,这里先看一下decode代码:

通过方法deserializationFactory.deserialize,此方法实际是根据版本号及openflowtype生成key在map中查找,实现如下:

假如此消息是hello消息且openflow协议版本号1.3,则具体实例为HelloMessageFactory,那么反序列化方法则为:

所以上面decode方法中dataobject实际指向是HelloMessageBuilder 五、从hello消息到of-Session

从hello反序列化到of-session(openflowplugin)层次比较深入,hello返序列化方法处理结束后仅仅代表数据包处理完成,但是业务层还未处理,即还需要创建session。方法处理完会回到netty的方法:MessageToMessageDecoder.channelRead,通过下图展示出从netty业务层:

业务层中有一个类是DelegatingInboundHandler,这个在注册netty流水线时已经提到了。我们直接看consume方法,这个地方是所有数据包处理入口。代码如下:

由上面代码可知,当时hello消息则会进入onHelloMessage,进入业务逻辑处理。下面这张图显示出,业务处理流程:

这个流程图调用关系很深,需要一点一点阅读代码,这里主要介绍几个关键方法,不一一介绍:

总结一下:

1、从openflowjava到openflowplugin流程比较繁琐,需要耐心阅读代码。

2、代码中有很多设计模式,需要了解设计模式后在阅读代码时候才能做到“知其然而知其所以然”

3、openflowjava底层是用netty作为连接管理层,因此需要简单了解netty。

4、有生以来第一次写java相关文章,很多逻辑可能存在"断篇",如有不合适之处,请批评指出。

5、接下来会介绍flowmod下发流程。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SDNLAB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档