前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Ryu的一些设计方法解读

Ryu的一些设计方法解读

作者头像
SDNLAB
发布2018-03-30 15:56:51
1.2K0
发布2018-03-30 15:56:51
举报
文章被收录于专栏:SDNLAB

作为一个业余研究Ryu的软件工程师,一直惊叹于Ryu设计的优雅与简洁。一年多坚持下来,也有自己的一些收获,写出来和大家分享一下。

我们的故事从@set_ev_cls这个被大量使用的装饰器开始。

装饰器的内容已经有小伙伴写到了,这里不再重复。我关心的重点在第一个参数ev_cls上,

比如simple_switch_13.py中@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)

EventOFPPacketIn,类究竟在哪定义,我在\ryu\controller\ofp_event文件中没有找到,甚至搜索完了整个ryu工程都没有搜到。与此类似的ofp_event.EventOFPPortStatus, ofp_event.EventOFPFlowRemoved,ofp_event.EventOFPDescStatsReply等等,他们这些类的定义也没有找到。

某个烈日炎炎的下午,不经意的我在\ryu\controller\ofp_event文件中发现了一点蛛丝马迹:

将ofp的msg名字加上“Event的前缀”,这个有点像。

喔,这个地方creat了一个类,好像就是ev_class(type的用法:创建类的类,元类,以name为类型,以EventOFPMsgBase为父类,并定义了初始化方法,并放到全局字典globals和_OFP_MSG_EVENTS),动态生成需要的类,小样,真有你的。

更进一步从模块名创建ev_class,明确标明了,有'cls_msg_type'属性的才有资格创建类。

终于看到调用的地方了,在同一个文件中的这段代码可不是定义函数,而是直接执行语句哦。其中get_ofp_modules就是获取ofp的版本文件的parser,然后根据这些文件创建对应了msg_ev_class.我们去ryu\ofproto\ofproto_v1_X_parser(X可以为0,1,2,3,你懂的)文件中确认一下。

看,还真是这样。连注释上都写得是一模一样的Example,其他诸如ofp_event.EventOFPPortStatus, ofp_event.EventOFPFlowRemoved,ofp_event.EventOFPDescStatsReply也能找到对应的地方。

这下终于真相大白,我们脑海中有了这样一幅画面,自动去搜索ofp不同版本的模块,找到有cls_msg_type属性的类,然后把它们的名字变换一下,生成对应的类。Ryu的优美与简洁,果然名不虚传。

还有我们的ofp_msg_to_ev,看它的定义是生成类的实例。在Datapath类的_recv_loop中,Ryu从数据流中解析出msg,然后根据msg生成上面msg_ev_class的实例,并通过ofp_brick发送给观察者。send_event_to_observers(ev, self.state)是通过SERVICE_BRICKS(服务实体链表,其实就是所有app的字典)来进行不同模块中的通信的。

在RyuApp的register_handler,register_observer可以看到,观察者和handler的注册都是通过类名。而RyuApp的get_handlers,get_observers方法传入得参数是实例。

这样我们就知道了@set_ev_cls如何用ofp的event类去修饰handler方法,以及如何由具体的报文,得到对应的实例,最后调用到具体的handler方法上。良好的命名规范还真有助于增加代码的可读性。

我们的李呈大神在《RYU源码解读》(http://www.sdnlab.com/6395.html)已经把ryu的启动流程给我们大致讲解了。

不过我本人觉得还不过瘾,有几点在这里补充一下。

1.hanglder.reuster_service是在import的时候被执行的,一般都在app文件的最开头,而不是在使用@set_ev_cls装饰器的时候。

2._Event的使用在\ryu\topology\switches中有如下代码

而在\ryu\base\app_manager文件中有

从这些线索中我们可以看到_EVENTS其实就是上文中动态生成的msg_ev_class的补充,因为不属于OFP模块的内容,自然需要other模块提供。当然Event类的来源还通过import得到,比如\ryu\lib\lacplib.py就定义了大量的Event类,simple_switch_lacp_13.py就是通过from ryu.lib import lacplib来使用的。

3.@set_ev_cls还有个兄弟@set_ev_handler,在\ryu\app\gre_tunnel和\ryu\controller\ofp_handler有使用。两者的区别在set_ev_handler收到对应的事件后自己处理就行了,不需要再通知给observer,而set_ev_cls先通知给observer,再自己处理。原因如下

读完了这些,不得不感叹,RYU实在是太美妙了。它的内部机制的实现,很值得我们学习和借鉴。

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

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

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

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

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