← 記事一覧

取り消せない LSA

ルーティングプロトコルに加わるのは握手である。抜けるほうは、送る機会すらないかもしれない一通のメッセージで終わる。

Michel Wijnberg

前回は、リンクステートプロトコルに、その 経路にならずに加わる話でした。今回は反対側の端、つまりもっと難しく、私が甘く見ていたほうの話です。

到着は握手です。双方が交渉し、双方が確認し、パケットが失われれば再試行します。OSPF と IS-IS の あらゆる状態機械は、到着を確実にするために存在しています。

退出に状態機械はありません。ルーターが何を言ったかを覚えておくことだけを目的とするプロトコルへ、 自分の離脱を一度だけ告げ、そのあなたはもういません。何も訂正できません。


ネットワークはあなたを抱え込む

誰にも告げずにレコーダーを止めても、劇的なことは何も起きません。それが問題なのです。

あなたのプロセスが消えても、あなたの LSA は消えません。それはすべてのルーターのデータベースに シーケンス番号と経過時間つきで居座り、経過時間が上限に達するまでそこにあります。OSPF では 1 時間です。その 1 時間、トポロジにはもう存在しないルーターが含まれ、あなたがどこへ行ったのかと 静かにいぶかしんでいる隣人への隣接を広告し続けます。

監視ツールが終了したというだけで、ネットワークが 1 時間ものあいだ真実でないことを記述するのです。

ですからきちんと別れを告げねばなりません。両プロトコルとも、同じ考えに帰着する方法を持っています。 消したいものを これを削除せよ という形で再度起点することです。

  • OSPF は LSA を経過時間 MaxAge、すなわち 3600 秒でフラッドし、受け取ったすべての ルーターが自分のデータベースからそれを流し去るようにします (RFC 2328 §13.4)。
  • IS-IS は LSP を 残存寿命ゼロ でフラッドします。同じ考え、別のフィールドです。

どちらも一通です。確認応答つきの切断も、「本当によいですか」も、再試行ループもありません。それが 効いてくるころにはプロセスは終了しつつあるからです。


別れのなかの罠

ここが間違えやすい部分で、認証つき IS-IS を動かしていなければ見つけられなかったところです。

パージ LSP は何も運びません。到達性も、ホスト名も、ケイパビリティもなし。その内容のすべては 「寿命ゼロ」と言う自分自身のヘッダだけです。だからこそ、守るべき中身が何もないメッセージのように 見えます。

それでも認証されなければなりません。RFC 5304 は、暗号認証を用いる実装に対して未認証のパージを 拒否することを要求し、パージが認証 TLV 以外の TLV を運ばないことを要求します。未認証のパージとは 何かと問えば、両方の要求が腑に落ちます。それは、他のルーターの状態を削除する一通の未署名パケット であり、シャットダウンの形ではなく攻撃の形をしています。

つまり、シャットダウン中に送る唯一のメッセージ、再試行できないメッセージ、他の内容をいっさい 持たないメッセージこそが、それでもなお署名されていなければならないメッセージなのです。ここを 誤ると、失敗は最悪の意味で静かです。自分の側からはシャットダウンはきれいに見え、パージは出ていき、 認証するルーターはそれを落とし、あなたの亡霊は寿命いっぱいデータベースに残ります。

コードが生む形もまさにそれです。パージ LSP は TLV をいっさい持たずに構築され、署名が設定されて いればマーシャラが認証 TLV を足します。認証済みネットワークでは、そのメッセージの内容のすべてが 自分自身の署名です。それは最適化ではありません。去ることと、去ったように見えることの違いです。


送る機会が与えられない別れ

仕組みの前に、その下にある前提を。逆向きに設計してしまいやすいところだからです。

上のすべては、正常なシャットダウンを描いています。プロセスは自分が止まると知っており、もう一通 送る時間がある。それが簡単なほうのケースであり、設計の基準にすべきケースではありません。

設計の基準にすべきなのは、メッセージがまったくないケースです。待ってくれない kill シグナル。 電源を失うホスト。メモリ不足で刈られるコンテナ。どれにおいてもパージは決して送られず、ネット ワークはすでに存在をやめたルーターを抱えたまま、何かが起きたという通知もなく取り残されます。

ですからパージは ベストエフォート であり、設計はそれに寄りかかれません。正しくなければなら ないのは、それが起きなかったと仮定する経路です。立ち上がり、自分の亡霊がまだ設置されているのを 見つけ、それを上書きすること。その経路が働くなら、正常なパージは障害の窓を 1 時間から 1 秒へ 縮める最適化です。働かないなら、正常なパージは必要だったまさにそのときに失敗する気休めです。

パージは収束を良くします。それが正しさの機構であってはなりません。

だから、この記事の残りは止まることではなく再起動の話になります。


戻ってきたら、すでにそこに自分がいる

問題のもう半分は再起動であり、実際のバグを生むのはこちらです。

きれいに止まらなかったレコーダー、あるいはネットワークが忘れるより速く再起動したレコーダーは、 前回の実行の LSA がシーケンス番号つきでまだあちこちに設置されている状態に戻ってきます。信じて もらうには、新しい起点がそれを上回らねばなりません。

一行の比較で済みそうに聞こえます。そうではありません。書き下す価値のある理由があります。

OSPF のシーケンス番号は 符号つき 32 ビットです。初期値 0x80000001 は表現可能な最も負の数 であり、そこから増えていきます。したがって「以前のシーケンス番号を見たか」を、ゼロを 値なし の 番兵として実装するという自然なやり方は、テストを生き延びる形で誤りになります。ゼロは有効な OSPF シーケンス番号には決してなりませんが、int32(0) はあらゆる有効値より大きいのです。古い LSA は、 「そんなものはなかった」を意味するはずの番兵との比較に常に負けてしまいます。コードは代わりに明示 的なブール値を持ち、なぜ当たり前の版が罠なのかを説明するコメントを添えています。

次に いつ やるかがあり、当たり前に思える答えは二つとも誤りです。

最初の直感は、亡霊を見つけた瞬間、データベース交換の最中に MaxAge フラッドで流し去ることです。 Cisco の実装がそれにひどく反応するのを観測しました。隣接がまだ Loading のあいだに MaxAge の フラッシュが届くと、フラッディングがおよそ 40 秒ごとの周期的リセットに入るのです。誰かの仕様違反 だと指させるものではありません。ただ、それらのルーターがそうしたというだけです。

それを学んだうえでの二番目の直感は、待つことです。古いシーケンス番号を記録しておき、隣接が Full に達したら再起点する。これは デッドロックします。隣人は亡霊を広告し続けるのでこちらの要求 リストに残り続け、リストは完全には空にならず、Full には決して達さず、それを解決したはずの起点は 決して起きません。回復は約 30 分後のリフレッシュタイマ待ちになります。

答えはどちらでもなく、見落としやすい区別にかかっています。Loading 中に危険なのは MaxAge フラッシュ であって、起点ではありません。だからレコーダーは Loading の最中にただちに 再起点します。自分のコピーと亡霊の両方より高いシーケンス番号を持つ普通の LSA として、そしてその ついでに隣人の要求リストから古いエントリを落とします。普通の LSA はそこで安全です。フラッシュは 安全ではありません。

これらは仕様のどこにも書かれていません。ネットワークが、二度、二通りのやり方で実際にやったこと です。

Age、Seq#、Cksum の各列を表示した LSDB ブラウザー。3 台のルーターには実測値が入っており(経過秒数は 1492、978、572、シーケンス番号は 0x8000057x 前後)、残る 2 台はダッシュになっている。その 2 台には SNMP による再構成しか存在せず、表の上の見出しがそう明記している
Age、Seq#、Cksum の各列を表示した LSDB ブラウザー。3 台のルーターには実測値が入っており(経過秒数は 1492、978、572、シーケンス番号は 0x8000057x 前後)、残る 2 台はダッシュになっている。その 2 台には SNMP による再構成しか存在せず、表の上の見出しがそう明記している

この記事が扱う 2 つの列は、LSA の取り消しを難しくしている当のふたつです。誰かが捨てるまでに 3600 に達しなければならない経過時間と、上回らなければならないシーケンス番号です。レコーダーが 隣接関係を保っているところでは、どちらも実測値です。SNMP のウォークだけが LSA を再構成した ところでは、ブラウザーはもっともらしいゼロではなくダッシュを表示します。


隣接を飲み込んだ 5 秒ルール

そして興味深いほうの失敗。私の好きな種類、つまり二つの正しい規則が組み合わさって誤った結果になる やつです。

RFC 2328 §12.4 は、同じ LSA の二度の起点のあいだに最低 5 秒を要求します。理にかなったレート制限 であり、Osprey はこれを守ります。

これとは別に、隣接が Full に達する前に送る上書き用 LSA は意図的に リンクを持ちません。まだ 形成し終えていない隣接を広告することは、まだ存在しない隣接関係についての主張になってしまうから です。

さて、この二つを同じ 1 秒のなかに置いてみます。レコーダーは Full ではないのでリンクなしで亡霊を 上書きします。その直後に隣接が Full に達し、レコーダーは本物の LSA、つまりリンクの入ったほうを 起点しようとします。その起点は 5 秒の窓の内側に落ち、レートリミッタに捨てられます。

エラーは出ません。再試行もされません。レコーダーはいま、正しく、そして準拠した形で、リンクのない ルーターを広告しており、周期的リフレッシュが回ってくるまでそれを広告し続けます。

そのリフレッシュは 30 分 です。

2026-08-05 のラボデプロイで、両方の事象が同じ 1 秒に落ちたときに計測しました。レコーダー自身の 隣接が 30 分間 down として表示されたのです。隣接が上がっているかどうかを言うことが仕事のすべて である製品において。そして誠実な部分は、どの部品も設計どおりに振る舞ったということです。レート リミッタは RFC に従いました。Full 前の LSA はリンクを主張しないのが正しかった。バグは両者の あいだの隙間にありました。この種のバグがいつもいる場所です。

修正は、まとめられた一回限りの再試行です。レートリミッタに拒まれた起点は捨てられず、窓が開く 瞬間に向けて再武装されます。


なぜ去るほうが難しい半分なのか

到着はフィードバックのある交渉です。Hello が間違っていれば隣接は形成されず、あなたは即座に、 大きな声で、前に進まない状態機械のなかでそれを知ります。

退出は、まもなく存在をやめるプロセスが送る、確認応答のない一通のメッセージです。一度目で正しく 組み立てられ正しく署名されていなければならず、その失敗は、あなたの立っている場所からは成功と まったく同じに見えます。

この非対称性こそ、このコードでシャットダウン経路のほうが起動経路よりコメントが多い理由であり、 中身のない唯一のメッセージに最も厳しい要件がついている理由です。


要点

きれいに去れない監視システムは受動的ではありません。止まるまでは受動的で、そのあとは他人の トポロジデータベースのなかの 1 時間ぶんの作り話です。

難しさの大半は仕様にはありません。規則と規則の継ぎ目にあります。正しいレート制限、正しい Full 前 LSA、明らかに正しく見えて静かに誤っている番兵値。どれもプロトコルの誤解ではありません。すべて 同じ形、すなわち正しいものが二つ出会っている形をしています。


次回: 加わるべきデータベースがそもそも存在しないプロトコルと、丁寧に尋ねても MIB が教えて くれないもの。データベースのないプロトコル。

Osprey は自社運用型のネットワーク可視化・エンジニアリング基盤です。32 台まで無料でお試しいただけます。他の記事を読むこともできます。