最近看了Opendaylight的源碼辣辫,仔細(xì)研讀openflow_plugin,SAL桥氏,上層服務(wù)(Arphandler)档泽。以下分析是基于Opendaylight的Hydrogen版本。不過講的這些插件應(yīng)該可以在Helium適用竣付,畢竟各個成熟的bundle不會大幅度變化。
Opendaylight使用OSGi框架涝焙,這個框架的巨大好處是可以熱插拔各個組件卑笨,即不用關(guān)閉應(yīng)用就能為ODL安裝各個應(yīng)用。其結(jié)構(gòu)如下:
ODL控制器有多個小項目仑撞,每個小項目是一個bundle(組件)赤兴,組件之間可以為其他組件提供服務(wù)妖滔。openflow1.0插件屬于其南向各種plugin的一個。
首先Openflow插件的結(jié)構(gòu)如下:
這個插件的位置位于controller/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/,它里面有兩個文件夾桶良,core和internal座舍。
core是openflow1.0的核心代碼,里面有一些重要java文件講一下陨帆,
■IController.java定義了openflow控制器與交換機(jī)交互的抽象接口曲秉,無具體實現(xiàn)代碼
■Controller.java控制器核心操作
■ControllerIO.java主要是處理交換機(jī)的連接請求,一個java的線程,每五秒檢測一次
internal是openflow1.0插件上層的服務(wù)
■DataPacketMuxDemux.java
下面分析一下幾個重要的文件:
ControllerIO.java疲牵,這是一個java的線程承二,每五秒檢測一次,是否有新連接請求進(jìn)來纲爸,有則處理亥鸠。
它會調(diào)用Controller.java的handlerNewConnection,這里會給這一個新的交換機(jī)生成一個SwitchHandler识啦,它是一個線程负蚊,專門和交換機(jī)進(jìn)行通信。SwitchHandler的handleMessages()函數(shù)用來處理各類消息颓哮;SwitchHandler用MessageReadWriteService.java文件實現(xiàn)與交換機(jī)的Socket連接家妆,這也是為什么一個交換機(jī)對應(yīng)一個SwitchHandler。SwitchHandler就在SwitchHandler.java文件內(nèi)冕茅。
在Internal里的核心在Controller.java伤极,他的主要作用:
■處理交換機(jī)發(fā)來的event,保存一個event隊列
■控制器啟動一個線程處理Event隊列
■每種消息使用一個listener
處理Event的隊列線程也在Controller.java實現(xiàn)姨伤,Switch_message就是交換機(jī)發(fā)送來的openflow消息塑荒。Event隊列的Event定義在SwithEvent.java文件。
Event隊列的Event是從哪里來的呢姜挺?來自SwitchHandler.java,因為每個Switch有一個SwitchHandler的線程彼硫,SwitchHandler收到消息就封裝成Event后加入到Controller的Event隊列里炊豪。請仔細(xì)閱讀SwitchHandler.java的代碼,它里面會區(qū)分各個openflow的消息拧篮。
Controller對的Event的處理中词渤,假如是消息的Event,也就是MessageEvent,調(diào)用receive(ISwitch sw, OFMessage msg)串绩,這個函數(shù)在DataPacketMuxDemux.java實現(xiàn)缺虐。
這里大家一定很奇怪,為什么DataPacketMuxDemux.java能收到消息礁凡,我們需要明白高氮,opendaylight定義了很多接口慧妄,DataPacketMuxDemux.java里實現(xiàn)了接口IMessageListener,而Opendaylight為每個openflow消息都定義了一種IMessageListener剪芍,如果要監(jiān)聽這種消息塞淹,我們只需要設(shè)置addMessageListener(OFType,?this)函數(shù)里加上自己要監(jiān)聽的Openflow的消息類型,不信你看看DataPacketMuxDemux是否有這個函數(shù)罪裹,它因此可以收到Pack_in消息饱普。
這個函數(shù)處理中,調(diào)用receiveDataPacket状共,數(shù)據(jù)就會進(jìn)入SAL層套耕,SAL層收到openflow_plugin發(fā)出的Pack_in消息同樣是實現(xiàn)了一個接口IPluginOutDataPacketService,這個接口由SAL層的DataPacketService.java實現(xiàn)峡继,大家看了代碼肯定會發(fā)現(xiàn)它還實現(xiàn)了另一個接口IDataPacketService冯袍,這個接口是接收從SAL上層各個服務(wù)發(fā)送的數(shù)據(jù)包。所以SAL層起到了一個處理分發(fā)的作用鬓椭。在SAL層收到下層plugin發(fā)送到包后颠猴,會送入上層的各個服務(wù)
各個服務(wù)(如ArpHandler)會通過監(jiān)聽IListenDataPacket接口來收到從SAL層發(fā)來的數(shù)據(jù)。這里有個問題講明白小染,上層監(jiān)聽這個端口的可能有很多個服務(wù)翘瓮,那么每個監(jiān)聽此接口的服務(wù)都會收到SAL轉(zhuǎn)發(fā)的數(shù)據(jù)包備份。
下面是整個數(shù)據(jù)傳輸結(jié)構(gòu)圖:
SAL層中處理數(shù)據(jù)包的是DataPacketService裤翩,而處理流表操作FlowProgrammerService资盅。所以SAL的每個Service都可以看成是處理南北數(shù)據(jù)通路的一種服務(wù)。關(guān)鍵需要搞懂的是南北通路中的數(shù)據(jù)傳輸過程和機(jī)制踊赠。上面組件之間傳輸通過接口實現(xiàn)呵扛。
需要主要注意的是Openflow_plugin內(nèi)的Controller.java,ContrllerIO.java筐带,SwitchHandler.java今穿,MessageReadWriteService.java(這里是和Switch通信的Socket的實現(xiàn)),DataPacketServices.java這幾個文件伦籍,需要認(rèn)真閱讀蓝晒。
基本上ODL的代碼還算易懂。
作者簡介:
王鈺琪帖鸦,2013/07-至今?北京郵電大學(xué)網(wǎng)絡(luò)技術(shù)研究院?網(wǎng)絡(luò)與交換技術(shù)國家重點實驗室攻讀碩士研究生
點擊閱讀原文