コンテンツにスキップ

VRF ステートテーブル(STATE_DB)

概要

SONiC の VRF 削除処理は vrfmgrd(Linux VRF デバイス管理)と orchagent/VRFOrch(SAI VR オブジェクト管理)が非同期に動作するため、両者の完了を同期するための sentinel として STATE_DB に 2 つのテーブルが使われる。

DB テーブル名 書込み主体 意味
STATE_DB VRF_TABLE\|<name> vrfmgrd Linux VRF デバイスが作成済み + APP_DB に書き込み済み
STATE_DB VRF_OBJECT_TABLE\|<name> VRFOrch (orchagent) SAI VR (Virtual Router) オブジェクトが作成済み

CONFIG_DB の設定フィールドを保持する VRF テーブル とは別物。このページで説明するテーブルは読み取り専用の状態情報。

データフロー

flowchart LR
  CDB[("CONFIG_DB<br/>VRF")]
  VRFMGRD["vrfmgrd"]
  STATE_VRF[("STATE_DB<br/>VRF_TABLE")]
  APPDB[("APP_DB<br/>APP_VRF_TABLE")]
  ORCHAGENT["VRFOrch<br/>(orchagent)"]
  STATE_OBJ[("STATE_DB<br/>VRF_OBJECT_TABLE")]
  SAI["SAI<br/>sai_virtual_router_api"]

  CDB --> VRFMGRD
  VRFMGRD --> STATE_VRF
  VRFMGRD --> APPDB
  APPDB --> ORCHAGENT
  ORCHAGENT --> SAI
  ORCHAGENT --> STATE_OBJ
  STATE_VRF -->|"isVrfStateOk()"| VRFMGRD
  STATE_OBJ -->|"isVrfObjExist()"| VRFMGRD

凡例

STATE_DB の 2 テーブルは VRF 削除時の順序保証に使われる。詳細は本文参照。

VRF_TABLE

key 構造

VRF_TABLE|<name>

<name> は VRF 名(例: VrfRedmgmt)。CONFIG_DB VRF テーブルのキーと同一。

フィールド一覧

フィールド 書込み主体 デフォルト 説明
state string vrfmgrd "ok" (固定) VRF が APP_DB に登録済みであることを示す sentinel

書き込みタイミング

  • SET: CONFIG_DB VRF への SET 操作受信後、setLink() を呼んで Linux VRF デバイスを作成し、APP_DB VRF_TABLE に書き込んだあとに m_stateVrfTable.set(vrfName, {{"state","ok"}}) を実行 (vrfmgr.cpp:289)
  • DEL: VRFOrch が SAI VR を削除して VRF_OBJECT_TABLE|<name> を消したことを isVrfObjExist() で確認してから m_stateVrfTable.del(vrfName) を実行 (vrfmgr.cpp:339)

consumer

プロセス 参照方法 目的
intfmgrd m_stateVrfTable.get(alias, temp) (intfmgr.cpp:671, 680) VRF が存在しない間はインタフェースへの VRF バインドを保留
vxlanmgr isVrfStateOk()m_stateVrfTable.get(vrfName, temp) (vxlanmgr.cpp:744) VXLAN VRF マッピング設定の前提条件チェック

VRF_OBJECT_TABLE

key 構造

VRF_OBJECT_TABLE|<name>

フィールド一覧

フィールド 書込み主体 デフォルト 説明
state string VRFOrch "ok" (固定) SAI VR オブジェクトが正常に作成済みであることを示す sentinel

書き込みタイミング

  • SET (hset): sai_virtual_router_api->create_virtual_router()SAI_STATUS_SUCCESS を返した場合のみ m_stateVrfObjectTable.hset(vrf_name, "state", "ok") を実行 (vrforch.cpp:120, 150)
  • DEL: remove_virtual_router() 成功後に m_stateVrfObjectTable.del(vrf_name) を実行 (vrforch.cpp:193)

consumer

プロセス 参照方法 目的
vrfmgrd isVrfObjExist()m_stateVrfObjectTable.get(vrfName, temp) (vrfmgr.cpp:208, 331) VRF 削除時に orchagent の SAI VR 削除完了を待機してから Linux VRF デバイスを削除

削除同期シーケンス

VRF 削除時の正常な順序:

1. CONFIG_DB VRF|<name> DEL
2. vrfmgrd: doTask で DEL を受信
   → isVrfObjExist() が true の間はループ待機 (VRFOrch がまだ SAI VR を削除していない)
3. vrfmgrd: APP_DB VRF_TABLE del → orchagent へ通知
4. VRFOrch: APP_DB VRF_TABLE DEL を受信
   → SAI remove_virtual_router() を実行
   → VRF_OBJECT_TABLE del (vrfmgr.cpp の待機ループを unblock)
5. vrfmgrd: isVrfObjExist() が false に
   → VRF_TABLE del
   → delLink() で Linux VRF デバイス削除

値依存挙動マトリクス

テーブル フィールド 実挙動
VRF_TABLE state "ok" vrfmgrd が SET を受理し APP_DB に書き込み済み
VRF_TABLE (エントリなし) VRF が未作成、または削除処理が完了済み
VRF_OBJECT_TABLE state "ok" SAI create_virtual_router() が成功して VR オブジェクトが存在する
VRF_OBJECT_TABLE (エントリなし) orchagent が SAI VR を作成していない(または削除済み)

暗黙デフォルト・コード由来挙動 (Phase A)

調査日 2026-05-14。ソース: sonic-swss/cfgmgr/vrfmgr.cpp, sonic-swss/orchagent/vrforch.cpp, sonic-swss/orchagent/vrforch.h 中間調査: meta/_intermediate/cdb-flow/state-vrf-defaults.md

state フィールドの値はハードコード

両テーブルとも "ok" がコードにハードコードされており、他の値("error" 等)は取り得ない。失敗した場合はエントリ自体が存在しないか、書き込み前に処理が中断される。

// vrfmgr.cpp:288-289
fvVector.emplace_back("state", "ok");
m_stateVrfTable.set(vrfName, fvVector);

// vrforch.cpp:120
m_stateVrfObjectTable.hset(vrf_name, "state", "ok");

VRF_TABLE の state=ok は Linux VRF 作成成功を保証しない

setLink() が失敗(テーブル ID 枯渇、ip link add エラー)した場合でも SWSS_LOG_ERROR を記録したあと処理を継続し、m_stateVrfTable.set() が呼ばれる (vrfmgr.cpp:281-289)。厳密には「SET 操作を vrfmgrd が受理した」を意味する。

VRF_OBJECT_TABLE は SAI 成功のときのみ書き込まれる

SAI_STATUS_SUCCESS 以外のとき parseHandleSaiStatusFailure(handle_status)false を返すため hset が呼ばれない (vrforch.cpp:97-120)。VRF_OBJECT_TABLE エントリの存在は「SAI VR オブジェクトが実際に存在する」ことの evidence となる。

mgmt VRF の非対称性

vrfmgrd は mgmt VRF についても m_stateVrfTable.set() を呼ぶため VRF_TABLE|mgmt が存在しうる。一方 VRFOrch は mgmt VRF に対して SAI VR を作成しない(起動時のデフォルト VR を使用)ため VRF_OBJECT_TABLE|mgmt は存在しない。

YANG 未定義テーブル

sonic-vrf.yang は CONFIG_DB の VRF テーブルのみをモデル化する。STATE_DB の VRF_TABLE / VRF_OBJECT_TABLE に YANG スキーマはなく、フィールド定義はコードのみで保証される。

最大 VRF 数制限

vrfmgrd は起動時に VRF_TABLE_START=1001 から VRF_TABLE_END=5097 の範囲でルーティングテーブル ID を管理する。最大 4096 個の VRF を同時に保持でき、超過すると getFreeTable() が 0 を返して Linux VRF 作成失敗 → VRF_TABLE への書き込みは依然発生する(前述の非保証挙動)。

例外条件・特殊挙動

  • orchagent クラッシュ後の stale エントリ: orchagent が VRF 削除の途中で落ちた場合、VRF_OBJECT_TABLE|<name> が残留し vrfmgrd の削除ループが永続的にブロックされる。再起動 (warm start なし) で解消。
  • VRF_TABLE の DEL タイミング: isVrfObjExist() が false になった瞬間に m_stateVrfTable.del()delLink() が連続して実行される。この間に intfmgrdvxlanmgrVRF_TABLE を参照すると "VRF not ready" として処理を遅延させる可能性がある。
  • VNET テーブル経由の VRF: VNET (m_appVnetTableProducer) への書き込みも m_stateVrfTable.set() を呼ぶ (vrfmgr.cpp:308)。VNET VRF の場合、VRF_TABLE は存在するが VRF_OBJECT_TABLE は存在しない(VNETOrch は VRF_OBJECT_TABLE を書かない)。

確認コマンド

# VRF_TABLE エントリ一覧
sonic-db-cli STATE_DB keys 'VRF_TABLE|*'

# VRF_TABLE の state フィールド確認
sonic-db-cli STATE_DB hgetall 'VRF_TABLE|VrfRed'

# VRF_OBJECT_TABLE エントリ一覧
sonic-db-cli STATE_DB keys 'VRF_OBJECT_TABLE|*'

# VRF_OBJECT_TABLE の state フィールド確認
sonic-db-cli STATE_DB hgetall 'VRF_OBJECT_TABLE|VrfRed'

関連リファレンス