0%

传统数据包收发流程

传统的数据包收发流程

当网卡收到一个数据包之后,通过DMA的方式将这个数据包放到接收队列中,接着触发一次硬件中断,收到这个中断通知的程序(操作系统),会为这个数据包创建一个缓冲对象(sk_buff), 将其拷贝到缓冲对象中。

这里有几个知识点,DMA可以解放CPU,让硬件直接通讯,网卡直接把数据放到内存中就不需要CPU参与。

中断分为两种,一种是硬中断,另外一种是软中断。其中中断相当于玩游戏过程中,外卖小哥突然来电话告知快餐已送达。必须停止手上的工作来处理中断。

硬中断一般是由外部设备,比如:网卡,键盘触发引起。他们让CPU停止正在处理的事情转而处理优先级更高的中断程序。

软中断是指处理硬件中断服务程序对操作系统内核的中断。

将上述信息整理解释如下:网卡收到数据包后,不需要CPU参与,直接把这个数据包放到内存中的一块特殊的缓冲区中,这个缓冲区是一个环形的,大小有限,如果一直往里面塞数据,很快就会被塞满,所以必须尽快处理。于是网卡触发了一个硬件中断告诉CPU停止当前工作,CPU就会转到网卡驱动程序处理这个数据包,驱动程序将其包装成sk_buff这个系统内核对象。接着网卡驱动触发了一次软件中断,告诉内核数据包已经准备好了,于是内核接收到这个中断,开始解析这个数据包,整个过程如下:

DMAData

从上面的介绍可以看出,处理简简单单的一个数据包还是很复杂的,linux在2.6之后有一个优化,可以批量处理数据包。

具体流程是先关闭中断,然后等待数据包过来,等到收到N个数据包后,就将这些数据包放到内存环形缓冲区中,然后发送一个硬件中断,等处理程序处理完环形缓冲区的数据包后,网卡再打开中断继续接收数据包。

虽然网卡可以批量处理,但是内核解析数据包的效率还是很低。数据包会先到链路层,检查数据包的合法性,然后找出上层(也就是IP层)的类型,是IPV4还是IPV6,然后去掉数据包的帧头,帧尾,再交给网络层

网络层取出IP头,根据网络包的下一步走向,也就是目标IP地址是否属于本机,来判断是继续转发出去还是自己处理,如果是自己处理就需要再解析,去掉IP头然后交给上层传输层

传输层取出TCP或者UDP头,根据<源IP, 源端口, 目标IP, 目标端口>作为标识,找到对应的socket,并把数据拷贝到socket的接收缓冲区中。至此最上层的应用程序就可以处理这个数据包了。

-------------Thanks for your attention-------------