0

我正在使用 Mellanox Technologies MT27800 系列 [ConnectX-5],使用 dpdk 多 rx 队列和 rss "ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP"

我分析流量并需要同一会话的所有数据包到达同一进程(会话现在可以是 ip+port)

所以具有相同 ip + 端口的数据包到达同一个队列。

但是如果某些数据包是 ip 分片的,数据包会到达不同的进程。这是一个问题!

我如何计算 c++ 代码中的哈希值,就像在卡中完成的那样,所以我可以重新组装数据包并将它们发送到同一个进程,就像非碎片数据包一样

4

2 回答 2

0

@Davidboo 基于评论中的问题和解释,您所描述的是

  1. 同一会话的所有数据包都到达同一进程(会话现在可以是 ip+port) - 这意味着您正在寻找对称哈希
  2. 一些数据包是 ip 分段的,数据包到达不同的进程 - 你需要在对称 RSS 之前重新组装数据包
  3. Mellanox Technologies MT27800 系列 [ConnectX-5] - 当前 NIC 不支持在 NIC(嵌入式交换机)中重新组装。

因此,实际的问题是what is the right way to solve the problem with the following constrains。有 3 个(1 个硬件和 2 个软件)解决方案。

  • 选项 1 (HW):使用智能 NIC 或网络设备卸载卡,它可以进入流量并在发送到主机服务器之前对碎片进行重组
  • 选项 2 (SW):禁用 RSS 并使用单个 RX 队列。检查数据包是否分片。如果是,重新组装,然后使用rte_flow_distributorrte_eventdev with atomic flow将流量分散到工作核心。
  • 选项 3 (SW):禁用 RSS,但使用n + 1RX queues 和nSW ring 。默认情况下,所有数据包都将在队列 0 上接收。基于 JHASH(用于 SW RSS)添加rte_flow将流固定到队列的规则1 to (n + 1)

假设您无法更改 NIC,我的建议是使用 eventetdev 的选项 2,原因如下。

  1. 允许 HW 或 SW DLB (eventdev) 将流量分布在多个内核上要容易得多。
  2. rte_flow_distributor 类似于硬件 RSS,其中静态固定会导致拥塞和丢包。
  3. 与选项 3 不同的是,不需要维护状态流表来跟踪流。

如何达到同样的效果。

  1. 使用 dpdk 示例代码框架来创建基本的端口初始化。
  2. 启用 DPDK rte_ethdev 以PTYPES在不解析帧和有效负载的情况下识别 IP、非 IP、IP 是否分段。
  3. 检查数据包通过使用RTE_ETH_IS_IPV4_HDR and rte_ipv4_frag_pkt_is_fragmentedipv4 和RTE_ETH_IS_IPV6_HDR and rte_ipv6_frag_get_ipv6_fragment_headeripv6 进行分段(请参阅 DPDK 示例ip_reassembly)。
  4. 提取 SRC-IP、DST-IP、SRC-PORT、DST-PORT(如果数据包不是 SCTP、UDP 或 TCP,则将 src 端口和 dst 端口设置为 0)并使用rte_hash_crc_2byte. 这将确保它是对称散列(SW RSS)。
  5. 然后将带有哈希值的数据包提供给 eventdev 阶段或流分发器阶段(请参阅eventdev_pipeline or distributor)。

笔记:

  • 每个工作核心都将运行业务逻辑。
  • Broadwell Xeon 核心可以处理大约 30Mpps。
  • 在 icelake Xeon 核心上可以处理大约 100Mpps。
于 2022-01-13T11:33:17.957 回答
0

而不是ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP您只能使用ETH_RSS_IP仅从数据包的 IP 地址计算 RSS 哈希值。这样即使数据包被分片,数据包的片段也会到达同一个 CPU 内核。

可以使用以下库在软件中计算数据包的 RSS 值https://doc.dpdk.org/api/rte__thash_8h.html 虽然可以使用此选项,但我仍然建议您查看建议的设置ETH_RSS_IP仅.

启用时ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP,RSS 功能会使用 IP 地址和 src + dst 端口来计算 RSS 哈希值。由于 IP 分段数据包中没有端口,因此无法计算与非分段 IP 数据包相同的值。

您可以:

  • 重新组装 IP 片段以形成完整的 IP 数据包,然后使用rte_thash库计算 RSS 值,
  • 仅从 IP 地址计算 RSS 值(仅使用ETH_RSS_IP设置)。

由于您只在 CPU 内核上进行负载平衡,我认为后一种选择非常适合您的用例。

于 2022-01-13T09:52:19.397 回答