CLOVER🍀

That was when it all began.

Linuxで現在設定されている(使用可能な)TCP輻輳制御アルゴリズムを見る

これは、なにをしたくて書いたもの?

最近、こちらの本を読んでいるのですが。

輻輳制御とそのアルゴリズムについて、いろいろと紹介されています。

このあたりについて、今まであまり意識したことがなかったので、「さて、手元のLinux環境ではどうなっているのか?」ということで
調べてみました。

輻輳制御自体については、こちらあたりを参考に。

第1回 TCPの輻輳制御とは何か:基本から学ぶ TCPと輻輳制御 ……押さえておきたい輻輳制御アルゴリズム|gihyo.jp … 技術評論社

アルゴリズムとしては、Googleが開発したBBRが注目されていたりするようで?

TCPを高速化する新アルゴリズム「BBR」、Googleが開発 - Computerworldニュース:Computerworld

輻輳制御の新アルゴリズム TCP BBR を GCP に導入 | Google Cloud Blog

【Linux】輻輳制御アルゴリズムの紹介 | アカスブログ

環境

今回の環境は、こちらです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic


$ uname -srvmpio
Linux 4.15.0-54-generic #58-Ubuntu SMP Mon Jun 24 10:55:24 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu Linux 18.04 LTS、カーネルは4.15です。

現在のTCP輻輳制御アルゴリズムを見る

これは、カーネルパラメーター「net.ipv4.tcp_congestion_control」を見ればOKです。

$ sudo sysctl -a 2>&1 | grep -i tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic

現在選択されているのは、「cubic」ですね。なお、「congestion」という単語は、輻輳、混雑、渋滞などを表します。

https://github.com/torvalds/linux/blob/v4.15/Documentation/networking/ip-sysctl.txt#L247-L254

tcp_congestion_control - STRING
Set the congestion control algorithm to be used for new
connections. The algorithm "reno" is always available, but
additional choices may be available based on kernel configuration.
Default is set as part of kernel configuration.
For passive connections, the listener congestion control choice
is inherited.
[see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ]

「reno」はいつでも使えるよ、デフォルトで設定されるのはカーネルの設定で決まるよ、という感じですね。

あと、このカーネルパラメーターの説明を見ると、システムコールsetsockoptでも指定できそうですね。

Man page of GETSOCKOPT

Man page of TCP

利用可能な輻輳制御アルゴリズムを見る

これは、カーネルパラメーター「net.ipv4.tcp_available_congestion_control」を参照します。

$ sudo sysctl -a 2>&1 | grep -i tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = reno cubic

「reno」、「cubic」が利用可能ですね。

https://github.com/torvalds/linux/blob/v4.15/Documentation/networking/ip-sysctl.txt#L237-L240

tcp_available_congestion_control - STRING
Shows the available congestion control choices that are registered.
More congestion control algorithms may be available as modules,
but not loaded.

その他のアルゴリズムは?

「net.ipv4.tcp_available_congestion_control」を見ると、利用可能な輻輳制御アルゴリズムは「reno」と「cubic」の2つでした。

先に記載したBBRや、他にもいろいろあるようです。

一覧は、こちら。

TCP congestion control / Algorithms

Linuxカーネルのソースコード上では、「tcp_[アルゴリズム名].c」として実装されています。

https://github.com/torvalds/linux/tree/v4.15/net/ipv4

例えば、CUBICであれば「tcp_cubic.c」、

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/tcp_cubic.c

BBRであれば「tcp_bbr.c」です。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/tcp_bbr.c

「tcp_reno.c」はパッと見ではいないのですが、Reno(正確にはNewReno)は「tcp_cong.c」のようです。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/tcp_cong.c

NewRenoおよびCUBICは、カーネルのビルド時に指定することで有効化できるようです(「TCP_CONG_[アルゴリズム名])。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/Makefile#L47-L62

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/Kconfig#L479-L739

NewRenoは無条件に組み込まれるのですが、CUBICについてもデフォルトで組み込まれるようになっています。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/Kconfig#L493-L499

config TCP_CONG_CUBIC
tristate "CUBIC TCP"
default y
---help---
This is version 2.0 of BIC-TCP which uses a cubic growth function
among other techniques.
See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf

BBRは、「default n」ですね。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/Kconfig#L663-L676

config TCP_CONG_BBR
tristate "BBR TCP"
default n
---help---

BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to
maximize network utilization and minimize queues. It builds an explicit
model of the the bottleneck delivery rate and path round-trip
propagation delay. It tolerates packet loss and delay unrelated to
congestion. It can operate over LAN, WAN, cellular, wifi, or cable
modem links. It can coexist with flows that use loss-based congestion
control, and can operate with shallow buffers, deep buffers,
bufferbloat, policers, or AQM schemes that do not provide a delay
signal. It requires the fq ("Fair Queue") pacing packet scheduler.

カーネルビルド時に有効にしておくと、組み込まれるみたいです。

ところで、他のアルゴリズムを有効にする設定を見ていると、「default m」みたいなものがあります。

https://github.com/torvalds/linux/blob/v4.15/net/ipv4/Kconfig#L515-L524

config TCP_CONG_HTCP
tristate "H-TCP"
default m
---help---
H-TCP is a send-side only modifications of the TCP Reno
protocol stack that optimizes the performance of TCP
congestion control for high speed network links. It uses a
modeswitch to change the alpha and beta parameters of TCP Reno
based on network conditions and in a way so as to be fair with
other Reno and H-TCP flows.

これは、カーネルモジュールとなるみたいですね…。

実際に、カーネルをビルドしたりするのは、また別の機会にやってみようかなと思います。

このあたり、眺めていてちょっと面白かったです。