這篇文章只是個筆記,大部分都是網上摘的,不過如果後續折騰軟路由以及相關協議開發還是相當有用的:
一、硬件層:物理信號的接收與轉換
外部流量(如以太網幀)通過物理介質(網線/光纖)傳輸,最終到達服務器的網絡接口卡(NIC,Network Interface Card)。網卡的核心功能是將物理信號(電/光)轉換為數字信號,並完成初步的數據封裝/校驗。
關鍵硬件處理步驟:
信號接收與數字化
網卡的PHY(物理層芯片)將光/電信號轉換為二進制數字信號(比特流),並通過MAC(介質訪問控制)子層組裝成以太網幀(包含MAC頭、IP頭、傳輸層頭、數據負載、CRC校驗碼)。
硬件校驗與過濾
- CRC校驗:網卡硬件自動驗證以太網幀尾部的CRC校驗碼,若校驗失敗則丟棄該幀(避免無效數據進入系統)。
- MAC地址過濾:網卡檢查目標MAC地址是否為本機MAC(單播)、廣播地址(FF:FF:FF:FF:FF:FF)或多播地址(若網卡啟用了多播接收)。非目標MAC的幀會被丟棄(除非網卡處於混雜模式)。
DMA傳輸到內存
若幀有效,網卡通過DMA(直接內存訪問)將數據直接寫入內核預分配的接收緩衝區(RX Ring Buffer),避免CPU頻繁參與數據拷貝,提升效率。
二、中斷與軟中斷:通知內核處理數據
DMA完成後,網卡通過硬中斷(Hardware Interrupt)通知CPU:“有新數據到達!”。為避免硬中斷頻繁打斷CPU(影響性能),現代Linux採用NAPI(New API)機制優化中斷處理流程。
關鍵中斷處理步驟:
硬中斷觸發
網卡的IRQ(中斷請求)線向CPU發送信號,CPU暫停當前任務,跳轉到網卡驅動註冊的中斷服務例程(ISR, Interrupt Service Routine)。
ISR快速處理
ISR的主要任務是確認數據已通過DMA寫入內存,並觸發軟中斷(Softirq)(一種延遲執行的軟中斷,由內核線程
ksoftirqd處理),然後將CPU控制權交還。注:現代網卡驅動普遍啟用NAPI,ISR僅標記“有數據待處理”,由軟中斷統一處理批量數據包,減少硬中斷次數。
軟中斷處理
內核的軟中斷子系統(
net_rx_action)被觸發,從RX Ring Buffer中讀取數據包,並傳遞給網絡驅動進一步處理。
三、驅動層:數據包的初步解析與傳遞
網卡驅動(如e1000e、ixgbe)負責將硬件層面的原始數據轉換為內核可識別的**sk_buff(Socket Buffer)**結構,並傳遞給上層協議棧。
關鍵驅動處理步驟:
數據包校驗與完整性檢查
驅動驗證以太網幀的完整性(如CRC已由硬件完成,此處可能跳過),並剝離鏈路層頭部(MAC頭),提取IP數據報(若為IPv4/IPv6)。
傳遞給網絡協議棧
驅動將封裝好的
sk_buff傳遞給內核網絡子系統的入口函數(如netif_rx()),進入協議棧處理流程。
四、內核協議棧:分層處理與路由決策
內核網絡協議棧按OSI模型分層處理數據包,從鏈路層→網絡層→傳輸層逐步向上,最終到達應用層。在此過程中,netfilter等模塊會介入進行流量控制或修改。
1. 鏈路層(Link Layer)處理
- 功能:處理以太網幀的頭部(源/目標MAC地址、類型字段),判斷上層協議類型(如IPv4的類型字段為
0x0800)。 - 關鍵操作:
- 若幀類型為ARP(地址解析協議),則傳遞給ARP模塊處理(解析IP到MAC的映射)。
- 若為IP協議(IPv4/IPv6),則剝離鏈路層頭部,將IP數據報傳遞給網絡層。
2. 網絡層(Network Layer,IP處理)
IP協議棧根據IP頭部的目標IP地址,決定數據包是本機接收還是轉發(若本機啟用了路由功能)。
關鍵處理步驟:
- 校驗和驗證:檢查IP頭部的校驗和(防止傳輸過程中數據損壞),失敗則丟棄。
- 選項處理:處理IP頭部的可選字段(如記錄路由、時間戳等,通常默認忽略)。
- 路由決策:
- 本地接收:若目標IP是本機配置的IP地址(或廣播/多播地址),則進入傳輸層處理。
- 轉發:若本機是路由器且目標IP不在本地網絡,則根據路由錶轉發至其他接口(需啟用
ip_forward)。
Netfilter介入點:PREROUTING鏈
在IP數據報進入網絡層後、路由決策前(或路由決策後,取決於數據包方向),netfilter框架的PREROUTING鏈會被觸發。常見操作包括:
- DNAT(目的地址轉換):修改目標IP/端口(如將公網IP映射到內網服務器)。
- 過濾(Filter):通過
iptables/nftables規則丟棄或接受數據包(如阻止特定IP的訪問)。 - 標記(Mark):為數據包打標籤(如
MARK目標),供後續模塊(如tc)使用。
3. 傳輸層(Transport Layer)處理
根據IP頭部的協議字段(如TCP=6,UDP=17),數據包被傳遞給對應的傳輸層協議處理模塊(如TCP調用tcp_v4_rcv()函數)。
TCP協議處理示例:
- 校驗和驗證:檢查TCP頭部的校驗和(基於偽IP頭+TCP頭+數據計算),失敗則丟棄。
- 端口分發:根據TCP頭部的目標端口,找到對應的socket(應用程序通過socket註冊的監聽端口)。
- 連接狀態管理:若為已建立連接(ESTABLISHED),將數據放入socket的接收緩衝區(
sk_buff隊列);若為新連接(SYN),則觸發三次握手流程。
UDP協議處理示例:
- 無連接特性,直接根據目標端口查找socket,將數據包放入接收緩衝區(無需建立連接)。
五、流量控制(Traffic Control, tc)
tc(Traffic Control)是Linux的流量整形工具,通過qdisc(排隊規則)、class(分類)和filter(過濾)對流量進行調度、限速、優先級調整。其介入位置通常在鏈路層與網絡層之間(入隊前)或傳輸層與協議棧之間(出隊後),具體取決於配置。
關鍵處理場景:
- 入隊控制(Ingress Shaping):在數據包進入協議棧前(如通過
ifb虛擬設備),對流量進行限速、丟棄或重新標記(如配合netfilter的MARK)。 - 出隊控制(Egress Shaping):在數據包離開網卡前,根據優先級調度(如優先保證VoIP流量),避免擁塞丟包。
注:tc通常用於出口流量控制,但通過ifb等虛擬設備也可實現入口流量管理。
六、應用層:數據傳遞給用戶空間
傳輸層將數據包放入socket的接收緩衝區後,應用程序通過系統調用(如recv()、read())從用戶空間觸發數據拷貝。
關鍵步驟:
- 系統調用觸發:應用程序調用
recv(sockfd, buf, len, 0),內核檢查socket的接收緩衝區是否有數據。 - 數據拷貝:若有數據,內核將
sk_buff中的負載從內核空間拷貝到用戶空間的buf中。 - 喚醒進程:若應用程序因等待數據而阻塞(如調用
recv()時處於睡眠狀態),內核會喚醒該進程繼續執行。
總結:完整處理流程圖
1物理介質 → 網卡(信號接收/DMA) → 硬中斷 → 軟中斷/NAPI → 驅動(解析/MAC過濾) → 鏈路層(協議分發) → netfilter PREROUTING → 網絡層(IP路由/校驗) → 傳輸層(TCP/UDP分發) → tc(流量控制) → socket接收緩衝區 → 應用程序(系統調用讀取)