POX控制器的分析(二)

       在上一篇具体讲述POX有哪些组件,以及各个组件的功能,这篇文章主要理解POX的启动以及组件是如何启动的,以及组件与事件的关系:


由上图知,of_01 主要是运行一个线程,该线程不断与交换机进行TCP连接, 当某交换机送来一个协议消息时,of_01会触发该消息 所对应的事件。openflow则与所有的物理交换机相连,而控制器可以通过openflow控制所有的交换机,任意交换机传上来的消息都会触发openflow的事件,在设计自己的组件时,如果不需要监听特定的交换机,监听openflow肯定没错。

事件组成:

  • source:给组件提供可被监听的事件,通过raise函数触发事件给监听它的组件;
  • sink:监听source的组件。

 启动pox.py:

Pox.py 里面大部分都是注释,真正只有以下几行代码:


调用pox.boot模块中的boot()函数。

这时就想了解boot函数的作用,下面是进入boot.py里查看的代码:



 

可以看出里面的内容包括:

第442~444行代码将pox和ext的两个文件夹的路径加入到了系统的path里;

还有启动了POX以及相关组件。

关键代码是第459行的_do_launch()函数启动了相关组件,其中_post_startup()由下图390~392行启动openflow.of_01,core.goUp则启动了core里面的登记Debug信息和事件机制。

在core.py的代码中,有core = POXCore()。代码中还有这个函数的定义class POXCore() (EventMixin)。可以看出,POXCore这个类是revent.py中class EventMixin的一个子类,是处理事件最高层的模块。另外,如果看后面的代码可以知道,POX的启动是由_do_Launch()函数完成的。

组件启动:

 组件启动函数:pox.boot.do_launch

这些代码完成了模块的加载+初始化工作,其中:

第135~155行代码创建component_order的列表,用于存放组件的名称。然后再逐个启动,初始化;

第157~164行代码通过创建组件的函数名,并定义了组件的加载顺序;

第166~169行代码使用_do_import()函数将相关组件模块引入;

第171行代码检查了类中是否存在相应的launch函数。其中sys.modules 是一个字典,它包含了从Python 开始运行起,被导入的所有模块。用sys.modules[name]可以获取name模块的引用。由于类的实例会有一个__dict__的特性字典,其中是该类的所有特性。

如:

第172行从特性中初始化函数实例;

第189行代码就是执行初始化函数的语句。

 
pox的过程如下: 



组件启动代码:

以l3_learning组件来举例:


我们观察到最后一行需要注册组件,这时就需要查看core.registerNew()这个函数:


可执行语句很少,基本上注释已经完全涵盖了这个函数的作用。主要是在pox注册一个新的线程,如果已存在名字则重载,返回新的实例。同时我们看到在这个函数里面使用到了register()函数,函数定义如下:


Register()实现了在初始化的时候,将相关组件加入到了pox.core.core之中。这时Core raise了一个ComponentRegistered事件,是以组件为参数注册事件。

注册阶段结束了?还没有,有一个问题还没有解决:组件的event_handler是如何与events绑定在一起的呢?

组件与事件的关系:(事件绑定)


上面可以看出:组件通过监听内核core来注册事件。

这时就需要listenTo()函数,经过查找在revent.py里面:


这时接着调用autoBindEvents()函数:


从注释中我们可以看出这个函数的作用:

无非就是讲handler端的sink和event的source连接起来,方式就是先在sink端将所有event的名字放在一个字典中,然后在sink中寻找带有“__handle__event”的函数,最后,如果两边有对应的event和handler,就建立连接。


其中又调用了addListener()函数,这个函数的功能最重要:



建立一个与eventType对应的handlers,将带有handler和eid等信息的entry添加到handlers队列中,priority决定这个handlers在处理时的优先级,若无特殊优先级,则按正常顺序放在队尾

下面还有一个问题:handler在哪?这个问题关系到事件如何被处理。其实,从autoBindEvent的函数定义可以看到,最后addListener函数的执行对象是source。也就是说,handler列表在发起事件的组件中可以看到。因而我们来看source类,即:


第83行代码中使用raiseEvent()函数,其中参数为组件注册。来看raiseEvent函数:


就这样事件就绑定完成了。

POX的过程图如下:


额外的一个小case:在POX中添加新模块,将新模块存入ext文件夹,可以通过参数,直接调用。如:

copy一个模块(forwarding.l2_learning.py)到ext文件夹中,改名为ext/my_component.py,执行新模块为:./pox.py my_component.

以上的学习是在网上看北邮赵伟明的blog,加上自己的理解总结的,看完后发现制定POX控制器团队的优秀,还有就是自己暂时分析到这里,当然还有好多代码也没有看,需要今后边学边看,自己还需要很长的道路需要走,需要更加努力,这样才能在SDN的学习有更多自己的成果。




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值