(八)ODL Openflowplugin Switch Rpc封装及流表下发源码分析

作者简介:陈卓文,国内某游戏公司私有云团队开发者,主要从事SDN/NFV开发。

前面一系列文章,我们深入探讨了:“OFP启动”、“Switch从上线到下线在OFP的整个生命周期”。本文,我们展开可能是开发者接触最多的问题:如何下发流表,及其在OFP中是如何实现;OFP是如何封装对底层Switch的操作;

附:
第一篇:(一)ODL OpenflowPlugin启动流程源码分析
第二篇:(二)ODL Openflowplugin Switch连上控制器Handshake过程源码分析
第三篇:(三)ODL Openflowplugin Switch生命周期对象ContextChain创建源码分析
第四篇:(四)ODL Openflowplugin Master选举及Context服务实例化源码分析
第五篇:(五)ODL Openflowplugin Mastership及ReconciliationFramework源码分析
第六篇:(六)ODL Openflowplugin 控制器成为SLAVE过程源码分析
第七篇:(七)ODL Openflowplugin Switch断开控制器下线源码分析

OFP对底层Switch的封装

Openflowplugin将对底层Switch的操作都定义为RPC(YANG),在openflowplugin/model目录下存储定义的RPC。比如,在前文提及的Master/Slave选举,其最终都会到set-role rpc(sal-role.yang)向Switch发出本地是其Master/Slave节点。又如,在sal-echo.yang中定义了OFP与Switch之间发现echo消息动作。而在OFP中对这些RPC都有实现,并通过此方式对北向应用提供服务。

对底层Switch下发流表的RPC在sal-flow.yang中定义,其中定义了add-flow、remove-flow、update-flow三个RPC。而sal-flow.yang的RPC实现在SalFlowServiceImpl中(org.opendaylight.openflowplugin.impl.services.sal.)。下面我们具体展开下发流表这一个服务SalFlowService,希望读者可以举一反三,在需要对Switch进行其他操作时参考本文。

SalFlowService流服务

什么是SalFlowService

sal-flow.yang中定义的是对底层switch修改流表的rpc,以add-flow为例:

在ODL底层已经实现了上面的RPC接口,在SalFlowServiceImpl对象中实现了sal-flow.yang中定义的RPC。SalFlowServiceImpl实现了sal-flow.yang中的RPC,比如add-flow

那么在OFP底层是如何将实例化SalFlowServiceImpl并注册到RPC实现(RpcProviderRegistry)的呢?北向应用是如何调用SalFlowServiceImpl呢?

注册SalFlowService

回顾前几篇笔记,当ContextChainImpl对象作为singleton service选举,在某个节点称为leader/master后,就会调用各个context的instantiateServiceInstance方法。其中包括RpcContextImpl.instantiateServiceInstance方法,在RpcContext的实例化服务实例的过程中,会注册openflowplugin/model中定义的RPC的实现,其中就包括SalFlowServiceImpl。

实例化服务过程中,会初始化SalFlowServiceImpl并调用RpcContextImpl.registerRpcServiceImplementation注册为Routed RPC,所有的RPC实现都是以同样的方式注册为Routed Rpc。

RpcContextImpl.registerRpcServiceImplementation方法会将SalFlowServiceImpl注册为Routed Rpc:

那么什么是Routed Rpc,为什么将SalFlowServiceImpl注册为Routed Rpc,我们下面展开!

怎么使用SalFlowServiceImpl

在解释什么是Routed Rpc,为什么将SalFlowServiceImpl注册为Routed Rpc之前,我们先来认识怎么使用SalFlowServiceImpl。然后再看SalFlowServiceImpl是怎么和Router Rpc发生关系。

在北向应用中只需要调用SalFlowServiceImpl提供的方法即可完成添加流、删除流、更新流的操作,因为封装了这些RPC。

北向应用使用SalFlowServiceImpl步骤如下:
(1)在blueprint中引用SalFlowService

注解:
odl:rpc-service什么意思?是odl对blueprint的扩展,实现直接从OSGI在获取此RPC的implementation。参考

(2)在blueprint中实例化对象,可直接传入上述引用的salFlowService rpc-service,并在类中使用。

比如blueprint中实例化对象时,传入参数为salFlowService。

(3)最终在代码中调用,首先build AddFlowInput对象(RPC定义),然后直接调用salFlowService.addFlow方法。

Routed Rpc

什么是Routed Rpc

不是所有RPC都能被注册为Routed Rpc,需要在YANG中有额外定义。

我们回到RPC的定义,以此add-flow为例:

其中uses node-flow语句中的的node-flow grouping定义如下:

node-flow定义中的uses "inv:node-context-ref"语句,在opendaylight-inventory.yang中定义了node-context-ref如下,包含leaf节点node

add-flow Rpc的input有一个leaf为node,且其定义为:

回到注册Router Rpc的代码,我们关注registerPath方法,注册Routed Rpc:

(1)可以看到调用registerPath方法,传入参数了NodeContext.class。此正是上述YANG定义leaf node的属性ext:context-reference "node-context";NodeContext.class正是opendaylight-inventory.yangidentity node-context通过yangtools编译出来的类。
(2)调用registerPath方法,传入的第二个参数是nodeInstanceIdentifier代表的是当前这个rpcContext的switch(device)的nodeInstanceIdentifier

Routed Rpc的注册方法是需要注册Rpc定义的leaf node(包含属性ext:context-reference)

可参考:
1.https://ask.opendaylight.org/question/99/how-does-request-routing-works/
2.官方项目coretutorials

这样注册的Routed Rpc有什么特殊之处?
这样做,在调用add-flow rpc时,ODL底层RPC系统会根据input中的node(leaf)的值进行路由!关于将SalFlowServiceImpl注册为Routed Rpc有什么用?为什么不是普通的Local Rpc?在下面揭晓!

集群情况下的SalFlowServiceImpl(Cluster)

总结一下,每个Switch在某个节点选举Master后,会创建SalFlowServiceImpl对象,并将其注册为Routed Rpc,SalFlowServiceImpl对象就实现了更新流的RPC(sal-flow.yang),相当于每个Switch的SalFlowServiceImpl对象封装了对Switch流的操作。

然而在集群的环境下,每个Switch只会有一个SalFlowServiceImpl在其Master的控制节点上。那么能否在其他Slave节点上,对Switch进行修改流的操作?由于注册的是Routed Rpc,在集群任何节点上都可以对任意一个Switch操作流。比如在一个Switch的Slave控制节点上对此Switch添加流add-flow,也能下发流表成功。

在下发流表的代码实现中,我们需要像上述使用方式一样build 带switch的nodeInstanceIdentifer的AddFlowInput对象,然后调用SalFlowService接口,底层Rpc系统就根据nodeInstanceIdentifer值,找到nodeInstanceIdentifer关联的Rpc实现SalFlowServiceImpl(注意与SalFlowService的不同)。ODL底层Rpc系统会将此请求(add-flow)路由到Switch的Master控制节点的SalFlowServiceImpl中,然后对Switch下发流表(在Master节点下发流表)。

总结:

  • 1.每个Switch(Device)都会在它的Master的控制节点上,实例化SalFlowServiceImpl对象并注册到RPC系统,并注册为Routed Rpc,且Rpc的标识是Switch的nodeInstanceIdentifier
  • 2.所以上层应用在调用SalFlowService接口addFlow方法,底层RPC系统会根据传入的AddFlowInput input中的leaf node的值(nodeInstanceIdentifier)能够决定最终调用到的是哪个具体的SalFlowServiceImpl实现。

这就是routed rpc,注册时需要注册path(包括类型和值),调用时根据值路由到对应的rpc实现。也是为什么OFP是把所有RPC实现都注册为Router Rpc。

总结

本文,我们以SalFlowServiceImpl为例子,展开描述OFP在哪定义Switch操作的Rpc、应用中如何调用Rpc;并且我们深入了每个Switch是如何注册Routed Rpc、什么是Routed Rpc、Router Rpc有什么作用。

希望读者不仅知道SalFlowService怎么使用,还能够理解OFP中关于Switch的Rpc的细节,能够根据以上对SalFlowService的分析,我们同样可以按一样的方式使用其他服务,比如:SalGroupServiceImpl等等。


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。 本站中所有编译类文章仅用于学习和交流目的,编译工作遵照 CC 协议,如果有侵犯到您权益的地方,请及时联系我们。
  • 本文链接https://www.sdnlab.com/22486.html
分享到:
相关文章
条评论

登录后才可以评论

陈卓文 发表于18-10-15
0