訂閱
糾錯
加入自媒體

Linux內核源代碼:tcp/ip協議棧的調用

2021-06-21 10:33
一口Linux
關注

6 數據鏈路層流程

6.1 發(fā)送端

功能上,在物理層提供比特流服務的基礎上,建立相鄰結點之間的數據鏈路,通過差錯控制提供數據幀(Frame)在信道上無差錯的傳輸,并進行各電路上的動作系列。

數據鏈路層在不可靠的物理介質上提供可靠的傳輸。

該層的作用包括:物理地址尋址、數據的成幀、流量控制、數據的檢錯、重發(fā)等。在這一層,數據的單位稱為幀(frame)。數據鏈路層協議的代表包括:SDLC、HDLC、PPP、STP、幀中繼等。

實現上,Linux 提供了一個 Network device 的抽象層,其實現在 linux/net/core/dev.c。具體的物理網絡設備在設備驅動中(driver.c)需要實現其中的虛函數。Network Device 抽象層調用具體網絡設備的函數。

發(fā)送端調用dev_queue_xmit,這個函數實際上調用__dev_queue_xmit:

發(fā)現它調用了dev_hard_start_xmit函數:

調用xmit_one:

調用trace_net_dev_start_xmit,實際上調用__net_dev_start_xmit函數:

到此,調用鏈結束。gdb調試如下:

6.2 接收端

簡要過程:

一個 package 到達機器的物理網絡適配器,當它接收到數據幀時,就會觸發(fā)一個中斷,并將通過 DMA 傳送到位于 linux kernel 內存中的 rx_ring。

網卡發(fā)出中斷,通知 CPU 有個 package 需要它處理。中斷處理程序主要進行以下一些操作,包括分配 skb_buff 數據結構,并將接收到的數據幀從網絡適配器I/O端口拷貝到skb_buff 緩沖區(qū)中;

從數據幀中提取出一些信息,并設置 skb_buff 相應的參數,這些參數將被上層的網絡協議使用,例如skb->protocol;

終端處理程序經過簡單處理后,發(fā)出一個軟中斷(NET_RX_SOFTIRQ),通知內核接收到新的數據幀。

內核 2.5 中引入一組新的 API 來處理接收的數據幀,即 NAPI。所以,驅動有兩種方式通知內核:(1) 通過以前的函數netif_rx;(2)通過NAPI機制。該中斷處理程序調用 Network device的 netif_rx_schedule 函數,進入軟中斷處理流程,再調用 net_rx_action 函數。

該函數關閉中斷,獲取每個 Network device 的 rx_ring 中的所有 package,最終 pacakage 從 rx_ring 中被刪除,進入 netif _receive_skb 處理流程。

netif_receive_skb 是鏈路層接收數據報的最后一站。它根據注冊在全局數組 ptype_all 和 ptype_base 里的網絡層數據報類型,把數據報遞交給不同的網絡層協議的接收函數(INET域中主要是ip_rcv和arp_rcv)。該函數主要就是調用第三層協議的接收函數處理該skb包,進入第三層網絡層處理。

入口函數是net_rx_action:

發(fā)現調用napi_poll,實質上調用napi_gro_receive函數:

napi_gro_receive 會直接調用 netif_receive_skb_core。而它會調用__netif_receive_skb_one_core,將數據包交給上層 ip_rcv 進行處理。

調用結束之后,通過軟中斷通知CPU,至此,調用鏈結束。gdb驗證如下:

7 物理層流程

7.1 發(fā)送端

物理層在收到發(fā)送請求之后,通過 DMA 將該主存中的數據拷貝至內部RAM(buffer)之中。在數據拷貝中,同時加入符合以太網協議的相關header,IFG、前導符和CRC。對于以太網網絡,物理層發(fā)送采用CSMA/CD,即在發(fā)送過程中偵聽鏈路沖突。

一旦網卡完成報文發(fā)送,將產生中斷通知CPU,然后驅動層中的中斷處理程序就可以刪除保存的 skb 了。

7.2 接收端

一個 package 到達機器的物理網絡適配器,當它接收到數據幀時,就會觸發(fā)一個中斷,并將通過 DMA 傳送到位于 linux kernel 內存中的 rx_ring。

網卡發(fā)出中斷,通知 CPU 有個 package 需要它處理。中斷處理程序主要進行以下一些操作,包括分配 skb_buff 數據結構,并將接收到的數據幀從網絡適配器I/O端口拷貝到skb_buff 緩沖區(qū)中;從數據幀中提取出一些信息,并設置 skb_buff 相應的參數,這些參數將被上層的網絡協議使用,例如skb->protocol;

終端處理程序經過簡單處理后,發(fā)出一個軟中斷(NET_RX_SOFTIRQ),通知內核接收到新的數據幀。

內核 2.5 中引入一組新的 API 來處理接收的數據幀,即 NAPI。所以,驅動有兩種方式通知內核:(1) 通過以前的函數netif_rx;(2)通過NAPI機制。該中斷處理程序調用 Network device的 netif_rx_schedule 函數,進入軟中斷處理流程,再調用 net_rx_action 函數。

該函數關閉中斷,獲取每個 Network device 的 rx_ring 中的所有 package,最終 pacakage 從 rx_ring 中被刪除,進入 netif _receive_skb 處理流程。

netif_receive_skb 是鏈路層接收數據報的最后一站。它根據注冊在全局數組 ptype_all 和 ptype_base 里的網絡層數據報類型,把數據報遞交給不同的網絡層協議的接收函數(INET域中主要是ip_rcv和arp_rcv)。該函數主要就是調用第三層協議的接收函數處理該skb包,進入第三層網絡層處理。

8 時序圖展示和總結

時序圖如下:

本次實驗主要是通過分析Linux內核源代碼,一步步地通過gdb進行調試函數調用鏈,最終清楚了tcp/ip協議棧的調用過程。因為時間有限,部分細節(jié)可能會有錯誤,希望讀者多加指正。

<上一頁  1  2  3  4  
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權或其他問題,請聯系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

    掃碼關注公眾號
    OFweek人工智能網
    獲取更多精彩內容
    文章糾錯
    x
    *文字標題:
    *糾錯內容:
    聯系郵箱:
    *驗 證 碼:

    粵公網安備 44030502002758號