news 2026/9/6 14:08:05

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 网络协议栈完整篇:从 sock_sendmsg、sk_buff 到NAPI 收发包与排障

跨洲吞吐上不去、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_sendmsgtcp_transmit_skbtcp_rcv_established
net/ipv4/tcp_ipv4.ctcp_v4_rcvtcp_v4_connect
net/ipv4/ip_output.c/ip_input.cip_queue_xmitip_rcv
net/core/skbuff.cinclude/linux/skbuff.hskb 生命周期与head/data/tail/end
net/core/dev.cinclude/linux/netdevice.hdev_queue_xmitnetif_receive_skbnapi_struct
net/sched/sch_generic.cqdisc 入队/出队
net/ipv4/fib_*.cnet/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_sendmsgtcp_sendmsgtcp_transmit_skb/tcp_write_xmitip_queue_xmitip_local_outdev_queue_xmit→ qdisc →ndo_start_xmit→ DMA。

调用链

发包与收包主路径

send/write

sock_sendmsg

tcp_sendmsg

tcp_transmit_skb

ip_queue_xmit

ip_local_out / nf_hook

dev_queue_xmit

qdisc_run

ndo_start_xmit → DMA

NIC RX / 硬中断

napi_schedule

napi_poll

netif_receive_skb / GRO

ip_rcv → tcp_v4_rcv

sk_data_ready → read

分层与数据流

应用

socket/sock

TCP/拥塞

IP/FIB/NF

qdisc

net_device

NAPI/GRO


重点知识

1. 发送路径:从sock_sendmsgndo_start_xmit

struct socket是 BSD 门面;状态在struct sock/tcp_sock(窗口、重传队列、sk_write_queue)。sock_sendmsgtcp_sendmsg装 skb,受发送窗口、拥塞窗口、qdisc、驱动 ring 共同约束。

瓶颈表象
socketssSend-Q打满
TCPss -tin低 cwnd、高 retrans
qdisctc -s qdisc深度涨
驱动ethtool -Sdrop / tx_timeout

skb 层间推拉data/tail,避免整包拷贝;TSO/GSO 推迟分段以降 CPU——抓包见大段不一定是线速异常。

2. 接收路径与 NAPI / GRO

NIC DMA → 硬中断napi_schedule→ softirqnapi_poll(受 budget)→ GRO /netif_receive_skbip_rcvtcp_v4_rcv→ socket 队列 →sk_data_ready

  • NAPI:抑中断风暴;/proc/net/softnet_stattime_squeeze升 → 预算不够或单核过载。
  • GRO:聚合后tcpdump可能见「巨帧」,非网卡乱发超长帧。
  • 多队列:RSS/RPS/RFS 打散 softirq;单核 100% 其它核空闲优先查亲和,勿盲目加rmem

进阶:XDP、sockmap、kTLS 改变处理/丢弃层级,排障时纳入路径图。

3. TCP 状态机、窗口与拥塞控制

三次握手 / 四次挥手、滑动窗口与拥塞控制决定「能不能发出去、以多快发出去」:

算法族行为特征实践注意
Reno/CUBIC丢包驱动降窗高丢包链路易吞吐塌陷
BBR估带宽与 RTT常需fqqdisc;注意 bufferbloat

只改tcp_congestion_control=bbr不配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-iE'drop|err|miss'
参数族作用常见坑
tcp_rmem/tcp_wmem套接字缓冲自动调节未按 BDP(带宽×RTT)估算
rmem_max/wmem_max缓冲上限setsockopt被截断
somaxconn/tcp_max_syn_backlog监听与半连接高并发建连超时
rp_filter反向路径过滤非对称路由误丢包
netdev_max_backlogsoftirq 前积压softnet drop
tcp_congestion_control+qdisc拥塞与 pacingBBR 无 fq

FIB 最长前缀匹配选路;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、nftconntrack -S
抓包见「巨帧」GRO/GSO/TSO关闭 GRO 对比或看驱动 offload 状态
内核丢包难定位skb 在钩子处被释放dropwatchbpftracekfree_skb

观测速查:ss -sss -tincat /proc/net/softnet_statnstat、SYN 抓包、perf top -e softirq_entry。安全侧:SYN cookie、nft 限速、TLS/kTLS;调优与加固分开,避免为抗洪关掉必要 backlog。


Checklist

  • 能口述sock_sendmsgtcp_sendmsgip_queue_xmitdev_queue_xmitndo_start_xmit及文件位置
  • 能口述收包:napi_schedulenapi_pollnetif_receive_skbip_rcv/tcp_v4_rcvsk_data_ready
  • 分清瓶颈在应用阻塞、TCP 窗口/拥塞、qdisc、还是驱动 ring(ss/tc/ethtool
  • tcp_rmem/wmem前算过 BDP,并确认rmem_max/wmem_max未截断
  • 启用 BBR 时已确认 qdisc 为fq(或等价 pacing)
  • connect失败查过半连接队列、防火墙与路由对称性,而非只加超时
  • 非对称路由评估过rp_filter;GRO 大包未误判为网卡故障
  • 调优前有ss/nstat/softnet_stat基线,配置可回滚

小结

设计意图:sk_buff统一包模型,socket/sock隔离协议,NAPI 把收包挪到可控 softirq,qdisc 分隔协议决策与设备出队。排障按「系统调用 → 协议状态 → netfilter/路由 → qdisc → 驱动/NAPI」推进;优先改可观测、可回滚的缓冲/队列/亲和,再碰拥塞算法与卸载。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 14:06:13

Linux新手必学:常用命令、权限与文本处理实战指南

简介:一份面向Linux新手的常用命令速查手册,系统梳理了通用命令、Ubuntu专用命令与系统信息查看三大类操作。内容覆盖date、pwd、more/less、chmod、ps、kill等基础指令,也包含dpkg与apt软件包管理、uname、cat /proc/cpuinfo等系统状态查询&…

作者头像 李华
网站建设 2026/9/6 14:02:31

Linux sort命令详解:从文本排序到日志分析实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 14:01:50

火电机组建模与仿真:基于Matlab/Simulink的600MW机组实现全解析

简介:这是基于Matlab/Simulink的大型火电机组建模与仿真研究毕业论文PDF,面向热能动力、电气工程及自动化等专业学生与相关科研人员,适合需要系统理解火电机组建模思路与仿真应用的读者。PDF文档共1个文件,包体仅5.16MB&#xff0…

作者头像 李华
网站建设 2026/9/6 14:01:18

微服务链路追踪实战:从traceId到全链路排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 14:00:05

量子计算为何比超算快1亿亿倍:从量子叠加与并行性解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 13:57:21

API实测对比DeepSeek与GPT:中文推理、代码生成与模型选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华