Ubuntu 22.04 のFlow-based ECMPが壊れている話

Ubuntu 22.04 で Flow-based ECMP Routing を実行しようとしたが、正しく分散してくれなかった話のメモ。

Symptom

事象的には これ とほぼ同様。

background

Linux上でRoutingを実行する(受信したパケットのヘッダにある宛先IPアドレスをLookupし、ルーティングテーブル上の該当するプレフィクスのNext-Hopへパケットを転送させる)ことを考える。

ここでとあるプレフィクスへのNext-Hopを複数作成し、かつそれらが等コスト経路 (ECMP) となる場合、Linuxカーネルは fib_multipath_hash_policy のsysctl値に基づいてハッシュを作成し、そのハッシュごとにNext-Hopを選択することでトラフィックを分散させる。これにより、複数のNext-Hop間で通信をロードバランシングしつつ、同一のFlowであれば常に一意のNext-Hopに転送させることができる。

現在はこの仕様を応用して、ECMPルーティングをL4ロードバランサのように扱う場合がある(L2-L4ヘッダを利用してハッシュを作成し、それをベースにロードバランシングすればいい)。私もそのケースに用いようとしている。

これはパケットヘッダとそのハッシュに基づくステートレスな動作であり、パケットのステートには一切関係しない。

problem

......しかし手元の環境のUbuntu 22.02ではこの動作が壊れていて、実際には同じハッシュとなる(完全に同じフローを持つ)パケットが同じNext-Hopへと転送されない場合がある。すべてのパケットがそうなるわけではない。再現性は確認できていない。

上記のRedditではNICドライバの問題とされていたが、私の環境はクラウド上なので virtio_net ドライバだ。

Debian は Debian 11で問題が再現したが、Debian 12までバージョンアップすると問題が解消した。

Ubuntuは23のLatestまでバージョンアップしても改善しない。