Linux 網絡協議棧基於 TCP/IP 四層模型,在內核中實現高性能、模塊化、可擴展的網絠處理管道。本文自底向上剖析物理層、鏈路層、網絡層 (IP/ICMP/ARP)、傳輸層 (TCP/UDP)、應用層,並深入內核架構:Socket 層、協議無關層、協議實現層、設備無關接口層、驅動層,揭示 sk_buff、net_device、sock 核心數據結構與收發流程。
| TCP/IP 層 | Linux 內核實現 | 核心協議/組件 |
|---|---|---|
| 應用層 | 用戶態進程 | HTTP, DNS, SSH, MySQL, gRPC... (調用 Socket API) |
| 傳輸層 | 內核協議棧 | TCP (可靠、流式、擁塞控制), UDP (不可靠、數據報), SCTP, DCCP |
| 網絡層 | 內核協議棧 | IPv4/IPv6 (路由、分片、重組), ICMP (錯誤/查詢), ARP/RARP (地址解析), IGMP/MLD (組播) |
| 鏈路層 | 內核 + 驅動 | Ethernet (MAC, VLAN), WiFi, PPP, Bonding, Bridge, VXLAN, 虛擬設備 (veth, tun/tap) |
| 物理層 | 硬件 | 網卡 (NIC), 光模塊, 雙絞線, 光纖, 總線 (PCIe, USB) |
net/)+---------------------------------------------------------------+ | 1. 系統調用接口層 (Socket API) | | socket(), bind(), listen(), accept(), connect(), | | send/recv(), sendto/recvfrom(), setsockopt(), ioctl() | | → 入口: net/socket.c, sys_socket() 等 | +---------------------------------------------------------------+ | 2. 協議無關接口層 (Core Socket Layer) | | struct socket, struct sock, struct proto_ops | | 統一面向用戶態的操作向量: inet_stream_ops, inet_dgram_ops | | 管理 sock 狀態、接收/發送隊列、等待隊列、鎖、內存限制 | | → 核心: net/core/sock.c, net/ipv4/af_inet.c | +---------------------------------------------------------------+ | 3. 協議實現層 (Protocol Implementation) | | IPv4: net/ipv4/ (ip_input.c, ip_output.c, tcp_*.c, udp.c) | | IPv6: net/ipv6/ | | 核心邏輯: 三次握手、滑動窗口、擁塞控制 (CUBIC/BBR)、 | | IP 路由查找 (FIB/TRIE)、分片重組、Netfilter 掛鉤點 | | → 關鍵數據結構: sk_buff (封包描述符), dst_entry (路由緩存) | +---------------------------------------------------------------+ | 4. 設備無關接口層 (Network Device Interface) | | struct net_device_ops (ndo_open, ndo_start_xmit, ndo_stop) | | 統一不同驅動 (e1000e, igb, mlx5, virtio_net) 的操作接口 | | 流控: NAPI (中斷+輪詢), XDP (eBPF 早期掉包/轉發) | | → 核心: net/core/dev.c | +---------------------------------------------------------------+ | 5. 驅動程序層 (Device Drivers) | | 具體硬件驅動: drivers/net/ethernet/intel/e1000e/, | | drivers/net/ethernet/mellanox/mlx5/, | | drivers/net/virtio_net.c | | 負責: 硬件初始化、DMA 映射、中斷處理、收發環管理、 | | 硬件校驗和卸載 (TSO, LRO, RSS, Checksum Offload) | +---------------------------------------------------------------+
struct sk_buff {
struct sk_buff *next, *prev; // 雙向鏈表 (接收/發送隊列)
struct net_device *dev; // 輸入/輸出設備
unsigned char *head, *data; // 線性數據區頭/當前數據頭
unsigned char *tail, *end; // 尾部/結束位置
unsigned int len, data_len; // 總長度/片段數據長度
__u16 mac_header, network_header; // 各層頭部偏移
__u16 transport_header;
struct sock *sk; // 關聯 socket
struct dst_entry *dst; // 路由緩存條目
unsigned int mark; // 防火牆標記/策略路由
__be16 protocol; // 協議類型 (ETH_P_IP, ETH_P_IPV6)
// ... 引用計數、時間戳、擴展標簽 (secmark, nfct) ...
}
skb_reserve(skb, headroom) 為各層封裝預留空間,避免頻繁 skb_cow 複制。skb_shinfo(skb)->frags[] 指向頁片段 (零拷貝、大頁支持)。skb_clone 複製元數據共享數據區 (引用計數),skb_copy 完全深拷貝。ndo_poll_controller / napi_schedule → 關閉中斷,啟動 NAPI 輪詢。poll() 循環從 Ring 取數據 → napi_build_skb() / napi_alloc_skb() 構建 sk_buff → skb->protocol = eth_type_trans(skb, dev) 解析以太網類型 → netif_receive_skb(skb) 進入協議棧。ip_rcv() → 校驗和、分片重組、路由查找 (fib_lookup) → Netfilter PREROUTING → ip_local_deliver() → 協議分發 (inet_protos[protocol])。tcp_v4_rcv() → 查找 sock (__inet_lookup_skb) → 狀態機處理 (SYN/ACK/DATA/FIN) → 放入接收隊列 (sk_receive_queue) → 喚醒等待進程 (sk_data_ready)。recv() → tcp_recvmsg() → 從隊列拷貝數據到用戶緩衝區 (copy_to_user) → 更新窗口、發送 ACK。send() → tcp_sendmsg() → 分配 sk_buff、拷貝用戶數據 (copy_from_user) → 加入發送隊列 (sk_write_queue) → 嘗試發送 (tcp_push)。tcp_transmit_skb() → 構建 TCP 頭、計算校驗和 (硬件卸載) → ip_queue_xmit()。ip_output() → 路由查找、分片 (超過 MTU) → Netfilter POSTROUTING → dst_output() → dev_queue_xmit()。dev_queue_xmit() → QDisc (qdisc_pfifo_fast/fq_codel/htb) 排隊/整形 → __dev_xmit_skb() → 驅動 ndo_start_xmit() → 填充 Ring Buffer → 觸發硬件發送 → 完成中斷回收 skb。sendfile, splice, vmsplice, copy_file_range 避免用戶/內核態拷貝。Linux 網絡協議棚是內核中最複雜、最高性能的子系統之一。理解 四層模型映射、五層內核架構、sk_buff 生命週期、NAPI 收發流程、核心優化技術,是高性能網絡編程 (DPDK/XDP/eBPF)、內核網絡調試 (dropwatch, perf, bpftrace)、容器網絡 (CNI, CNI 插件, Service Mesh Sidecar) 故障診斷的核心基礎。

紅旗 Linux 桌面 5.0 安裝與使用 SAP GUI 客戶端完整教學
Ubuntu 14.04 運行 adb 提示「No such file or directory」解決方案
修正 SSH 登入後 ulimit 限制不生效的 PAM 配置問題
Linux Kickstart 全自動安裝實戰:從原理到 anaconda/ks.cfg 完整流程
Docker 容器與宿主機時間不同步?兩種修正時區的標準做法
Ubuntu 圖形介面建立使用者帳號:系統設定 → 使用者帳號 → 解鎖 → 新增標準/管理員帳號
Linux 原始碼套件安裝完整指南:./configure、make、make install、前綴路徑、清理與解除安裝