基於乙太網交換機的Linux協議棧虛擬化技術

才智咖 人氣:2.84W

摘要:網路協議棧虛擬化的目標是在一臺網路裝置上虛擬出多個協議棧以實現網路裝置的一虛多功能。由於Linux作業系統的網路協議棧本身是不支援這種網路協議棧虛擬化技術的,因此本文通過對Linux作業系統3.11.10版本IPV4網路協議棧進行改造以實現Linux網路協議棧的虛擬化,並在裝置平臺上驗證了經過網路協議棧虛擬化改造後的乙太網交換機對業務流的隔離功能。

基於乙太網交換機的Linux協議棧虛擬化技術

關鍵詞:協議棧;虛擬化;網路裝置

1 引言

隨著網路規模的不斷擴大,業務種類的不斷豐富,網路對業務的隔離以及安全性、可靠性等屬性提出了越來越高的要求[1]。此外,隨著硬體能力的迅速提升,多框、叢集、分散式路由交換系統的成熟,單臺物理網路裝置的業務處理能力已經達到了一個新的高度[2]。為了將單臺物理裝置的強大業務處理能力充分利用,彈性的適應當前的業務需求和未來的發展,網路裝置的一虛多(即將一臺物理裝置虛擬成多個邏輯裝置)成為了網路與通訊界追求的目標[3]。Linux作業系統因其具有的開源、安全和穩定等優點,受到網路裝置製造商的青睞,被廣泛應用到網路裝置的嵌入式開發中。

目前,國內外對Linux作業系統虛擬化的研究都著力於作業系統級的全域性性資源隔離虛擬化,而缺少對網路協議棧虛擬化的深入研究。對於小規模乙太網而言,全域性性的資源隔離會對網路裝置的程序資源造成不必要的浪費,增加了網路裝置的負荷,影響網路資料包處理速率。

因此,本文在乙太網交換機裝置上研究了Linux嵌入式作業系統中虛擬協議棧技術,以實現業務流的隔離,提高單個乙太網交換機裝置的資源利用率[4]。

2 Linux網路協議棧的層次結構

網路協議棧是指TCP/IP協議棧,實現了一個網路中資料傳輸的過程:包括上層協議到底層協議,和由底層協議到上層協議。Linux網路協議棧的層次架構模型如圖1所示,最上面一層為使用者空間中的應用層,中間部分為核心空間中的網路協議棧部分,底層為物理裝置[5]。在網路協議棧中使用者空間和核心空間之間的資料通過套接字快取(socket buffer) 來傳遞,相應的資料結構為sk_buffer。

圖1 Linux網路協議棧層次架構

Linux網路協議棧的最上層是系統呼叫介面,為使用者空間中的應用程式提供一種訪問核心網路協議棧的介面。通過網路協議棧進行通訊都需要對套接字進行操作,網路協議棧提供了兩種呼叫介面給使用者程序。一種是在sys_socketcall中會根據網路系統呼叫號呼叫具體的功能,另一種是通過普通檔案操作來訪問網路協議棧,將套介面的輸入、輸出操作當成典型的檔案讀寫操作來進行。

套接字是一個與協議無關的介面層,它提供了一組通用介面來支援各種協議,它對使用者層的應用程式遮蔽了與協議相關的實現細節,將應用程式傳送的與協議無關的請求對映到與協議相關的實現。傳輸層負責資料的傳輸和資料的控制,提供端到端資料交換機制,傳輸層協議包括面向連線的TCP協議和麵向無連線的UDP協議。網路層負責接收、傳送或轉發資料包,網路層的協議包括IP協議、ARP協議、RARP協議、ICMP協議和IGMP協議等。鄰居子系統為三層協議地址與二層協議地址提供了的對映關係,此外還快取了二層首部,以加速資料包的傳送。在傳送資料包的時候,先進行路由查詢,如果找到對應的路由,再檢視鄰居表中是否存在相應的對映關係,如果不存在則新建對應的鄰居項;然後再判斷鄰居項是否為可用狀態,如果不可用則把資料報存至傳送快取佇列後傳送請求;在接收到請求應答後,將對應的鄰居項置為可用,並將其快取佇列中的資料包傳送出去;如果在指定時間內為收到響應包,則將對應鄰居項置為無效狀態。對於乙太網交換機而言,鄰居子系統提供了三層IP地址和二層MAC地址的對映,鄰居表就是ARP表。

網路協議棧底部是一個與硬體無關的網路裝置介面層,它將網路層的不同協議與各種網路裝置連線在一起。裝置無關介面層提供了一組通用函式供底層網路裝置驅動程式和上層協議棧呼叫。當輸出資料時協議棧不必關心底層的網路裝置,而當輸入資料時網路裝置驅動同樣也不必關心上層的協議棧。協議棧向裝置傳送資料包時都需呼叫dev_queue_xmit函式。該函式對sk_buffer進行排隊,最終由底層裝置驅動程式進行傳輸。而接收報文通常是呼叫netif_rx函式實現的。當底層裝置驅動程式收到一個報文時,就會通過呼叫netif_rx函式將報文的sk_buffer上傳至網路層。

乙太網交換機裝置上網路介面卡(NIC)的相關資訊是由net_device結構來描述的,net_device包括了硬體資訊成員變數、介面資訊成員變數、裝置操作介面變數和一些輔助成員變數。網路介面卡的IPv4地址等相關配置資訊存放在in_device結構中,net_device中有一個指標指向in_device。每個網路介面卡都會有一個對應的net_device結構。當裝置啟動時呼叫register_netdevice函式註冊到系統中,註冊過的網路介面卡NIC可通過unregister_netdevice函式登出。net_device結構中包含了一個名為hard_start_xmit的介面,通常在初始化網路介面卡時設定該介面。當協議棧向網路介面卡傳送資料包時,會通過裝置無關介面呼叫到此介面[6]。

3 Linux協議棧虛擬化的實現框架

Linux協議棧虛擬化技術是屬於控制平面的虛擬化,Linux協議棧虛擬化技術的實現分為以下四個部分:路由表的虛擬化、網路介面的虛擬化、與上層應用介面的虛擬化、套接字層的虛擬化。路由表的虛擬化通過對儲存路由表項的資料結構的虛擬化擴充套件來實現,使每一個虛擬出來的協議棧都對應一份獨立的路由轉發表例項,虛擬協議棧的路由轉發表例項之間互不干擾[7]。網路介面的虛擬化使網路介面卡在收發資料包的時候,可以區分出這個資料包是屬於哪個虛擬協議棧,也使資料包在協議棧中傳遞的時候,可能選擇正確的函式處理介面。以上兩部分都是通過virtual_id標識來區分不同的虛擬協議棧,每個虛擬協議棧都自己唯一的virtual_id標識,virtual_id和虛擬協議棧是一一對應的。

圖2 虛擬化協議棧架構

3.1 路由表的虛擬化

Linux協議棧中使用資料結構fib_table來描述路由表資訊,所有的fib_table結構連結在全域性散列表fib_table_hash中。fib_table_hash儲存在資料結構struct net中的struct netns_ipv4成員中。引數不同的'fib_table_hash表示不同型別的路由表,例如fib_table_hash[RT_TABLE_LOCAL]表示裝置本地地址的路由表。路由表的虛擬化是將指標資料結構struct hlist_head*fib_table_hash重定義為指向指標的資料結構struct hlist_head** fib_table_hash,使用不同virtual_id標識來區分不同虛擬協議棧的路由錶轉發例項,例如本地路由表就重定義為fib_table_hash[RT_TABLE_LOCAL][virtual_id]。