コンテンツにスキップ

NEIGH テーブル

概要

スタティック隣接(Permanent neighbor)エントリを CONFIG_DB に保持するテーブル1nbrmgrd (NbrMgr::doSetNeighTask) が購読し、Netlink RTM_NEWNEIGH でカーネルの neighbor テーブルへ書き込む。 動的に学習した neighbor は neighsyncd → APPL_DB NEIGH_TABLE 経路で処理されるため、本テーブルはあくまで手動投入のスタティック neighborが対象となる。

FG-NHG (Fine-Grained ECMP) 構成では minigraph.py が本テーブルを自動生成する(MAC フィールドなし、family フィールドのみ)2

データフロー (自動生成)

flowchart LR
  CDB[("CONFIG_DB<br/>NEIGH")]
  NM["nbrmgrd<br/>(NbrMgr)"]
  KNB["Linux kernel<br/>neighbor table"]
  CDB --> NM
  NM -->|RTM_NEWNEIGH| KNB

凡例

CONFIG_DB から SAI までの典型経路を docs/reference/config-db-orch-map.md から機械生成したミニ図。詳細・例外は本ページ本文と対応表を参照。

key 構造

NEIGH|<port>|<ip_address>
  • <port>: インターフェイス名(例: Ethernet0Vlan1000PortChannel1
  • <ip_address>: 対向の IPv4 または IPv6 アドレス(例: 10.0.0.22000::2

フィールド

フィールド 必須 説明
neigh yang:mac-address 任意 対向の MAC アドレス
family string (IPv4\|IPV4\|IPv6\|IPV6) 任意 IP ファミリ(Consumer は参照しない — 後述)

コード由来の暗黙デフォルト

neigh — MAC アドレス

条件 実装挙動 根拠
neigh フィールド省略 MacAddress デフォルトコンストラクタ(ゼロ MAC 00:00:00:00:00:00)→ setNeighbor() 内で !mac が真 → NUD_DELAY + NTF_USE でカーネルに ARP/NDP 解決を要求 nbrmgr.cpp:175–183
有効な MAC 文字列 ndm_state = NUD_PERMANENT でカーネルに永続 neighbor として設定 nbrmgr.cpp:189
無効な MAC 文字列 std::invalid_argument を catch → エラーログ → エントリをサイレント drop(再試行なし) nbrmgr.cpp:342–353

neigh を省略して書き込むと、MAC なしエントリとして ARP 解決を要求する仕様は意図的(FG-NHG などの use case)。ただし解決失敗時の再投入ロジックはない。

family — dead field(CONFIG_DB NEIGH 文脈)

doSetNeighTask は受け取ったフィールドをループしているが field == "neigh" のみ分岐処理し、family フィールドは一切読まない3

IP ファミリ判定は key の <ip_address> 部分から IpAddress::isV4() で自動判定する(nbrmgr.cpp:147/164)。

YANG に family フィールドが定義されているにもかかわらず、実装上は無視される YANG-実装 discrepancy。APPL_DB NEIGH_TABLEfamily フィールド(neighsyncd が書き込み、restore_neighbors.py が必須チェック)とは別文脈。

DEL_COMMAND — 未実装(既知の設計不足)

CONFIG_DB から NEIGH エントリを削除しても、doSetNeighTaskDEL_COMMAND ブランチは「Not yet implemented」ログのみで処理なし4
カーネルに NUD_PERMANENT で設定済みの neighbor エントリは削除されない。手動で ip neigh del を実行するか再起動が必要。

値依存挙動マトリクス

neigh (yang:mac-address)

カーネルへの挙動
有効な MAC(例: 00:11:22:33:44:55 NUD_PERMANENT で永続 neighbor を設定
省略 / ゼロ MAC NUD_DELAY + NTF_USE で ARP/NDP 解決を要求
不正な MAC 文字列 サイレント drop(エラーログのみ)
ブロードキャスト MAC(ff:ff:ff:ff:ff:ff YANG では許可(mac-address 型)。ただし neighsyncd 側では拒否(APPL_DB 文脈); CONFIG_DB nbrmgr 経路では制御なし

family (string)

Consumer の挙動
IPv4 / IPV4 / IPv6 / IPV6 nbrmgrd は読まない(dead field)。ファミリは IP アドレスから自動判定
省略 同上

制約

  • port は YANG で PORTCHANNEL_LIST.namePORT_LIST.name、または Vlan[0-9]+ パターンへの union 型。
  • neighbor(key の ip_address 部分)は inet:ip-address 型で IPv4/IPv6 両対応。
  • neigh MAC に YANG mandatory 指定なし。省略可能(ただし実装挙動は上記の通り)。
  • family に YANG mandatory 指定なし。実装は無視する。

購読者

Consumer ソースファイル 役割
nbrmgrd (NbrMgr::doSetNeighTask) sonic-swss/cfgmgr/nbrmgr.cpp SET 操作を受け取り Netlink でカーネル neighbor テーブルを更新
minigraph.py / sonic-cfggen sonic-buildimage/src/sonic-config-engine/minigraph.py FG-NHG 構成時に NEIGH を自動生成(書き込み側)

書き込み入り口

経路 詳細
sonic-cfggen (minigraph) FG-NHG 構成時に formulate_fine_grained_ecmp() が生成。family のみ設定、neigh なし
手動 sonic-db-cli sonic-db-cli CONFIG_DB hset 'NEIGH|<port>|<ip>' neigh <mac>
config_db.json システム起動時の DB 初期化で取り込み

タイミングと副作用

  1. インターフェイス状態依存: isIntfStateOk(alias) が STATE_DB INTERFACE_TABLE を確認。インターフェイスが未準備なら処理をスキップし、次の SELECT_TIMEOUT (1000 ms) サイクルで再試行する(nbrmgr.cpp:357–361)。
  2. warm reboot: nbrmgrd 起動時に NEIGH_RESTORE_TABLE|Flags|restored = "true" を 120 秒タイムアウトで待機。タイムアウト超過時はワーニングを記録して処理を続行する(nbrmgrd.cpp:54–61)。
  3. VoQ 環境: DEVICE_METADATA.switch_type == "voq" 時のみ STATE_SYSTEM_NEIGH_TABLE を追加購読し、リモート neighbor をカーネルへ挿入する別経路が有効になる(nbrmgr.cpp:78–84)。

関連 CONFIG_DB / YANG / CLI

  • 関連 CONFIG_DB: INTERFACEDEVICE_METADATAVOQ_INBAND_INTERFACE
  • 関連 YANG: sonic-neigh
  • 関連 CLI: なし(sonic-db-cli または config_db.json 経由で投入)

関連リファレンス

  • YANG: sonic-neigh
  • DEVICE_NEIGHBOR テーブル(L2 Topology / LLDP 用。本テーブルとは異なる)

引用元

運用ヒント

典型値(スタティック neighbor の手動設定)

sonic-db-cli CONFIG_DB hset 'NEIGH|Ethernet0|10.0.0.2' neigh '00:11:22:33:44:55'

FG-NHG 用(minigraph.py が自動生成):

"NEIGH": {
  "Ethernet0|192.168.1.1": {
    "family": "IPv4"
  }
}

確認コマンド

sonic-db-cli CONFIG_DB keys 'NEIGH|*'
sonic-db-cli CONFIG_DB hgetall 'NEIGH|Ethernet0|10.0.0.2'
ip neigh show dev Ethernet0

よくある誤設定

  • neigh フィールドを省略したまま設定すると ARP 解決トリガになる(エラーにならず動作が不明瞭)。
  • CONFIG_DB から削除しても (sonic-db-cli CONFIG_DB del) カーネルの neighbor エントリは残る。カーネル側も ip neigh del で明示的に削除すること。
  • family フィールドは YANG に定義があるが CONFIG_DB NEIGH 文脈では Consumer が読まないため、設定しても動作に影響しない。

例外条件・特殊挙動

Consumer 条件 挙動
nbrmgrd neigh フィールドに無効な MAC 文字列 invalid_argument catch → エラーログ → エントリをサイレント drop(再試行なし)
nbrmgrd DEL_COMMAND 「Not yet implemented」ログのみ。カーネル neighbor は削除されない
nbrmgrd インターフェイス未準備(STATE_DB に未登録) エントリをキューに保留し、1000 ms ごとに再試行
nbrmgrd VoQ 以外環境で STATE_SYSTEM_NEIGH に変更 doStateSystemNeighTask は VoQ 時のみ登録されるため無視
minigraph.py FG-NHG 構成時 family のみ設定の NEIGH エントリを自動生成。neigh MAC は省略 → ARP 解決トリガとして機能

Evidence: sonic-swss/cfgmgr/nbrmgr.cpp:342–353, 373–376, 357–361, 78–84; sonic-buildimage/src/sonic-config-engine/minigraph.py:584

実コンテナ動作トレース

段階 1 — Consumer 登録

nbrmgrd 起動時に NbrMgr コンストラクタが CFG_NEIGH_TABLE_NAME ("NEIGH") を購読対象として登録。

vector<string> cfg_nbr_tables = { CFG_NEIGH_TABLE_NAME };
NbrMgr nbrmgr(&cfgDb, &appDb, &stateDb, cfg_nbr_tables);

段階 2 — SET ハンドラ (doSetNeighTask)

  1. key を | で分割 → alias(インターフェイス名)と IpAddress ip
  2. isIntfStateOk(alias) → STATE_DB INTERFACE_TABLE を確認。未準備なら it++ で skip(次 tick 再試行)
  3. フィールドループで field == "neigh" のみ MacAddress mac にパース。失敗なら drop
  4. setNeighbor(alias, ip, mac) を呼び出し Netlink RTM_NEWNEIGH を発行
  • MAC あり: ndm_state = NUD_PERMANENT + MAC アドレス属性 (NDA_LLADDR) 付きで RTM_NEWNEIGH
  • MAC なし(ゼロ): ndm_state = NUD_DELAYndm_flags = NTF_USERTM_NEWNEIGH → カーネルが ARP/NDP 解決を開始

段階 4 — SAI 経由なし

本テーブルはカーネルの neighbor テーブルを直接操作する(Netlink 経由)。SAI / orchagent 経路は通らない。
ASIC への neighbor プログラムは neighsyncd が APPL_DB NEIGH_TABLE を経由して neighorch へ伝達する別経路で行われる。