10Gbps の NIC を挿してパケット転送をなるべく高速に行う際のポイントについて列挙します。
FreeBSD 13.0 から Fib の検索アルゴリズムが変わりました。
options FIB_ALGO
を付けてカーネルをビルドすると sysctl で次のように検索アルゴリズムを表示・選択できるようになります。
net.route.algo.debug_level: 5 net.route.algo.inet.algo: bsearch4 net.route.algo.inet.algo_list: bsearch4, radix4_lockless, radix4 net.route.algo.inet6.algo: radix6_lockless net.route.algo.inet6.algo_list: radix6_lockless, radix6 net.route.algo.fib_max_sync_delay_ms: 1000 net.route.algo.bucket_change_threshold_rate: 500 net.route.algo.bucket_time_ms: 50
デフォルトで IPv4 はロックのかかるアルゴリズムになっていますので、経路表のエントリ数が多い場合には lockless のアルゴリズムを選びましょう。
なお、FreeBSD-14-Current では Options FIB_ALGO
は GENERIC カーネルに入っています。
Receive Side Scaling を有効にするには以下の全てを満たす必要があります。
10Gbps の NIC にはほとんどの場合、TSO (TCP Segment Offload) や LRO (Large Receive Offload) の機能がついています。 これらは大きなデータを転送する際にパケットの分割、統合を NIC 側で行ってくれるものです。 ルータの場合は必要ないため、これらを off にします。もし、これらが働くと End-to-End の原則を破るため、良くないです。
ifconfig のオプションに -tso -lro -vlanhwtso
を付けておきます。
sysctl net.inet.ip.redirect=0
を設定すると fast forwarding するようになり高速にパケット転送されます。
これは、12系以前では net.inet.ip.redirect=1 (デフォルト)だと fast forwarding のコードパスを通らないためです。
以下の commit でこの動作が変更されました。
https://cgit.freebsd.org/src/commit/?id=f389439f50fc4c27d15d3017b622270e25ba71c7
IPv6 を転送する時には同様に net.inet6.ip6.redirect=0
を設定します。