ndn-dpdk论文
Title:NDN-DPDK:在商用硬件上以100 Gbps的速率进行NDN转发
摘要:
由于命名数据网络(NDN)数据平面要求使用可变长度的分层名称以及每个数据包状态更新对可能较大的表进行基于名称的查找,因此实现高速NDN转发仍然是一个挑战。为了解决这一差距,我们开发了一种高性能NDN路由器,能够在商品硬件上运行时达到高于100 Gbps的转发速率。本文介绍了我们的设计并讨论了它的折衷。我们通过几种优化技术实现了这一性能,其中包括采用更好的算法和高效的数据结构,以及利用现代多核CPU和多硬件队列提供的并行性,并使用用户空间驱动程序绕过内核。我们的开源转发器是NDN的第一个软件实现,其吞吐量超过100 Gbps,同时支持完整协议语义。
我们还提供了广泛的基准测试结果,以评估许多性能维度,并诊断数据包处理管道中的当前瓶颈,以实现未来的可伸缩性增强。最后,我们确定了未来的工作,包括硬件辅助的入口流量调度、跨转发线程的动态负载平衡,以及适应磁盘内容存储的新型缓存解决方案。
关键词:
命名数据网络、信息中心网络、NDN转发器、软件路由器、数据包转发引擎、高速转发、网络性能、内核绕过、商品硬件、性能基准测试
1. 简介:
命名数据网络(NDN)是一种新的网络协议,具有以数据为中心的通信架构,基于命名内容的检索,而不是主机之间的数据包传递。
它是以信息为中心的网络(ICN)最突出的例子之一。NDN中的通信是接收器驱动的:消费者发送带有所需内容名称的兴趣数据包,网络使用该名称将请求转发给生产者或网络内缓存,最终数据包通过反向路径返回给消费者。NDN网络中的一个基本组件是转发器(或路由器),它按照[29,第3章]描述的行为实现NDN的通信模型。因此,NDN路由器必须使用可变长度的分层名称对可能较大的表执行基于名称的查找,并同时根据每个数据包更新其内部状态。这使得线速NDN转发难以实现。与此同时,由于缺乏这种高速能力,许多科学和其他数据密集型应用[1、4、23、27、28]受到阻碍。
本文介绍了NDN-DPDK的设计,它是一种高性能的NDN转发器,能够在商品x86硬件上实现超过100 Gbps的吞吐量。NDNDPDK采用了多种架构优化,从更好的算法和数据结构到减少内核和系统调用开销,这是通过利用快速用户空间数据包处理框架数据平面开发工具包(DPDK)实现的[17]。DPDK可用于许多常见的10/100 Gbps以太网适配器,并提供一组库来加速数据包处理任务,如环形缓冲区、内存池和线程管理。这使我们的转发器能够直接从用户空间接收和传输数据包,而无需经过Linux内核。此外,NDN-DPDK充分利用了现代多核CPU提供的并行性。
我们在GitHub1上提供的开源代码库具有几个独特的功能,这些功能推动了NDN软件路由器的发展:
- 首先,据我们所知,NDN-DPDK是第一个在实际硬件上完整实现高速NDN转发引擎的软件。之前的尝试[10、11、16、22、30、33、36]要么侧重于数据平面功能的子集,要么不支持完整的NDN协议和名称匹配语义,要么将模块性和灵活性优先于性能,要么依赖于模拟而非实际实现。
- 其次,由于NDN允许兴趣名称作为数据名称的前缀,因此我们提出了一种新的方法,用于兴趣和数据之间的快速前缀匹配。这种方法的一个重要组成部分是PIT Token,它是添加到每个数据包中的一个小的hopbyhop头字段,用于加速PIT查找。
- 第三,为了有效地支持NDN的ContentStore中的前缀匹配,我们开发了一种基于间接条目的新解决方案。如果没有这样的解决方案,带有不精确名称的兴趣将必须由生产者回答,从而降低网络内缓存的有效性。
本文的其余部分组织如下:
第2节概述了NDN-DPDK的设计。
第3节描述了转发器的输入和输出阶段,其中还介绍了兴趣和数据的分组调度。
第4节和第5节介绍了主要数据结构及其实现细节。
第6节讨论了对NDN转发策略的支持。
第7节介绍了广泛性能基准的结果。最后,我们在第8节回顾了与ICN转发相关的以往出版物,并在第9节总结了本文,其中还列出了我们未来的工作。
2.设计概述
egress:出口 ingress:入口
NDN-DPDK的转发平面采用多线程架构(图1)。每个数据包分三个阶段进行处理:
(1)输入阶段从网络接口接收数据包,对其进行解码,并根据名称调度表(NDT)将其发送给转发线程。
(2) 转发阶段将NDN转发规则应用于数据包;这一阶段包括传统的FIB(转发信息库)、PIT(待定兴趣表)和CS(内容存储)组件,以及转发策略。
(3) 输出阶段准备传出数据包,并将其传递到网络接口进行传输。此体系结构允许转发器使用所有可用的CPU内核并并行处理多个数据包。
2.1 内存池和NUMA套接字
NDN-DPDK使用DPDK的mempool库在1 GiB巨型页面中预分配其大部分数据结构。这消除了在数据包处理热路径上调用malloc()的不可预知的延迟,并降低了处理运行时内存分配失败的复杂性。这些内存池也固定在物理内存页上,不能被内核调出,这确保了一致的访问延迟。
大多数服务器级机器采用非统一内存访问(NUMA)设计。在NUMA下,每个CPU、内存DIMM和PCIe外围设备都属于一个NUMA插槽。CPU访问本地内存(位于同一NUMA插槽上的内存)的速度比访问非本地内存(不同NUMA插槽中的内存)快。使用DPDK的环境抽象层(EAL)库,NDN-DPDK将其线程固定到特定的CPU内核,并在NUMA本地内存中分配线程使用的大多数数据结构。这将最小化这些数据结构的内存访问延迟。
类似地,PCIe以太网适配器也属于NUMASocket。
给定适配器上接收的所有数据包都存储在该适配器的NUMA套接字的本地内存池中。因此,NDN-DPDK将为每个接口提供服务的输入和输出线程分配给位于同一NUMA套接字上的CPU内核。即使如此,在正常操作期间,不可避免地要跨NUMA套接字边界访问数据包:例如,当传入数据包被发送到另一个NUMA套接字上的转发线程时,或者当出口接口碰巧位于不同的NUMA套用字上时。
2.2分片数据结构
一个经典的NDN转发器有三个主要数据结构(或表):FIB引导向生产者转发兴趣,PIT将数据返回消费者,CS提供网络内缓存。NDN-DPDK有多个转发线程,它们都需要访问这三个表。然而,并发访问需要线程安全,这将增加设计复杂性并降低性能。
相反,NDN-DPDK尝试尽可能避免共享表:每个转发线程都有一个PIT和CS的私有实例,以及FIB的(部分)副本。前两个不需要任何跨线程访问,因此它们是使用非线程安全的数据结构实现的,而FIB仍然需要从控制平面进行更新,因此采用低开销读拷贝更新(RCU)同步机制(第4节)。这种方法还可以为NUMA本地内存中的每个线程分配所有三个表,以最小化访问延迟,如第2.1节所述。
2.3内部数据包队列
每个转发线程通过一组三个FIFO队列接收输入级发送给它的数据包,每个队列对应一种数据包类型:兴趣、数据、无。这些队列由DPDK的环库提供,它实现了一个具有固定容量的环缓冲区和无锁的排队/出列操作。数据包从这些队列中的任何一个队列中以突发方式获取,而不是一次一个。突发出列摊销了环缓冲区记帐操作的开销,并减少了CPU指令缓存未命中的数量,因为相同类型的多个数据包被一起处理,通常遵循相同的代码路径。
初步测试表明,在转发线程较少的配置中,转发阶段很容易成为瓶颈。
为了缓解这个瓶颈,NDN-DPDK在输入阶段和转发阶段之间采用了基于CoDel的[15]队列管理算法。如果最小排队延迟保持在target以上(默认情况下为5 ms),间隔毫秒(最初为100 ms),则转发线程会在下一个数据包中插入拥塞标记[25],提示使用者放慢速度。
转发器还通过在每次迭代时从兴趣队列中取出比从数据队列中更少的数据包,将数据优先于兴趣。这是因为丢弃数据包不仅会浪费已用于处理相应兴趣的资源,还会导致PIT条目延迟到到期,而丢失兴趣的危害较小。
2.4数据包的寿命
输入线程接收到一个传入的帧,它根据NDN包格式[19]对其进行解析,并将其识别为兴趣(第3.1节)。然后,根据其名称(第3.2节),将数据包分配给转发线程,并将其放置在转到该线程的队列中。转发线程将兴趣出列。
它首先查询PIT和CS(第5节),但假设该节点最近没有收到任何同名的兴趣或数据,则在两个表中都找不到匹配项。因此,线程创建一个新的PIT条目,并将入口接口记录为下游节点。接下来,它执行FIB查找(第4节),以确定应该采用哪种转发策略进行转发决策以及潜在的下一跳。该策略被调用,并决定将兴趣转发到特定的下一跳(第6.1节)。
转发线程最终将Interest传递给输出线程进行传输(第3.4节)。
当数据包到达时,输入线程根据数据包中的逐跳标头字段(第3.3节)确定哪个转发线程之前处理了相应的兴趣,并将数据包传递给该线程。转发线程首先查找可以满足的PIT条目(第5.2节)。然后,它检查哪些下游节点表达了匹配的兴趣,并将数据包的副本传递给输出线程进行传输(第3.4节)。它还通知转发策略已满足兴趣,以便该策略在未来做出更好的决策(第6节)。最后,数据包被缓存在CS中,PIT条目被删除。
3.face I/O和数据包调度
NDN-DPDK针对连接到PCIe总线的10/100 Gbps以太网适配器进行了优化。使用DPDK的轮询模式驱动程序,NDN-DPDK可以直接从用户空间发送和接收数据包,而无需经过操作系统内核。这通过消除系统调用和中断处理的开销,显著提高了性能。
NDN接口是网络接口概念的概括,可以在网络接口上传输和接收NDN数据包。
与其他NDN转发器不同,NDN-DPDK仅支持point-to-point face,并且故意不支持多播通信。这直接源于NDN-DPDK在高性能计算和数据密集型科学中的主要用例[35],其中网络被紧密管理,对等点被管理配置,因此不需要基于多播的发现。此外,为了简化接口系统,NDN-DPDK目前仅支持以太网接口,不能通过IP或任何其他协议进行隧道。用户可以在给定的以太网适配器上创建一个或多个接口;每个面通过不同的远程MAC地址和可选的VLAN ID进行区分。
3.1 Input Stage
如图2所示,转发器的输入管道从从以太网适配器接收帧开始。如前所述,同一适配器上可以有多个face,但每个face对必须具有不同的远程MAC地址或VLAN ID。适配器配置为将属于每个face的帧引导到不同的接收队列。输入线程连接到这些接收队列中的一个或多个,并负责通过三步过程解码每个传入帧:(1)去除以太网头和任何VLAN标记;(2) 解码为NDNLP数据包[21],必要时进行重新组装;(3) 继续解码重新组装的NDN网络层数据包,并将其分类为Interest、Data或Nack。
解码例程将有关已解析数据包的信息以及数据包缓冲区本身存储在缓冲区标头中保留的专用区域中。这避免了需要单独的内存分配,这样可以提高吞吐量,但会在每个数据包的基础上消耗更多内存。此外,NDN-DPDK的解码例程经过优化以服务于转发器,不必满足消费者或生产者应用程序的需求。与任何通用NDN库中的解析器相比,这导致了一些设计差异。例如:
- 对于数据,解码刚好在Content元素之前停止,因为转发算法不需要知道数据包的有效载荷或其签名。
- 出于类似原因,解码器会忽略Interest的ApplicationParameters元素及其后面的所有内容。
- 对于数据包中的MetaInfo元素,解码器只读取FreshnessPeriod字段,因为其他字段不影响转发。
3.2 按name分派Interest
包解码后,输入线程将每个网络层包分派给转发线程。对于Interest,名称前缀决定哪个转发线程将处理该数据包。
具体在哪个线程是通过对名称进行哈希映射得到的
此调度算法基于名称,因此具有相同名称的两个兴趣最终位于同一转发线程中,从而确保兴趣聚合的有效性。通过使用名称前缀而不是整个名称,具有公共前缀的兴趣将转到同一转发线程,从而使转发策略能够基于每个前缀收集度量值。
正如我们将在第6节中看到的,转发策略以FIB入口粒度运行。理论上,interest分配可以遵循FIB条目,这将实现上述两个目标。然而,FIB是一个相当复杂的数据结构,在输入阶段执行完全查找会太慢。因此,调度算法使用了一种更简单的方法来确定粒度:它将Interest名称的前k个组件作为前缀。如果兴趣的名称组件少于k个,则使用整个名称。选择k的值时,应确保生成的前缀比大多数FIB条目短,以保持转发策略测量有效,但也应足够长,以便有足够数量的不同前缀在转发线程之间进行负载平衡。NDN-DPDK在其默认配置中设置k=2,但此参数可以根据传入流量的特性进行调整。
确定名称前缀后,调度算法查询名称调度表(NDT),这是NDNDPDK转发器特有的表(图3)。输入线程将Interest分派到队列中,该队列指向由NDT条目标识的转发线程。为了尽可能简单并保持可预测的查找速度,NDT不是名称索引数据结构,而是2b个条目的线性向量(默认情况下为b=16),其中每个条目包含一个转发线程标识符。查找算法在名称前缀上计算SipHash[2],将哈希值的低位b作为向量的索引,并在该条目中返回转发线程标识符。这允许NDT查找在O(1)时间复杂度内完成。
3.3根据Token分派数据包
数据必须发送到处理兴趣的同一转发线程。如第2.2节所述,每次转发线程有一个PIT的私有实例。因此,有关待处理Interest的信息仅在转发Interest的转发线程中可用,并且只有该线程能够正确处理数据以响应转发Interest。
尽管我们可以对数据名称执行另一个基于前缀的调度,但名称调度算法在一个特定的情况下会崩溃。NDN协议允许名称发现:如果兴趣的名称是数据名称的前缀,并且兴趣包含CanBePrefix标志,则可以满足兴趣。例如,数据/A/B/1可以满足名称为/A且CanBePrefix=1的兴趣。应用第3.2节中的名称分派算法,并观察到在这种情况下兴趣名称少于两个组件,我们可以看到数据将在/A/B前缀下分派,而兴趣将在/A前缀下分派。如果与这些前缀对应的NDT条目映射到两个不同的线程标识符,则数据将转到不了解兴趣的转发线程。
为了解决这个问题,我们引入了PIT令牌,即每个数据包的NDNLP头中包含的8字节逐跳字段[21]。
下游节点在传输兴趣时附加PIT令牌。
上游节点在用Data或Nack数据包回复Interest时应附加相同的令牌。NDN-DPDK使用此令牌的一些位来编码转发线程标识符。
当转发线程传输兴趣时,它将自己的标识符放入PIT令牌。当数据返回时,输入线程可以简单地读取PIT令牌的这一部分,并将数据发送到正确的转发线程。
对于Nack数据包,两种调度方法都可以正常工作。
我们选择了令牌调度方法,因为它更高效。
3.4输出阶段
输出阶段控制传出数据包的传输。
对于每个传出的网络层数据包,它执行NDNLP分段(如果需要),预先发送以太网头,并将生成的链路层帧排队,以便在以太网适配器上传输。在当前版本的NDN-DPDK中,输出线程的工作负载很轻。然而,随着我们计划在输出阶段实施更先进的拥塞控制和队列管理方案,未来这种情况可能会增加。
4. FIB 结构
FIB是一个以读取为主的表。转发线程在FIB上执行最长前缀匹配(LPM),以确定每个传入兴趣的发送位置。另一方面,很少需要FIB更新,只在响应来自控制平面的管理命令时才进行更新。
NDN-DPDK的FIB设计灵感来自So等人[30]。在其设计中,FIB条目存储在由名称前缀键控的哈希表中。他们还提出了一种两阶段LPM查找算法:
(1)FIB有一个固定参数M,因此大多数FIB条目名称的组件少于M。
(2) 当插入名称超过M个组件的FIB条目时,会在深度M处插入一个虚拟条目,该条目指示前缀下的最大FIB深度。
(3) 给定一个Interest,FIB上的LPM以Interest名称的Mcomponent前缀开头。
(4) 如果此查找找到虚拟条目,LPM将在虚拟条目中指示的最大FIB深度处重新启动。
(5) 否则,LPM将继续使用较短的前缀,直到找到正常的FIB条目。
在NDN-DPDK中,我们采用了相同的FIB结构(图4)和相同的两阶段查找算法。然而,我们的多线程架构需要线程安全,这是通过两种技术实现的。
首先,我们使用Userspace Read-Copy Update(URCU)库[3],13]允许来自转发线程的FIB查询和来自管理线程的FIC更新同时进行。
RCU的一个优点是其读取端开销最小,这与FIB的以读取为主的特性非常匹配。我们使用基于静态的RCU风格,因为它的开销最小。这种风格要求每个线程定期指示静态状态;对于转发线程,这发生在处理每个突发数据包之前。哈希表实现来自URCU的无锁可调整大小的RCU哈希表,禁用了调整大小功能以提供更可预测的性能。
FIB条目是从DPDK内存池而不是默认的malloc()内存分配器分配的。
其次,每个转发线程都被赋予其私有FIB实例。
每个FIB实例仅包含转发线程提供的名称前缀。与在所有转发线程之间共享单个FIB相比,此方法确保FIB条目与转发线程分配在同一NUMA套接字上,避免了跨NUMA边界的内存访问。此外,它允许转发策略(第6节)将收集的测量值存储在FIB条目本身,而不需要单独的测量值表。
5. 组合PIT和CS设计
PIT和Content Store都在数据平面中频繁读取和修改,特别是:
(1)查询CS中的每个传入兴趣,以检查缓存的数据是否能够满足它。
(2) 如果没有,则转发interest,并且必须插入PIT条目,除非已经存在PIT条目。
(3) 收到数据包后,将查询PIT,以确定可以满足哪些待定interest。
(4) 当满足PIT条目时,必须擦除该条目并插入CS条目以缓存数据。
(5) 如果CS已满,则可能需要收回一些条目,以便为新数据腾出空间。
注意到第4项通常会删除一个PIT条目,并在相同的名称前缀处插入一个CS条目,因此等[30]建议将PIT和CS合并到一个哈希表中,这样就可以用CS条目替换一个满意的PIT条目而不会产生第二次查表的成本。NDN-DPDK采用了这种设计,并将PIT和CS合并到PIT-CS复合表(PCCT)中。
然而,[30]适用于CCNx协议[14],它与NDN在“兴趣到数据”匹配规则上有所不同。如果NDN和CCNx具有相同的名称,则它们都会分配Data3数据包以满足兴趣。如果兴趣名称是数据名称的前缀,并且兴趣带有CanBePrefix标志,则NDN还允许数据满足兴趣。此外,NDN兴趣可以携带转发提示,当存在时,应使用该提示代替兴趣名称来确定转发路径。这些主要协议差异使得我们的PCCT设计不可避免地与[30]中描述的不同。
考虑到PIT和CS中的频繁更新,跨所有转发线程共享的线程安全PCCT很容易成为瓶颈。我们早就决定每个转发线程都应该有自己的PCCT私有实例。与FIB情况相反,控制平面不需要与PIT或CS交互。因此,我们可以使用非线程安全的数据结构来实现PCCT,这些结构通常比线程安全的对应结构更快。
5.1逻辑结构
PCCT的总体结构是三种数据结构的组合:
- 用于分配PCCT条目的DPDK内存池。
- 用于基于名称的查找的名称哈希表。这将重用在数据包调度期间已经计算的SipHash值(第3.2节)。
- 令牌散列表,使用数据包上携带的PIT令牌,查找传入数据可以满足哪些PIT条目(第5.2节)。
逻辑上,每个PCCT条目都包含一个名称、一个选择的转发提示、两个PIT条目和一个CS条目(图5)。名称是必需的,但所有其他字段都是可选的。
条目由其名称和所选转发提示的组合标识。当转发线程处理携带转发提示的Interest时,它使用这些提示执行FIB查找,并选择与FIB条目匹配的第一个提示。然后,根据该兴趣创建的PIT条目及其回复数据的CS条目被放置在具有所选转发提示的PCCT条目上。将后者作为PCCT条目标识符的一部分,在逻辑上将每个转发提示的PIT和CS隔离到不同的分区中。这减轻了由转发提示引起的众所周知的缓存中毒攻击,并使NDN-DPDK成为第一个安全支持转发提示的NDN转发器。
每个PCCT条目最多可以包含两个具有相同名称和所选转发提示的PIT条目。根据NDN协议[19],兴趣可以带有CanBePrefix和/或MustBeFresh标志影响转发和缓存中的“兴趣到数据”匹配。
然而,该协议对PIT应如何聚合具有相同名称但不同标志的兴趣的方式含糊不清。我们认为,两个仅在CanBePrefix标志上不同的兴趣可以聚合,因为此标志的存在会扩大可匹配的数据集。另一方面,无法聚合MustBeFresh标志不同的两个兴趣,因为使用标志集转发它们会拒绝非新数据,否则会满足没有标志的兴趣,而如果没有标志转发它们,则可能会错误地使用非新数据满足MustBeRefresh兴趣。因此,我们决定在每个PCCT条目中最多存储两个PIT条目,一个带有MustBeFresh,另一个没有。
5.2按数据进行PIT查找
如前所述,NDN协议允许兴趣和数据之间的前缀匹配。当数据包到达时,转发器必须在PIT上执行LPM查找,以确定可以满足哪些待定兴趣。这可能会成为性能瓶颈,甚至成为攻击面,因为数据名称可以包含许多组件。将两阶段查找算法(第4节)应用于PIT是不可行的,因为维护M的开销太高。相反,我们提出了一种基于PIT令牌的不同方法,即第3.3节中已经介绍的用于数据包调度的短逐跳报头字段。在这里,我们扩展了它的用法,以加速PIT查找。
每当转发线程插入PIT条目时,它都会将PCCT条目令牌分配给封闭的PCCT条目,并将其添加到令牌哈希表中。然后,从此PIT条目创建的每个传出利息将在其PIT令牌字段中携带PCCT条目令牌。
当数据包返回时,转发线程可以通过令牌哈希表在O(1)时间内快速找到PCCT条目。仍有必要通过名称比较验证数据是否确实满足兴趣,以防止来自伪造令牌的攻击。
5.3内容存储中的前缀匹配
作为哈希表,PCCT仅支持使用由兴趣/数据名称和所选转发提示组成的键进行精确匹配查询。因此,如果兴趣名称是数据名称的前缀,并且兴趣带有CanBePrefix标志,则完全匹配算法无法从哈希表中检索数据。这严重限制了网络内缓存的有效性,因为任何带有不精确名称的兴趣都必须由制作人回答,而不是由CS来满足。
为了解决这个问题,NDN-DPDK引入了间接CS条目的概念,以提供对前缀匹配的部分支持。间接CS条目是以兴趣命名的特殊CS条目,包含指向直接CS条目的指针。相比之下,直接CS条目是以数据命名的常规CS条目,包含数据包本身的位。
当转发器收到一个数据以回复具有非精确名称的兴趣时,它会将两个条目插入CS:一个带有数据名称和数据包的直接条目,一个带有兴趣名称和指向直接条目的指针的间接条目。这允许CS与前缀名称匹配,前提是使用者应用程序始终使用相同的前缀(或前缀的一小部分)来执行名称发现。如果未来的兴趣与之前的兴趣同名,则使用该兴趣名称在CS中进行精确匹配查找将找到间接条目,从中我们可以跟踪指针并检索直接条目和缓存的数据包。相反,如果到达具有不同名称的Interest,即使它与Data匹配,转发器也无法找到缓存的Data,因为该Interest名称的间接CS条目不存在。
6. 转发战略
转发策略是控制兴趣转发行为各个方面的组件。当本地CS无法满足即将到来的兴趣时,该策略决定将其转发到何处。它还决定在收到Nack时是否执行任何纠正措施。这些决定基于输入,例如匹配FIB条目中的下一个跃点、PIT条目中的下游和上游记录,以及共享公共前缀的兴趣最近数据检索的任何收集的测量值。
早期NDN部署的经验表明,不同的应用程序需要不同的兴趣转发行为。
这为使用不同的决策算法支持多种转发策略,并根据应用程序需求和网络环境动态选择转发策略提供了强大的动力。正如Jacobson等人[9]所述,基本思想是每个FIB条目都包含一个程序,该程序是为专门用于转发选择的抽象机器编写的,它决定了如何转发兴趣。NDN-DPDK使用扩展的BPF(eBPF)[5,18]实现了这一愿景,这是对原始伯克利包过滤器(BPF)[12]的改进。
6.1策略程序
每个策略都是一个eBPF程序,即可以由eBPF虚拟机执行的低级指令列表,例如加载/存储、算术和比较运算符。此外,程序可以调用核心转发引擎为策略提供的一些高级例程。这些包括设置计时器,在指定的面上发送当前兴趣,以及用Nack响应兴趣。
策略程序导出在以下情况下调用或触发的主函数:
- 兴趣数据包到达,无法满足缓存的数据。战略必须决定如何推进。
- 数据包到达并满足兴趣。此触发器允许策略收集路径度量,例如往返时间和满意度
- Nack数据包到达,不属于转发平面自动处理的简单情况之一。然后,该策略可以决定是否必须采取任何纠正措施。
- 策略先前计划的计时器到期。
FIB和PIT条目都包含一个可写的暂存区,用于存储策略的状态和记录度量值。FIB条目暂存区(图4)适用于与整个名称空间相关的信息,而PIT条目暂存区域(图5)适用于特定待定兴趣相关的信息。除这些区域外,该策略能够检查当前数据包,并对FIB和PIT条目中的字段子集具有只读访问权限。
6.2 策略选择和FIB更新
NDN-DPDK将转发策略与每个FIB条目相关联。
当兴趣到达且CS无法满足时,转发平面执行FIB查找,匹配的FIB条目不仅确定潜在的下一跳,还确定应该处理兴趣的策略。该设计与[9]一致,但策略eBPF程序不存储在FIB条目中,而是由FIB条目引用,因此可以由多个FIB条目使用相同的策略,而不存储重复副本。数据和Nacks始终由处理兴趣的相同策略处理。如果策略或FIB条目在利息待定期间发生更改,转发器将使用内置的回退程序处理返回的数据/拒绝数据包,并且不会触发任何策略。
FIB更新后,该策略必须使用空的暂存区域重新启动,因为在FIB更新期间迁移暂存区域中的数据是不可行的。事实上,尽管FIB条目受RCU保护(第4节),但FIB条目暂存区不受保护。
虽然这允许策略修改暂存区域,而无需执行相对昂贵的写入端RCU过程,但这也意味着控制平面线程无法安全地将暂存区域内容从旧FIB条目复制到新FIB条目。