ODL源码分析之flowmod下发流程

上一篇简单分析了openflowjava到openflowplugin(介绍的hello消息),本篇介绍如何从openflowplugin到openflowjava,即介绍flowmod消息。 一、ModelDrivenSwitchImpl核心类

在上篇中提到了类ModelDrivenSwitchImpl。可以说这个类是openflow交换机的抽象。几乎所有操作都需要调用类的方法,比如:addflow,addgroup等。简单看一下构造函数:

二、Flowmod下发流程

Flowmod分为三种,add、update、remove。这三种类型操作类似,这里以addflow为例进行分析。

代码addflow非常简单,但是有几点需要说明:

上面简单分析了一下最外层逻辑处理,归为两点:

1)创建返回类型UpdateOutput的task并提交到线程池。

2) 接收返回类型UpdateOutput的future并且转成对应的Output,如AddOutput、RemoveOutput。

下面开始flowmod下发流程分析,逻辑层次比较深入还是先放一张流程图:

由上图可知,flowmod下发流程层次很深,这里只分析一下几个方法:

1、toFlowModInput方法,该方法可以说是将业务数据转成标准flowmod消息入口。如果需要扩展flowmod消息,则需要从这个函数着手修改:

代码MatchReactor.getInstance().convert(…),最终会调用到MatchConvertorImpl.convert这个函数中,就有我们常见的协议字段,如:inport,ipv4等。这个函数主要是组建oxm。这些内容没有什么逻辑,只要按照标准协议填写即可,不再累赘阐述。

方法toInstructions,getActions也类似,按照标准协议填写即可。

以上内容主要想说明,当我们扩展flowmod消息的时候,能够知道在哪里修改即可。

2、方法MessageDispatchServiceImpl.flowMod

3、简单分析netty中write方法,此方法功能是将数据包发到网络中。

在说write方法之前,简单说一下netty背景知识吧。netty为了降低应用程开发帮我们做了很多东西,比如说常见的tcp粘包、丢包问题,最简编解码,异步IO等。应用程序基本不要关心这些底层内容,不像C/C++语言开发时,需要由应用程序自己处理粘包,丢包以及自己构造异步IO,这些内容如果处理不好,会带来很大问题。

然而关于编解码问题,netty只是做了最基本的序列化工作,比如说分割符,定长编解码等,对于咱们Openflow协议这种编解码,netty是没有提供的,而且也不应该由netty提供。

我们来看一下write方法:

针对上面的ctx.write(buf, promise);这行代码再多说两句,这个函数只是将消息放到netty队列中,择机发到网络中。那么择机发送是什么时候发送呢?一般有两个条件:

1、队列已满。

2、超时。

然而应用程序若想立即将数据包发送到网络中则需要调用方法writeAndFlush。在这里讨论这些内容,主要因为某些应用要求实时性比较高的时候,所以可以考虑这种方式。

三、再谈序列化OFEncoder.encode

在上一篇中,我们提到了序列化,这个在简单过一下吧。OFEncoder是序列化入口,所有序列化操作都需要调用该类的方法,或者是调用encode方法。

关于序列化工厂注册内容,请参考上一篇文章。

四、Session存储关系图

控制器所有操作都是建立在session基础之上的,换句话说就是建立在连接之上的,下图就是session相关组织结构图。

1.单例模式保存所有session对象

SessionManagerOFImpl是一个单例,保存当前有效session会话。从hello握手成功session一直存在,直到交换机与控制器断链后。

2.SessionListener有两个方法,onSessionAdded,onSessionRemoved。这两方法从便可知道用于管理添加、删除session对象。这两个方法主要是操作HashMap即ConcurrentHashMap<SwitchSessionKeyOF, SessionContext> sessionLot。这个hashmap中每一个元素都是一个有效的连接,也就是说有一个元素存在就对应着一个交换机。

3.Hashmap中键值value是SessionContext,这个上下文包含了一个ModelDrivenSwitchImpl,实则是ODL对交换机的抽象。也就是说ODL用类ModelDrivenSwitchImpl来表示一个交换机。抽象出来的ModelDrivenSwitchImpl进行再次包装,插入到SessionContext的notifaction队列当中。以便能够处理后续的notification消息。

4.在ModelDrivenSwitchImpl中有一个属性OFRpcTaskContext,这个属性是关联SessionContext以及Notification服务等。控制器给交换机发送的消息中大部分都是采用RPC形式,所以rpcTaskContext是至关重要的。

以上全部内容基本上(加上前一篇)就是ODL代码从上到下,从下到上,openflow消息处理流程。有些内容分析不到位,请各位网友多多批评指出,欢迎大家及时讨论。

原文发布于微信公众号 - SDNLAB(SDNLAB)

原文发表时间:2016-04-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

WCF服务端运行时架构体系详解[上篇]

WCF的服务端架构体系又可以成为服务寄宿端架构体系。我们知道,对于一个基于某种类型的服务进行寄宿只需要使用到一个唯一的对象,那就是ServiceHost。甚至在...

20690
来自专栏逆向技术

16汇编第十讲完结Call变为函数以及指令的最后讲解

16汇编完结Call变为函数以及指令的最后讲解 学了10天的16位汇编,这一讲就结束了,这里总结一下昨天的LOOP指令的缺陷,因为lOOP指令的缺陷,所以我们都...

193100
来自专栏Jacklin攻城狮

iOS,面试必看,最全梳理

目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了。今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送...

25920
来自专栏java 成神之路

并发编程基础知识点

36160
来自专栏IT杂记

Java Socket Timeout总结

1. Socket timeout     Java socket有如下两种timeout: 建立连接timeout,暂时就叫 connect timeout;...

87890
来自专栏无题

线程安全与锁优化——深入理解JVM阅读笔记

我根据我的理解把一些关键的要点整理了出来,并对其中一些内容作了删改。 参考地址:http://www.cnblogs.com/pacoson/p/5351355...

36750
来自专栏Java后端技术栈

Java多线程编程-(16)-无锁CAS操作以及Java中Atomic并发包的“18罗汉”

通过上面的学习,我们应该很清楚的知道了在多线程并发情况下如何保证数据的安全性和一致性的两种主要方法:一种是加锁,另一种是使用ThreadLocal。锁是一种以时...

9930
来自专栏微服务那些事儿

java多线程(一)快速认识线程

答:继承Thread类,实现Runnable接口,为了展示自己学识的渊博,还可能还会说实现Callable接口通过FutureTask包装器来创建Thread线...

16440
来自专栏Golang语言社区

Golang构建HTTP服务(一)--- net/http库源码笔记

实现一个最简单HTTP server需要多少代码?只需要一行,Python2的python -m SimpleHTTPServer,ruby的ruby -run...

63950
来自专栏coder修行路

Beego 框架学习(一)

 Beego官网本身已经整理的非常详细了,但是作为一个学习者,我还是决定自己好好整理一下,这样在后面使用的时候自己对每部分才能非常熟悉,即使忘记了,也可以迅速定...

58080

扫码关注云+社区

领取腾讯云代金券