功能
網絡子系統負責系統的網絡IO,通過與網絡裝置(路由器、交換機等)的資料互動,實作端到端的資料互動過程。下圖示意網絡資料流:

圖 8-1 網絡資料流視圖
網絡子系統位于端系統中,從上圖可以看出網絡子系統在資料面劃分成應用層、傳輸層、網絡層、鍊路層、實體層。每一層可以對應到OSI^定義的網絡七層模型^1。
架構
網絡子系統架構可以分軟體視角,硬體視角兩個次元描述。軟體視角淡化實體位置、裝置差異,強調邏輯分層;硬體視角強調系統次元描述架構組成元素,本文以鲲鵬920晶片作為系統參考對象。
軟體視角的網絡子系統是linux網絡子系統;硬體視角的網絡子系統是鲲鵬網絡子系統。
linux網絡子系統
linux kernel 4.19版本中,網絡子系統代碼目錄定義如下:
/net
/net/core
/driver/net
linux網絡子系統按照邏輯分層方式描述架構分層。通過邏輯抽象分層,linux網絡子系統給使用者态提供統一的BSD Socket接口通道,并同時支援各種不同的硬體,各種不同的網絡協定。
圖8-2 linux網絡子系統
linux 網絡子系統内子產品衆多,功能複雜,本文不詳細講解每個子產品的功能及實作。我們從資料面、管理面兩個次元描述該子系統的工作原理。
資料面
在發送方向上,應用程式通過send()系統調用接口進行封包發送,封包内容會先進入核心空間完成必要的協定層處理,此時硬體Device未必是就緒狀态,是以Driver程式必須等其就緒才能通知其進行封包發送處理。在此之前,封包必須緩存在主存内。
在接收方向上,硬體Device收到資料封包後,驅動收到中斷通知完成資料封包讀取進核心空間,完成必要的協定層處理,此時應用程式未必是就緒狀态,是以核心需等其就緒後才能喚醒其進行封包接收處理。在此之前,封包必須緩存在主存内。
封包在核心中緩存是通過一個稱之為sk_buff的資料結構進行管理的,該結構複雜,内部細節較多,這裡不展開描述。其基本原理是:
封包頭的解析/封裝采取空間預留技術,在協定層内各種協定封包頭處理過程中,協定頭解析/封裝結果隻需在預留白間内偏移,省去了很多記憶體拷貝,遷移操作。
封包體的構造采取資料分段技術,當封包體内容過長時,可以通過分段形式不斷補充資料,sk_buff以鍊方式管理資料包,同樣也省去了很多記憶體拷貝、遷移操作。
以上兩個邏輯可以圖例方式表達:
圖8-3 封包收發邏輯
在圖例中更容易清晰看到:
記憶體拷貝:收發兩個方向(硬體裝置使用者應用程式),都存在兩次拷貝操作,一次是軟體拷貝,一次是硬體拷貝。
執行排程:收報流程中,硬體裝置中斷觸發驅動軟體配置設定sk_buff,驅動軟體觸發軟中斷驅動協定層完成封包處理,待使用者線程就緒時喚醒其執行接收封包處理。發送流程中,使用者線程配置設定sk_buff,協定層完成封包處理後入發送緩存隊列,随後通過軟中斷排程觸發驅動軟體通知硬體裝置進行發送封包。
是以linux網絡子系統資料面在空間性能方面存在記憶體拷貝的性能開銷,時間性能方面存在多次排程切換的性能開銷。
管理面
linux網絡子系統管理面通過一個重要對象進行管理:網絡裝置。
圖8-4 網絡裝置驅動架構
網絡裝置驅動架構中,對協定層抽象出統一的封包收發接口,使協定層與各種網絡裝置充分解耦。通過注冊回調函數方式,實作具體硬體裝置的收發封包接口調用。其中關鍵的資料結構是struct net_device,其對各種網絡裝置進行抽象、封裝,屏蔽硬體差異。
網絡裝置驅動程式通過register_netdev()注冊裝置上線,注冊時攜帶協定層定義的資料結構、回調函數,進而配合協定層對其進行控制。
例如網卡硬體能力實作了很多offloading功能,盡量将一些機械重複的工作下沉至網卡硬體,其目的是解放CPU,提升系統吞吐量。net_device就通過xx_features進行表達硬體的能力,如下所示:
struct net_device {
...
netdev_features_tfeatures;
netdev_features_thw_features;
netdev_features_twanted_features;
netdev_features_tvlan_features;
netdev_features_thw_enc_features;
netdev_features_tmpls_features;
netdev_features_tgso_partial_features;
...
}
裝置上線注冊時,驅動程式根據硬體實際情況設定這些字段通知協定層硬體能力,協定層在處理封包時根據硬體能力就跳過某些計算過程。
結語
linux網絡子系統是站在單CPU視角看資料面、管理面,現代伺服器普遍是SMP/NUMA系統結構,僅僅從單CPU視角看網絡子系統不能完整展現伺服器内網絡子系統的工作過程。
下面我們介紹下鲲鵬920系列的網絡子系統,用來展示更多工作過程。
鲲鵬網絡子系統
以鲲鵬920作為參考對象,介紹其網絡子系統。
圖 8-5 鲲鵬網絡子系統
組成部分:
網絡ICL:
網絡ICL(I/O Clusters)就是鲲鵬920網絡子系統。網絡ICL與PCIe系統架構相容,可以支援多個PCI Function,每個PCI Function具備獨立的任務空間、配置空間,以處理各自獨立的服務資料、硬體參數配置。簡單的說就是網絡ICL可以向總線上報多個PCI Function。
PCI Function:
PCI Function可以呈現為實體網卡(PF)或虛拟網卡(VF),每個PF/VF可以被配置設定到1個或多個隊列對(QP),其包括Tx隊列和Rx隊列,這些隊列會映射到主存空間(Tx Queue、Rx Queue)。通過QP,PF或VF就可以進行主存的訪存操作。
當PF或VF被配置設定多隊列對時,這個網卡就具備同時與多個CPU進行封包收發處理(RSS技術)。
主存:
主存會提供存儲空間映射到QP,并以ring buffer形式管理Tx Queue、Rx Queue。
中斷:
接收到封包時,通過觸發中斷通知CPU的裝置驅動程式處理收到的封包;發送封包完成後,通過觸發中斷通知CPU釋放主存内的封包資源。
CPUs:
多核CPU,運作使用者态程式、網絡協定棧、網絡驅動程式,軟體形式通過總線觸發Tx Schedule排程封包發送。
總線:
鲲鵬920片内總線。
Tx Schedule:
當主存 Tx Queue的ring buffer非空時,Tx Schedule就會被觸發運作,執行發送排程操作。排程輸出結果是觸發TxDMA進行封包加載操作。
TxDMA / RxDMA:
TxDMA 用于将資料包從主存讀取後加載進Packet Buffer,RxDMA用于從Packet Buffer讀取後加載進主存隊列。TxDMA / RxDMA的資料讀存操作目的隻有一個:給CPU”減負“,提升CPU使用率。
NIC Engine
PPP:提供NIC Engine可程式設計能力,為封包處理提供靈活性。包括提供基于VLAN和MAC資訊的Rx方向的過濾能力,提供Flow Director機制實作RSS負載平衡能力。
Packet Buffer:提供Tx/Rx兩個方向的封包緩存能力。
MAC複用器:
支援以太幀的發送/接收,實作CRC計算和校驗,提供流控、自協商等能力。
為了更好的了解其工作原理,我們從封包收發兩方面描述其工作原理。
接收資料流
接收資料流是指網絡ICL從實體鍊路媒介中接收到資料,經過解析、過濾、複制等處理後,将資料封包存儲到Packet Buffer,然後由RxDMA将資料封包存儲至主存,最後向軟體報告。
圖 8-5 接收資料流過程
發送資料流
發送資料流是指網絡裝置驅動程式對ring buffer添加包任務,随後觸發Tx Schedule發起排程,由NIC Engine完成主存内封包讀取,TSO,封包編輯,MAC發送等操作。發送完成後,産生中斷通知CPU釋放包任務資源。
圖 8-6 發送資料流過程