资讯动态

Linux 网络协议栈完整篇:从 sock_sendmsg、sk_buff 到NAPI 收发包与排障

发布时间:2026/9/6 14:08:07 来源:尧图企业网站定制
跨洲吞吐上不去、connect超时却ping正常、收包 CPU 飙在softirq、调了tcp_rmem仍无感——根因多半落在socket → TCP/IP → qdisc → 驱动某一层而不是某一个sysctl名字写错。本文沿发包与收包主路径对照源码锚点把状态机、sysctl、NAPI/GRO、常见坑与可执行 Checklist 合成一篇闭环便于用ss/tcpdump/softnet_stat验证。源码锚点路径作用net/socket.csock_sendmsg、__sys_sendmsg等系统调用入口include/net/sock.hstruct sock协议无关状态、队列、回调net/ipv4/tcp.c/tcp_output.c/tcp_input.ctcp_sendmsg、tcp_transmit_skb、tcp_rcv_establishednet/ipv4/tcp_ipv4.ctcp_v4_rcv、tcp_v4_connectnet/ipv4/ip_output.c/ip_input.cip_queue_xmit、ip_rcvnet/core/skbuff.c、include/linux/skbuff.hskb 生命周期与head/data/tail/endnet/core/dev.c、include/linux/netdevice.hdev_queue_xmit、netif_receive_skb、napi_structnet/sched/sch_generic.cqdisc 入队/出队net/ipv4/fib_*.c、net/netfilter/FIB 选路与 netfilter 挂钩Documentation/networking/网络子系统文档总览核心对象/* include/linux/skbuff.h */structsk_buff{structsk_buff*next,*prev;structsock*sk;sk_buff_data_ttail,end;unsignedchar*head,*data;unsignedinttruesize;/* … */};/* include/linux/netdevice.h */structnapi_struct{unsignedlongstate;intweight;int(*poll)(structnapi_struct*,int);structnet_device*dev;/* … */};发包骨架sock_sendmsg→tcp_sendmsg→tcp_transmit_skb/tcp_write_xmit→ip_queue_xmit→ip_local_out→dev_queue_xmit→ qdisc →ndo_start_xmit→ DMA。调用链发包与收包主路径send/writesock_sendmsgtcp_sendmsgtcp_transmit_skbip_queue_xmitip_local_out / nf_hookdev_queue_xmitqdisc_runndo_start_xmit → DMANIC RX / 硬中断napi_schedulenapi_pollnetif_receive_skb / GROip_rcv → tcp_v4_rcvsk_data_ready → read分层与数据流应用socket/sockTCP/拥塞IP/FIB/NFqdiscnet_deviceNAPI/GRO重点知识1. 发送路径从sock_sendmsg到ndo_start_xmitstruct socket是 BSD 门面状态在struct sock/tcp_sock窗口、重传队列、sk_write_queue。sock_sendmsg→tcp_sendmsg装 skb受发送窗口、拥塞窗口、qdisc、驱动 ring 共同约束。层瓶颈表象socketss的Send-Q打满TCPss -tin低 cwnd、高 retransqdisctc -s qdisc深度涨驱动ethtool -Sdrop / tx_timeoutskb 层间推拉data/tail避免整包拷贝TSO/GSO 推迟分段以降 CPU——抓包见大段不一定是线速异常。2. 接收路径与 NAPI / GRONIC DMA → 硬中断napi_schedule→ softirqnapi_poll受 budget→ GRO /netif_receive_skb→ip_rcv→tcp_v4_rcv→ socket 队列 →sk_data_ready。NAPI抑中断风暴/proc/net/softnet_stat的time_squeeze升 → 预算不够或单核过载。GRO聚合后tcpdump可能见「巨帧」非网卡乱发超长帧。多队列RSS/RPS/RFS 打散 softirq单核 100% 其它核空闲优先查亲和勿盲目加rmem。进阶XDP、sockmap、kTLS 改变处理/丢弃层级排障时纳入路径图。3. TCP 状态机、窗口与拥塞控制三次握手 / 四次挥手、滑动窗口与拥塞控制决定「能不能发出去、以多快发出去」算法族行为特征实践注意Reno/CUBIC丢包驱动降窗高丢包链路易吞吐塌陷BBR估带宽与 RTT常需fqqdisc注意 bufferbloat只改tcp_congestion_controlbbr不配fq收益常打折效果以本机ss -tin的 cwnd/rtt/delivery_rate 为准。somaxconn/tcp_max_syn_backlog过小 → SYN 丢或connect超时SYN cookie 抗洪不能掩盖 backlog 配错。长连接关注 keepalive 与防火墙对ESTABLISHED的超时。4. sysctl 配置与可验证调优配置写入/etc/sysctl.d/改前用ss/nstat建基线sysctlnet.core.rmem_max net.core.wmem_maxsysctlnet.ipv4.tcp_rmem net.ipv4.tcp_wmemsysctlnet.core.somaxconn net.ipv4.tcp_max_syn_backlogsysctlnet.ipv4.tcp_congestion_control net.ipv4.conf.all.rp_filtersysctlnet.core.netdev_budget net.core.netdev_max_backlog tc qdisc replace dev eth0 root fq# BBR 常配ss-tinstate established;ethtool-geth0ethtool-Seth0|grep-iEdrop|err|miss参数族作用常见坑tcp_rmem/tcp_wmem套接字缓冲自动调节未按 BDP带宽×RTT估算rmem_max/wmem_max缓冲上限setsockopt被截断somaxconn/tcp_max_syn_backlog监听与半连接高并发建连超时rp_filter反向路径过滤非对称路由误丢包netdev_max_backlogsoftirq 前积压softnet droptcp_congestion_controlqdisc拥塞与 pacingBBR 无 fqFIB 最长前缀匹配选路ARP/NDISC 解析下一跳。ping通只说明 ICMP 可达TCP 仍可能卡在策略路由、conntrack 或半连接队列。5. 常见坑与排障顺序固定顺序复现 → 收集ss/nstat/softnet_stat/ethtool -S/抓包 → 对比近期 sysctl/qdisc/防火墙变更 → 最小化隔离 → 记下根因与回归项。现象优先怀疑核对命令/点connect超时、ping正常半连接队列、防火墙、路由/NATss -s、SYN 抓包、iptables/nft、路由对称性吞吐上不去cwnd/RTT、缓冲不足、qdisc、丢包ss -tin、BDP、tc -s、对端重传softirq CPU 打满单队列、RPS 未开、budget、GRO 关闭softnet_stat、/proc/interrupts、RSS/RPS合法包被丢rp_filter、netfilter、conntrack 满sysctl、nft、conntrack -S抓包见「巨帧」GRO/GSO/TSO关闭 GRO 对比或看驱动 offload 状态内核丢包难定位skb 在钩子处被释放dropwatch、bpftrace跟kfree_skb观测速查ss -s、ss -tin、cat /proc/net/softnet_stat、nstat、SYN 抓包、perf top -e softirq_entry。安全侧SYN cookie、nft 限速、TLS/kTLS调优与加固分开避免为抗洪关掉必要 backlog。Checklist能口述sock_sendmsg→tcp_sendmsg→ip_queue_xmit→dev_queue_xmit→ndo_start_xmit及文件位置能口述收包napi_schedule→napi_poll→netif_receive_skb→ip_rcv/tcp_v4_rcv→sk_data_ready分清瓶颈在应用阻塞、TCP 窗口/拥塞、qdisc、还是驱动 ringss/tc/ethtool调tcp_rmem/wmem前算过 BDP并确认rmem_max/wmem_max未截断启用 BBR 时已确认 qdisc 为fq或等价 pacingconnect失败查过半连接队列、防火墙与路由对称性而非只加超时非对称路由评估过rp_filterGRO 大包未误判为网卡故障调优前有ss/nstat/softnet_stat基线配置可回滚小结设计意图sk_buff统一包模型socket/sock隔离协议NAPI 把收包挪到可控 softirqqdisc 分隔协议决策与设备出队。排障按「系统调用 → 协议状态 → netfilter/路由 → qdisc → 驱动/NAPI」推进优先改可观测、可回滚的缓冲/队列/亲和再碰拥塞算法与卸载。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价