楊曉,劉琦
(西華大學計算機與軟件工程學院,成都 610039)
人類社會已經進入網絡無所不在的信息時代,截至2017年3月,全球互聯網用戶突破37.4億,全球每人平均每月的網絡流量也將于2021年達到61GB(從2016年的24GB)?;ヂ摼W能夠快速發展主要得益于它優良的體系結構和網絡技術,然而伴隨著推廣的深入和網絡規模的不斷擴大,爆炸式的增長使其自身結構的僵化問題越來越明顯,互聯網原有的結構反而成為阻礙它進一步發展的最大障礙。
SDN(軟件定義網絡)是一種新式的網絡架構,這種方式給了可以破除當前網絡架構存在的瓶頸的希望。在傳統的網絡結構中,控制平面和數據平面是整合在同一個網絡設備中,而SDN的一個核心點就是通過打破垂直整合,將網絡的控制邏輯從底層的路由器和交換機中分離出來,促進網絡控制(邏輯)中心化,引入對網絡可編程的能力[1]。網絡策略的制定、交換硬件中的執行以及流量的轉發之間的分離,這是我們所期望靈活性的關鍵之處。通過將網絡控制問題分離成一些易于解決的小部分,SDN使得在網絡中易于創造和引入新的抽象,這樣簡化了網絡管理,有利于網絡革新和發展。另外,在傳中的IP網絡中所有的轉發行為都是基于單一的IP地址進行轉發,而在SDN中,所有轉發都是基于流(一套基于數據包頭域的規則)進行轉發,這種細粒度的方式更加方便于策略的實現[2]。
IEEE 802.3ax標準的 LACP(Link Aggregation Con?trol Protocol,鏈路聚合控制協議)是一個關于動態鏈路聚合的協議,它通過協議報文LACPDU(Link Aggrega?tion Control Protocol Data Unit,鏈路聚合控制協議數據單元)和相連的設備交互信息[3]。當端口啟用LACP協議后,端口通過發送LACPDU來通告自己的系統優先級、系統MAC、端口的優先級、端口號和操作key等[4]。相連設備收到該報文后,根據所存儲的其他端口的信息,選擇端口進行相應的聚合操作,從而可以使雙方在端口退出或者加入聚合組上達到一致。在傳統網絡中的交換設備,一般存在多個以太網口,同時在大型網絡中也可能會存在單點鏈路帶寬瓶頸,例如Web服務器,同一時間可能會有上千萬的訪問量,單個接口無法滿足這么大的吞吐量。LACP可以利用這些接口聚合為一個更大帶寬的邏輯接口,同時可以實現鏈路的容錯性,當聚合端口中的一條或幾條鏈路故障,仍能保證鏈路的連通性。
如何將傳統網絡架構遷移至新的軟件定義網絡架構中去,一直是近些年來討論研究的熱點。本文就嘗試探索如何傳統的網絡架構中的鏈路聚合遷移至新的軟件定義網絡架構中。本文通過SDN方式基于Ryu控制器(SDN開源控制器)研究和實現LACP功能,使得LACP協議可以在軟件定義網絡環境中實現。
依據IEEE的802.1ax協議標準并基于Ryu控制器平臺,設計交換模塊、LACP解析與封裝模塊、LACP處理邏輯模塊。
本系統是基于Ryu控制器的,Ryu控制器是基于事件機制的,每個OpenFlow消息在進入到Ryu控制器后,都會被封裝成一個事件;每個應用在加載時,主動向Ryu控制器注冊在某個通信階段,自己期望的處理事件。
本系統注冊事件列表如下:
● ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER
●lacplib.EventPacketIn,MAIN_DISPATCHER
●lacplib.EventSlaveStateChanged,MAIN_DISPATCHER
●ofp_event.EventOFPPacketIn,MAIN_DISPATCH?ER
●ofp_event.EventOFPFlowRemoved,MAIN_DISPATCHER
在Ryu控制器中,通信階段分為以下四個:
●HANDSHAKE_DISPATCHER:連接建立階段,交換Hello信息
●CONFIG_DISPATCHER:等待接收交換機特性階段
●MAIN_DISPATCHER:正常通信階段
●DEAD_DISPATCHER:連接斷開階段
程序可以指定在某個階段,來處理相應的事件,當在其他非指定階段出現注冊事件,則不會觸發相應方法執行。
當相應的OpenFlow消息到達Ryu控制器,控制器的事件調度器會根據應用的注冊的事件類型,來調用對應的方法,對事件進行處理。
本系統分為LACP解析與封裝模塊,LACP處理邏輯模塊、交換模塊。模塊之間彼此獨立,通過Ryu事件調度器,完成彼此之間的協作。LACP處理模塊位于Ryu事件處理中最頂層,最原始的packet-in數據包首先會觸發它的處理,以執行與LACP相關的功能;在對原始的pack-in事件進行過濾后,將不包含LACP信息的packet-in事件重新發回到Ryu控制器系統中,以觸發交換模塊處理。在LACP處理邏輯模塊中,會使用LACP解析封裝模塊,來將原始的字節流轉換為可以處理的信息,同時將處理的結果序列化為可以在網絡中傳輸的LACP協議數據包字節流。而交換模塊則單純處理與MAC尋址相關的功能。LACP處理邏輯模塊和交換模塊彼此之間是解耦,它們之間的通過Ryu控制器進行協作。事件之間關系如圖1所示。

圖1 事件邏輯
作為交換模塊,主要實現學習MAC地址,并根據學習到的信息進行數據包的轉發,當有端口的LACP狀態變化的事件時,清理與LACP端口相關的流表信息。因為,為了實現LACP功能,控制器是通過流表來控制交換機的轉發行為,所以當相應接口失效,或者接口重新加入聚合組,需要清空與之相關的流表,重新建立新的轉發方式。交換模塊處理邏輯如圖2。
交換模塊注冊對以下三個事件監聽入口:
●ofp_event.EventOFPSwitchFeatures
●lacplib.EventPacketIn
●lacplib.EventSlaveStateChanged
事件ofp_event.EventOFPSwitchFeatures會在連接建立階段,完成對tablemiss流表添加,以完成MAC地址的學習。事件lacplib.EventPacketIn會在正常通信階段,處理經過LACP模塊過濾后的packet-in事件,這些事件經過過濾后,所有的packet-in事件只會與數據包的交換有關,屏蔽的與LACP的聯系,減少了LACP模塊與交換模塊之間的耦合性。事件lacplib.Event?SlaveStateChanged會在正常通信階段,處理交換機中端口狀態變化(從非LACP狀態到LACP狀態,或LACP狀態失效),完成對交換機內的流表清理初始化工作。

圖2 交換模塊處理邏輯
由于在網絡中傳輸的LACP數據包都是字節流,無法直接處理,所以根據IEEE 802.1ax協議標準,并借助程序開發語言Python中的struct模塊來設計解析與封裝模塊,將原始LACP字節流的解析成可以處理的信息,以及將處理好的數據封裝為可以在網絡中傳輸的字節流。此模塊用于協助LACP模塊對協議的處理。
在解析數據包時,當LACP模塊調用本模塊解析協議的原始數據時,會調用struct模塊中的struct.un?pack_from,根據LACP協議字段值順序以及大小,以偏移量作為參數將原始的字節流解碼為可以處理的信息。主要解析的關鍵字表1所示。同樣在封裝數據包,使用struct模塊中的pack方法,根據LACP協議字段順序進行組裝,得到一個可以直接發送的網絡數據包。

表1 LACP協議關鍵字段值
作為在Ryu平臺實現鏈路聚合控制協議,主要是通過控制actor_state字段值,來與對端交互。本系統主要就是根據此字段值來實現鏈路的聚合。actor_state為一字節,8個比特位,每個位對應的含義如表2。
●LACP_Activity:標志LACP活動狀態,主動為1,被動為0。
●LACP_Timeout:標志鏈路超時時間控制值,Short Timeout為 1,Long Timeout為 0。
●Aggregation:如果標志值為1,則系統認為這個鏈路為可聚合;如果為0,則這個鏈路為獨立的。
●Synchronization:如果值為1,系統認為這個鏈路是IN_SYNC狀態,即這個鏈路已經分配給合適的鏈路聚合組,這個組已經與兼容的鏈路聚合相關聯;為0表示為OUT_OF_SYNC,表示該鏈路未在聚合態。
●Collecting:如果值為1,在這條鏈路聚集傳入的幀為enabled狀態,即在沒有管理性更改,或接收消息更該的情況下,不會被禁用;否則為0。
●Distributing:如果值為0,在這條鏈路上分發傳出的幀為enabled狀態,即 在沒有管理性更改,或接收消息更該的情況下不會被禁用;否則為0。
●Defaulted:如果值為1,標志表示本端的接收計算機正在使用默認的運行對端信息,這些信息是為對端管理配置的;如果為0,已在LACPDU中收到正在使用的運行對端信息。
●Expired:如果值為1,表示本端的接收機是過期狀態;如果為0,本端接收機為過期。
當有關于LACP的packet-in事件觸發時,Ryu控制器會調用這個模塊進行處理。處理邏輯關系見圖3。同時控制器中維護一個綁定信息狀態變量bond,以記錄不同交換機不同端口LACP狀態信息(是否啟用LACP,超時時間)。
首先根據事件中的信息,在bond中查看接收此LACP數據包的交換機端口的狀態,來判定這個端口是否啟用了LACP;若對應端口未啟用LACP,則將此接口啟用,并向 Ryu控制器發送 lacplib.EventSlaveStat?eChanged事件,以通告端口的狀態改變。

表2 actor_state控制字段
接著,依據數據包中的LACP超時時間類型為SHORT_TIMEOUT_TIME或者 LONG_TIMEOUT_TIME,來設置流表的超時時間。因為作為被動端,交換機會根據流表的超時時間自動調整端口的狀態。當流表的超時時間達到,但仍未收到主動端的LACP數據包,以更新超時計時器,則表示LACP超時時間到達,交換機會主動刪除這條超時的流表,并向控制器發送ofp_event.EventOFPFlowRemoved流表移除消息,在控制器收到此條消息會主動更新控制器中保存的綁定信息,并清除交換機內與該端口相關的LACP流表信息。以此,來自動完成與主動端鏈路狀態保持。
然后,根據LACP超時時間,來判斷超時時間是否變化,如果變化需要修改控制器中保存的綁定狀態信息,并下發指令,修改交換機內相應LACP流表的超時時間。
最后,作為對packet-in消息回復,構造響應LACP數據包,通過packet-out消息發送響應信息給主動端,以完成和主動端的交互。

圖3 LACP處理邏輯
LACP模塊包含的關鍵方法:
●do_lacp:LACP 處理
●_create_response:創建回應數據包,并序列化
●_create_lacp:構造LACP響應數據包
●_get_slave_enabled:獲取端口的LACP狀態
●_set_slave_enabled:設置LACP狀態
●_get_slave_timeout:獲取端口的超時時間信息
●_set_slave_timeout:設置端口的超時時間信息
本實驗通過仿真工具Mininet構建一個具有一個OpenFlow交換機,四臺主機網絡,其中主機h1與交換機之間有兩條網絡連接線。如圖4所示。

圖4 實驗拓撲
完成后,如圖5看到邏輯接口bond0為MASTER,物理接口h1-eth0和h1-eth1為SLAVE。

圖5 h1最終配置結果
執行程序,在終端中有一下信息輸出,如圖6??梢钥闯鯨ACP起用,被動端的接口也已經UP,timeout事件從默認的0秒變為LONG_TIMEOUT_TIME,即90秒。lacp的響應數據包被發送出去。在最后輸出信息:“slave state changed port:2 enabled:True”表示應用接收到了EventSlaveStateChanged事件。

圖6 程序執行輸出
控制器端的輸出如圖7。

圖7 控制器終端輸入信息
檢查流表,如圖8,可以看出:在當LACP數據包(類型為0x8809)從h1的eth1接口被發送(進入端口為 s1-eth2,mac 地址為 00:00:00:00:00:12),packet-in消息被發送;在當lacp數據包從h1的eth0接口被發送出去時,packet-in消息被發送出去;同時還包含一條table-miss流表項。

圖8 流表信息
首先驗證鏈路可以改進鏈接速度,將去往h1的流量分布到兩個鏈路上。
首先執行,h2 ping h1如圖9。

圖9
當繼續發送ping,檢查OpenFlow交換機的流表信息,如圖10,相比剛開始,添加了兩條流表項。從這可以看出,S1-eth 1被用于h2和h1的通信。

圖10
接著從h3 ping h1,結果如圖11。

圖11
在OpenFlow交換機中可以看到如圖12,可以看出又添加了兩條流表項,但是參數duration的值比較小。由此可以得知,交換機的eth 2接口用于h3和h1通信。

圖12
同樣在從h4到h1執行ping測試??梢缘玫饺绫?的端口使用表。

表3
由此得出,兩條鏈路都為H1通信服務。鏈路聚聚合用成功。
驗證可以實現,數據鏈路的容錯性。當前狀態是,當從h2和h4與h1通信,交換機的端口eth 2被使用,當從h3與h1通信,eth1被使用。將交換機的eth 1從聚合鏈路中移除。由于H1的eth 0停止,h3與h1無法通過ping測試,當經過90秒后,新的消息日志會出現,如圖13。

圖13
可以看出超時時間到達,斷開的接口的所有學習的MAC地址和流表項都會刪除,回到初始狀態。如果有新的通信活動在h1和h3之間,存在的聚合鏈路會學習新的MAC地址,注冊新的流表項。如圖14。

圖14
之前的無法ping測試,現在恢復,如圖15。

圖15
由此可以看出,即使某些鏈路出現問題,仍然能夠實現通信,實現了容錯性。
本文根據OpenFlow協議,以及鏈路聚合控制協議LACP,在基于Ryu框架中,探索如何將鏈路聚合在軟件定義網絡環境中實現。從本實驗可以看出軟件定義網絡的優勢:不用接觸底層設備,可以用過中心控制器來管控網絡,為網絡管理帶來便利性;快捷的部署,對于新的技術協議,在傳統的環境中去驗證十分困難,但在SDN環境中,屏蔽底層細節,通過統一的流表樣式來控制交換機的數據包轉發行為,為以后的網絡發展與技術革新帶來新的動力。本設計在一定程度上實現了鏈路聚合控制協議,但并未實現主動式的,交換機只作為一種被動式角色。今后的研究可以嘗試,設計一套完整的LACP協議的實現。