3-3 RIP — 距離ベクトル型の本質と限界
動的ルーティングプロトコルの始祖 RIP を題材に、距離ベクトル型の伝播モデル、ホップ数メトリックの限界、Split Horizon と Route Poisoning による収束防衛、そして 4 つのタイマーがどう絡むかを CSR1000v 3 台の実機 RIB と debug ip rip で追う。最後に IOS-XE 17.3 で count-to-infinity がどこまで再現できるかも検証する。
1. 前節の振り返りと本節の内容
3-2 では複数の経路情報源から 1 つを選ぶ枠組み (Longest Match → AD 比較) と、同一ソース内で経路を絞るためのメトリックを整理した。検証ラボの最後で、静的を消すと OSPF (AD=110) が、OSPF も止めると RIP (AD=120) が席を取り、それぞれが自分のメトリックで R1↔R3 直結を選ぶ様子も観察した。
本節はこのとき動かしっぱなしにしていた RIP に焦点を当てる。RIP は 1988 年の RFC 1058 以来、動的ルーティングプロトコルの始祖として扱われてきた 距離ベクトル型 (Distance Vector) の代表格である。現代のキャリア網や企業基幹で RIP が選ばれることはほぼ無くなったが、距離ベクトル型の動作原理は EIGRP の DUAL 理解にそのまま効くため、教科書としての価値は今も大きい。
本節では距離ベクトル型の伝播モデル、ホップ数というメトリックの限界、4 つのタイマー (Update / Invalid / Holddown / Flush)、Split Horizon と Route Poisoning によるループ防止、そして count-to-infinity が IOS-XE で本当に再現するかまでを、CSR1000v 3 台の debug ip rip を撮りながら確認する。
2. 距離ベクトル型の伝播モデル
RIP の動作を 1 行で書くと「隣接が言ったメトリックに +1 して、自分の database に取り込み、また別の隣接へ再放送する」になる。これが 距離ベクトル (Distance Vector) という名前の中身で、各ルータが持つ情報は「宛先プレフィックス + そこに行くまでの距離 (= ホップ数) + 次のルータ (= 隣接の IP)」の 3 点だけである。
重要なのは 「経路の中身」を知らない という点である。R1 は「10.30.3.0/24 へは R2 (10.12.0.1) 経由で metric 2」という事実だけを持ち、その先 R2 が誰経由で届けるかは関知しない。R2 が嘘をついても (たとえば本当は届かない宛先を metric 1 で広告しても) R1 はそれを信じる。距離ベクトル型は「噂で伝わるルーティング」と呼ばれることがあるが、噂の出所を遡れない設計上の制約がループ防止の難しさに直結する。
対比として、3-5 で扱う リンクステート型 (Link State) の OSPF は逆の発想で動く。各ルータがネットワーク全体のトポロジを LSA で集めて手元で再構築し、Dijkstra で最短経路を自分で計算する。経路の中身 (どのリンクが生きていてどのリンクが死んでいるか) を全員が共有するため、噂の伝言ゲームに頼らない。距離ベクトル型は計算が軽く設定も単純だが、トポロジ全体の整合性は隣接同士の地道な情報交換でしか保てない。
3. RIPv1 と RIPv2 の差分
RIP には 1988 年策定の v1 (RFC 1058) と 1998 年改訂の v2 (RFC 2453) があり、教科書で RIP と書けば普通 v2 を指す。両者の差を表で並べる。
| 観点 | RIPv1 | RIPv2 |
|---|---|---|
| アドレッシング | classful (サブネットマスクを広告しない) | classless (VLSM / CIDR 対応) |
| 配信方式 | broadcast (255.255.255.255) | multicast (224.0.0.9) |
| 認証 | 無し | plain text / MD5 |
| Auto-summary | 強制 (classful 集約) | 既定有効だが no auto-summary で無効化できる |
| ホップ数上限 | 15 | 15 (同じ) |
| 経路タグ | 無し | あり (再配送識別用) |
VLSM が使えないという点だけで v1 は現代ネットワークでは事実上採用できず、本節以降でも RIPv2 だけを扱う。設定の冒頭で version 2 を明示し、no auto-summary で classful 集約を切るのが最低限の作法になっている。
router rip
version 2
no auto-summary
network 10.0.0.0network 10.0.0.0 は 3-2 §11 で触れたとおり「広告するプレフィックス」ではなく「RIP を起動する IF を選ぶセレクタ」である。10.x.x.x に該当する IP を持つ IF (本ラボでは Gi2 / Gi3 / Lo0 / Lo10 など) で RIP が起動し、結果としてそれらの IF のサブネットが広告される。
4. メトリック: ホップ数だけの世界
RIP のメトリックは 経由ルータ数 (ホップ数) だけである。1 Gbps のリンクも 56 kbps のリンクも同じ「1 ホップ」と数え、ホップ数最小の経路が無条件に勝つ。3-2 §6 の表で並べた他プロトコル (帯域ベースの OSPF、複合の EIGRP) とは思想が異なる。
設計上の上限は 15 ホップ で、16 を到達不能 (infinity) として扱う。16 ホップを超える経路を作りたければ最初から RIP は選べない。これは実装の都合ではなく仕様で、後述する count-to-infinity の自然な上界として 16 が選ばれた経緯がある。
本ラボでは R1 / R2 / R3 の三角構成にそれぞれ Loopback を追加し、RIP で広告して経路がどう伝わるかを観察する。アドレス計画は 3-2 を流用し、各ルータに「サービス側 Loopback」を 1 つずつ追加する。
| 用途 | アドレス | 備考 |
|---|---|---|
| R1 Lo10 | 10.10.1.0/24 | R1 が RIP で広告するサービス網 |
| R2 Lo20 | 10.20.2.0/24 | R2 のサービス網 |
| R3 Lo30 | 10.30.3.0/24 | R3 のサービス網 (後段でこれを落とす) |
その他 (R1/R2/R3 Lo0, P2P /31 リンク 3 本) は 3-2 と同一である。

3 台に同じ router rip / version 2 / no auto-summary / network 10.0.0.0 を投入し、60 秒待ってから R1 視点で RIP database を見る。
R1#show ip rip database
10.0.0.0/8 auto-summary
10.0.1.1/32 directly connected, Loopback0
10.0.2.1/32
[1] via 10.12.0.1, 00:00:22, GigabitEthernet2
10.0.3.1/32
[1] via 10.13.0.1, 00:00:07, GigabitEthernet3
10.10.1.0/24 directly connected, Loopback10
10.12.0.0/31 directly connected, GigabitEthernet2
10.13.0.0/31 directly connected, GigabitEthernet3
10.20.2.0/24
[1] via 10.12.0.1, 00:00:22, GigabitEthernet2
10.23.0.0/31
[1] via 10.13.0.1, 00:00:07, GigabitEthernet3
[1] via 10.12.0.1, 00:00:22, GigabitEthernet2
10.30.3.0/24
[1] via 10.13.0.1, 00:00:07, GigabitEthernet3R3 の 10.30.3.0/24 を R1 は metric 1 で学習している。これは R1↔R3 直結 (Gi3) 経由で 1 ホップという意味で、R2 経由 (2 ホップ) よりホップ数が小さいため直結が勝った。3-2 で OSPF が同じ宛先を直結経由で取った構図 (帯域ベースのコスト計算でも結局直結が短かった) と一致する。
ルーティングテーブルにもこのとおり載る。
R1#show ip route rip
10.0.0.0/8 is variably subnetted, 12 subnets, 3 masks
R 10.0.2.1/32 [120/1] via 10.12.0.1, 00:00:00, GigabitEthernet2
R 10.0.3.1/32 [120/1] via 10.13.0.1, 00:00:12, GigabitEthernet3
R 10.20.2.0/24 [120/1] via 10.12.0.1, 00:00:00, GigabitEthernet2
R 10.23.0.0/31 [120/1] via 10.13.0.1, 00:00:12, GigabitEthernet3
[120/1] via 10.12.0.1, 00:00:00, GigabitEthernet2
R 10.30.3.0/24 [120/1] via 10.13.0.1, 00:00:12, GigabitEthernet3[120/1] は AD=120 / メトリック=1 を意味し、3-2 で見た [1/0] (static) や [110/2] (OSPF) と同じ並び順である。10.23.0.0/31 が R1↔R3 経由と R1↔R2↔R3 経由の両方で metric 1 として登録されているのは、両経路がホップ数で並んだため ECMP として両方 RIB に載せたものである (maximum-paths 4 が既定値)。
ここで RIP のホップ数だけメトリックの限界が見える。仮に R1↔R2 リンクが 1 Gbps、R1↔R3 リンクが 56 kbps だったとしても、RIP は両方を「1 ホップ」と数えて区別しない。実速度を見ない設計の限界として広く知られている話で、1990 年代後半に企業網が高速化していくにつれ RIP が OSPF / EIGRP に置き換えられていった最大の理由がここにある。
5. RIP の 4 つのタイマー
距離ベクトル型は隣接同士の周期通信で世界を保つ。RIP は 4 つのタイマーでこの保ち方を統制している。
| タイマー | 既定値 | 役割 |
|---|---|---|
| Update | 30 秒 | 全 RIP IF に database 全体を周期広告 |
| Invalid | 180 秒 | Update が途切れた経路を metric=16 に昇格 (到達不能扱い) |
| Holddown | 180 秒 | Invalid 化した経路について、他経路からの「もっと悪い」広告を一定期間拒否 |
| Flush | 240 秒 | 経路を database から完全に削除 |

show ip protocols で実際の設定値が確認できる。
R1#show ip protocols
Routing Protocol is "rip"
Sending updates every 30 seconds, next due in 9 seconds
Invalid after 180 seconds, hold down 180, flushed after 240タイマー設計の意図は 「定期的に再確認することで世界を保つ」 と 「不安定な広告に振り回されない」 の両立である。Update の 30 秒は隣接の生存確認も兼ねており、180 秒間届かなければ隣接が消えたか経路が消えたかと判断する。Holddown は「直前まで使っていた経路が消えた」と分かった直後に、別経路からの広告 (それが本当に正しいかまだ怪しい) で安易に席を埋めないための猶予期間である。
このタイマー設計は穏当に見えて、収束 (再計算が安定するまでの時間) を分単位に押し上げる主因でもある。180 秒 (= 3 分) の Invalid 待ちは、現代の LAN ではあまりに遅い。EIGRP の Hold Time が既定 15 秒、OSPF の Dead Interval が既定 40 秒であるのと比べると、RIP の収束の遅さが際立つ。
6. debug ip rip で Update の中身を見る
タイマーの周期動作を直接観察するため、R1 で debug ip rip を 60 秒回す。出力は 30 秒ごとに 2 周分の Update が見える。
*May 20 12:20:51.622: RIP: sending v2 update to 224.0.0.9 via GigabitEthernet3 (10.13.0.0)
*May 20 12:20:51.622: RIP: build update entries
*May 20 12:20:51.622: 10.0.1.1/32 via 0.0.0.0, metric 1, tag 0
*May 20 12:20:51.622: 10.0.2.1/32 via 0.0.0.0, metric 2, tag 0
*May 20 12:20:51.623: 10.10.1.0/24 via 0.0.0.0, metric 1, tag 0
*May 20 12:20:51.623: 10.12.0.0/31 via 0.0.0.0, metric 1, tag 0
*May 20 12:20:51.623: 10.20.2.0/24 via 0.0.0.0, metric 2, tag 0
*May 20 12:20:51.853: RIP: received v2 update from 10.13.0.1 on GigabitEthernet3
*May 20 12:20:51.853: 10.0.2.1/32 via 0.0.0.0 in 2 hops
*May 20 12:20:51.854: 10.0.3.1/32 via 0.0.0.0 in 1 hops
*May 20 12:20:51.854: 10.20.2.0/24 via 0.0.0.0 in 2 hops
*May 20 12:20:51.854: 10.23.0.0/31 via 0.0.0.0 in 1 hops
*May 20 12:20:51.854: 10.30.3.0/24 via 0.0.0.0 in 1 hops宛先マルチキャスト 224.0.0.9 が RIPv2 標準で、Gi3 (R3 向け) と Gi2 (R2 向け) の両方から同じタイミングで Update が飛んでいる。注目すべきはこの Gi3 向け Update に R3 から学んだ経路 (10.0.3.1/32, 10.23.0.0/31, 10.30.3.0/24) が含まれていない ことで、これが次節の Split Horizon の動作である。
各エントリの形式は <prefix> via <next-hop>, metric <N>, tag <T> で、via 0.0.0.0 は「next-hop の指定なし = 受信者から見た送信者の IP を next-hop と解釈せよ」を意味する。多くの距離ベクトル型でこの省略形が標準である。
7. Split Horizon: 同じ IF からは広告し返さない
Split Horizon は 「ある IF から学んだ経路は、同じ IF からは広告しない」 という単純なルールで、距離ベクトル型のループ防止策のうち最も古典的かつ強力なものである。

R2 視点で show ip interface | include Split horizon を見ると、両 P2P IF で有効になっている。
R2#show ip interface GigabitEthernet2 | include Split horizon
Split horizon is enabled
R2#show ip interface GigabitEthernet3 | include Split horizon
Split horizon is enabledR2 の RIP database は 10.10.1.0/24 を R1 から学んでいる。
R2#show ip rip database 10.10.1.0 255.255.255.0
10.10.1.0/24
[1] via 10.12.0.0, 00:00:09, GigabitEthernet2R2 は Gi2 (R1 向け) からこの経路を学んだので、Split Horizon により Gi2 からは 広告し返さない。R1 側の debug ip rip で R2 → R1 向け Update を観察すると、Gi2 から受信する Update に 10.10.1.0/24 が含まれないことが確認できる。
*May 20 12:22:28.866: RIP: received v2 update from 10.12.0.1 on GigabitEthernet2
*May 20 12:22:28.866: 10.0.2.1/32 via 0.0.0.0 in 1 hops
*May 20 12:22:28.867: 10.0.3.1/32 via 0.0.0.0 in 2 hops
*May 20 12:22:28.867: 10.20.2.0/24 via 0.0.0.0 in 1 hops
*May 20 12:22:28.867: 10.23.0.0/31 via 0.0.0.0 in 1 hops
*May 20 12:22:28.867: 10.30.3.0/24 via 0.0.0.0 in 2 hopsR2 が R1 に送る Update の中身は「R2 自身が直結で持つ 10.0.2.1/32 と 10.20.2.0/24」「R3 から学んだ 10.0.3.1/32 と 10.30.3.0/24 と 10.23.0.0/31」だけで、R1 から学んだ経路は 1 つも含まれていない。Split Horizon が機械的に「同じ IF からは消す」を実行している証拠である。
逆方向の R1 → R3 向け Update (Gi3) も同様で、R1 が R3 から学んだ 10.0.3.1/32, 10.23.0.0/31, 10.30.3.0/24 は含まれず、R1 直結と R2 経由のものだけが流れる。
Split Horizon が無いと何が起きるかは §10 の count-to-infinity 再現実験で扱う。
8. Route Poisoning と Triggered Update
Split Horizon が「広告しない」という静的なフィルタなのに対し、Route Poisoning は「経路が消えた瞬間に metric=16 で能動的にアナウンスする」という積極的な振る舞いである。
距離ベクトル型でもっとも怖いのは「経路が消えたという事実が伝わらないまま、誰かが古い情報で広告し続ける」状況で、Update の周期 30 秒 + Invalid 180 秒の組み合わせを愚直に待つと最悪 3 分以上、隣接が古い経路を信じたままになる。Route Poisoning はこの待ち時間を圧縮するための工夫で、自分が知っていた経路が消えたと判断した瞬間 (= 直結リンクが落ちた、隣接からの Update が止まった) に metric=16 (infinity) を載せた即時 Update を全 IF に放出する。受け取った隣接は「もうこの経路は到達不能だ」と直ちに認識し、自分の database から外して同じ poison を伝言する。
これと並んで動くのが Triggered Update で、経路の状態が変わった瞬間に通常の 30 秒周期を待たずに即座に Update を送る機構である。RIPv2 の RFC では推奨機能、Cisco 実装ではデフォルト動作で、show ip protocols の Triggered RIP 列が No と表示されていても (これは別の機能のフラグ)、Route Poisoning は自動的に Triggered で送出される。
実機でどう効くかは次節のタイマー実測ではっきり見える。
9. タイマー実測: Lo30 を落として収束を観察する
R3 で interface Loopback30 / shutdown を打ち、R1 視点で 10.30.3.0/24 がいつ消えるかを 30 秒ごとに撮る。教科書通りなら Invalid (180s) + Holddown 経由で Flush (240s) まで残るはずだが、実機 IOS-XE 17.3 の挙動はだいぶ違う。
===== t=30s =====
R1#show ip route 10.30.3.0
% Subnet not in table
R1#show ip rip database 10.30.3.0 255.255.255.0
10.30.3.0/24 is possibly downt=30s で既に RIB から消えている。Holddown 状態 (is possibly down) ではまだ database に残っているが、ルーティングテーブルからは外れている。
===== t=60s =====
R1#show ip route 10.30.3.0
% Subnet not in table
R1#show ip rip database 10.30.3.0 255.255.255.0
%Route not in databaset=60s では database からも完全に消えた。t=90 以降も Route not in database のまま安定する。Invalid 180s / Holddown 180s / Flush 240s の数字を待つ必要は無かった。
これが Route Poisoning + Triggered Update の合わせ技の結果である。R3 が Lo30 を落とした瞬間に「10.30.3.0/24 を metric 16 で広告する」即時 Update を全 RIP IF に流し、R2 がそれを受けて自分の database を更新しながら R1 にも metric 16 で伝言する。R1 はこれを受け取って「もう使えない経路だ」と即座に判断し RIB から外す。Invalid タイマーは「Update が途切れた時の救済」であって、明示的に poison が来たら待つ必要が無い。
教科書の「RIP は収束に数分かかる」という記述はあくまで Update が単に届かない病的なケース (隣接装置が機械的にハングして poison を出さずに沈黙した状況など) の上限で、現代のまともな実装が動いている限りは秒オーダーで収束する。ただし距離ベクトル型固有の「噂で伝わる」モデルは変わらないので、ルータ数が増えるほど poison が末端まで届くまでに時間がかかる点は依然として弱点である。
復活させた挙動も対称で、R3 で no shutdown を打って 45 秒待つと R1 の database と RIB に metric 1 で戻ってくる。
R1#show ip route 10.30.3.0
R 10.30.3.0/24 [120/1] via 10.13.0.1, 00:00:18, GigabitEthernet310. count-to-infinity を再現できるか
距離ベクトル型の教科書には必ず登場する count-to-infinity は、Split Horizon が効かない状況で経路喪失情報が遅れて伝わる時に発生する。「R3 で経路が消えた」と R2 がまだ知らない間に、R1 が「私はこの経路を持っている (R2 経由で metric 2)」と R2 に広告すると、R2 はそれを信じて metric 3 で再学習してしまう。次の周期で R2 が R1 に「metric 3 で持っている」と返し、R1 は metric 4 に上がる… この応酬で metric が 1 周期ごとに +1 されていき、16 に達して初めて「到達不能」と判断される。
本ラボで Split Horizon を全 P2P IF で無効化し、R3 で Lo30 を落として再現を試みる。
R1(config)# interface GigabitEthernet2
R1(config-if)# no ip split-horizon
R1(config-if)# interface GigabitEthernet3
R1(config-if)# no ip split-horizon
(R2 / R3 も同様に Gi2 / Gi3 で Split Horizon 無効化)debug ip rip を 200 秒回して R1 視点で 10.30.3.0/24 のメトリック変化を追うと、教科書とは異なる結果になる。
*May 20 12:32:41.235: 10.30.3.0/24 via 0.0.0.0 in 16 hops (inaccessible)
*May 20 12:32:44.547: 10.30.3.0/24 via 0.0.0.0, metric 16, tag 0
*May 20 12:32:51.406: 10.30.3.0/24 via 0.0.0.0, metric 16, tag 0
*May 20 12:32:53.176: 10.30.3.0/24 via 0.0.0.0 in 16 hops (inaccessible)
...
(以降ずっと metric 16 のままで安定、count up は起きない)metric は 2 から 16 へ直接ジャンプし、3, 4, 5 … と段階的に上がる現象は観察されない。Split Horizon を切ったにもかかわらず count-to-infinity が再現しないのは、Route Poisoning が独立に動いているからである。R3 が Lo30 を落とした瞬間に R2 へ「metric 16」の即時 Update を投げ、R2 がそれを R1 に転送する。R1 は metric 16 を受け取って即座に「到達不能」とマークし、その状態で R1 → R2 への Update を送る時にはもう metric 16 で送り返す。互いに「持っている」と主張し合う隙が無い。
教科書で count-to-infinity が紹介される時の前提は「Route Poisoning が無い、もしくは効かない実装」であり、現代の Cisco IOS-XE のように Poison Reverse が標準実装されている環境では、Split Horizon を切るだけでは再現できない。完全に再現するには Poison Reverse を切る必要があるが、IOS-XE の RIP には IF 単位で Poison Reverse を切るコマンドが用意されていない (内部実装としてハードコードされている)。
つまり実機ベースで言うなら、距離ベクトル型のループ防止は Split Horizon と Route Poisoning の二重の安全網 で守られており、片方を切っただけでは破綻しない設計になっている。教科書的な count-to-infinity は、両方の安全網が同時に失われる極端な状況 (ベンダ独自実装での不具合、古い RIPv1 装置の混在など) でしか起きないという事実を、実機の挙動が裏付けている。
11. 落とし穴・補足
実運用と検証で踏みやすい注意点を 5 点挙げる。
no auto-summaryを忘れると VLSM が壊れる: 既定有効の auto-summary は、classful 境界 (例: 10.0.0.0/8) を跨ぐ IF から経路を出す時に強制的に集約をかける。本ラボのように/24や/31を混在させると、Lo10 (10.10.1.0/24) と P2P (10.12.0.0/31) がともに10.0.0.0/8に集約されて広告され、受信側で経路が混線する。RIPv2 ではno auto-summaryが事実上必須である。network文の意味は IF セレクタ: 3-2 §11 と同じ注意で、network 10.0.0.0は「10.x.x.x のサブネットを広告する」ではなく「IP が 10.x.x.x の IF で RIP を起動する」と読む。広告したくない IF はpassive-interfaceで隣接形成を止めるか、distribute-listで出力を絞る。- マルチキャスト 224.0.0.9 は TTL=1 で局所配信: RIPv2 の Update 配信先は 224.0.0.9 だが、これは TTL=1 の「直接接続セグメント限定」マルチキャストで、ルータを跨いで広がらない。Update がスイッチ越えで別 VLAN に漏れる事故は v1 broadcast 時代の話で、v2 で multicast 化された主な動機がこの局所化である。
- Triggered RIP と Triggered Update を混同しない:
show ip protocolsのTriggered RIP列は WAN 用途の最適化機能 (Demand Circuit RIP, RFC 2091) のフラグで、本節で扱う「経路変化時の即時 Update」とは別物。後者は実装の動作で常に有効、前者は明示的に enable する珍しいオプション。 - RIPng は IPv6 用で v3 ではない: RIP の IPv6 版は RIPng (next generation) で、UDP/521、マルチキャスト FF02::9、メトリックは依然ホップ数。RIPv3 という名前のプロトコルは存在しない。本シリーズでは IPv6 編 (3-12) で軽く触れる。
12. 次節 (3-4 EIGRP) への接続
本節で距離ベクトル型の伝播モデル、ホップ数メトリックの限界、4 つのタイマーと Route Poisoning による収束、Split Horizon によるループ防止、そして count-to-infinity が実機ではどこまで再現するかを CSR1000v 3 台と debug ip rip で確認した。RIP はホップ数だけで実回線速度を見ない設計と、隣接の Update に全面依存する伝言ゲーム的な伝播モデルが現代規模のネットワークで通用しなくなり、1990 年代後半以降は OSPF と EIGRP に席を譲ってきた。それでも距離ベクトル型の動作原理は EIGRP の DUAL (Diffusing Update Algorithm) を理解する土台として欠かせない。
3-4 では Cisco が距離ベクトル型を拡張した EIGRP (Enhanced IGRP) を扱う。RIP のホップ数オンリーから複合メトリック (帯域 + 遅延 + 信頼性 + 負荷 + MTU) へ、Update の周期広告から差分更新 + Hello ベースの隣接管理へ、Holddown 任せの収束から DUAL による事前計算済みバックアップ経路 (Feasible Successor) へと、距離ベクトル型がどう進化したかを実機で追う。