ONOS二次開發——Netconf命令下發


最近對onos進行了二次開發,主要實現了Juniper路由器的 driver開發。在Driver中利用NETCONF協議讀取並修改路由器配置、生成NETCONF命令、並下發到路由器是Driver開發的重要部分。開發過程中,我們研讀了onos里NETCONF相關的代碼,了解設備是如何進行連接,session是如何創建,命令是如何發送的。在這里分享給大家。

一、前期准備

要進行設備的連接,有兩個很重要的前提。一個是物理設備可以被onos控制器所識別。第二個是該設備對應的驅動已經在控制器中加載。只有這兩個前提條件被滿足,onos才能與設備進行連接,從而下發控制命令。
如果對這兩個步驟還不是很了解的同學,可以參考以下連接:https://wiki.onosproject.org/display/ONOS/NETCONF

對於驅動是如何加載的分析,我們將會在后續的文章中進行介紹。

二、設備連接的建立

進入正題,當控制器要對具體的設備進行控制時,第一步要做的就是與該設備進行連接。

首先進入的是org.onosproject.net.device.impl.DeviceManager的deviceConnected方法。

1、根據設備所屬的BasicDeviceConfig獲得設備的基本配置。
2、根據傳進來的deviceDescription和獲得的配置信息重新更新deviceDescription並且創建role(master、none、standby等)
3、調用applyRole(deviceId,role)將設備與role綁定。需要注意的是,當調用完這個方法之后就已經創建了onos與設備的連接,並將創建的session保存起來,方便以后調用(具體的實現請往下看)。
4、將device的信息存入store中。

走到這一步,onos就完成了與設備的連接,當需要對設備發送命令時,只要找到對應的session就可以進行發送了。

從上面的分析我們知道applyRole是一個很重要的方法。接下來我們就分析一下applyRole是如何完成上述的功能。

從上面的源碼中我們看到,在applyRole函數中最關鍵的就是調用了DeviceProvider的roleChanged(deviceId,newRole)函數。因為DeviceProvider是一個接口,它具體實現的類是NetconfDeviceProvider,對應的函數是Rolechanged。


可以看出,在roleChanged函數中,根據role的類型進行不同的處理。特別注意的是,當role顯示為master時,通過initiateConnection函數調用NetconfControllerImpl類的connectDevice(deviceId)方法,完成NetconfDeviceInfo和NetconfDevice 的創建。並完成與設備的連接。

下面是NetconfControllerImpl類中connectDevice(deviceId)函數的具體代碼:


首先通過deviceId從deviceService中獲得username、password等信息。然后根據得到的用戶信息以及之前存儲的設備信息生成NetconfDeviceInfo。再根據生成的NetconfDeviceInfo,最后通過createDevice函數調用deviceFactory的createNetconfDevice方法生成NetconfDevice,同時與該設備進行連接。

createNetconfDevice方法的具體實現在NetconfControllerImpl類中。在該方法中他調用了DefaultNetconfDevice的構造函數,創建了NetconfDevice。從下圖構造函數代碼中,我們可以看見,系統在創建NetconfDevice的同時,也創建了netconfSession,並將netconfSession作為Device的一個屬性保存起來。當用戶需要與某設備進行交互時,只需要找到對應的Device對象,就能獲得與該設備進行交互的session。

【注意】以下就是onos與device進行連接的具體代碼。
與DeviceFactory一樣,SessionFactory的createNetconfSession函數,也是調用了NetconfSessionImpl的構造函數,進行netconfSession的創建。

與設備進行連接的操作是通過NetconfSessionImpl類startConnection函數完成的。

1、根據deviceInfo的ip和port的信息構建connection。
2、調用connect函數進行連接
3、根據deviceinfo中的username等信息,看用戶是否被授權。
4、如果用戶被授權則調用startSshSession

在startSshSession中,創建Stream線程為以后的交流提供服務。同時向設備發送hello的NETCONF命令,完成兩個設備間所支持功能的同步,為以后使用NETCONF命令進行交流打下基礎。

至此onos就完成了與設備的連接,並將創建的session保存在netconfController中。在下一節中我們將介紹如何使用創建的session進行命令的發送。

三、NETCONF命令的發送

當控制器與設備建立好連接以后,我們就可以通過控制器想設備發送命令了。
本文以onos中的device-configuration命令為例,講解netconf命令是如何下發,同時控制器是如何獲得路由器返回信息的。

3.1 NETCONF命令發送

當用戶在onos的終端輸入device-configuration命令以后,就進入了org.onosproject.cli.net.DeviceConfigGetterCommand中。

系統根據具體的配置文件,找到ConfigGetter接口的具體實習類——NetconfConfigGetter。

在上一節我們介紹過,在NetconfControllerImpl的createDevice函數中,系統將生成的Device放入到了DevicesMap中,方便日后使用。

所有當需要發送命令的時候,系統先從NetconfController里的DevicesMap中獲得對應的Device,然后根據得到的Device找到對應的NetconfSession。

在獲得session以后,根據用戶傳入的信息構建對應的NETCONF命令。並通過NetconfSessionImpl中的sendRequest函數將命令發送給設備。

在sendRequest中,先對傳入的request格式進行檢查,確保符合NETCONF命令的規范。
確保request符合規范以后,使用request函數將request發送給設備。同時返回CompletableFuture futureReply。futureReply主要是用來讀取設備返回的信息。如果設備無法在規定的時間內返回信息,則系統會拋出異常。

下面讓我們看一下onos是如何發送信息的。

進入到NetconfSessionImpl的request函數:

3.2 設備返回信息讀取

當NetconfStreamThread對象中的run函數接受到設備返回的信息以后,會對信息進行解析生成事件,發送給監聽器,並將信息傳達給CompletableFuture。

此時在主線程的sendRequest函數中,通過調用CompletableFuture的get方法獲得返回信息。

至此,NETCONF命令的下發和信息的返回過程就結束了。

不知道我有沒有講清楚,歡迎大家拍磚討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM