linux操作系統網絡數據流程(1)

前言

這部分準備總結主機如何從 網卡抓取數據然後再將數據通過TCP/IP協議棧逐個向上傳遞的。不過在總結這部分的時候不再像教科書一樣對各個數據結構進行補充,而是跳過數據結構部分直接動態的描述數據的流程和流向,部分地方可能會參考源代碼。

數據接收

傳統對數據的接收有兩種方式一種採用輪詢的方式,一種採用中斷的方式。而爲了提升數據傳輸的效率目前也提出了結合輪詢和中斷兩種方式的結合體NAPI方式。

NAPI的實現:如果一批數據的第一個數據包到達網絡設備,採用中斷的方式(硬中斷)通知系統,硬中斷處理中,系統將設備添加到cpu的設備輪詢隊列中,並關閉中斷,同時激活數據包處理軟中斷;軟中斷遍歷輪詢隊列中的網絡設備,並從中讀取數據包。具體實現流程如下:


寫到這裏將不得不開始將源代碼納入分析了。net_rx_action 該函數爲網絡輸入軟中斷處理例程。如果網絡設備有數據包輸入的時候,非NAPI和NAPI的網絡設備驅動程序,一般都會激活網絡輸入軟中斷處理例程。既然中斷(軟中斷或者硬中斷)涉及設備,那麼設備就不得不提及驅動程序。net_rx_action的調用自然也就是在驅動程序中調用的。

(軟中斷處理歷程在系統初始化的時候在net_dev_init函數中註冊的網絡報文輸入/輸出處理例程的。代碼如下)

拿e100驅動程序來說,數據包到達網絡設備的時候設備觸發中斷,然後由e100_intr函數處理。該函數調用__netif_rx_schedule函數最終激活net_rx_action網絡輸入軟中斷處理例程。net_rx_action執行過程中會調用e100_poll函數,該函數爲e100的輪詢處理函數該函數通過調用e100_rx_clean函數進一步調用netif_receive_skb函數將數據包向上傳遞。

不論是NAPI或者非NAPI的方式最後都將調用netif_receive_skb函數將數據向上傳遞。該函數遍歷ptype_all鏈表,輸入報文到ptype_all鏈表輸入接口,然後橋接轉發,如果轉發成功則不需要輸入到本地,否則遍歷ptype_base散列表,根據接收報文的傳輸層協議,調用相應的報文接收例程。如果是ip數據報則採用ip_rcv函數向上傳遞。

這裏有一點就是主機能對自己輸出的數據包進行捕獲,當使用socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL))創建原始套接口的時候就可以捕獲本地主機輸出的滿足條件的數據包。(這裏有一篇我本人關於使用該方式捕獲數據包的代碼樣例博文)而dev_queue_xmit_nit則用於接收本地輸出的數據包。並將數據包輸入到RAW套接口。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章