.. _dpdk:

23.7. DPDK

23.7.1. 简介

数据平面开发套件(DPDK)是一组用于增强和加速数据平面中数据包处理的库和驱动程序。其主要用途是通过绕过内核网络协议栈来提供更快的数据包处理,这可以带来显著的性能提升。关于如何设置DPDK的详细说明,请参阅 Suricata.yaml 了解DPDK的基本配置。 以下章节包含针对更特殊使用场景设置DPDK和Suricata的示例。

23.7.2. 大页内存分析

Suricata可以分析系统已使用的大页内存。当存在大页内存过度分配的可能性时,这尤其有用。 大页内存分析旨在检查正在使用的大页内存,并提供关于适当大页数量的建议。这能确保Suricata以最佳状态运行,同时为系统上的其他应用程序留出足够内存。该分析通过比较Suricata初始化前后的大页内存快照来工作。初始化完成后,Suricata不会再分配更多大页内存。 大页内存分析可在性能日志级别中查看,并在Suricata启动时打印输出。仅当Suricata检测到系统存在与大页内存分配相关的异常时才会打印。

建议从"干净"状态开始执行此分析——即所有大页内存都处于空闲状态时。特别建议在系统没有运行其他依赖大页内存的应用程序时进行。可通过以下两种方式之一进行检查:

# 全局检查
cat /proc/meminfo

HugePages_Total:    1024
HugePages_Free:     1024

# 按NUMA节点检查取决于NUMA节点ID、大页大小及nr_hugepages/free_hugepages - 例如:
cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages

在Suricata和其他大页相关应用程序终止后,如果空闲大页数量与总大页数不相等,则表明部分大页未被完全释放。 这可以通过从大页挂载目录(文件系统)中删除DPDK相关文件来解决。 在删除大页时需要格外小心,特别是当其他依赖大页的应用程序正在运行时,此操作会破坏它们的内存功能。 通常可按以下方式从大页目录中删除DPDK文件:

sudo rm -rf /dev/hugepages/rtemap_*

# 查看大页挂载位置:
dpdk-hugepages.py -s
# 或
mount | grep huge

23.7.3. 绑定接口

链路绑定轮询模式驱动程序(Bond PMD)是DPDK提供的一种软件机制,用于将多个物理网络接口聚合成一个逻辑接口。 绑定功能可用于:

  • 将分路接口的双向流量传递至同一工作线程

  • 通过监控多个链路建立冗余

  • 通过在多条链路上负载均衡流量来提高网络性能

Bond PMD本质上是一个操作多个物理网络接口的虚拟驱动程序。它支持多种工作模式,如`DPDK文档 <https://doc.dpdk.org/guides/prog_guide/link_bonding_poll_mode_drv_lib.html>`_所述。 不同的绑定模式可适应用户需求。 DPDK Bond PMD要求聚合的接口必须是相同设备类型——例如两个物理端口都运行mlx5 PMD。 Bond PMD支持多队列,因此可在worker运行模式下工作。它不应影响单个端口的流量分布,流量应按照RSS配置由物理端口分发,就像它们独立配置时一样。

作为Bond PMD的示例,我们可以设置Suricata监控两个接收来自光接口TAP流量的接口。这意味着Suricata在一个接口接收通信的一个方向,在另一个接口接收另一个方向。

...
dpdk:
  eal-params:
    proc-type: primary
    vdev: 'net_bonding0,mode=0,slave=0000:04:00.0,slave=0000:04:00.1'

  # DPDK抓包支持
  # RX队列(及IPS模式下的TX队列)按1:1比例分配给核心
  interfaces:
    - interface: net_bonding0 # 网卡端口的PCIe地址
      # 线程设置:可选值为"auto"或线程数
      # - auto会占用所有核心
      # IPS模式下需指定核心数且两个接口的数值必须匹配
      threads: 4
...

在suricata.yaml的DPDK部分,我们为虚拟设备添加了一个新的eal-params参数——vdev。 DPDK环境抽象层(EAL)可以在初始化期间初始化一些虚拟设备。 本例中,EAL创建了一个类型为`net_bonding`的新设备。net_bonding`后缀表示接口名称(本例中为0)。 设备名称后传递额外参数,如绑定模式(`mode=0)。这是DPDK Bond PMD文档中描述的轮询模式。 `net_bonding0`接口的成员(slaves)在绑定模式参数后追加。

当设备在EAL参数中指定后,就可以在Suricata的`interfaces`列表中使用。注意该列表不包含物理端口的PCIe地址,而是`net_bonding0`接口。 线程部分也通过启用set-cpu-affinity和列出应用于管理和工作CPU集的CPU来根据接口列表中的项目进行调整。

...
threading:
  set-cpu-affinity: yes
  cpu-affinity:
    management-cpu-set:
      cpu: [ 0 ]  # 亲和性设置中仅包含这些CPU
    receive-cpu-set:
      cpu: [ 0 ]  # 亲和性设置中仅包含这些CPU
    worker-cpu-set:
      cpu: [ 2,4,6,8 ]
...

23.7.4. 中断(节能)模式

DPDK传统上以其轮询模式操作而闻名。在此模式下,CPU核心持续从网卡(NIC)查询数据包。虽然这种方法具有降低延迟和提高性能等优点,但在流量零星或较低的场景中可能效率不高。持续轮询会导致不必要的CPU消耗。为解决这个问题,DPDK提供了`中断`模式。

中断模式带来的明显优势是能效提升。到目前为止在我们的测试中,尚未观察到性能下降。实际上Suricata的性能还略有提升。 (IPS运行模式的)用户应注意中断可能引入非确定性延迟。但延迟绝不会高于其他(如AF_PACKET/AF_XDP/...)抓包方法。

DPDK中的中断模式可以基于每个接口进行配置。这允许混合设置,其中一些工作线程在轮询模式下运行,而其他工作线程使用中断模式。中断模式的配置可在suricata.yaml文件的DPDK部分找到并修改。

以下是启用特定接口中断模式的示例配置:

...
dpdk:
    eal-params:
      proc-type: primary

    interfaces:
      - interface: 0000:3b:00.0
        interrupt-mode: true
        threads: 4

23.7.5. 自动接口配置

许多接口属性可以手动配置。但Suricata能根据网卡能力自动配置接口属性。这可以通过将`mempool-size`、mempool-cache-sizerx-descriptors`和`tx-descriptors`接口节点属性设置为`auto`来实现。 这将允许Suricata根据网卡能力基于最佳效果计算自动设置各个属性的大小。 例如,接收(RX)描述符基于不超过网卡支持描述符数量的最大"2的幂"来计算。TX描述符数量取决于配置的`copy-mode。 IDS(无)模式默认不使用TX描述符且不创建任何TX队列。IPS和TAP模式使用与RX描述符相同数量的TX描述符。 内存池及其缓存数量则从描述符数量派生而来。

Rx(和Tx)描述符设置为尽可能高的值以在流量激增时提供更多缓冲空间。但这需要更多内存。如有需要,仍可手动设置各个属性。

Note

Mellanox ConnectX-4网卡在TAP/IPS模式下不支持`tx-descriptors`的自动配置。可设置为固定值(如16384)。

23.7.7. 封装剥离

Suricata支持在支持的网卡上剥离硬件卸载的封装。目前支持VLAN封装剥离。 可通过`vlan-strip-offload`启用VLAN封装剥离功能。