

深入OpenFlowPlugin源码分析OpenFlow握手过程(二)
source link: https://www.tuicool.com/articles/uemmumI
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【编者的话】本文为OpenFlowPlugin(0.6.2)源码分析第二篇,也是OpenFlowPlugin为上层北向应用提供服务的关键逻辑的开篇!
回顾第一篇笔记,在Switch连上控制器Handshake完成后,会调用 ContextChainHolderImpl.deviceConnected
方法,会为Switch创建其对应的 ContextChain
对象则创建。
createContextChain(connectionContext);
先给出总结:在OpenFlowPlugin中,每个Switch都有唯一的 ContextChain
对象,管理其在OpenFlowPlugin的生命周期。
创建生命周期管理对象ContextChain
为连上的Switch创建 contextChain
对象,通过调用 ContextChainHolderImpl.createContextChain
方法。在创建ContextChain前,会先为Switch创建四个对象DeviceContext、RpcContext、StatisticsContext、RoleContext,四个对象封装了Switch的四种类型操作:Device基本信息、RPC请求、Statistics数据收集、Master/Slava角色调用。最后,将四个Context对象都传入ContextChain中管理。在下面会详细展开,每个步骤。
ContextChainHolderImpl.createContextChain
方法是Switch连上控制器Handshake完成后的核心调用,这个方法主要逻辑:
创建DeviceContext
创建deviceContext,且传入自身对象(ContextChainHolderImpl)引用:
final DeviceContext deviceContext = deviceManager.createContext(connectionContext); deviceContext.registerMastershipWatcher(this);
创建 deviceContext
处理:
- 设置
ConnectionAdapterImpl
对象中设置packetIn filter为true,目的是为了过滤后续过程中收到底层Switch的packetIn message- 注:可以看到在
ContextChainHolderImpl.createContextChain
方法后面会将packetIn filter恢复为false。
- 注:可以看到在
- 创建
OutboundQueueHandler
对象并传入对象引用到connectionAdapterImpl
和connectionContext
-
OutboundQueueHandler
对象用于Packet output先到Queue,再到ConnectionAdapterImpl
对象。另外一篇:《OpenFlowPlugin outbound机制》会展开,在此不深入。
-
- 创建
DeviceContextImpl
对象 - 创建
OpenflowProtocolListenerFullImpl
对象,并传入引用到connectionAdapterImpl
对象(setMessageListener
和setAlienMessageListener
),用于处理底层Switch传递给控制器的所有message。- 注意:在上两篇笔记中,当Switch连上控制器时调用
ConnectionManagerImpl.onSwitchConnected()
方法,会同样会传入一个MessageListener对象OpenflowProtocolListenerInitialImpl
,此对象仅能出来Hello message,在Handshake阶段使用。而此时Handshake已经结束,重新传入OpenflowProtocolListenerFullImpl
用于处理所有message。
- 注意:在上两篇笔记中,当Switch连上控制器时调用
创建RpcContext
创建RpcContext,且传入自身对象(ContextChainHolderImpl)引用:
final RpcContext rpcContext = rpcManager.createContext(deviceContext); rpcContext.registerMastershipWatcher(this);
创建rpcContext处理:
- 创建
RpcContextImpl
对象
创建StatisticsContext
创建StatisticsContext,且传入自身对象(ContextChainHolderImpl)引用:
final StatisticsContext statisticsContext = statisticsManager.createContext(deviceContext, ownershipChangeListener.isReconciliationFrameworkRegistered()); statisticsContext.registerMastershipWatcher(this);
创建StatisticsContext处理:
- 创建
MultipartWriterProvider
对象- 注意这里传入了deviceContext,是为了write到device的operational yang。
deviceContextImpl
中有写入device对应yang需要的TransactionChain
- 注意这里传入了deviceContext,是为了write到device的operational yang。
- 创建
StatisticsContextImpl
对象- 传入了
MultipartWriterProvider
对象,目的是StatisticsContextImpl
收集的数据可以写入device operational yang节点
- 传入了
创建RoleContext
创建RoleContext,且传入自身对象(ContextChainHolderImpl)引用:
final RoleContext roleContext = roleManager.createContext(deviceContext); roleContext.registerMastershipWatcher(this);
创建RoleContext处理:
- 创建
RoleContextImpl
对象; - 创建
SalRoleServiceImpl
对象,传入RoleContextImpl
。用于后续步骤,设置Switch的Master/Slave role。
创建ContextChain
在创建4个Context后,创建 ContextChainImpl
对象。然后向 ContextChainImpl
对象注册/加入各个对象:
- 给
ContextChainImpl
对象注册registerDeviceRemovedHandler,用于后续Switch下线过程清除Manger中各个Context的索引。 - 给
ContextChainImpl
对象添加Context(addContext
)。 - 最后将
ContextChainImpl
对象保存到ContextChainHolderImpl.contextChainMap
中,相当于一个索引。ContextChainHolderImpl
维护了各个Switch的ContextChain对象。
注意 addContext
是把传入的deviceContext/rpcContext/statisticsContext/roleContext封装到 GuardedContextImpl
对象。 GuardedContextImpl
对象仅做多一层封装,会记录具体Context的状态等。
@Override public <T extends OFPContext> void addContext(@Nonnull final T context) { contexts.add(new GuardedContextImpl(context)); }
最后,完成创建 ContextChainImpl
对象后,将设备从 connectingDevices
索引中删除。表示已经在控制器connected。
开始选举Master/Slave
上文基本展开了 ContextChainHolderImpl.createContextChain
方法详细讲解,唯独缺少最后一行代码,这也是最关键一行!调用ContextChain的registerServices方法:
contextChain.registerServices(singletonServiceProvider);
在展开这一行代码的逻辑之前,我们先回顾一下全文!可以看到,在Switch完成Handshake后,OpenFlowPlugin会为Switch创建ContextChain对象(包括各个Context)。考虑到多个控制器情况下,当Switch设置多个控制器(比如OVS:set-controller),那么哪个控制器能够对Switch操作,比如下发流表。因为在每个控制器,OpenFlowPlugin都会为Switch创建ContextChain对象。
OpenFlow协议,支持多个控制器,且控制器有角色有三类Master、Master、Equal。为了控制层高可用使用Master/Slave模式;为了控制器负载均衡使用equal模式。
在此,我们不讨论Equal模式,我们讨论Master/Slave模型。OpenFlowPlugin默认是以集群模型实现的,假设存在三个控制器节点,那么就会选举出一个节点作为某一个Switch的Master(不同Switch,Master不一定相同);如果OpenFlowPlugin作为单点控制器运行,那么它就是所有连上的Switch的Master。
假设在三节点的集群情况下,Switch连上所有控制节点,此时每个控制节点都有Switch的ContextChain对象,那么哪个节点是该Switch的Master?关键就是上面的这一行代码!由于篇幅问题,我们在下篇展开!
总结
在Switch完成Handshake后,OpenFlowPlugin会为Switch创建各个Context对象(Device/RPC/Statistics/Role),以及ContextChain对象。
Recommend
-
108
作者简介:陈卓文,国内某游戏公司私有云团队开发者,主要从事SDN/NFV开发,个人邮箱:[email protected] 本文为OpenflowPlugin源码分析第一篇,会有一系列文章深入openflowpl...
-
38
作者简介:隙中驹,开放网络拥护者及实践者,熟悉传统网络技术及行业解决方案,关注SDN/NFV等ICT融合技术。 email:[email protected] OpenFlow协议从2009年发布的v1.0到最近...
-
61
作者简介:陈卓文,国内某游戏公司私有云团队开发者,主要从事SDN/NFV开发。 1.MastershipChangeServiceManager是什么 2.MastershipChangeServiceM...
-
42
作者简介:陈卓文,国内某游戏公司私有云团队开发者,主要从事SDN/NFV开发。 1.成为SLAVE流程 1.1 创建slaveTask 1.2 超时成为SLAV...
-
53
前言 随着云计算的火热,SDN/NFV,OpenFlow等名词频繁出现。在网络上,有很多介绍名词概念等的博文,但本人深入云底层SDN/NFV网络开发过程中,很少能够找到足够深入的文章学习。因此在学习过程中总结了几篇文章,深入分析OpenD...
-
27
【编者的话】OpenFlow协议支持多个控制器,其工作模式是怎样的?在OFP中,控制器节点会选举Master,该Master节点为北向应用提供该交换机的服务。本文深入OpenFlowPlugin中的Master选举过程,以及北向应用怎么感知选举并处理。 Op...
-
12
TCP协议三次握手过程分析
-
13
SSL协议握手过程报文解析 2021-06-08 21:35:00 https://blog.csdn.net/tterminator/article/details/50675540 SSL建立握手连接...
-
10
详细说下 TCP 三次握手的过程?-吴师兄学编程 当前位置:吴师兄学编程 > 计算机网络 > 详细说下 TCP 三次握手的过程? ...
-
7
本文主要分析 TCP 协议的实现,但由于 TCP 协议比较复杂,所以分几篇文章进行分析,这篇主要介绍 TCP 协议建立连接时的三次握手过程。 TCP 协议应该是 TCP/IP 协议栈中最为复杂的一个协议(没有之一),TCP 协议的复杂性来源于其面向连接和保证可靠传输。
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK