“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丢包分析”实验解析(三)--驱动接收包过程


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

查看所有标签

猜你喜欢:

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

数据结构、算法与应用

数据结构、算法与应用

(美)Sartaj Sahni / 汪诗林、孙晓东、等 / 机械工业出版社 / 2000-01 / 49.00

本书是关于计算机科学与工程领域的基础性研究科目之一――数据结构与算法的专著。 本书在简要回顾了基本的C++ 程序设计概念的基础上,全面系统地介绍了队列、堆栈、树、图等基本数据结构,以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法,为数据结构与算法的继续学习和研究奠定了一个坚实的基础。更为可贵的是,本书不仅仅介绍了理论知识,还提供了50多个应用实例及600多道练习题。 本书......一起来看看 《数据结构、算法与应用》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

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

HEX CMYK 互转工具