ICMPスロットリングとnet.ipv4.icmp_ratemask
はじめに
以下の記事で書いた環境を作っているときにtracerouteをしていたところ、不可解な事象に遭遇しました。
tracerouteをすると一部のルータから応答が来ず、途中で * が出力されました。しかもコマンドが完了するまでに5秒かかっています。
# time ip netns exec ogikubo traceroute -m 255 nishifunabashi
traceroute to nishifunabashi (10.254.4.23), 255 hops max, 60 byte packets
1 minamiasagaya (10.2.1.20) 0.036 ms 0.002 ms 0.001 ms
2 shinkoenji (10.2.2.20) 0.007 ms 0.002 ms 0.001 ms
3 higashikoenji (10.2.3.20) 0.011 ms 0.002 ms 0.002 ms
4 shinnakano (10.2.4.20) 0.007 ms 0.002 ms 0.003 ms
5 nakanosakaue (10.2.5.20) 0.012 ms 0.003 ms 0.003 ms
6 nishishinjuku (10.2.6.20) 0.009 ms 0.018 ms 0.003 ms
7 shinjuku (10.2.7.20) 0.007 ms 0.004 ms 0.003 ms
8 shinjukusanchome (10.2.8.20) 0.008 ms 0.030 ms 0.005 ms
9 shinjukugyoemmae (10.2.9.20) 0.009 ms 0.004 ms 0.004 ms
10 yotsuyasanchome (10.2.10.20) 0.011 ms 0.004 ms 0.004 ms
11 yotsuya (10.2.11.20) 0.011 ms 0.005 ms 0.037 ms
12 ichigaya (10.8.8.20) 0.021 ms 0.007 ms 0.005 ms
13 iidabashi (10.6.13.10) 0.027 ms 0.006 ms 0.006 ms
14 kudanshita (10.4.6.20) 0.019 ms 0.008 ms 0.006 ms
15 takebashi (10.4.7.20) 0.012 ms 0.008 ms 0.007 ms
16 otemachi (10.4.8.20) 0.019 ms 0.008 ms 0.008 ms
17 nihombashi (10.1.10.20) 0.053 ms 0.011 ms 0.008 ms
18 kayabacho (10.4.10.20) 0.020 ms 0.010 ms 0.008 ms
19 monzennakacho (10.4.11.20) 0.023 ms * *
20 * * *
21 * * *
22 * * *
23 * * *
24 * * *
25 * urayasu (10.4.17.20) 0.117 ms 0.015 ms
26 minamigyotoku (10.4.18.20) 0.035 ms 0.017 ms 0.011 ms
27 gyotoku (10.4.19.20) 0.019 ms 0.013 ms 0.011 ms
28 myoden (10.4.20.20) 0.018 ms 0.013 ms 0.012 ms
29 barakinakayama (10.4.21.20) 0.033 ms 0.016 ms 0.013 ms
30 nishifunabashi (10.254.4.23) 0.023 ms 0.014 ms 0.013 ms
real 0m5.007s
user 0m0.005s
sys 0m0.000s
いつも同じルータが応答なしになるわけではなく、何度か実行すると違うルータから応答がなくなったりします。
各仮想ルータ(network namespace)は同じ設定のはずなのになぜだろう?と思いました。
144個もospfdを起動しているので、リソースが不十分でパケットロスが起きているのかな?とも一瞬思ったのですが、tracerouteは一度に3パケットを出すこと、経由するホップが30であることから、パケットは3 × 30 = 90個しか出ていないはず。応答が1秒くらいで返ってくるとしても90pps(packets per second)。そんな低いppsでパケットロスがおきるとは考えづらいのです。
ヒント
tracerouteのマニュアルを読んでいると次の一節があることに気づきました。
-N squeries, --sim-queries=squeries
Specifies the number of probe packets sent out
simultaneously. Sending several probes concurrently can
speed up traceroute considerably. The default value is 16.
Note that some routers and hosts can use ICMP rate
throttling. In such a situation specifying too large
number can lead to loss of some responses.
一部のルータはICMPスロットリングをしていることがある、と書いてありました。
原因
ICMPスロットリングとはなんぞや?と調べてみると、ICMPのマニュアルに求めている答えと思しきものがありました。
icmp_ratelimit (integer; default: 1000; since Linux 2.4.10)
Limit the maximum rates for sending ICMP packets whose
type matches icmp_ratemask (see below) to specific
targets. 0 to disable any limiting, otherwise the minimum
space between responses in milliseconds.
icmp_ratemask (integer; default: see below; since Linux 2.4.10)
Mask made of ICMP types for which rates are being limited.
Significant bits: IHGFEDCBA9876543210
Default mask: 0000001100000011000 (0x1818)
Bit definitions (see the Linux kernel source file
include/linux/icmp.h):
0 Echo Reply
3 Destination Unreachable *
4 Source Quench *
5 Redirect
8 Echo Request
B Time Exceeded *
C Parameter Problem *
D Timestamp Request
E Timestamp Reply
F Info Request
G Info Reply
H Address Mask Request
I Address Mask Reply
The bits marked with an asterisk are rate limited by default (see
the default mask above).
デフォルトでは、Time Exceededを含む一部のICMPタイプにはレートリミットが設定されていて次に送るまでには1000ミリ秒かかる、ということでしょうか。1000ミリ秒に何パケット送れるのかっていう情報が書いてないのがちょっと気になりますが…
この値がどのように設定されているか確認します。
# sysctl net.ipv4.icmp_ratelimit
net.ipv4.icmp_ratelimit = 1000
# sysctl net.ipv4.icmp_ratemask
net.ipv4.icmp_ratemask = 6168
ratelimitはLinuxカーネルデフォルトの1000ミリ秒でした。
ratemaskはちょっと違う値が入っている?と一瞬思いますが、10進数6168は16進数0x1818なのでデフォルト値ですね。
# printf %x 6168
1818
設定変更
設定方法その1
以下のコマンドでratemaskを0にすることでTime Exceeded(とDestination Unreachable、Source Quench、Parameter Problem)に対するスロットリングを無効にできます。全network namespaceで同様のコマンドを実行しています。
ip netns exec ogikubo sysctl -w net.ipv4.icmp_ratemask=0
設定方法その2
ipコマンドに-aオプションをつけることですべてのnetwork namespaceで同じコマンドを実行することができます。
ip -a netns exec sysctl -w net.ipv4.icmp_ratemask=0
設定方法その3
ip netns addコマンドでnetwork namespaceを作る 前 であれば、ホスト空間(default network namespace)でicmp_ratemaskを設定しておくことで、新規作成されるnetwork namespaceはその設定を引き継ぎます。
sysctl -w net.ipv4.icmp_ratemask=0
結果
*が出力されてコマンド実行完了までが遅かったのが嘘のように早くなり、一瞬(0.006秒)で応答が返ってくるようになりました。
# time ip netns exec ogikubo traceroute -m 255 nishifunabashi
traceroute to nishifunabashi (10.254.4.23), 255 hops max, 60 byte packets
1 minamiasagaya (10.2.1.20) 0.084 ms 0.004 ms 0.001 ms
2 shinkoenji (10.2.2.20) 0.035 ms 0.002 ms 0.003 ms
3 higashikoenji (10.2.3.20) 0.020 ms 0.002 ms 0.001 ms
4 shinnakano (10.2.4.20) 0.021 ms 0.003 ms 0.003 ms
5 nakanosakaue (10.2.5.20) 0.021 ms 0.003 ms 0.003 ms
6 nishishinjuku (10.2.6.20) 0.022 ms 0.022 ms 0.003 ms
7 shinjuku (10.2.7.20) 0.039 ms 0.004 ms 0.003 ms
8 shinjukusanchome (10.2.8.20) 0.024 ms 0.004 ms 0.003 ms
9 shinjukugyoemmae (10.2.9.20) 0.024 ms 0.005 ms 0.004 ms
10 yotsuyasanchome (10.2.10.20) 0.025 ms 0.005 ms 0.005 ms
11 yotsuya (10.2.11.20) 0.025 ms 0.005 ms 0.013 ms
12 ichigaya (10.8.8.20) 0.034 ms 0.009 ms 0.005 ms
13 iidabashi (10.6.13.10) 0.029 ms 0.007 ms 0.006 ms
14 kudanshita (10.4.6.20) 0.027 ms 0.007 ms 0.007 ms
15 takebashi (10.4.7.20) 0.027 ms 0.008 ms 0.006 ms
16 otemachi (10.4.8.20) 0.027 ms 0.010 ms 0.007 ms
17 nihombashi (10.1.10.20) 0.116 ms 0.026 ms 0.008 ms
18 kayabacho (10.4.10.20) 0.032 ms 0.010 ms 0.007 ms
19 monzennakacho (10.4.11.20) 0.028 ms 0.010 ms 0.008 ms
20 kiba (10.4.12.20) 0.028 ms 0.022 ms 0.009 ms
21 toyocho (10.4.13.20) 0.034 ms 0.011 ms 0.009 ms
22 minamisunamachi (10.4.14.20) 0.030 ms 0.020 ms 0.010 ms
23 nishikasai (10.4.15.20) 0.033 ms 0.013 ms 0.010 ms
24 kasai (10.4.16.20) 0.035 ms 0.012 ms 0.010 ms
25 urayasu (10.4.17.20) 0.030 ms 0.011 ms 0.011 ms
26 minamigyotoku (10.4.18.20) 0.033 ms 0.013 ms 0.011 ms
27 gyotoku (10.4.19.20) 0.030 ms 0.014 ms 0.014 ms
28 myoden (10.4.20.20) 0.040 ms 0.014 ms 0.012 ms
29 barakinakayama (10.4.21.20) 0.034 ms 0.018 ms 0.012 ms
30 nishifunabashi (10.254.4.23) 0.034 ms 0.018 ms 0.014 ms
real 0m0.006s
user 0m0.004s
sys 0m0.000s
Discussion