DEVICE_NEIGHBOR 動作状態(device op state)¶
概要¶
DEVICE_NEIGHBOR テーブルは 直接接続される隣接機器と自スイッチポートの対応表 として CONFIG_DB に永続化される。
設定テーブルとしての役割に加え、複数のランタイム daemon が DEVICE_NEIGHBOR の key 集合(= ローカルポート名の集合)を「外部ポート一覧」として動的に参照する。このページでは、各 consumer がどのようなコード由来デフォルト・副作用を持つかを整理する。
データフロー (自動生成)¶
flowchart LR
CDB[("CONFIG_DB<br/>DEVICE_NEIGHBOR")]
DM["pfcwd / ecnconfig<br/>show interfaces / bgpcfgd"]
CDB --> DM
凡例
CONFIG_DB から SAI までの典型経路を docs/reference/config-db-orch-map.md から機械生成したミニ図。詳細・例外は本ページ本文と対応表を参照。
外部ポート一覧としての機能¶
SONiC の複数 daemon は DEVICE_NEIGHBOR.keys() を「自スイッチが持つ外部ポート(対向機器と直結するポート)の一覧」として扱う。DEVICE_NEIGHBOR が config としてだけでなく ランタイムの port scope 決定器 として機能する点が本ページの主題である。
consumer 別動作¶
pfcwd — 外部ポート判定¶
pfcwd start_default (pfcwd/main.py:405-416) は次のように外部ポートを決定する。
external_ports = list(self.config_db.get_table('DEVICE_NEIGHBOR').keys())
bp_ports = get_bp_ports(self.config_db)
active_ports = natsorted(set(external_ports + bp_ports))
| 条件 | 結果 |
|---|---|
| DEVICE_NEIGHBOR に 1 件以上のエントリあり | external_ports にそのキー(ポート名)が入る |
| DEVICE_NEIGHBOR が空 | external_ports = [] → バックプレーンポートのみが active_ports になる(外部ポートなし) |
pfcwd — サーバー向けポート判定¶
get_server_facing_ports() (pfcwd/main.py:97-108) は DEVICE_NEIGHBOR を起点に DEVICE_NEIGHBOR_METADATA の type を参照する。
candidates = db.get_table('DEVICE_NEIGHBOR')
for port in candidates:
neighbor = db.get_entry('DEVICE_NEIGHBOR_METADATA', candidates[port]['name'])
if neighbor and neighbor['type'].lower() == 'server':
server_facing_ports.append(port)
if not server_facing_ports:
server_facing_ports = [p[1] for p in db.get_table('VLAN_MEMBER')]
- DEVICE_NEIGHBOR_METADATA に対応エントリが存在しない、または
typeが'server'でない場合はサーバー向けポートとして列挙されない - サーバー向けポートが 0 件 の場合、
VLAN_MEMBERのポートにフォールバック
ecnconfig — ポート一覧(非 multi-ASIC 環境)¶
ecnconfig (scripts/ecnconfig:282-287) は非 multi-ASIC 環境で DEVICE_NEIGHBOR を外部ポート一覧として使用する。
port_table = self.config_db.get_table(DEVICE_NEIGHBOR_TABLE_NAME)
self.ports_key = list(port_table.keys())
if len(self.ports_key) == 0:
raise Exception("No active ports detected in table '{}'".format(DEVICE_NEIGHBOR_TABLE_NAME))
pfcwd との違い
pfcwd は空テーブルを「外部ポートなし」として継続するのに対し、ecnconfig は Exception を raise して動作停止する。multi-ASIC 環境では SYSTEM_PORT_TABLE を代替として使用する(ブランチ分岐)。
show interfaces neighbor expected — 隣接表示¶
show interfaces neighbor expected (show/interfaces/__init__.py:310-365) は DEVICE_NEIGHBOR と DEVICE_NEIGHBOR_METADATA を組み合わせて隣接情報を表示する。
| 表示カラム | データ元 | 欠落時 |
|---|---|---|
LocalPort |
DEVICE_NEIGHBOR の key | — |
Neighbor |
DEVICE_NEIGHBOR[port]['name'] |
KeyError → "No neighbor information available" 表示 |
NeighborPort |
DEVICE_NEIGHBOR[port]['port'] |
KeyError → 同上 |
NeighborLoopback |
DEVICE_NEIGHBOR_METADATA[device]['lo_addr'] |
文字列 'None' を表示 |
NeighborMgmt |
DEVICE_NEIGHBOR_METADATA[device]['mgmt_addr'] |
文字列 'None' を表示 |
NeighborType |
DEVICE_NEIGHBOR_METADATA[device]['type'] |
文字列 'None' を表示 |
mgmt_addr の所在
表示に使われる mgmt_addr は DEVICE_NEIGHBOR_METADATA 側のフィールドである。DEVICE_NEIGHBOR テーブル自体の mgmt_addr フィールドは現行 consumer から参照されない(dead field)。
lldpmgrd — 非購読(dead consumer)¶
lldpmgrd (dockers/docker-lldp/lldpmgrd:12-14) のソースに次の TODO が明記されている。
# TODO: Also listen for changes in DEVICE_NEIGHBOR and PORT tables in
# Config DB and update LLDP config upon changes.
現行実装での lldpmgrd が subscribe するテーブルは次の 3 つのみ:
APP_PORT_TABLE_NAME(APPL_DB) — port oper_status 変化CFG_MGMT_INTERFACE_TABLE_NAME(CONFIG_DB) — 管理 IP 変化CFG_DEVICE_METADATA_TABLE_NAME(CONFIG_DB) — hostname 変化
DEVICE_NEIGHBOR はまったく購読されていない。lldpmgrd の動作に DEVICE_NEIGHBOR の内容は現状影響しない。
bgpcfgd — DEVICE_NEIGHBOR_METADATA 依存待機¶
bgpcfgd (managers_bgp.py:139-140,219-224) は DEVICE_NEIGHBOR 本体ではなく DEVICE_NEIGHBOR_METADATA を依存テーブルとして登録する。
check_neig_meta = Trueの場合のみCFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAMEを deps に追加- BGP neighbor の
set_handlerでdata['name']が DEVICE_NEIGHBOR_METADATA に不在の場合 →return False(延期) - テーブル到着後に directory メカニズムが自動再処理
値依存挙動マトリクス¶
テーブル空時の consumer 別挙動¶
| consumer | テーブル空時の挙動 | エラー種別 |
|---|---|---|
| pfcwd start_default | external_ports = [] → バックプレーンポートのみで active_ports 構成 |
サイレント(動作継続) |
| pfcwd get_server_facing_ports | サーバー向けポート 0 件 → VLAN_MEMBER にフォールバック | サイレント(フォールバック) |
| ecnconfig (非 multi-ASIC) | Exception("No active ports detected...") raise → 動作停止 |
例外 |
| show interfaces neighbor expected | "DEVICE_NEIGHBOR information is not present." 表示して即 return |
ユーザー表示のみ |
| bgpcfgd | DEVICE_NEIGHBOR を直接参照しない | 影響なし |
| lldpmgrd | DEVICE_NEIGHBOR を購読しない(TODO 状態) | 影響なし |
コード由来の暗黙デフォルト¶
フィールド別コード由来挙動¶
| フィールド | YANG default | コード由来挙動 | カテゴリ |
|---|---|---|---|
peer_name (key) |
なし(必須) | pfcwd / ecnconfig が key 集合を外部ポート一覧として使用。空テーブル → pfcwd: 外部ポートなし / ecnconfig: Exception | 複合必須制約 |
name |
なし | bgpcfgd: DEVICE_NEIGHBOR_METADATA に不在 → return False 延期。lldpmgrd は参照しない(dead consumer) |
前提条件依存 + dead consumer |
port |
なし | show interfaces neighbor expected で直接参照。欠落時 KeyError → "No neighbor information available" 表示 | silent drop 候補 |
mgmt_addr |
なし | DEVICE_NEIGHBOR テーブルの mgmt_addr を参照する consumer なし(dead field)。show コマンドは DEVICE_NEIGHBOR_METADATA 側を参照 |
dead field |
local_port |
なし(leafref → PORT.name) | key(peer_name)を外部ポートとして使用するため、local_port と key が実質同値。テーブル空 → pfcwd が外部ポートなしと判定 / ecnconfig が Exception | YANG leafref + 副作用 |
type |
なし(string 制約なし) | DEVICE_NEIGHBOR の type を直接参照する consumer はコードベース上で確認できない。pfcwd は DEVICE_NEIGHBOR_METADATA 側の type を参照 |
dead field 候補 |
lldpmgrd は DEVICE_NEIGHBOR を実際には読まない(dead consumer)¶
現行実装では DEVICE_NEIGHBOR テーブルへの subscribe が実装されていない(TODO 状態)。lldpmgrd が読む CONFIG_DB テーブルは DEVICE_METADATA と MGMT_INTERFACE のみ。
mgmt_addr — DEVICE_NEIGHBOR 内は dead field¶
DEVICE_NEIGHBOR テーブル内の mgmt_addr を参照する consumer はコードベース上で確認できない。show interfaces neighbor expected が表示する管理 IP は DEVICE_NEIGHBOR_METADATA 側の mgmt_addr を参照している (show/interfaces/__init__.py:342-344)。DEVICE_NEIGHBOR の mgmt_addr は書いても読まれない。
type — DEVICE_NEIGHBOR 側は dead field 候補¶
pfcwd get_server_facing_ports() は DEVICE_NEIGHBOR_METADATA['type'] を参照する。DEVICE_NEIGHBOR 本体の type フィールドを参照するコードパスは現行 consumer で確認できない。
ecnconfig と pfcwd の空テーブル処理の非対称性¶
pfcwd は空テーブルをサイレントに処理(外部ポートなしとして継続)するが、ecnconfig は Exception を raise して停止する。この非対称性により、DEVICE_NEIGHBOR が空の環境では ecnconfig コマンドが使用不可になる一方、pfcwd は(外部ポートなしとして)動作を継続する。
Evidence:
sonic-utilitiespfcwd/main.py:97-108,405-416;scripts/ecnconfig:93,282-287;show/interfaces/__init__.py:310-365;sonic-buildimagedockers/docker-lldp/lldpmgrd:12-14;src/sonic-bgpcfgd/bgpcfgd/managers_bgp.py:139-140,219-224
関連 CONFIG_DB / YANG / CLI¶
- 関連 CONFIG_DB:
DEVICE_NEIGHBOR、DEVICE_NEIGHBOR_METADATA、PORT - 関連 YANG:
sonic-device_neighbor - 関連 CLI:
show interfaces neighbor expected
関連リファレンス¶
運用ヒント¶
典型値¶
- DEVICE_NEIGHBOR が空の場合、
ecnconfigコマンドはException("No active ports detected...")で停止する。 - pfcwd は DEVICE_NEIGHBOR が空でも動作するが、外部ポートに対する PFC Watchdog が有効化されない。
show interfaces neighbor expectedは DEVICE_NEIGHBOR と DEVICE_NEIGHBOR_METADATA の両テーブルが存在することを前提とする。
よくある誤設定¶
- DEVICE_NEIGHBOR の
mgmt_addrを管理 IP として参照しようとしても、show コマンドは DEVICE_NEIGHBOR_METADATA 側を使用するため表示されない。 nameフィールドが DEVICE_NEIGHBOR_METADATA に未登録だと BGP セッションが確立されない(bgpcfgd がreturn Falseで延期し続ける)。
確認コマンド¶
例外条件・特殊挙動¶
| consumer | 条件 | 挙動 |
|---|---|---|
| ecnconfig (非 multi-ASIC) | DEVICE_NEIGHBOR テーブルが空 | Exception("No active ports detected in table 'DEVICE_NEIGHBOR'") を raise して停止(ecnconfig:287) |
| pfcwd start_default | DEVICE_NEIGHBOR テーブルが空 | 外部ポートを空リストとして処理し、バックプレーンポートのみで PFC Watchdog を設定(pfcwd/main.py:413-416) |
| pfcwd get_server_facing_ports | DEVICE_NEIGHBOR に name フィールド欠落エントリあり |
KeyError が発生し pfcwd の起動シーケンスが中断する(pfcwd/main.py:102) |
| pfcwd get_server_facing_ports | DEVICE_NEIGHBOR_METADATA に type=='server' エントリがない |
VLAN_MEMBER をフォールバックとして使用(pfcwd/main.py:106-107) |
| show interfaces neighbor expected | DEVICE_NEIGHBOR が None | "DEVICE_NEIGHBOR information is not present." を表示して即 return(show/interfaces/init.py:317-319) |
| show interfaces neighbor expected | 指定インターフェイスの DEVICE_NEIGHBOR エントリがない | "No neighbor information available for interface {}" を表示(show/interfaces/init.py:346-348) |
| bgpcfgd | data['name'] が DEVICE_NEIGHBOR_METADATA に不在 |
log_info("DEVICE_NEIGHBOR_METADATA is not ready...") を出力して return False(延期処理)(managers_bgp.py:221-223) |
Evidence:
sonic-utilitiespfcwd/main.py:97-108,405-416;scripts/ecnconfig:282-287;show/interfaces/__init__.py:317-319,346-348;sonic-buildimagesrc/sonic-bgpcfgd/bgpcfgd/managers_bgp.py:221-223