本文内容为读书笔记,摘自《深入浅出DPDK》


65.网络报文的处理和转发主要分为硬件处理部分与软件处理部分,由以下模块构成:

  • ❑Packet input:报文输入。
  • ❑Pre-processing:对报文进行比较粗粒度的处理。
  • ❑Input classification:对报文进行较细粒度的分流。
  • ❑Ingress queuing:提供基于描述符的队列FIFO。
  • ❑Delivery/Scheduling:根据队列优先级和CPU状态进行调度。
  • ❑Accelerator:提供加解密和压缩/解压缩等硬件功能。
  • ❑Egress queueing:在出口上根据QOS等级进行调度。
  • ❑Post processing:后期报文处理释放缓存。
  • ❑Packet output:从硬件上发送出去。

如图5-1所示,我们可以看到在浅色和阴影对应的模块都是和硬件相关的,因此要提升这部分性能的最佳选择就是尽量多地去选择网卡上或网络设备芯片上所提供的一些和网络特定功能相关的卸载的特性,而在深色软件部分可以通过提高算法的效率和结合CPU相关的并行指令来提升网络性能。了解了网络处理模块的基本组成部分后,我们再来看不同的转发框架下如何让这些模块协同工作完成网络包处理。

图5-1 网络处理模块细分


66.转发框架介绍

传统的Network Processor(专用网络处理器)转发的模型可以分为run to completion(运行至终结,简称RTC)模型和pipeline(流水线)模型。

1. pipeline模型

从名字上,就可以看出pipeline模型借鉴于工业上的流水线模型,将一个功能(大于模块级的功能)分解成多个独立的阶段,不同阶段间通过队列传递产品。这样,对于一些CPU密集和I/O密集的应用,通过pipeline模型,我们可以把CPU密集的操作放在一个微处理引擎上执行,将I/O密集的操作放在另外一个微处理引擎上执行。通过过滤器可以为不同的操作分配不同的线程,通过连接两者的队列匹配两者的处理速度,从而达到最好的并发效率。

2. run to completion模型

run to completion(运行至终结)模型是主要针对DPDK一般程序的运行方法,一个程序中一般会分为几个不同的逻辑功能,但是这几个逻辑功能会在一个CPU的核上运行,我们可以进行水平扩展使得在SMP的系统中多个核上执行一样逻辑的程序,从而提高单位时间内事务处理的量。但是由于每个核上的处理能力其实都是一样的,并没有针对某个逻辑功能进行优化,因此在这个层面上与pipeline模型比较,run to completion模型是不高效的。


67.我们分别通过Ezchip和AMCC这家公司的NP芯片来进行举例说明网络处理器上是如何使用这两种转发模型的。

如图5-2所示,在NPA中最主要的就是TOP(Task Optimized Processor)单元,每个TOP单元都是对特定的事务进行过优化的特殊微处理单元,在处理特定的事务时会在性能上有较大的提升,一个报文从Input进入后会经历五个不同的TOP单元,每个TOP的输出又会是下个TOP的输入,但是这种硬件模型决定了在报文的不同处理中必须按照TOP的顺序来进行,不可能先进行报文修改再进行报文查找。如果需要这种顺序的报文处理,NPA也可以实现,但必须从TOP修改这个单元将报文再回传到TOP解析上,但这样包的处理速度会大幅下降。

图5-2 Ezchip NPA基于pipeline的转发模型

如图5-3所示,在AMCC 345x的模型中,对于报文的处理没有特殊的运算单元,只有两个NP核,两个NP核利用已烧录的微码进行报文的处理,如果把运行的微码看成处理报文的逻辑,两个NP核上总共可以跑48个任务,每个任务的逻辑都共享一份微码,则同一时刻可以处理48份网络报文。

图5-3 AMCC 345x基于run to completion的转发模型

表5-1总结了pipeline和run to completion(RTC)这两种NP的优缺点。

表5-1 NP RTC与pipeline的比较

在了解了专用的网络处理器的转发模型后,我们如何把它们的思想运用到通用CPU上呢?通用CPU可以保证所写包处理软件的通用性,最大程度地保护开发成果,降低开发成本,而且可以按需使用硬件,部分资源进行计算密集型的数据处理,部分资源进行I/O密集型的报文处理,最大限度地降低资本投入。可是,通用处理器真的能高效处理网络报文吗?答案是肯定的,我们现在就来看看基于通用IA平台的DPDK中是怎么利用专用网络处理器中的这两种模型来进行高速包处理的。

从图5-4a的run to completion的模型中,我们可以清楚地看出,每个IA的物理核都负责处理整个报文的生命周期从RX到TX,这点非常类似前面所提到的AMCC的nP核的作用。

在图5-4b的pipeline模型中可以看出,报文的处理被划分成不同的逻辑功能单元A、B、C,一个报文需分别经历A、B、C三个阶段,这三个阶段的功能单元可以不止一个并且可以分布在不同的物理核上,不同的功能单元可以分布在相同的核上(也可以分布在不同的核上),从这一点可以看出,其对于模块的分类和调用比EZchip的硬件方案更加灵活。以下我们来看DPDK中这两种方法的优缺点。

图5-4 DPDK转发模型

表5-2 DPDK RTC与pipeline的比较


68.DPDK run to completion模型

普通的Linux网络驱动中的扩展方法如下:把不同的收发包队列对应的中断转发到指定核的local APIC(本地中断控制器)上,并且使得每个核响应一个中断,从而处理此中断对应的队列集合中的相关报文。而在DPDK的轮询模式中主要通过一些DPDK中eal中的参数-c、-l、-l core s来设置哪些核可以被DPDK使用,最后再把处理对应收发队列的线程绑定到对应的核上。每个报文的整个生命周期都只可能在其中一个线程中出现。和普通网络处理器的run to completion的模式相比,基于IA平台的通用CPU也有不少的计算资源,比如一个socket上面可以有独立运行的16运算单元(核),每个核上面可以有两个逻辑运算单元(thread)共享物理的运算单元。而多个socket可以通过QPI总线连接在一起,这样使得每一个运算单元都可以独立地处理一个报文并且通用处理器上的编程更加简单高效,在快速开发网络功能的同时,利用硬件AES-NI、SHA-NI等特殊指令可以加速网络相关加解密和认证功能。运行到终结功能虽然有许多优势,但是针对单个报文的处理始终集中在一个逻辑单元上,无法利用其他运算单元,并且逻辑的耦合性太强,而流水线模型正好解决了以上的问题。下面我们来看DPDK的流水线模型,DPDK中称为Packet Framework。


69.DPDK pipeline模型

pipeline的主要思想就是不同的工作交给不同的模块,而每一个模块都是一个处理引擎,每个处理引擎都只单独处理特定的事务,每个处理引擎都有输入和输出,通过这些输入和输出将不同的处理引擎连接起来,完成复杂的网络功能,DPDK pipeline的多处理引擎实例和每个处理引擎中的组成框图可见图5-5中两个实例的图片:zoom out(多核应用框架)和zoom in(单个流水线模块)。

图5-5 DPDK pipeline

Zoom out的实例中包含了五个DPDK pipeline处理模块,每个pipeline作为一个特定功能的包处理模块。一个报文从进入到发送,会有两个不同的路径,上面的路径有三个模块(解析、分类、发送),下面的路径有四个模块(解析、查表、修改、发送)。Zoom in的图示中代表在查表的pipeline中有两张查找表,报文根据不同的条件可以通过一级表或两级表的查询从不同的端口发送出去。

此外,从图5-5中的pipeline level我们知道,DPDK的pipeline是由三大部分组成的,逻辑端口(port)、查找表(table)和处理逻辑(action)。DPDK的pipeline模型中把网络端口作为每个处理模块的输入,所有的报文输入都通过这个端口来进行报文的输入。查找表是每个处理模块中重要的处理逻辑核心,不同的查找表就提供了不同的处理方法。而转发逻辑指明了报文的流向和处理,而这三大部分中的主要类型可参见表5-3。

表5-3 DPDK Port、Table、Action支持的类型

用户可以根据以上三大类构建数据自己的pipeline,然后把每个pipeline都绑定在指定的核上从而使得我们能快速搭建属于我们自己的packet framework。

现在DPDK支持的pipeline有以下几种:

  • ❑Packet I/O
  • ❑Flow classification
  • ❑Firewall
  • ❑Routing
  • ❑Metering
  • ❑Traffic Mgmt

DPDK以上的几个pipeline都是DPDK在packet framework中直接提供给用户的,用户可以通过简单的配置文件去利用这些现成的pipeline,加快开发速度。

以Routing pipeline为例可以有以下构建形式:

关于具体如何使用DPDK的packet framework去快速搭建属于自己的高性能网络应用,可以参考DPDK源码中的sample。

图5-6 DPDK Routing Pipeline


70.转发算法

除了良好的转发框架之外,转发中很重要的一部分内容就是对于报文字段的匹配和识别,在DPDK中主要用到了精确匹配(Exact Match)算法和最长前缀匹配(Longest Prefix Matching, LPM)算法来进行报文的匹配从而获得相应的信息。

DPDK中主要支持CRC32和J hash,这里主要介绍CRC相关的内容和优化。

其实,精确匹配主要需要解决两个问题:进行数据的签名(哈希),解决哈希的冲突问题。CRC32和J hash是两个数字签名的不同算法。我们先来看下CRC。

CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n=p+r位的二进制序列;附加在数据序列之后的这个检验码与数据序列的内容之间存在着某种特定的关系。如果因干扰等原因使数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏。因此,通过检查这一关系,就可以实现对数据正确性的检验。

CRC中的两个主要概念如下:

(1)多项式模2运行:

实际上是按位异或(Exclusive OR)运算,即相同为0,相异为1,也就是不考虑进位、借位的二进制加减运算。如:10011011+11001010=01010001。

(2)生成多项式:

当进行CRC检验时,发送方与接收方需要事先约定一个除数,即生成多项式,一般记作G(x)。生成多项式的最高位与最低位必须是1。常用的CRC码的生成多项式有:

CRC8=X8+X5+X4+1
CRC-CCITT=X16+X12+X5+1
CRC16=X16+X15+X5+1
CRC12=X12+X11+X3+X2+1
CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

每一个生成多项式都可以与一个代码相对应,如CRC8对应代码100110001。

计算示例:

设需要发送的信息为M=1010001101,产生多项式对应的代码为P=110101, R=5。在M后加5个0,然后对P做模2除法运算,得余数r(x)对应的代码:01110。故实际需要发送的数据是101000110101110,见图5-9。

在CRC32的算法上DPDK做了以下的优化:

首先,将数据流按照8字节(优先处理)和4字节为单位进行处理,以8字节为例:

  • 方法一:当支持CRC32_SSE42_x64时,可以直接使用IA的硬件指令来一次处理:指令8crc32q。
  • 方法二:当支持CRC32_SSE42时,可以直接使用IA的硬件指令来一次处理:指令crc32l。

图5-9CRC计算示例

  • 方法三:当不允许或不能使用硬件相关指令进行加速操作时,可以直接使用查表的方法进行,利用空间换时间。

具体的哈希性能,DPDK有相关的单元测试,有兴趣的读者可以参考DPDK的源代码。

在处理哈希的冲突时用了如下的定义:

在rte的一个哈希桶中将会有RTE_哈希_哈希桶_ENTRIES个entry来解决冲突问题,可以说融合了分离链表和开放地址方法的优点。

在处理哈希、找到对应的数据时,DPDK提供了rte_哈希_lookup_multi。这个函数利用了multi-buffer的方式降低了指令之间的依赖,增强了并行性,加快了哈希处理速度。

struct rte_哈希_哈希桶 {struct rte_哈希_signatures signatures[RTE_哈希_哈希桶_ENTRIES];/* Includes dummy key index that always contains index 0 */uint32_t key_idx[RTE_哈希_哈希桶_ENTRIES + 1];uint8_t flag[RTE_哈希_哈希桶_ENTRIES];
} __rte_cache_aligned;

71.最长前缀匹配算法

最长前缀匹配(Longest Prefix Matching, LPM)算法是指在IP协议中被路由器用于在路由表中进行选择的一个算法。

因为路由表中的每个表项都指定了一个网络,所以一个目的地址可能与多个表项匹配。最明确的一个表项——即子网掩码最长的一个——就叫做最长前缀匹配。之所以这样称呼它,是因为这个表项也是路由表中与目的地址的高位匹配得最多的表项。

例如,考虑下面这个IPv4的路由表(这里用CIDR来表示):

192.168.20.16/28
192.168.0.0/16

DPDK中LPM的具体实现综合考虑了空间和时间,见图5-10。

前缀的24位共有2^24条条目,每条对应每个24位前缀,每个条目关联到最后的8位后缀上,最后的256个条目可以按需进行分配,所以说空间和时间上都可以兼顾。

当前DPDK使用的LPM算法就利用内存的消耗来换取LPM查找的性能提升。当查找表条目的前缀长度小于24位时,只需要一次访存就能找到下一条,根据概率统计,这是占较大概率的,当前缀大于24位时,则需要两次访存,但是这种情况是小概率事件。

LPM主要结构体为:一张有2^24条目的表,多个有2^8条目的表。第一级表叫做tbl24,第二级表叫做tbl8。

❑tbl24中条目的字段有:

struct rte_lpm_tbl24_entry { /* Stores Next hop or group index (i.e. gindex)into tbl8. */ union { uint8_t next_hop; uint8_t tbl8_gindex; }; /* Using single uint8_t to store 3 values. */ uint8_t valid      :1; /**< Validation flag. */ uint8_t ext_entry :1; /**< External entry. */ uint8_t depth      :6; /**< Rule depth. */
};

图5-10 DPDK LPM框图

❑tbl8中每条entry的字段有:

struct rte_lpm_tbl8_entry { uint8_t next_hop; /**< next hop. */ /* Using single uint8_t to store 3 values. */ uint8_t valid         :1; /**< Validation flag. */ uint8_t valid_group :1; /**< Group validation flag. */ uint8_t depth         :6; /**< Rule depth. */
}; 

用IP地址的前24位进行查找时,先看tbl24中的entry,当valid字段有效而ext_entry为0时,直接命中,查看next_hop知道下一跳。当valid为1而ext_entry为1时,查看next_hop字段知道tbl8的index,此时根据IP中的后8位确定tbl8中具体entry的下标,然后根据rte_lpm_tbl8_entry中的next_hop找下一跳地址。

同样,关于具体的LPM性能,DPDK也有相关的单元测试,有兴趣的读者可以参考DPDK的源代码。


72.ACL算法

ACL库利用N元组的匹配规则去进行类型匹配,提供以下基本操作:

❑创建AC(access domain)的上下文。

❑加规则到AC的上下文中。

❑对于所有规则创建相关的结构体。

❑进行入方向报文分类。

❑销毁AC相关的资源。

现在的DPDK实现允许用户在每个AC的上下文中定义自己的规则,AC规则中的字段用以下方式结构体进行表示:

struct rte_acl_field_def { uint8_t   type;          /**< type - RTE_ACL_FIELD_TYPE_*. */ uint8_t   size;          /**< size of field 1,2,4, or 8. */ uint8_t   field_index; /**< index of field inside the rule. */ uint8_t   input_index; /**< 0-N input index. */ uint32_t offset;        /**< offset to start of field. */
}; 

如果要定义一个ipv4 5元组的过滤规则,可以用以下方式:

struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { { .type = RTE_ACL_FIELD_TYPE_BITMASK, .size = sizeof(uint8_t), .field_index = PROTO_FIELD_IPV4, .input_index = PROTO_FIELD_IPV4, .offset = offsetof(struct ipv4_5tuple, proto), }, { .type = RTE_ACL_FIELD_TYPE_MASK, .size = sizeof(uint32_t), .field_index = SRC_FIELD_IPV4, .input_index = SRC_FIELD_IPV4, .offset = offsetof(struct ipv4_5tuple, ip_src), }, { .type = RTE_ACL_FIELD_TYPE_MASK, .size = sizeof(uint32_t), .field_index = DST_FIELD_IPV4, .input_index = DST_FIELD_IPV4, .offset = offsetof(struct ipv4_5tuple, ip_dst), }, { .type = RTE_ACL_FIELD_TYPE_RANGE, .size = sizeof(uint16_t), .field_index = SRCP_FIELD_IPV4, .input_index = SRCP_FIELD_IPV4, .offset = offsetof(struct ipv4_5tuple, port_src), }, { .type = RTE_ACL_FIELD_TYPE_RANGE, .size = sizeof(uint16_t), .field_index = DSTP_FIELD_IPV4, .input_index = SRCP_FIELD_IPV4, .offset = offsetof(struct ipv4_5tuple, port_dst), },
}; 

而定义规则时有以下几个字段需要注意:

priority:定义了规则的优先级。

category_mask:表明规则属于哪个分类。

userdata:当最高优先级的规则匹配时,会使用此userdata放入category_mask中指定的下标中。

ACL常用的API见表5-4。

表5-4 DPDK ACL常用API

ACL主要思路就是创建了Tier相关的数据结构,匹配字段中每个字段中的每个字节都会作为Tier中的一层进行匹配,每一层都作为到达最终匹配结果的一个路径。关于具体的ACL相关的使用,有兴趣的读者可以参考DPDK的源代码。


73.报文分发

Packet distributor(报文分发)是DPDK提供给用户的一个用于包分发的API库,用于进行包分发。主要功能可以用图5-11进行描述。

图5-11 DPDK Redistributor框图

从图5-11中可以看出,一般是通过一个distributor分发到不同的worker上进行报文处理,当报文处理完后再通过worker返回给distributor,具体实现可以参考DPDK的源代码。本书只列举出以下几个点:

❑Mbuf中的tag可以通过硬件的卸载功能从描述符中获取,也可以通过纯软件获取,DPDK的distributor负责把新产生的stream关联到某一个worker上并记录此Mbuf中的哈希值,等下一次同样stream的报文再过来的时候,只会放到同一tag对应的编号最小的worker中对应的backlog中。

❑distributor主要处理的函数是rte_distributor_process,它的主要作用就是进行报文分发,并且如果第一个worker的backlog已经满了,可能会将相同的流分配到不同的worker上。

❑worker通过rte_distributor_get_pkt来向distributor请求报文。

❑worker将处理完的报文返回给distributor,然后distributor可以配合第3章提到的ordering的库来进行排序。


系列文章

《《深入浅出DPDK》读书笔记(一):基础部分知识点》

《《深入浅出DPDK》读书笔记(二):网卡的读写数据操作》

《《深入浅出DPDK》读书笔记(三):NUMA - Non Uniform Memory Architecture 非统一内存架构》

《《深入浅出DPDK》读书笔记(四):并行计算-SIMD是Single-Instruction Multiple-Data(单指令多数据)》

《《深入浅出DPDK》读书笔记(五):同步互斥机制》

《深入浅出DPDK》读书笔记(六):报文转发(run to completion、pipeline、精确匹配算法、最长前缀匹配LPM)相关推荐

  1. DPDK报文收发 run to completion, pipeline

    摘自 深入浅出DPDK

  2. 深入浅出DPDK学习笔记(3)——— Cache和内存

    深入浅出DPDK学习笔记(3)--- Cache和内存 系统架构的演进 Cache系统简介 Cache的种类 TLB Cache Cache地址映射和变换 全关联型Cache 直接关联型Cache 组 ...

  3. 深入浅出数据分析读书笔记

    深入浅出数据分析读书笔记 一.数据分析引言 1.数据分析的基本流程:确定--分解--评估--决策.一个完整的分析项目可能经过多轮流程 确定:客户的论点和数据 分解:将手头的资料汇总为有用的格式 评估: ...

  4. Node.js: 深入浅出Nodejs读书笔记

    今天终于把朴灵老师写的<深入浅出Node.js>给学习 完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内 ...

  5. 3d游戏设计读书笔记六

    3d游戏设计读书笔记六 一.改进飞碟(Hit UFO)游戏: 游戏内容要求: 按 adapter模式 设计图修改飞碟游戏 使它同时支持物理运动与运动学(变换)运动 更改原 UFO_action 类 为 ...

  6. 深入浅出DPDK学习笔记——认识DPDK

    什么是DPDK? 对于用户来说, 它可能是一个性能出色的包数据处理加速软件库: 对于开发者来说, 它可能是一个实践包处理新想法的创新工场: 对于性能调优者来说, 它可能又是一个绝佳的成果分享平台.当下 ...

  7. Android驱动开发读书笔记六

    第六章 Linux 驱动的工作和访问方式是 Linux 的亮点之一,Linux 系统将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中,由于大多数Linux驱动都有与 ...

  8. C专家编程--读书笔记六 运行时数据结构

    第六章 一.知识点 1.代码和数据的区别也可以认为是编译时和运行时的分界线.编译器的绝大部分工作都跟翻译代码有关:必要的数据存储管理的绝大部分都在运行时进行.(P121) 2."a.out& ...

  9. 《七步掌握业务分析》读书笔记六

    分析技术和呈现格式 词汇表 强有力沟通的一个重要内容是一致地使用术语和惯用语.每次谈话都涉及对术语的共同理解. 工作流图(也称为流程图.UNL活动图和过程图) 工作流程把一个或多个业务过程的细节可视化 ...

最新文章

  1. 模糊集的例子(年轻 年老)
  2. linux sh/bash 编程常用
  3. JavaScript基础01【简介、js编写位置、基本语法(6种基本数据类型)】
  4. Ubuntu下面Master PDF Editor背景颜色设置
  5. WCF消息之XmlDictionaryWriter
  6. 【渝粤题库】国家开放大学2021春1009离散数学(本)题目
  7. BestCoder Round #67 (div.2) 1001——N bulbs
  8. android4.0蓝牙使能的详细解析 (转载)
  9. IOS LocationManager定位国内偏移,火星坐标(GCJ-02)解决方法
  10. android Camera 中的相关概念
  11. python读取excel绘图_python之读取Excel(xls/xlsx)文件
  12. hive不在同一台机 hue_【Impala篇】---Hue从初始到安装应用
  13. Deep Learning Notes: Chapter 1 Introduction
  14. 2021-07-20 诺瓦星云笔试复盘
  15. VMware要不要装在固态SSD上,虚拟机系统文件要不要放固态SSD上,虚拟机伤不伤固态SSD...
  16. 免费开源的电路图和PCB绘图软件KiCAD
  17. pythonturtle库填充_python turtle库笔记
  18. 如何判断本地(路由器)分配的IP是否是公网IP?
  19. 计算机上无线网络开关在哪里,笔记本电脑的无线网络开关在哪里
  20. 怎么用计算机里的坦克大战,坦克大战怎么使用重坦_坦克大战重坦篇_7k7k坦克大战...

热门文章

  1. 删除js数组中制定内容
  2. 【mysql union all limit的使用】
  3. 报 There is insufficient memory for the Java Runtime Environment to continue. 的问题
  4. 剑指offer25-合并两个排序的链表
  5. 读后感:软件测试经验与教训
  6. 【Python】windows电脑 python3.6安装lxml库
  7. Normalize.css用法
  8. Extjs window组件 拖动统制
  9. (TI xDM)SSCR Module—Shared Scratch Memory
  10. 什么是c语言内存编码,c语言内存泄露示例解析