前の話で、スタティックルートとは管理者がルーティングテーブルに1行を手で書き足すこと、ip route <prefix> <mask> <next-hop> の3要素を埋めるだけでルータは新しい行き先を覚える、というところまで読み解いた。書いた行はそのままテーブルに残る。3要素の形は、すでに読み解いたものだ。
CORE-RT-01 のコンフィグを引き続き眺めていると、こんな1行に出会う。
CORE-RT-01# show running-config | include ip route
ip route 10.1.30.0 255.255.255.0 10.1.1.2
ip route 0.0.0.0 0.0.0.0 10.1.1.254
2行目の ip route 10.1.30.0 255.255.255.0 10.1.1.2 までは、3要素を埋めた具体的な宛先指定だ。10.1.30.0/24 宛は 10.1.1.2 へ渡せ、と読める。けれど、3行目の ip route 0.0.0.0 0.0.0.0 10.1.1.254 だけがおかしい。ip route の後の3つの値が、ぜんぶゼロかゼロに近い値で並んでいる。
この1行は、何のためにルーティングテーブルに並んでいるのだろう。プレフィックスもマスクも全部ゼロ。値が極端すぎて、何の宛先帯を指しているのかすら直感的には掴めない。
形は3要素のはずだ。けれど値が「全部ゼロ + 全部ゼロ + 上流のIP」と、何とも奇妙にも見える。3要素の読み方をそのまま当てはめて、これがどんな宛先帯への経路を表しているか、5秒だけ自分の言葉で組み立ててみてほしい。何か違和感が立ち上がるはずだ。
0.0.0.0/0 は『他のどの行にもマッチしないとき最後に使う1行』だ。最長一致のルールが、特別扱いではなく自然にこの行を『最後の手段』にしている。


全部ゼロのプレフィックス・マスク — ip route 0.0.0.0 0.0.0.0 の構造と値の意味
CORE-RT-01 のコンフィグに並んでいる1行を、もう一度見る。
ip route 0.0.0.0 0.0.0.0 10.1.1.254
ip route のあとに3つの値の塊がある。1つ目が 0.0.0.0(宛先プレフィックス)、2つ目が 0.0.0.0(サブネットマスク)、3つ目が 10.1.1.254(next-hop)。形は前の話と同じ3要素だ。違うのは、1つ目と2つ目が「全部ゼロ」で埋まっていることだけだ。
2つ目のマスクから読む。前のシリーズ(IPアドレス)で、サブネットマスク 255.255.255.0 は /24 と等価だった。255.255.0.0 なら /16、255.0.0.0 なら /8。マスクの中のビットが1のところが「町の大きさを決める」部分で、ビットが0のところが「番地として残る」部分。では 0.0.0.0 はどうなるか。32bit ぜんぶがゼロ。/N で書けば /0。プレフィックス長は0bit ということになる。
プレフィックス長が0bit ということは、宛先IPに対して『何ビット分の一致を求めるか』という条件が『0ビット分』だ。0ビット分しか問わないのだから、どんな宛先IPでも条件を満たす。10.1.30.10 でも、8.8.8.8 でも、203.0.113.5 でも、宛先IPがなんであれ、この1行は条件としては満たしている。
どんな宛先IPにも当てはまる行がルーティングテーブルにあると、ルータはどんなパケットでもこの行を使ってしまうのではないか。本当にそうなら、ip route 10.1.30.0 255.255.255.0 10.1.1.2 のような具体的な経路を書く意味がなくなる。テーブルに複数の行が並ぶとき、どの行が選ばれるかを決めるルールが必要になる。
テーブルの行同士がどう選ばれるか — 最も具体的な行が勝つ
ルータが宛先IPでルーティングテーブルを引くとき、選ばれる行は1つだけだ。複数の行が当てはまったとき、どの行を選ぶかのルールがある。
複数の行が宛先IPに当てはまった場合、最も具体的な行(プレフィックスが最も長い行)が選ばれる。
広い指定よりも、絞った指定が勝つ。「日本にいる人」と「東京都にいる人」と「千代田区にいる人」のすべてが当てはまる場所にいるとき、最も具体的な「千代田区」が住所として選ばれる。最も具体的な行が勝つ、というルールは、テーブルのどの行にも共通する。
CORE-RT-01 のルーティングテーブルに、次の2行が並んでいるとする。
| 行 | プレフィックス長 | |
|---|---|---|
| 行A | 10.1.30.0/24 → 10.1.1.2 | 24bit |
| 行B | 0.0.0.0/0 → 10.1.1.254 | 0bit |
宛先IP 10.1.30.10 でテーブルを引く。
- 行Aの条件は「上位24ビットが
10.1.30と一致するか」。10.1.30.10はこれを満たす。当てはまる。 - 行Bの条件は「上位0ビットが一致するか」。0ビットしか問わないので、必ず満たす。当てはまる。
両方とも当てはまる。けれど、選ばれるのは1つだけ。最長一致のルールは「より具体的な行(プレフィックスが長い方)」を選ぶ。24bit > 0bit。だから、行A が勝つ。10.1.30.10 宛のパケットは 10.1.1.2 へ渡される。


宛先IP 8.8.8.8 ではどうか。
- 行Aの条件は「上位24ビットが
10.1.30と一致するか」。8.8.8.8はこれを満たさない。当てはまらない。 - 行Bの条件は「上位0ビットが一致するか」。必ず満たす。当てはまる。
当てはまるのは行B だけ。選ばれるのは行B。8.8.8.8 宛のパケットは 10.1.1.254 へ渡される。
プレフィックス長が長い(=具体的)ほど、他の行と条件が重なったときに優先される。プレフィックス長が短い(=広い)ほど、他に当てはまる行があれば必ず順番を譲る。
0.0.0.0/0 のプレフィックス長が 0bit の意味 — なぜ最後の手段になるのか
プレフィックスとマスクが両方ゼロの1行は、どんな宛先IPにも当てはまる。それなのに、なぜルータはどんなパケットでもこの行を使ってしまわないのか。
0.0.0.0/0 はプレフィックス長が0bit。ルーティングテーブルで考えうる最も短いプレフィックスだ。/24 の経路があれば 24bit > 0bit で必ず負ける。/16 の経路があっても 16bit > 0bit で負ける。/1 の経路があっても 1bit > 0bit で負ける。テーブルに他のどんなプレフィックス長の行があっても、0bit は最も非特異な側に位置するので、必ず譲る。
0.0.0.0/0 が選ばれるのは、テーブルの他のどの行にも当てはまらない宛先IPの場合だけだ。他に当てはまる行が一つでもあれば、その行が選ばれる。他に当てはまる行が一つもないとき、最後に残るのが 0.0.0.0/0 — それが「他に道がなければここへ」という働き方だ。


全部ゼロの1行を初めて見たとき、多くの人がこう感じる — 「全部ゼロは何でも当てはまる、つまり全てを上書きする最強の経路」。これは正反対だ。全部ゼロは、確かに何でも当てはまる。けれど、最長一致のルールにおいて、何でも当てはまる行は最も非特異な行であり、他の行に必ず負ける。だから、テーブルの中で「最後に残ったときだけ選ばれる」位置にいる。最強ではなく、最後の手段。
テーブルのどの行にも同じ最長一致のルールが適用されている。0.0.0.0/0 が最後の手段として機能するのは、設計者が特別なフラグを立てたからではなく、プレフィックス長の数学によって最も非特異な側に位置づけられているからだ。
書き方も ip route 0.0.0.0 0.0.0.0 <next-hop> と3要素の形のまま、プレフィックスとマスクを「全部ゼロ」で埋め、next-hop に「他に道がなければ最後にここへ渡す相手」を書く。普通は上流のルータの IP が入る。本話の例では 10.1.1.254 がその相手だ。すでに読み解いた3要素の構文は、極端な値を入れた場合にもそのまま生きている。
コンフィグに並んでいる ip route 0.0.0.0 0.0.0.0 10.1.1.254 の1行は、奇妙な記号の組み合わせではなく、テーブルの他の行に当てはまらない宛先だけを受け取る最後の経路として読める。次の話では、show ip route の出力を読み解き、具体的な経路と最後の手段が同じテーブルのどこにどう並んでいるかを画面で確認する。