Cisco CMLを使用したOSPF Router ID重複時のLSDB分裂の検証
※この記事の内容は検証、執筆で一部AIを使用しています。
- OSPF Router IDの一意性が要求されるスコープは「同一ドメイン(LSDBを共有する範囲)」単位。VRFやプロセス番号で分けたつもりでも、対向ルータがVRF非対応の単一プロセスだとドメインが融合する
- 同一エリア内でRIDが重複すると、Router LSA(Type-1)がLSDB上の同一スロットを取り合う。ただし症状は教科書的な「flood war(上書き合戦)」とは限らず、LSDBのビュー分裂という形で静かに安定してしまうケースを観測した
- この状態では隣接はFULL・LSAは存在する・ログも出ないのに、SPFの双方向チェック不成立で経路だけが消える。隣接確認だけでは原因に辿り着けない
検証環境
- Cisco Modeling Labs (CML) / IOL
- ルータ2台(R1, R2)
e0/0 ── e0/0 (vrf A)
R1 R2 ── Lo15: 172.16.15.1/24 (vrf A)
e0/1 ── e0/1 (vrf B)
- R1: VRFなし・単一OSPFプロセス(エリアのみ分割)
- R2: VRF-lite。vrfA用に
ospf 10、vrfB用にospf 20、両プロセスともRouter ID 1.1.1.1(意図的に重複させる) - 検証対象の経路: vrfA側の 172.16.15.0/24
初期コンフィグ
R1:
router ospf 1
router-id 11.11.11.11
network 10.0.10.0 0.0.0.255 area 10
network 10.0.20.0 0.0.0.255 area 20
R2:
vrf definition A
address-family ipv4
!
vrf definition B
address-family ipv4
!
interface e0/0
vrf forwarding A
ip address 10.0.10.2 255.255.255.0
!
interface e0/1
vrf forwarding B
ip address 10.0.20.2 255.255.255.0
!
interface Loopback15
vrf forwarding A
ip address 172.16.15.1 255.255.255.0
!
router ospf 10 vrf A
capability vrf-lite
router-id 1.1.1.1
network 10.0.10.0 0.0.0.255 area 10
network 172.16.15.0 0.0.0.255 area 10
!
router ospf 20 vrf B
capability vrf-lite
router-id 1.1.1.1
network 10.0.20.0 0.0.0.255 area 20
前提: Router ID一意性のスコープ
まず整理しておきたいのが「RIDはどの範囲で一意であるべきか」という点。答えは同一ドメイン(LSDBを共有する範囲)内であって、筐体単位でもプロセス単位でもない。
| 組み合わせ | 可否 |
|---|---|
| 同一筐体内、別VRFのプロセス同士が同じRID | ○ 問題なし(LSDBが別) |
| 別筐体、同一VRFドメイン内で同じRID | ✕ 衝突 |
| 別筐体、別ドメイン(vrfAとvrfB)で同じRID | ○ 問題なし |
ここで重要なのが、ドメインの境界は「VRF設定」ではなく「誰とLSAを交換するか」で決まるという点。今回の構成ではR2側でVRFを分けていても、R1が単一プロセスで両リンクを収容しているため、R1が合流点となって全体が実質1つのドメインに融合する。その融合したドメイン内に「RID 1.1.1.1」を名乗るプロセスが2つ(R2のospf 10とospf 20)存在する、というのが今回の障害の前提条件になる。
検証1: 別エリアのままでは何も起きない
初期状態(Area 10 / Area 20に分割)では何の問題も起きない。
- Type-1(Router LSA)はエリアスコープなので、Area 10とArea 20に分かれている限り、同じLink State ID 1.1.1.1のLSA同士は衝突しない
- 「エリア間で172.16.15.0/24が漏れるのでは?」も起きない。Area 0が存在しないため、R1は複数エリアに足を持っていてもABRとして動作せず、Type-3(Summary LSA)を一切生成しない
R1# show ip ospf | include Border ← ABR申告なし
R1# show ip ospf database summary ← 空
R2# show ip route vrf B ← 172.16.15.0/24なし
非0エリア同士をルータで繋いでもエリア間ルーティング自体が成立しないことがわかる。virtual-linkが存在する理由がLSDBの空っぽさから確認できる。ただしこれは分離設計ではなく単なるOSPFの機能不全状態であり、どこかがArea 0に変わったりredistribute(Type-5はASスコープ)が入った瞬間に崩れる。
検証2: 同一エリア化すると172.16.15.0/24が消える
両リンクをArea 10に統一する(R1のe0/1とR2のospf 20を area 10 に変更)。隣接は両方FULLで安定しているのに、R1のルートテーブルから172.16.15.0/24が消えた。
R1# show ip ospf neighbor
Neighbor ID Pri State Dead Time Address Interface
1.1.1.1 1 FULL/BDR 00:00:33 10.0.10.2 Ethernet0/0
1.1.1.1 1 FULL/BDR 00:00:33 10.0.20.2 Ethernet0/1
R1# show ip route 172.16.15.1
% Network not in table
LSDBを見ると「乗っ取り」が起きている
R1# show ip ospf database router 1.1.1.1
Link State ID: 1.1.1.1
Advertising Router: 1.1.1.1
LS Seq Number: 8000000F
Length: 36
Number of Links: 1
Link connected to: a Transit Network
(Link ID) Designated Router address: 10.0.20.1 ← vrfB側のリンクのみ
このLSA出力の読みどころ:
- Number of Linksと中身: 「ルータ1.1.1.1」の自己申告なのに、10.0.10.0へのリンクも172.16.15.0/24のstubリンクも無い。つまり今LSDBに居座っているのはospf 20(vrfB)版で、ospf 10版(Links: 2、172.16.15.0/24入り、Length: 48)が上書きされて消えている
- Length: 36 vs 48 の差はちょうどリンク1本分(12バイト)
- Seq/Checksumが観測中ずっと同一 + LS ageが単調増加: 短時間の観測では上書き合戦は起きておらず「静止期間」にある
- 1.1.1.1のRouter LSAが1枚しか存在しないこと自体が異常の本体: 本来2プロセスは別ルータとして2枚のLSAを持つべきだが、Link State ID(=RID)が同じためLSDB上の同一スロットを取り合い、片方しか存在できない
なぜ経路が消えるのか: SPFの双方向チェック
Area 10のLSDBにはNetwork LSA(DR発)が「1.1.1.1は10.0.10.0に接続している」と主張している。しかし1.1.1.1のRouter LSA側は10.0.10.0へのリンクを申告していない。SPFはリンク採用前に双方向の合意を要求するため、この「片思い」のリンクは破棄され、e0/0の先にある172.16.15.0/24への経路が計算不能になる。
ここが今回のポイントで、hello層(隣接)は完全に正常、LSDBにLSAは存在する、それでも経路だけが無い。show ip ospf neighbor を何度眺めても異常は見えない。
検証3: flood warは起きず、LSDBが「ビュー分裂」していた
当初は「ospf 10とospf 20がSeqを競り上げながら交互に上書きし合う(flood war)」を予想し、%OSPF-4-FLOOD_WAR ログの採取を狙っていた。しかし結果は予想と異なった。
- R1のLSDB: Seq 0x8000000F のospf 20版が10分以上変化なく安定
- FLOOD_WARログはR1/R2ともに皆無
R2のospf 10側のLSDBを見て理由が判明した。
R2# show ip ospf 10 database router 1.1.1.1
LS Seq Number: 8000000E ← R1より古い
Length: 48
Number of Links: 2 ← 自分版(172.16.15.0/24入り)のまま
突き合わせるとこうなる。
| 場所 | Seq | 中身 |
|---|---|---|
| R1のLSDB | 0x8000000F | ospf 20版(Links: 1) |
| R2 ospf 10のLSDB | 0x8000000E | 自分版(Links: 2、172.16.15.0/24入り) |
ospf 10は自分のSeq Eを最新として動作しており、R1側により新しいSeq Fのospf 20版が存在することを認識していない。OSPFのフラッディング原則では新しいインスタンスは必ず全員に伝播するはずで、Seq FがR2のe0/0側に届いていない(あるいは処理されていない)ことが異常。同一RIDの隣接が同一セグメント構成に2ついる状態はRFC 2328が想定しておらず、フラッディング実装の隙間を突いている可能性がある。
この「ビュー分裂」状態は、flood warよりも発見が難しい。
- LSA再生成が起きないのでSeqカウンタも動かず、ログも一切出ない
- SPF結果だけが恒常的に間違い続ける
- OSPFの大前提「同一エリアのLSDBは必ず収束・一致する」が静かに破られている
(フラッディングがどこで止まっているかの特定は debug ip ospf flood + clear ip ospf 20 process で追跡する予定 — 続編に書く)
トラブルシュート手順
この種の障害に対する調査手順をまとめると以下になる。
-
ルート種別を見る:
show ip route <prefix>— O / O IA / O E1・E2 で疑う場所が変わる -
LSDBを見る:
show ip ospf database router <RID>— Number of Links、中身、Length、Seq、LS age - 両端のLSDBを突き合わせる: 同じLSAのSeqが食い違っていたらビュー分裂
- 隣接(neighbor)がFULLでも正常とは限らない。壊れるのはLSDBとSPF結果のレイヤ
NX-OSの場合、重複RIDのhelloはサイレント破棄され show ip ospf traffic の dup rid カウンタに計上される。ログが出ない点はIOSと同様なので、カウンタも確認するとよい。
正しい設計
やってはいけないこと
- エリア分割でVRF分離の代用: Area 0があればABRがType-3で相互広報する(正式なルート交換)。Area 0が無ければ「偶然漏れない」だけで、設計としては機能不全状態に依存している
- 単一プロセスのルータを複数VRFの合流点にする: その時点でドメインは融合している
やるべきこと
- 分離したいならドメイン(プロセス×VRF)自体を分ける。R1側もVRF-lite化する:
R1:
vrf definition A
address-family ipv4
!
vrf definition B
address-family ipv4
!
interface e0/0
vrf forwarding A
ip address 10.0.10.1 255.255.255.0
!
interface e0/1
vrf forwarding B
ip address 10.0.20.1 255.255.255.0
!
router ospf 10 vrf A
router-id 11.11.11.11
capability vrf-lite
network 10.0.10.0 0.0.0.255 area 0
!
router ospf 20 vrf B
router-id 11.11.11.11
capability vrf-lite
network 10.0.20.0 0.0.0.255 area 0
※ vrf forwarding を入れるとそのI/FのIP設定が消えるため、VRF→IP→OSPFの順で投入する
- RIDは「筐体ごとに一意」で設計する: R1が全VRFで11.11.11.11、R2が全VRFで2.2.2.2、のような振り方なら筐体内のプロセス間重複は無害で、かつドメイン内衝突も起きない。VRFごとにRIDを変える必要は技術的には無いが、トラブルシュート時にLSDB上で筐体を識別しやすくする意味で、アドレス体系に載せて分けておく運用も合理的だろう
まとめ
-
RID一意性のスコープはLSDB共有範囲であることがわかった。VRF・プロセス・エリアの設定の見た目ではなく、「LSAがどこまで届くか」で決まる
-
同一エリア内RID重複の症状はflood warとは限らない。ビュー分裂として静かに安定し、ログもカウンタも動かないまま経路だけが壊れる形態があることがわかった
-
「隣接FULL・LSAあり・経路なし」の三点セットを見たらSPF双方向チェックとLSAの中身を疑う
-
非0エリア×2 + Area 0なし ではABRは動作しない(virtual-linkの存在理由)
続編予定
-
debug ip ospf floodによるフラッディング停止点の特定 - flood warの意図的な再点火と
%OSPF-4-FLOOD_WARの採取 - RID分離による復旧確認と、R1 VRF-lite化(上記「正しい設計」)の動作確認
検証はCML上のIOLで実施。NX-OSとの構文差(instance-tag、vrf member、redistribute時のroute-map必須など)はあるが、本記事で扱った挙動はOSPFプロトコル仕様およびIOS/NX-OS共通の実装原理に基づくもの。

