日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux网络协议栈之数据包处理过程,Linux网络协议栈之数据包处理过程

發布時間:2025/3/13 linux 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux网络协议栈之数据包处理过程,Linux网络协议栈之数据包处理过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文檔是基于 x86 體系結構和轉發 IP 分組的。

數據包在 Linux 內核鏈路層路徑?接收分組

1 接收中斷

如果網卡收到一個和自己 MAC 地址匹配或鏈路層廣播的以太網幀,它就會產生一個中斷。此網卡的驅動程序會處理此中斷:

從 DMA/PIO 或其他得到分組數據,寫到內存里去;

接著,會分配一個新的套接字緩沖區 skb ,并調用與協議無關的、網絡設備均支持的通用網絡接收處理函數 netif_rx(skb)。 netif_rx() 函數讓內核準備進一步處理 skb 。

然后, skb 會進入到達隊列以便 CPU 處理(對于多核 CPU 而言,每個 CPU 維護一個隊列)。如果 FIFO 隊列已滿,就會丟棄此分組。在 skb 排隊后,調用 __cpu_raise_softirq() 標記 NET_RX_SOFTIRQ 軟中斷,等待 CPU 執行。

至此, netif_rx() 函數調用結束,返回調用者狀況信息(成功還是失敗等)。此時,中斷上下文進程完成任務,數據分組繼續被上層協議棧處理。

2 softirq 和 bottom half

內核 2.4 以后,整個協議棧不再使用 bottom half (下半文,沒找到好的翻譯),而是被軟中斷 softirq 取代。軟中斷softirq 優勢明顯,可以同時在多個 CPU 上執行;而 bottom half 一次只能在一個 CPU 上執行,即在多個 CPU 執行時嚴格保持串行。

中斷服務程序往往都是在 CPU 關中斷的條件下執行的,以避免中斷嵌套而使控制復雜化。但是 CPU 關中斷的時間不能太長,否則容易丟失中斷信號。為此, Linux 將中斷服務程序一分為二,各稱作“ Top Half ”和“ Bottom Half ”。前者通常對時間要求較為嚴格,必須在中斷請求發生后立即或至少在一定的時間限制內完成。因此為了保證這種處理能原子地完成, Top Half 通常是在 CPU 關中斷的條件下執行的。具體地說, Top Half 的范圍包括:從在 IDT 中登記的中斷入口函數一直到驅動程序注冊在中斷服務隊列中的 ISR 。而 Bottom Half 則是 Top Half 根據需要來調度執行的,這些操作允許延遲到稍后執行,它的時間要求并不嚴格,因此它通常是在 CPU 開中斷的條件下執行的,比如網絡底層操作就是這樣,由于某些原因,中斷并沒有立刻響應,而是先記錄下來,等到可以處理這些中斷的時候就一塊處理了。但是, Linux 的這種 Bottom Half (以下簡稱 BH )機制有兩個缺點,也即:

( 1 )在任意一時刻,系統只能有一個 CPU 可以執行 Bottom Half 代碼,以防止兩個或多個 CPU 同時來執行 Bottom Half 函數而相互干擾。因此 BH 代碼的執行是嚴格“串行化”的。

( 2 ) BH 函數不允許嵌套。

這兩個缺點在單 CPU 系統中是無關緊要的,但在 SMP 系統中卻是非常致命的。因為 BH 機制的嚴格串行化執行顯然沒有充分利用 SMP 系統的多 CPU 特點。為此, Linux2.4 內核在 BH 機制的基礎上進行了擴展,這就是所謂的“軟中斷請求”( softirq )機制。 Linux 的 softirq 機制是與 SMP 緊密不可分的。為此,整個 softirq 機制的設計與實現中自始自終都貫徹了一個思想:“誰觸發,誰執行 ”( Who marks , Who runs ),也即觸發軟中斷的那個 CPU 負責執行它所觸發的軟中斷,而且每個 CPU 都由它自己的軟中斷觸發與控制機制。這個設計思想也使得 softirq 機制充分利用了 SMP 系統的性能和特點。

3 NET_RX_SOFTIRQ 網絡接收軟中斷

這一階段會根據協議的不同來處理數據分組。 CPU 開始處理軟中斷 do_softirq() ,,接著 net_rx_action() 處理前面標記的 NET_RX_SOFTIRQ ,把出對列的 skb 送入相應列表處理(根據協議不同到不同的列表)。比如, IP 分組交給 ip_rcv()處理, ARP 分組交給 arp_rcv() 處理等。

4 處理 IPv4 分組

下面以 IPv4 為例,講解 IPv4 分組在高層的處理。

linux 內核協議棧之網絡層

ip_rcv() 函數驗證 IP 分組,比如目的地址是否本機地址,校驗和是否正確等。若正確,則交給 netfilter 的NF_IP_PRE_ROUTING 鉤子(關于netfilter細節可以參考 Hacking the Linux Kernel Network Stack );否則,丟棄。到了 ip_rcv_finish() 函數,數據包就要根據 skb 結構的目的或路由信息各奔東西了。

ip_local_deliver() 處理到本機的數據分組;

ip_forward() 處理需要轉發的數據分組;

ip_mr_input() 轉發組播數據包

至此,數據分組的接受和處理工作就告一段落了,至于于此相對的數據分組的發送,我就貼個圖吧,具體細節可參考 The Linux? Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel Prentice Hall August 01, 2004

dev_queue_xmit() 處理發送分組

附一張 Linux 2.4 核的 netfilter 框架下分組的走向圖:

總結下:

1.中斷處理函數中:

網卡收到一幀------------------------〉

引發中斷-------------------〉

cpu調用相應的中斷處理函數(指向此網卡驅動中的相應的處理函數)(把此packet讀到ram中)--------------------〉

呼叫netif_rx函數來打上timestamp,并把此skb放入到cpu設置的隊列中-----------------〉

標記軟中斷(__cpu_raise_softirq)---------------------〉中斷完成。

2.當軟中斷被調用時(一共在三個地方調用),呼叫NET_RX_SOFTIRQ(其實就是net_rx_action()函數)來處理網絡方面的軟中斷。-----------------〉

net_rx_action()根據數據包的協議類型在數組ptype_base[16]里找到相應的協議,并從中知道了接收的處理函數,然后把數據包交給處理函數,這樣就交給了上層處理,實際調用處理函數是通過net_rx_action()里的pt_prev- func()這一句。例如如果數據包是IP協議的話,ptype_base[ETH_P_IP]- func()(ip_rcv()),這樣就把數據包交給了IP協議。根據包的類型,查找系統中注冊了的相應的包處理函數,對于ipv4的ip包,呼叫ip_rcv-------------〉

NF_IP_PRE_ROUTING--------------〉

ip_rcv_finish(進行對此包的路由操作)---------------------〉

根據路由的結果,呼叫ip_local_deliver(給本機的包)/ip_forwardd(要轉發的包)/ip_error()(出現錯誤的包)/ip_mr_input()(多播包的處理)ip_forward:要進行轉發的包,check ttl, mtu, call NF_IP_FORWARDS,--------------〉

ip_forwmard_finish(check other ip options for forwardd!)-------------------〉

ip_send(如果需要分片,則調用ip_fragment,否則調用ip_finish_output()(call NF_IP_POST_ROUTING,然后時ip_finish_output2(填充鏈路層頭部到skb結構中)--------------〉

hh- hh_output/dsr- neighbour- output

總結

以上是生活随笔為你收集整理的linux网络协议栈之数据包处理过程,Linux网络协议栈之数据包处理过程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。