龙空技术网

从netmap到dpdk,从硬件到协议栈,4个维度让网络体系构建起来

Linux特训营 446

前言:

眼前朋友们对“dpdk lpm算法”大致比较关心,各位老铁们都想要分析一些“dpdk lpm算法”的相关内容。那么小编也在网上网罗了一些对于“dpdk lpm算法””的相关知识,希望各位老铁们能喜欢,姐妹们快快来了解一下吧!

netmap是一个高效的收发报文的地方 I/O 框架,已经集成在一起 FreeBSD 的内部了。

当然,也可以在 Linux 下编译使用

目录

1. io虚拟化的 vhost与virtio

2. netmap与dpdk实现原理

3. 用dpdk手撕一个协议栈

4. arp/udp/icmp/ip协议头解析

5. 柔性数组的优缺点

6. 零拷贝的底层原理

详细教程资料关注+后台私信;资料;两个字可以免费视频领取+文档+各大厂面试题 资料内容包括:C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,嵌入式 等。

I/O虚拟化简介

I/O虚拟化(Input/output virtualization,简称IOV)是虚拟化的一种新形式,是来自物理连接或物理运输上层协议的抽象,让物理服务器和虚拟机可以共享I/O资源。

在现实生活中,可用的物理资源往往是有限的,虚拟机的个数往往会比实际的物理设备个数要多。为了提高资源的利用率,满足多个虚拟机操作系统对外部设备的访问需求,虚拟机监视器必须通过I/O虚拟化的方式来实现资源的复用,让有限的资源能被多个虚拟机共享。为了达到这个目的,监视器程序需要截获虚拟机操作系统对外部设备的访问请求,通过软件的方式模拟出真实的物理设备的效果,这样,虚拟机看到的实际只是一个虚拟设备,而是真正的物理设备,这种模拟的方式就是I/O虚拟化的一种实现,下图所示就是一个典型的虚拟机I/O模型。

dpdk实现原理

DPDK特点

DPDK全称为Date planedevelopment kit,是一个用来进行包数据处理加速的软件库。与传统的数据包处理相比,DPDK具有以下特点:

1) 轮询:在包处理时避免中断上下文切换的开销,

2) 用户态驱动:规避不必要的内存拷贝和系统调用,便于快速迭代优化

3) 亲和性与独占:特定任务可以被指定只在某个核上工作,避免线程在不同核间频繁切换,保证更多的cache命中

4) 降低访存开销:利用内存大页HUGEPAGE降低TLB miss,利用内存多通道交错访问提高内存访问有效带宽

5) 软件调优:cache行对齐,预取数据,多元数据批量操作

DPDK框架

在上图中,核心库Core Libs提供系统抽象、大页内存、缓存池、定时器及无锁环等基础组件。

PMD库,提供全用户态驱动,以便通过轮询和线程绑定得到极高网络吞吐,支持各种本地和虚拟网卡。

Classify库,支持精确匹配,最长匹配和通配符匹配,提供常用包处理的查表操作。

Qos库,提供网络服务质量相关组件,限速和调度。

详细教程资料关注+后台私信;资料;两个字可以免费视频领取+文档+各大厂面试题 资料内容包括:C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,嵌入式 等。

Mellanox DPDK中保留了Linux内核态驱动,框图如下:

Mellanox DPDK在用户空间使用PMD驱动,与网卡之间有两条路径,控制路径使用user verbs,经过内核,用于对象的创建、初始化、修改、查询和释放。数据路径之间访问网卡,进行数据的收发。

Mellanox DPDK与传统的Linux内核态驱动可以共存,当前未被DPDK使用的端口可以通过Linux网络协议栈进行报文收发。

DPDK的原生TCP/IP协议栈

初始化分析

我们直接先看一下f-stack提供的demo的main函数,有一个宏观认识。

代码非常简单,和正常的socket编程一样调用socket,bind,listen等接口,可以看到f-stack其提供的ff_socket,ff_bind,ff_listen和posix接口是完全兼容的。其他关键的区别就是最开始的ff_init(argc, argv)调用,这个主意是为了f-stack框架的启动初始化,下面会分析,另一个就是ff_run(loop, NULL),熟悉dpdk的人应该能猜到,这就是启动主循环开始网卡的收发逻辑。下面一张图看一下ff_init的主要初始化逻辑。

其中最关键的就是ff_dpdk_if_up,这个函数为每个dpdk接管的port创建一个struct ifnet结构,并将这个结构注册到freebsd中,其中调用的ether_ifattach就是freebsd的接口,这个结构可以理解为网卡对应的虚拟设备,这个设备也是dpdk和freebsd关联的核心。Ifnet有很多handle函数,会被做如下初始化:

    ifp->if_start = ff_veth_start;ifp->if_transmit = ff_veth_transmit;   ifp->if_qflush = ff_veth_qflush;   ifp->if_output = ether_output;   ifp->if_input = ether_input;……

其中核心是if_input,if_output和if_transmit三个函数,if_input就是ifnet的收包函数,可以理解为协议栈的入口函数,有些类似于kernel协议栈的netif_receive_skb函数;但是把if_output比喻成协议栈的出口函数就有点不恰当了,因为启动还有bridge的转发逻辑,其中(ether_output)调用的ifp->if_transmit可以理解为真正的协议栈出口函数,类似于kernel的dev_queue_xmit。

转发流程分析

转发流程以ff_run开始的main_loop开始,我们以tcp收到syn+ack及回复流程为例,分析这个转发过程(syn+ack处理不会上送app,由协议栈完成),直接上图,流程如下:

标签: #dpdk lpm算法 #netmap dpdk 对比