龙蜥开源内核追踪利器 Surftrace:协议包解析效率提升 10 倍 | 龙蜥技术

简介:如何将网络报文与内核协议栈清晰关联起来精准追踪到关注的报文行进路径呢?

文/系统运维 SIG

Surftrace 是由系统运维 SIG 推出的一个 ftrace 封装器和开发编译平台,让用户既能基于 libbpf 快速构建工程进行开发,也能作为 ftrace 的封装器进行 trace 命令编写。项目包含 Surftrace 工具集和 pylcc、glcc(python or generic C language for libbpf Compiler Collection),提供远程和本地 eBPF 的编译能力。

通过对 krobe 和 ftrace 相关功能最大化抽象,同时对各种场景下的追踪能力增强(比如网络协议抓包),使得用户非常快速的上手,对定位问题效率提升 10 倍以上。另外,现如今火到天际的技术——eBPF,Surftrace 支持通过 libbpf 及 CO-RE 能力,对 bpf 的 map 和 prog 等常用函数进行了封装和抽象,基于此平台开发的 libbpf 程序可以无差别运行在各个主流内核版本上,开发、部署和运行效率提升了一个数量级。

Surftrace 最大的优势在于将当前主流的 trace 技术一并提供给广大开发者,可以通过 ftrace 也可以使用 eBPF,应用场景覆盖内存、IO 等 Linux 各个子系统,特别是在网络协议栈跟踪上面,对 skb 内部数据结构,网络字节序处理做到行云流水,把复杂留给自己,简单留给你。今天就让我们来见识一下 Surftrace 在网络领域的强劲表现吧。

一、理解 Linux 内核协议栈

定位网络问题是一个软件开发者必备一项基础技能,诸如 ping 连通性、tcpdump 抓包分析等手段,可以对网络问题进行初步定界。然而,当问题深入内核协议栈内部,如何将网络报文与内核协议栈清晰关联起来,精准追踪到关注的报文行进路径呢?

1.1 网络报文分层结构

引用自《TCP/IP 详解》卷一。

如上图所示,网络报文对数据报文数据在不同层进行封装。不同 OS 均采用一致的报文封装方式,达到跨软件平台通讯的目的。

1.2 sk_buff 结构体

sk_buff 是网络报文在 Linux 内核中的实际承载者,它在 include/linux/skbuff.h 文件中定义,结构体成员较多,本文不逐一展开。

用户需要重点关注下面两个结构体成员:

unsignedchar *head, *data;

其中 head 指向了缓冲区开始,data 指向了当前报文处理所在协议层的起始位置,如当前协议处理位于 tcp 层,data 指针就会指向 struct tcphdr。在 IP 层,则指向了struct iphdr。因此,data 指针成员,是报文在内核处理过程中的关键信标。

1.3 内核网络协议栈地图

下图是协议栈处理地图,可以保存后放大观看(图源网络)。

不难发现,上图中几乎所有函数都涉及到 skb 结构体处理,因此要想深入了解网络报文在内核的处理过程,skb->data 应该就是最理想的引路蜂。

二、Surftrace 对网络报文增强处理

Surftrace 基于 ftrace 封装,采用接近于 C 语言的参数语法风格,将原来繁琐的配置流程优化到一行命令语句完成,极大简化了 ftrace 部署步骤,是一款非常方便的内核追踪工具。但是要追踪网络报文,光解析一个 skb->data 指针是远远不够的。存在以下障碍:

  • skb->data 指针在不同网络层指向的协议头并不固定;
  • 除了获取当前结构内容,还有获取上一层报文内容的需求,比如一个我们在 udphdr结构体中,是无法直接获取到 udp 报文内容;
  • 源数据呈现不够人性化。如 ipv4 报文 IP 是以一个 u32 数据类型,可读性不佳,过滤器配置困难。

针对上述困难,Surftrace 对 skb 传参做了相应的特殊处理,以达到方便易用的效果。

2.1 网络协议层标记处理

以追踪网协议栈报文接收的入口__netif_receive_skb_core 函数为例,函数原型定义:

staticint__netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc,  struct packet_type **ppt_prev);

解析每个 skb 对应报文三层协议成员的方法:

surftrace 'p __netif_receive_skb_core proto=@(struct iphdr *)l3%0->protocol`

协议成员获取方法为 @(struct iphdr *)l3%0->protocol。

tips:

  • 可以跨协议层向上解析报文结构体,如在 l3 层去分析 struct icmphdr 中的数据成员
  • 不可以跨协议层向下解析报文结构体,如在 l4 层去分析 struct iphdr 中的成员

2.2 扩充下一层报文内容获取方式

surftrace 为 ethhdr、iphdr、icmphdr、udphdr、tcphdr 结构体添加了 xdata 成员,用于获取下一层报文内容。xdata 有以下 5 类类型:

数组下标是按照位宽进行对齐的,比如要提取 icmp 报文中的 2~3 字节内容,组成一个 unsigned short 的数据,可以通过以下方法获取:

data=@(struct icmphdr*)l3%0->sdata[1]

2.3 IP 和字节序模式转换

网络报文字节序采取的是大端模式,而我们的操作系统一般采用小端模式。同时,ipv4 采用了一个 unsigned int 数据类型来表示一个 IP,而我们通常习惯采用 1.2.3.4 的方式来表示一个 ipv4 地址。上述差异导致直接去解读网络报文内容的时候非常费力。surftrace 通过往变量增加前缀的方式,在数据呈现以及过滤的时候,将原始数据根据前缀命名规则进行转换,提升可读性和便利性。

2.4  牛刀小试

我们在一个实例上抓到一个非预期的 udp 报文,它会往目标 ip 10.0.1.221 端口号  9988 发送数据,现在想要确定这个报文的发送进程。由于 udp 是一种面向无连接的通讯协议,无法直接通过 netstat 等方式锁定发送者。用 Surftrace 可以在 ip_output 函数处中下钩子:

intip_output(struct net *net, struct sock *sk, struct sk_buff *skb)

追踪表达式:

surftrace 'p ip_output proto=@(struct iphdr*)l3%2->protocol ip_dst=@(struct iphdr*)l3%2->daddr b16_dest=@(struct udphdr*)l3%2->dest comm=$comm body=@(struct udphdr*)l3%2->Sdata[0] f:proto==17&&ip_dst==10.0.1.221&&b16_dest==9988'

追踪结果:

surftrace 'p ip_output proto=@(struct iphdr*)l3%2->protocol ip_dst=@(struct iphdr*)l3%2->daddr b16_dest=@(struct udphdr*)l3%2->dest comm=$comm body=@(struct udphdr*)l3%2->Sdata[0] f:proto==17&&ip_dst==10.0.1.221&&b16_dest==9988' echo 'p:f0 ip_output proto=+0x9(+0xe8(%dx)):u8 ip_dst=+0x10(+0xe8(%dx)):u32 b16_dest=+0x16(+0xe8(%dx)):u16 comm=$comm body=+0x1c(+0xe8(%dx)):string' >> /sys/kernel/debug/tracing/kprobe_events echo 'proto==17&&ip_dst==0xdd01000a&&b16_dest==1063' > /sys/kernel/debug/tracing/instances/surftrace/events/kprobes/f0/filter echo 1 > /sys/kernel/debug/tracing/instances/surftrace/events/kprobes/f0/enable echo 0 > /sys/kernel/debug/tracing/instances/surftrace/options/stacktrace echo 1 > /sys/kernel/debug/tracing/instances/surftrace/tracing_on <...>-2733784 [014] .... 12648619.219880: f0: (ip_output+0x0/0xd0) proto=17 ip_dst=10.0.1.221 b16_dest=9988 comm="nc" body="Hello World\!  @"

通过上述命令,可以确定报文的发送的 pid 为 2733784,进程名为 nc。

三、实战:定位网络问题

接下来我们从一个实际网络网络问题出发,讲述如何采用 Surftrace 定位网络问题。

3.1 问题背景

我们有两个实例通讯存在性能问题,经抓包排查,确认性能上不去的根因是存在丢包导致的。幸运的是,该问题可以通过 ping 对端复现,确认丢包率在 10% 左右。

通过进一步抓包分析,可以明确报文丢失在实例 B 内部。

通过检查 /proc/net/snmp 以及分析内核日志,没有发现可疑的地方。

3.2 surftrace 跟踪

在 1.1 节的地图中,我们可以查到网络报文是内核由 dev_queue_xmit 函数将报文推送到网卡驱动。因此,可以在这个出口先进行 probe,过滤 ping 报文,加上 -s 选项,打出调用栈:

surftrace 'p dev_queue_xmit proto=@(struct iphdr *)l2%0->protocol ip_dst=@(struct iphdr *)l2%0->daddr f:proto==1&&ip_dst==192.168.1.3' -s

可以获取到以下调用栈:

由于问题复现概率比较高,我们可以将怀疑的重点方向先放在包发送流程中,即从 icmp_echo 函数往上,用 Surftrace 在每一个符号都加一个 trace 点,追踪下回包到底消失在哪里。

3.3 锁定丢包点

问题追踪到了这里,对于经验丰富的同学应该是可以猜出丢包原因。我们不妨纯粹从代码角度出发,再找一下准确的丢包位置。结合代码分析,我们可以在函数内部找到以下两处 drop 点:

通过 Surftrace 函数内部追踪功能,结合汇编代码信息,可以明确丢包点是出在了 qdisc->enqueue 钩子函数中。

rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK;

此时,可以结合汇编信息:

找到钩子函数存入的寄存名为 bx,然后通过 surftrace 打印出来。

surftrace 'p dev_queue_xmit+678 pfun=%bx'

然后将 pfun 值在 /proc/kallsyms 查找匹配。

至此可以明确是 htb qdisc 导致丢包。确认相关配置存在问题后,将相关配置回退,网络性能得以恢复。

四、总结

Surftrace 在网络层面的增强,使得用户只需要有相关的网络基础和一定的内核知识储备,就可以用较低编码工作量达到精准追踪网络报文在 Linux 内核的完整处理过程。适合用于追踪 Linux 内核协议栈代码、定位深层次网络问题。

参考文献:

【1】《TCP/IP详解》

【2】《Linux内核设计与实现》

【3】《深入理解 Linux 网络技术内幕》

【4】surftrace readmde:

surftrace/ReadMe.md at master · aliyun/surftrace · GitHub

【5】https://lxr.missinglinkelectronics.com

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源要正式写进法律了?

作者 | 何苗 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;去年&#xff0c;当大家还在为开源的快速发展而欢呼之际&#xff0c;影响了全球数百万台计算机Log4j 漏洞事件给开源软件开发者与使用者敲响了一记警钟。因而今年&#xff0c;开源软件及其供应链安全…

阿里云软著申请|这项保护,让我得到了10万赔偿

简介&#xff1a;对于企业来说&#xff0c;申请软件著作权是证明自己和保护自己的强力护盾。除此之外&#xff0c;它还有着很多不可忽视的意义与价值。阿里云软著申请&#xff0c;一站式智能服务&#xff0c;助力企业和开发者高效发展&#xff0c;省时省力更省心。 前几日&…

宜搭小技巧|海量数据管理难?这招帮你事半功倍

简介&#xff1a;一键生成数据管理页&#xff0c;海量数据随心管理&#xff01; 话接上回&#xff0c;宜小搭组织大家团建&#xff0c;当收集完大家的报名信息后&#xff0c;有小伙伴想要修改已提交的信息&#xff0c;面对海量的数据&#xff0c;整理查找太费时间。 如何快速…

1024 程序员节官方剧透:重磅大咖再聚,共话中国技术新生态

在二进制垒起的计算机世界里&#xff0c;1024 对于程序员而言&#xff0c;早已不再是单纯的一串数字&#xff0c;不断演进的开发时代赋予了它特殊的意义。 伴随着一份份热衷与期盼&#xff0c;10 月 22-24 日&#xff0c;由湖南湘江新区管委会主办&#xff0c;长沙工业与信息化…

前端性能优化实战

简介&#xff1a;引用彼得德鲁克的一句话&#xff0c;“You cant manage what you cant measure。一件事如果你无法衡量它、你就无法管理它”&#xff0c;性能同样如此。如果没有一个准确的方案来对性能进行度量&#xff0c;那优化就无从谈起。那么对于我们来说&#xff0c;哪些…

Elastic与阿里云助力汽车及出行产业数字化转型

简介&#xff1a;目前&#xff0c;阿里云和Elastic在全国已经有很多的项目正在开展合作&#xff0c;而在移动出行领域与享道出行的合作案例&#xff0c;则是代表性的。 在汽车产业变革逐步深入的当下&#xff0c;云计算、大数据等信息技术成为了汽车企业经历数字化转型时的“刚…

企业版Spark Databricks + 企业版Kafka Confluent 联合高效挖掘数据价值

简介&#xff1a;本文介绍了如何使用阿里云的Confluent Cloud和Databricks构建数据流和LakeHouse&#xff0c;并介绍了如何使用Databricks提供的能力来挖掘数据价值&#xff0c;使用Spark MLlib构建您的机器学习模型。 前提条件 已注册阿里云账号&#xff0c;详情请参见阿里云…

解决微服务架构下流量有损问题的实践和探索

简介&#xff1a;绝⼤多数的软件应⽤⽣产安全事故发⽣在应⽤上下线发布阶段&#xff0c;尽管通过遵守业界约定俗成的可灰度、可观测和可滚回的安全⽣产三板斧&#xff0c;可以最⼤限度的规避发布过程中由于应⽤⾃身代码问题对⽤户造成的影响。但对于⾼并发⼤流量情况下的短时间…

5月25日,阿里云开源 PolarDB-X 将迎来升级发布

简介&#xff1a;2022年5月25日&#xff0c;阿里云开源 PolarDB-X 将升级发布新版本&#xff01;PolarDB-X 从 2009 年开始服务于阿里巴巴电商核心系统&#xff0c; 2015 年开始对外提供商业化服务&#xff0c;并于 2021 年正式开源。本次发布会将重磅推出在稳定性、生态融合以…

技术分享丨云企业网CEN2.技术揭晓

简介&#xff1a;随着企业数字化转型的加速&#xff0c;越来越多的企业选择了将业务部署在云上&#xff0c;这其中有超过20%的企业有全球组网的需求&#xff0c;这就使得云上网络的规模越来越大&#xff0c;复杂度也越来越高&#xff0c;为了应对这些变化&#xff0c;阿里云推出…

MAE 自监督算法介绍和基于 EasyCV 的复现

简介&#xff1a;自监督学习&#xff08;Self-Supervised Learning&#xff09;能利用大量无标注的数据进行表征学习&#xff0c;然后在特定下游任务上对参数进行微调。通过这样的方式&#xff0c;能够在较少有标注数据上取得优于有监督学习方法的精度。近年来&#xff0c;自监…

企业实践|分布式系统可观测性之应用业务指标监控

简介&#xff1a;本文主要讲述如何建立应用业务指标Metrics监控和如何实现精准告警。Metrics 可以翻译为度量或者指标&#xff0c;指的是对于一些关键信息以可聚合的、数值的形式做定期统计&#xff0c;并绘制出各种趋势图表。透过它&#xff0c;我们可以观察系统的状态与趋势。…

1024 程序员节城市嘉年华,共话技术生涯的一万种可能!

更硬核的技术峰会&#xff0c;更多元的主题论坛&#xff0c;更丰富的科技元素……更热血的 1024 程序员节闪亮登场&#xff01;由湖南湘江新区管委会主办&#xff0c;长沙工业与信息化局、长沙信息产业园管委会与 CSDN 联合承办的第三届 2022 1024 程序员节将于 10 月 22 - 24 …

作业帮在线业务 Kubernetes Serverless 虚拟节点大规模应用实践

简介&#xff1a;目前方案已经成熟&#xff0c;高峰期已有近万核规模的核心链路在线业务运行在基于阿里云 ACKECI 的 Kubernetes Serverless 虚拟节点。随着业务的放量&#xff0c;未来运行在 Serverless 虚拟节点上的服务规模会进一步扩大&#xff0c;将节省大量的资源成本。 …

浅析微服务全链路灰度解决方案

简介&#xff1a;帮助应用发布版本过程中更精细化&#xff0c;提高了发布过程中的稳定性。服务转移⾄请求链路上进行流量控制&#xff0c;有效保证了多个亲密关系的服务顺利安全发布以及服务多版本并⾏开发&#xff0c;进⼀步促进业务的快速发展。 作者&#xff1a; 十眠&…

译:零信任对 Kubernetes 意味着什么

这篇是 Buoyant 的创始人 William Morgan 文章《# What Does Zero Trust Mean for Kubernetes?》[1]的翻译&#xff0c;文章很好的解释了什么是零信任、为什么要实施零信任&#xff0c;以及服务网格如何以最小的代码实现零信任。零信任是营销炒作&#xff0c;还是新的机会&…

Serverless 应用中心:Serverless 应用全生命周期管理平台

简介&#xff1a;Serverless 应用中心&#xff0c;是阿里云 Serverless 应用全生命周期管理平台。通过 Serverless 应用中心&#xff0c;用户在部署应用之前无需进行额外的克隆、构建、打包和发布操作&#xff0c;即可快速部署和管理应用。Serverless 应用中心帮助用户快速联动…

云钉一体:EventBridge 联合钉钉连接器打通云钉生态

简介&#xff1a;今天&#xff0c;EventBridge 联合钉钉连接器&#xff0c;打通了钉钉生态和阿里云生态&#xff0c;钉钉的生态伙伴可以通过通道的能力驱动阿里云上海量的计算力。 作者&#xff1a;尘央 背景 “以事件集成阿里云&#xff0c;从 EventBridge 开始”是 EventB…

开源当道,群英荟萃!1024 程序员节北京峰会火热来袭

1024 程序员节&#xff0c;致敬每一位二进制世界的主角。由开放原子开源基金会主办&#xff0c;北京经开区国家信创园、CSDN 承办的 2022 1024 程序员节北京峰会将于 10 月 24 日精彩来袭。以“软件新时代 开源创未来”为主题&#xff0c;聚焦开源新潮流&#xff0c;诚邀广大程…

超全,一图了解 2022 长沙 · 中国 1024 程序员节!

超全版来啦&#xff01;2022 长沙 中国 1024 程序员节重磅大咖再聚&#xff0c;共话中国技术新生态你想了解的全在这里收藏&#xff01;收藏&#xff01;收藏&#xff01;