“tcp丢包分析”实验解析(三)--驱动接收包过程

栏目: IT技术 · 发布时间: 4年前

内容简介:tcp丢包分析系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,薛晓雯校对。继续分析实验,上回说到了为了深刻理解实验,我们要知道这些函数的作用以及所在层次。这四个函数的层次是自底向上递增的,那么先看第一个函数

tcp丢包分析系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,薛晓雯校对。

tcp丢包分析系列文章:

“tcp丢包分析”实验解析(一)--proc文件系统

“tcp丢包分析”实验解析(二)--kprobe和tracepoint

继续分析实验,上回说到了 kprobe 机制,说完机制自然要再说说策略,也就是实验里对 pre_handler 的实验,这才是本质内容。本实验总共对4个地方添加了 kprobe 钩子:

为了深刻理解实验,我们要知道这些函数的作用以及所在层次。这四个函数的层次是自底向上递增的,那么先看第一个函数 eth_type_trans

“tcp丢包分析”实验解析(三)--驱动接收包过程

当一个包中断到来,驱动ISR响应,首先会调用 dev_alloc_skb 来生成一个SKB,随后就要调用 eth_type_trans 来获取包的协议填充到这个SKB中,内核注释一句话解释:

为什么要填充它的 protocol 呢?因为驱动接收包后就中断,随后进入哪条处理路径完全取决于 protocol 。根据上图,完成 dev_alloc_skb 以及 eth_type_trans 随后会调用 netif_rx (或者 netif_rx_schedule ,随后讲解)触发软中断, ISR 返回。之后软中断调用 process_backlog 中的 poll 函数,最终 netif_receive_skb 会调用 deliver_skb 将报文传递给相应的协议处理函数,即这就是协议栈的入口函数,实际会调用 __netif_receive_skb ,也是我们第三个添加 kprobe 钩子的函数, -core 后缀表明它是在特定场景(忽略XDP等)使用的简单版本。

那么第二个函数 napi_gro_receive 是什么?看过内核网络的老板们都应该听说过 NAPI ,我这里简单说下方便大家理解。综合整个收包逻辑,大致可以分为以下两种方式:

a. 每个数据包到来即中断CPU,由CPU调度中断处理程序进行收包处理,收包逻辑又分为上半部和下半部,核心的协议栈处理逻辑在下半部完成。

b. 数据包到来,中断CPU,CPU调度中断处理程序并且关闭中断响应,调度下半部不断轮询网卡,收包完毕或者达到一个阀值后,重新开启中断。

方式a就是上图讲述的过程,而方式b是 Linux NAPI 采用的方式。NAPI是中断与轮询的结合,可以想象,数据量很低与很高时,NAPI可以分别发挥中断与轮询方式的优点,性能较好。如果数据量不稳定,则NAPI则会在两种方式切换上消耗不少时间,效率反而较低一些。下面这个图显示了NAPI过程和传统过程的对比:

“tcp丢包分析”实验解析(三)--驱动接收包过程

可以看到 napi_gro_receive 可以就是NAPI方式处理POLL后的事宜。GRO也是一种合并各种包一起接收的技术,这里不展开了,参考https://lwn.net/Articles/358910/。

tcp_v4_rcv 则是比较上层的函数了,层次如图所示

“tcp丢包分析”实验解析(三)--驱动接收包过程

回到实验,来看 pre_handler 实现,这里截取两个:

第一行函数其实看起来就有点懵,这其实是遵守了X86-64的ABI,来获取函数的参数。什么意思?在函数调用过程中,寄存器 pt_regs 保存了函数的参数列表,X86-64的约定如下:

“tcp丢包分析”实验解析(三)--驱动接收包过程

当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。

当参数为7个以上时, 前 6 个与前面一样, 但后面的依次从 “右向左” 放入栈中。

例如:

H(a, b, c, d, e, f, g, h);

a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%r8, f->%r9

h->8(%esp)

g->(%esp)

call H

所以,第一个语句 structsk_buff*skb=(void*)regs->di; 其实就是拿到函数 eth_type_trans 的第一个参数,即一个skb。 eth_type_trans 前面说过是在驱动中完成的,所以它拿到SKB的data还是指在MAC报头的,所以 pre_handler 需要将 skb->data 加一个以太网报头长度 ETH_HLEN (实际上是14)的长度变成IP报头。而 kprobe_napi_gro_receivepre_handler 则需要从rsi中取得SKB,因为 napi_gro_receive 中第二个参数接收SKB。

最后的任务就是实现 trace_packet 了:

可以看到主要还是为了根据报头获取源地址和目标地址的信息,也是本实验的目的所在。函数重点在 find_alloc_desc 上,这是用户态自己实现的不是内核函数,后续分析。

“tcp丢包分析”实验解析(三)--驱动接收包过程


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法基础

算法基础

布拉萨德 / 邱仲潘 / 清华大学出版社 / 2005-7 / 49.00元

本书是关于算法导论的经典教材,书中包括大量例题解答与命题证明。本书是按照算法类型而不是按照应用类型对算法进行介绍,以其清晰的概念讲解赢得专家们的广泛赞誉。本书适用对象广泛。对于学习算法设计与分析的本科生和研究生,本书是优透选教材。对于从事算法计算研究和工程应用的科研人员和工程技术人员,本书也是一本优秀的基础性读物。一起来看看 《算法基础》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具