数据包从网卡到应用进程

数据包从网卡到应用进程_第1张图片

 从空间来看,从网卡到内核空间,再到用户空间,整个过程就是内核将网卡中的数据包拷贝到应用程序。

1.网卡

网卡收到的是数据包的电信号,收到该电信号之后,会将该电信号转化为数字信息,然后进行FCS校验,最后检查数据包的MAC地址是否匹配。

网卡将电信号转化为数字信息之后包含的数据包的信息如下所示:

数据包从网卡到应用进程_第2张图片

还原后的数据信息会在网卡上,根据 FCS(帧校验序列,Frame Check Sequence)校验数据,判断数据在传输过程是否因噪音等影响导致信号失真,从而导致数据错误,需要丢弃这种无效的数据包。

FCS校验后对数据包的MAC地址进行匹配,不匹配的包也会丢弃。

数据包从网卡到应用进程_第3张图片

 没有丢弃的数据包就被网卡存放到了网卡的缓冲区中,该缓冲区就是一个FIFO队列。

2.内核空间

内核空间的处理过程包含了三部分,网卡驱动程序处理,cpu处理,内核协议栈处理。

(1)网卡驱动

系统以及驱动共同为该网卡在内核的使用一段连续的物理内存中实现了一个rx ring buffer,即一个环形的接收缓冲区,rx ring buffer存储的并不是实际的packet数据,而是一个描述符,这个描述符指向了它真正的存储地址,实际的packet数据保存在skb_buffer里面,skb_buffer是系统启动网卡时,为网卡分配的数据包保存缓冲区。

数据包从网卡到应用进程_第4张图片

网卡驱动在运行时,会向cpu注册一个中断处理函数,当有数据包来到网卡时,网卡驱动将新数据包的skb_buffer分配好,并将新数据包的描述符写入到ring buffer,并通知网卡有新的数据包描述符在ring buffer中。

网卡通过DMA方式从ring buffer中取出新数据包的描述符,并根据该描述符,通过DMA的方式将新数据包从网卡自身的缓冲区中写入到skb_buffer,然后触发cpu的硬中断,告诉cpu有新的数据包到达。

数据包从网卡到应用进程_第5张图片

cpu此时反调网卡驱动注册的处理函数,网卡驱动禁用网卡的硬中断,避免下次再有数据包过来,再次触发cpu网卡中断,处理函数返回,硬中断结束,并启动了软中断,并将 skb 挂到 CPU 的处理队列中。

(2)网卡队列与软中断

当网卡支持多队列特性时,当网卡驱动加载时,会通过获取的网卡型号,得到网卡的硬件queue的数量,并结合CPU核的数量,最终通过Sum=Min(网卡queue,CPU core)得出所要激活的网卡队列数量(Sum),并申请对应个数的中断号,分配给激活的各个队列。

    当某个队列收到报文时,触发相应的中断,收到中断的核,将该任务加入到协议栈负责收包的该核的队列中(NET_RX_SOFTIRQ在每个核上都有一个实例)。

数据包从网卡到应用进程_第6张图片

(3)软中断

    当软中断启动后,NAPI系统被软中断唤醒。软中断处理程序轮询的从 Ring Buffer 上读取数据包并翻译成标准的 skb 数据结构,该处理队列的处理核如果没有具体绑定配置时,是由cpu0根据数据包的五元组进行hash分配的,单队列网卡上的中断默认也由cpu0处理。CPU 从队列中接收到 skb 之后就会执行指令,让内核协议栈处理该 skb 对应的数据包。

(4)socket

cpu完成数据包的拷贝后,根据MAC头部的以太类型字段判断协议种类并调用处理该协议的软件(即协议栈),通常我们接触的以太类型是 IP协议,因此会调用TCP/IP协议栈来处理,应用iptables,路由表,tc等内核工具对该数据包进行处理。

3.用户空间

应用层一般有两种方式接收数据,一种是recvfrom函数阻塞在那里等着数据来,这种情况下当socket收到通知后,recvfrom就会被唤醒,然后读取接收队列的数据;另一种是通过epoll或者select监听相应的socket,当收到通知后,再调用recvfrom函数去读取接收队列的数据。两种情况都能正常的接收到相应的数据包。

其中,当处理用户空间的cpu与实际接收数据包的cpu处于不同队列时,就会造成cpu的高速缓存的miss,造成资源消耗,这与多队列网卡的出现,提高cpu对网卡队列的处理效率一起,构成了DPDK技术的快速应用的原因。

参考文献:

1.网络数据包收发流程(二):不配置NAPI的情况 - CasonChan - 博客园

2.多队列网卡及网卡中断绑定阐述_梦想专栏-CSDN博客

3.网卡网络驱动监控---网络数据包流程监控一 - 简书

4.计算机网络——数据从网卡到应用的过程_JMW1407的博客-CSDN博客

你可能感兴趣的