内容简介:tcp丢包分析系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,薛晓雯校对。继续分析实验,上回说到了为了深刻理解实验,我们要知道这些函数的作用以及所在层次。这四个函数的层次是自底向上递增的,那么先看第一个函数
tcp丢包分析系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,薛晓雯校对。
tcp丢包分析系列文章:
“tcp丢包分析”实验解析(一)--proc文件系统
“tcp丢包分析”实验解析(二)--kprobe和tracepoint
继续分析实验,上回说到了 kprobe
机制,说完机制自然要再说说策略,也就是实验里对 pre_handler
的实验,这才是本质内容。本实验总共对4个地方添加了 kprobe
钩子:
为了深刻理解实验,我们要知道这些函数的作用以及所在层次。这四个函数的层次是自底向上递增的,那么先看第一个函数 eth_type_trans
:
当一个包中断到来,驱动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过程和传统过程的对比:
可以看到 napi_gro_receive
可以就是NAPI方式处理POLL后的事宜。GRO也是一种合并各种包一起接收的技术,这里不展开了,参考https://lwn.net/Articles/358910/。
tcp_v4_rcv
则是比较上层的函数了,层次如图所示 :
回到实验,来看 pre_handler
实现,这里截取两个:
第一行函数其实看起来就有点懵,这其实是遵守了X86-64的ABI,来获取函数的参数。什么意思?在函数调用过程中,寄存器 pt_regs
保存了函数的参数列表,X86-64的约定如下:
当参数少于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_receive
的 pre_handler
则需要从rsi中取得SKB,因为 napi_gro_receive
中第二个参数接收SKB。
最后的任务就是实现 trace_packet
了:
可以看到主要还是为了根据报头获取源地址和目标地址的信息,也是本实验的目的所在。函数重点在 find_alloc_desc
上,这是用户态自己实现的不是内核函数,后续分析。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 关于在接收POST请求,Tomcat偶发性接收到的参数不全问题排查分析
- 异步接收MSMQ消息
- 如何突破商品期货Tick接收限制
- SpringMVC接收和响应json数据
- 如何使用 jq 接收 blob 数据
- 转的关于公众号接收信息的返回
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构、算法与应用
(美)Sartaj Sahni / 汪诗林、孙晓东、等 / 机械工业出版社 / 2000-01 / 49.00
本书是关于计算机科学与工程领域的基础性研究科目之一――数据结构与算法的专著。 本书在简要回顾了基本的C++ 程序设计概念的基础上,全面系统地介绍了队列、堆栈、树、图等基本数据结构,以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法,为数据结构与算法的继续学习和研究奠定了一个坚实的基础。更为可贵的是,本书不仅仅介绍了理论知识,还提供了50多个应用实例及600多道练习题。 本书......一起来看看 《数据结构、算法与应用》 这本书的介绍吧!