學習SDN相關的學習也已經有快半年了,期間從一無所知到懵懵懂懂,再到現在的有所熟悉,經歷了許多,也走了不少彎路,其中,最為忌諱的便是,我在學習過程中,尚未搞明白OpenFlow協議的情況下,便開始對SDN進行相關操作,今天寫這篇博客,一方面是為了鞏固我以前所學的東西,另一方面,重新學習SDN相關的協議,以改正我之前的錯誤認知,當然,由於還是初學者,仍會存在一些錯誤的認識,歡迎各位留言指正。
OpenFlow協議的思路,即使網絡設備維護一個FlowTable,並且只通過FlowTable對報文進行處理,FlowTable本身的生成、維護和下發完全由外置的控制器Controller來實現。
此外,OpenFlow交換機把傳統網絡中,完全由交換機/路由器控制的報文轉換為由交換機和控制器來共同完成數據的
轉發操作,從而實現數據的轉發與路由控制的分離。控制器則通過事先規定好的接口操作OpenFlow交換機中的流表,從而達到數據轉發的目的。
OpenFlow控制器與交換機的交互通信圖
在OpenFlow交換機中,包含安全通道,多級流表和組表。通過安全通道,OpenFlow交換機可以和控制器建立基於OpenFlow協議的連接;而流表則用來匹配OpenFlow交換機收到的報文;組表用來定義流表需要執行的動作。
本文基於mininet和ryu,對OpenFlow協議報文進行分析。
OpenFlow協議主要是通過對不同類型消息的處理來實現控制器與交換機之間的路由控制的。目前OpenFlow協議主要支持三種消息類型,分別是controller-to-switch、symmetric(對稱型消息)以及asynchronous(異步消息類型)。每種消息類型分別對應多種事件,如異步消息類型中我們最常見的PacketIn事件,也是我們等下所主要闡述的事件。
OpenFlow協議所支持的三種消息類型
常用的消息主要是Hello消息、Feature消息,Echo消息,以及Packet_in、Packet_out和Flow_mod等。其中Hello、Feature、Echo消息分別包含REQUEST與REPLY消息,每一個消息REQUEST與REPLY的Transaction ID相同,交換機通過ID進行識別對應事件端口。
在通常的交換機事件發生時,主要經過如下幾個交互步驟:
OpenFlow協議下的交換機與控制器交互流程
其中,Hello消息是在OpenFlow初始化中就已經實現,基於ryu的消息獲取,在我目前這個階段尚未獲知如何截獲。而交換機特征報文以及PacketIn報文均可獲取。OpenFlow協議的報文一般為如下格式:
OpenFlow協議基本報文格式
正如圖中看到的,報文分為協議版本、消息類型、消息包(包括頭部)長度、與包有關的事件ID(回復配對請求時使用相同的ID)以及所對應消息類型的報文信息。其中,不同的消息類型所對應的 報文信息是不同的。
為了更好的說明這一點,本文分別截獲了PacketIn以及switch_features兩種報文格式:
PacketIn報文
switch_features報文
顯然,兩種報文總的來看,形式相同,唯有最后一部分的格式不同,這是由於不同事件所導致的。報文的截取,可以通過在ryu控制器中,輸出經OpenFlow協議描述后的msg消息得到。
而在總的消息報文中,觸發的不同事件,其最后一部分所對應的報文亦是不同,以PacketIn報文為例,它的基本格式為:
PacketIn報文格式
PacketIn報文包含緩存ID號、控制器的標識符、數據、匹配字段、包被發送的原因、被查詢流表的標識符以及幀的全長。不同的消息類型的報文,由於觸發的消息不同,所描述的信息不同,故導致這部分報文存在差異,這一點通過比較所截獲的兩種報文信息可以看出。
報文的定義格式可以在相應的RYU源碼中看到。