将 IPsec 解密分散到多个 CPU 上

将 IPsec 解密分散到多个 CPU 上

尽管有多个 IPsec 隧道 (SA),所有解密的 IPsec 流量都在单个 CPU 上处理。如何在多个 CPU 之间分担负载?

我在 AWS 上的 Ubuntu 22.04 上运行 Strongswan IPsec ,c5n.2xlargeaesni_intel加载,有 8 个 SA。此实例的工作方式类似于 IP 路由器,可中继所有流量,无论是封装还是解封装。(IPsec 配置为“隧道”模式,使用 UDP 端口 4500 进行 NAT 遍历。)

使用top -1我发现,对于加密的流量,CPU 负载均匀分布在 8 个 CPU 上,无论ip xfrm state条目(子 SA)的数量或 ECMP 的配置方式如何。这很好。(我的理解是aesni_intel内核模块提供了这种行为。)

但是,对于正在解密的流量,在所有 ECMP 配置中,所有流量都分配给同一个 CPU。

我尝试过的 ECMP 配置:

  • /proc/sys/net/ipv4/fib_multipath_hash_policy=0(L3 ECMP)
  • /proc/sys/net/ipv4/fib_multipath_hash_policy=1(L4 ECMP)
  • /proc/sys/net/ipv4/fib_multipath_hash_policy=4(自定义 ECMP),/proc/sys/net/ipv4/fib_multipath_hash_fields=255(所有字段)

我将使用其他云和实例类型,但这是我测试过的,希望我学到的知识可以应用于其他情况。

我的理解是,通常情况下,给定 SA 的解密发生在单个 CPU 上,但 SA 应该分布在多个 CPU 上。但事实并非如此。

我该怎么做才能让解密负载在多个 CPU 之间分担?

示例ip xfrm state条目:

[root@33a14363e632 /]# ip xfrm state
src 1.1.0.10 dst 1.2.0.10
    proto esp spi 0xcc688295 reqid 1 mode tunnel
    replay-window 0 flag af-unspec
    aead rfc4106(gcm(aes)) 0x78b083dcfd8bad769a5f63fb3e565a88b7431453 128
    encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
    anti-replay context: seq 0x0, oseq 0x3a, bitmap 0x00000000
    if_id 0x1
src 1.2.0.10 dst 1.1.0.10
    proto esp spi 0xcb32714b reqid 1 mode tunnel
    replay-window 32 flag af-unspec
    aead rfc4106(gcm(aes)) 0x12061cd6fe8a7102c03990ddc8c8f0d5314785a1 128
    encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
    anti-replay context: seq 0x3c, oseq 0x0, bitmap 0xffffffff
    if_id 0x1

所有 SA 的 IP 地址都相同。我猜这与 NIC 如何对数据包进行排队有关。我认为 NIC 根据 L3 或 L4 哈希选择队列,而不管内核 ECMP 配置如何,并忽略 ESP SPI。

相关内容