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 構造¶
<name> は VRF 名(例: VrfRed、mgmt)。CONFIG_DB VRF テーブルのキーと同一。
フィールド一覧¶
| フィールド | 型 | 書込み主体 | デフォルト | 説明 |
|---|---|---|---|---|
state |
string | vrfmgrd |
"ok" (固定) |
VRF が APP_DB に登録済みであることを示す sentinel |
書き込みタイミング¶
- SET: CONFIG_DB
VRFへの SET 操作受信後、setLink()を呼んで Linux VRF デバイスを作成し、APP_DBVRF_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 構造¶
フィールド一覧¶
| フィールド | 型 | 書込み主体 | デフォルト | 説明 |
|---|---|---|---|---|
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()が連続して実行される。この間にintfmgrdやvxlanmgrがVRF_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'
関連リファレンス¶
- CONFIG_DB:
VRFテーブル — VRF の設定フィールド (fallback,vni) - CONFIG_DB:
MGMT_VRF_CONFIGテーブル — mgmt VRF 設定 - YANG:
sonic-vrf— CONFIG_DB スキーマ定義(STATE_DB は未定義) - CLI:
config vrf - HLD: VRF サポート設計