- 解决的问题
- 网络数据接收时,存在丢包,一般因为如下问题:
- 内存拷贝
- 中断
- 多次调用
- 网络数据接收时,存在丢包,一般因为如下问题:
- 零拷贝发展史
- BPF
- Berkeley Packet Filter
- 参考资料:
- https://baike.baidu.com/item/bpf/5307621?fr=aladdin
- libpcap
- 4,libpcap提供的一个最有用的函数是pcap_compile(), 它可以把一个输入输出的逻辑表达式变为BPF代码!tcpdump利用这个函数完成在用户输入的命令行和BPF代码之间的转换!tcpdump有个我们很感兴趣但是很少使用的参数 ,-d,可以输出BPF代码!把tcpdump -d中的-d换成-dd,将显示出一段C代码,可以把它复制到自己的程序中,可以通过调用setsockopt()来过滤端口!
- 摘自:https://blog.csdn.net/shenwansangz/article/details/48088431
- 先看看哪些应用是通过这个库写出来的吧,snort,tcpdump。wireshark用的winpcap。可见还是非常的强大的,它同样支持BPF信息过滤机制
- 转自:https://www.cnblogs.com/lanjianhappy/p/10578840.html
- libpcap工作机制:
- A:本地网卡设置为混杂模式(这种模式能够接受所有流经本机所在网络得数据包)
- B:数据包经过BPF过滤
- C:交给linux内核层数据包缓冲区,用户层应用程序通过系统调用将数据包从内核缓冲区取出并放入用户空间内存区
- 缺陷:
- 数据包经过了linux得内核网络协议栈,从网卡到用户空间的传递过程,存在多次的拷贝和中断相应,消耗大量得cpu时间片,降低系统整体的数据分析能力。
- 4,libpcap提供的一个最有用的函数是pcap_compile(), 它可以把一个输入输出的逻辑表达式变为BPF代码!tcpdump利用这个函数完成在用户输入的命令行和BPF代码之间的转换!tcpdump有个我们很感兴趣但是很少使用的参数 ,-d,可以输出BPF代码!把tcpdump -d中的-d换成-dd,将显示出一段C代码,可以把它复制到自己的程序中,可以通过调用setsockopt()来过滤端口!
- pf_ring
- 转自:https://www.cnblogs.com/lanjianhappy/p/10578840.html
- 在linux内核层添加了一种新的带缓存得协议族,结合网卡得内存访问模式DMA以及中断模式NAPI技术,减少cpu得中断次数。位于用户层得应用程序通过mmap技术直接访问linux内核层得网络数据包,减少数据拷贝。它是一种独立模块的形式,能够进行模块的卸载和加载。
- 缺陷:
- 数据从网卡内存缓存区到内核sk_buf数据存储,进行一次拷贝,并没有实现真正意义得零拷贝。f另外它得预处理和数据包的捕获仍然在内核层完成。
- 2.PF_RING 比 PACKET_MMAP区别?
- (1)PACKET_MMAP实现了用户空间和内核空间的零copy,但是从网卡到内核空间还是有一层copy的,所有不是真正的zero-copy。
- (2)PF_RING提供免费版本和收费版本,其中免费模式,实现的原理跟PACKET_MMAP是类似的,不是真正的zero-copy;但是收费的DNA模式,实现了真正的zero-copy(由于收费模式提供时库,所有没法看代码是怎么实现的)
- 转自:https://www.cnblogs.com/lanjianhappy/p/10578840.html
- dpdk
- 特性:
- 用户态拷贝: 加入uio驱动
- 大页内存
- CPU亲核特性
- 零拷贝
- 分流方式:
- TAP/TUN
- RSS (Receive Side Scaling)
- 特性:
- BPF
- 背景知识:
- sk_buf
sk_buff是Linux网络代码中最重要的结构体之一。它是Linux在其协议栈里传送的结构体,也就是所谓的“包”,在他里面包含了各层协议的头部,比如ethernet, ip ,tcp ,udp等等。也有相关的操作等。熟悉他是进一步了解Linux网络协议栈的基础。
- 已解决疑问
- 1. 接收模块是否有单独的线程?
- 有内核线程 ,处理函数 kni_thread_single
- 收到包后,调用:kni_net_poll_resp(dev)通知
kni_net_poll_resp(struct kni_dev *kni) { if (kni_fifo_count(kni->resp_q)) wake_up_interruptible(&kni->wq); }
- 1. 接收模块是否有单独的线程?
- 遗留问题:
- 1. DPDK如何实现用户态拷贝?
- 在网上看到的DPDK面试题
- DPDK提供了两种与linux kernel协议栈交互:
- 两种都是通过创建虚拟设备用于收发报文
- TAP
- 应该是发送??: 从用户态拷贝到内核态;
- 应该是接收? 从内核态sk_buff拷贝到用户态
- KNI
- RX: PMD分配mbuf,
- TAP
- 两种都是通过创建虚拟设备用于收发报文
- 1. DPDK如何实现用户态拷贝?