Topics で読み物として読む
この HLD は実装詳細を含みます。機能の概念・設定・運用を読み物として読みたい場合は Topics 09 章: Telemetry / SNMP / ログ を参照。
裏取りステータス: code-verified
sonic-buildimage/dockers/docker-snmp/snmpd.conf.j2:27-33 で SNMP_AGENT_ADDRESS_CONFIG をループ → agentAddress 出力、未設定時は :32-33 で udp:161 / udp6:161 フォールバック。sonic-config-engine/minigraph.py:2310-2324 で minigraph 解析時に Management IP / Loopback IP から SNMP_AGENT_ADDRESS_CONFIG を自動生成(verified at: 2026-05-09)。
SNMP IPv6 応答の SRC IP 不整合と SNMP_AGENT_ADDRESS_CONFIG による回避¶
どんな問題か¶
SONiC 単一 ASIC 機の SNMP over IPv6 がタイムアウトする バグの設計修正1。
- SNMP request が
SRC=fc00::72、DST=Loopback IPv6 fc00:1::32で到着 snmpd(IPv6 socket[::]:161) が受理 → response 生成- kernel が
ip -6 route get fc00::72で best path を探し、src=fc00::71(PortChannel IP) を選ぶ - クライアントは「DST と異なる SRC」で受信し、request-id がマッチせず timeout
sequenceDiagram
participant C as client
participant K as kernel
participant S as snmpd
C->>K: req SRC=fc00::72 DST=fc00:1::32 (Loopback)
K->>S: 配送 (listen [::]:161)
S->>K: resp DST=fc00::72
Note over S,K: IPv6 では DST IP 引き継ぎ無し
K->>K: route get → src=fc00::71 (PortChannel)
K->>C: resp SRC=fc00::71 ≠ Loopback
C-->>C: request-id mismatch → timeout
なぜ IPv4 では出ないか / multi-ASIC では出ないか¶
- IPv4: net-snmp が
ipi_spec_dstで request の DST を SRC として強制する - multi-ASIC: snmpd は host namespace、Loopback0 は asic namespace で 分離。受信 namespace の routing table 内で完結するため、SRC が混じらない1
IPv6 にはこの仕組みが無く、kernel route lookup 任せになるのが根本原因1。
修正方針¶
agentAddress を 0.0.0.0/::0 でなく Loopback / Management の具体 IP に bind する1。socket fd を IP 別に分離すれば、応答送信時もその fd(= 対応 IP)から出ていく。
bind 状態の変化¶
# 修正前
socket 7 UDP [0.0.0.0]:161
socket 8 UDP/v6 [::]:161
# 修正後(SNMP_AGENT_ADDRESS_CONFIG に Loopback0 + Management を投入)
socket 7 UDP 10.250.0.101:161 # Management v4
socket 8 UDP 10.1.0.32:161 # Loopback0 v4
socket 9 UDP/v6 fc00:2::32:161 # Management v6
socket 10 UDP/v6 fc00:1::32:161 # Loopback0 v6
Loopback IPv6 への request は fd=10 で受信 → 同じ fd で送出 → SRC は Loopback v6 で固定。
自動投入される条件¶
| 起動経路 | SNMP_AGENT_ADDRESS_CONFIG |
|---|---|
config load_minigraph |
自動: parser が Loopback0 / Management IP を登録1 |
config_db.json 直ロード |
無し。0.0.0.0/::0 のまま IPv6 問題が再発。回避には config snmpagentaddress add <ip> |
| multi-ASIC 機 | 対象外(namespace 分離で発症しない)1 |
flowchart LR
MG[minigraph.xml] -->|parser| CFG[CONFIG_DB.SNMP_AGENT_ADDRESS_CONFIG]
JSON[config_db.json] -.->|手動 add のみ| CFG
CFG --> CONFD[snmpd.conf.j2 rendering]
CONFD --> SD[snmpd<br/>各 IP に bind した socket fd]
関連 PR: sonic-buildimage#15487(修正本体)/ #16013(link-local IPv6 対応)/ #17045(minigraph parser 拡張)1。
CLI / 設定例¶
config snmpagentaddress add 10.1.0.32
config snmpagentaddress add fc00:1::32
config snmpagentaddress add fe80::abcd # link-local (PR #16013)
show snmpagentaddress
制限事項¶
- 単一 ASIC 機向け修正(multi-ASIC は元から発症しない)1
config_db.json直ロード時はSNMP_AGENT_ADDRESS_CONFIG自動投入なし1- Loopback / Management の どちらを bind するかはオペレータ責任
- 本質的修正は net-snmp 側で
IPV6_PKTINFOを使う対応だが、本 HLD は 回避策
干渉する機能¶
snmpd(SNMP docker): 起動時にsnmpd.confのagentAddressを読むminigraph parser:SNMP_AGENT_ADDRESS_CONFIG自動生成- kernel routing:
0.0.0.0/::0bind の場合のみ介入
トラブルシューティング¶
sonic-db-cli CONFIG_DB keys 'SNMP_AGENT_ADDRESS_CONFIG*'
docker exec snmp cat /etc/snmp/snmpd.conf | grep agentAddress
docker exec snmp ss -ulnp | grep snmpd
tcpdump -ni any port 161 # req DST vs resp SRC 比較
ip netns list # multi-ASIC は分離されているはず
関連 Topics¶
- 09-telemetry-snmp: SNMP / telemetry 全般