Linux 路由转发与 flow offload 问题分析 – 其一

1. 背景

一直使用 ip rule 做国内国外 IP 的分流,策略路由规则也从 5000 多行增加到了现在的 8000 多行。尽管 Linux 路由查找算法已经十分先进了(从早期的 hash 表升级到了后来的 LPC-trie),但是仅限于具体路由表内规则的查找。完整的路由查找过程还需要进行策略路由的匹配,且策略路由是用链表进行存储的,因此 fib_lookup() (FIB, forwarding information base) 查找过程需要遍历所有的策略路由规则,这就带来了性能问题。

问题现象是,openwrt 19.07 的时候,数千条策略路由没有任何性能问题;
而升级到 openwrt 21.02 后发现查找性能极其缓慢,尤其是目标 IP 处在策略路由列表靠后的情况,跑几兆就能把 cpu 核心吃满;意外发现 flow offloading 可以解决这个问题,也就没有深入分析,但是这个疑惑一直在心里硌着;
直到近期升级到 openwrt 22.03,手里两个 MTK 设备的 software flow offloading 失效,不得不重新捡起这个问题。。。当然了,那个 software flow offloading 问题就留下一篇博客去讲了。

2. 测试

测试条件都是添加近 8000 条路由策略,目标 IP 的优先级需要尽量靠后,然后进行 NAT 转发性能测试,和本机 socket 收发性能测试(INPUT/OUTPUT)。
考虑到 openwrt 21.02 以来的大变更主要就是 DSA 交换机架构和 fw4/nftables,因此还拉上了一些 Linux 发行版,手动创建 iptables/nftables NAT 规则进行测试。

结果如下表,似乎和 Linux 内核、iptables/nftables 都没什么关系,而 19.07 没有性能问题反而是一个例外情况。实际上这个版本的 openwrt 也没什么黑科技,没有 fastpath,没有 shortcut-fe,也没有打开 flow offloading, 甚至清空 openwrt 默认的 iptables 规则,手敲一行 SNAT 一样跑的很欢。。。

system kernel iptables / nftables NAT NAT + FLOWOFFLOAD INPUT/OUPUT
OpenWRT 19.07 4.14 ipt
OpenWRT 21.02 5.4 nft X
OpenWRT 22.03 5.10 nft X
Debian 9 4.9 ipt X -
Debian 10 4.19 nft X -
Debian 11 5.15 nft X -

3. 分析总结

在揭晓答案之前,有必要简单回顾一下 Linux 路由查找的历史:

  • Linux 2.6.39, commit 3630b7c0, 基于 hash 的路由查找算法(cat /proc/net/rt_cache)被替换为 LPC-trie (cat /proc/net/fib_trie)。
  • Linux 3.6, commit f4530fa5 优化了 ip rule 的查找逻辑,在没有策略路由条目的情况下,会跳过 rule 的查找过程; 更重要的一点是,commit 5e9965c1 移除了路由缓存 Routing Cache。
  • Linux 4.1, commit 0ddcf43d, 继续优化 ip rule 查找逻辑,在没有策略路由条目的情况下,会合并 local 和 main 表,提高查找效率。

所以总的来说,在 3.6 版本内核移除了 Routing Cache 之后,对于大量 ip rule 的查找就进入了一个很低效的状态,直到现在也没有解决。而 openwrt 19.07 显然是对内核进行了一些 patch 来实现类似的功能,翻了一下 patch 列表 backport-4.14,前排的 020-backport_netfilter_rtcache.patch 非常显眼。

结论如下:

    1. OpenWRT 19.07 NAT 场景策略路由性能 OK 的核心原因是 netfilter_rtcache 这个补丁,缓存路由查找结果,提高 NAT 转发性能。且这个补丁未出现在后续的版本中,估计是因为 flow offload 从新的角度,更全面地解决了包转发性能问题,rtcache 不再那么有价值了。
    1. INPUT/OUTPUT 场景策略路由性能 OK 的原因是 socket 层面还有一层路由缓存,会将第一次路由查找的结果缓存在 struct sock 结构体中 (sk_dst_cache)

问题大概就分析到这里,其实还有很多细节没有提及,但是对于理解 Linux 路由查找过程非常有帮助,关键的几篇文章都贴在了参考资料中,强烈推荐阅读前三个链接。

4. Refer

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


The reCAPTCHA verification period has expired. Please reload the page.

*