在 Linux 内核网络开发中,网络丢包一直是一个令人头疼的问题。传统的网络抓包工具(如 tcpdump)虽能协助排查问题,但效率不高,且在深入分析网络丢包时存在诸多限制。如今,随着 eBPF 技术的崛起,字节跳动 STE 团队基于该技术开发了一款强大的内核网络抓包工具—— netcap(全称 net capture,内部原名 xcap),并已正式 开源!
📌 GitHub 地址:https://github.com/bytedance/netcap
该工具可以用于 美国服务器,在海外部署 Linux 服务器的开发者也可以高效排查网络问题!
🌟 1. netcap 亮点概览
🔍 全内核追踪能力:相比 tcpdump 仅能捕获内核协议栈特定位置的数据包,netcap 可以跟踪整个内核网络协议栈(所有 skb 相关函数)。
💡 兼容 tcpdump 语法:可使用熟悉的 tcpdump 语法作为过滤条件,轻松掌握整个网络报文在内核中的完整路径。
⚡ 高效定位丢包:基于 eBPF 技术,大幅提升 Linux 服务器 的网络丢包问题排查效率,支持 美国服务器 及全球数据中心环境。
🛠️ 2. 使用示例
🔹 示例 1:追踪特定 IP 地址的 ICMP 报文
📌 目标:查看 10.227.0.45 的 icmp 包是否到达 内核预期的函数调用点。
netcap skb -f icmp_rcv@1 -i eth0 -e "host 10.227.0.45" -t "-nnv"
🔹 参数解析:
-f icmp_rcv@1:跟踪icmp_rcv函数的 第 1 个参数(即skb)。-i eth0:指定网卡接口。-e "host 10.227.0.45":tcpdump语法过滤规则,仅关注10.227.0.45的数据包。-t "-nnv":tcpdump格式化输出。
🔹 示例 2:定位 TCP 端口 9000 的丢包点
📌 目标:查看 TCP 端口 9000 的报文丢包位置,并打印调用栈。
netcap skb -f tracepoint:skb:kfree_skb -e "tcp port 9000" -S
🔹 参数解析:
-f tracepoint:skb:kfree_skb:监控kfree_skb事件,查找丢包发生位置。-e "tcp port 9000":仅关注 9000 端口的数据包。-S:打印 调用栈,快速定位丢包源头。
🔬 3. netcap 设计与实现
📌 核心架构
- 基于 eBPF:采用
kprobe/tracepoint动态 hook 关键函数,提取skb和sock结构体。 - 高效数据传输:通过
bpf map传递数据至 用户态,减少内核干扰,提高抓包效率。 - 与
tcpdump深度结合:利用tcpdump解析网络数据包,支持pcap格式存储。
🏗 技术实现
1️⃣ 基于 tcpdump 语法的 eBPF 过滤
netcap使用cbpfc库将 tcpdump 语法 转换为 C 语言函数,嵌入eBPF代码。- 过滤逻辑:
tcpdump语法 →cBPF指令码 →C 语言函数→eBPF 程序。
2️⃣ 如何解析并显示数据包
netcap启动后,会 自动运行tcpdump,以 标准输入流 解析pcap数据,并以用户指定的格式输出。
3️⃣ 如何获取完整的 skb 数据
- 在 发送方向,有些
skb结构未完整填充(如__ip_finish_output)。 netcap通过sock结构 推导 并 补全 关键信息,确保数据包完整。
🔄 4. 高级功能与扩展
🔹 多 Trace 点时间分析
📌 目标:跟踪数据包经过 多个 trace 点 的时间,计算网络延迟。
netcap skb -f tracepoint:net:netif_receive_skb,ip_local_deliver@1,ip_local_deliver_finish@3,icmp_rcv@1 -e "host 10.227.0.72 and icmp" -i eth0 --gather --gather-output-color cyan
📌 输出示例:不同 trace 点的 时间戳,可用于分析 数据包的网络时延。
🔹 自定义过滤与输出
📌 目标:用户可以 自定义过滤规则和输出格式,增强调试能力。
1️⃣ 自定义过滤
static inline int xcap_user_filter(void *ctx, void *pkt, u16 trace_index) {
return 1; // 返回 1 代表不过滤
}
2️⃣ 自定义输出
struct xcap_user_extend {
int a; // format: 0x%x
uint32_t b;
int64_t c;
uint8_t x1; // format: %c
};
📌 支持的数据类型:int8_t, uint8_t, char, int16_t, uint16_t, int, uint32_t, int64_t, uint64_t(不支持指针和数组)。
🚀 5. 未来展望
netcap 已经成为 Linux 服务器 上强大的网络抓包工具,特别适用于 美国服务器 和全球云计算环境。未来,团队将继续优化以下功能:
✅ 增强 DPDK 支持,提升高性能网络数据包抓取能力。
✅ 支持多种 Linux 内核版本,提升兼容性。
✅ 优化自定义输出,解决高并发场景下的日志错乱问题。
欢迎开发者们 Star & PR,一起共建开源项目!
GitHub 地址:https://github.com/bytedance/netcap
