linux 網路子系統底層機制分析
(1)網路子系統在linux中的地位非常重要。在如今這個嚴重依賴網際網路,強調協同工作的時代,乙個高效,穩定的網路處理系統是留住使用者群的基本手段。前段時間花了一部分時間學習了一下linux的網路子系統的源**以及一些處理機制。這部分是由於工作的原因,另一部分原因是想對linux的網路處理有乙個更加完整,深入的認識。趁著春節假期,對前段時間的學習做乙個總結,絕大部分內容參考自這本書,部分內容來自網際網路以及自己看**的總結。
網路子系統概貌
linux的網路子系統實現了tcp/ip協議棧。本來有乙個圖來表示socket以及各層的乙個資料流向,最後才發現沒有辦法上傳到csdn上來。
對應用程式原來說,與網路打交道的介面就是socket。從圖中可以看到,linux支援多種型別的socket,當然不只圖中表示的這幾種。比如說sock_stream型別的socket主要用於使用tcp協議的程式設計,而sock_ram型別的socket則可以繞過傳輸層,直接和ip層打交道,當然這也意味著你的工作量將會大大增加,
但帶來的將是靈活性。
上圖l3,l4中有橫向虛線,表示的是從下面一層進入的報文既可以直接往上走,也可以循著虛線方向到達一些特殊的模組。比如說由ipv4到l4,如果此報文是sock_raw型別的,則直接送到socket層處理,否則送到tcp,udp等四層處理模組。
對於出報文,最終由dev_queue_xmit函式傳送到特定介面的驅動,由它傳送到網路上。如果沒有指定乙個特定的介面,那麼根據報文的目的位址,由系統路由決定的到底由哪乙個網路介面傳送出去。
網路子系統對報文的處理
其實上面說報文並不是很恰當,因為在協議棧的不同層,其被處理的主體是不一樣的。在link層,是幀;在network層是報文;在transport層則是資料報。
在協議棧的各層,主要的處理流程基本上都是解析協議頭,封裝協議頭等等。為了適應各種協議,以及面對將來不斷增加的協議,linux的網路子系統採取的是註冊處理函式的方式來實現一種鬆散的耦合。在註冊的時候,會傳入乙個類似協議號的引數值,這樣二層的處理函式就能根據幀的協議欄位的值決定下一步處理的函式了。比如說在三層,可以註冊自己的協議處理函式,比如說處理協議號為100的報文,這樣,當系統收到乙個適當的報文(協議號字段為100)時將把此幀遞送到你註冊的處理函式當中。
Linux網路子系統中鏈路層中GRO的處理
根據上篇博文的介紹,gro需要支援gro的每種協議都要實現自己的報文匹配合併函式和合併完成函式。這裡我們先來看看鏈路層上 實現的自己的gro函式。鏈路層的接收匹配函式 napi gro receive napi,skb 該函式對報文進行匹配,並不合併報文。匹配規則 必須同時滿足以下兩個條件 1 兩個...
Linux網路子系統中報文的接收及NAPI的實現
報文的接收是整個協議棧的入口,負責從網絡卡中把報文接收並送往核心協議棧相應協議處理模組處理。一種是網絡卡產生中斷,通知核心進行接收報文。一次中斷接收乙個報文。在中斷處理程式中把報文從硬體快取中拷貝到記憶體中,並把報文加入到協議棧中對應的入口佇列中,中斷退出時呼叫收包軟中斷來從相應佇列來讀取報文進行處...
Linux網路子系統中協議棧的入口處理
網路驅動接收到報文後,會初始化skb protocol 字段。鏈路層的接收函式netif receive skb會根據該字段來確定把報文送給那個協議模組進一步處理。乙太網的裝置呼叫eth type trans 來給skb protocol賦值。be16eth type trans struct sk...