NAT_BINDINGS テーブル¶
概要¶
NAT_BINDINGS は dynamic NAT のバインディングを定義する CONFIG_DB テーブル。ACL テーブルと NAT pool を関連付け、対象トラフィックの動的 SNAT ルールを natmgrd 経由で kernel / ASIC に適用する1。エントリ最大 16 件。
データフロー (自動生成)¶
flowchart LR
CDB[("CONFIG_DB<br/>NAT_BINDINGS")]
DM["natmgrd"]
CDB --> DM
APPDB[("APP_DB<br/>NAT pool/rule")]
DM --> APPDB
SYNCD["orchagent / NatOrch"]
APPDB --> SYNCD
SAI["SAI<br/>sai_nat_api"]
SYNCD --> SAI
凡例
CONFIG_DB から SAI までの典型経路を docs/reference/config-db-orch-map.md から機械生成したミニ図。詳細・例外は本ページ本文と対応表を参照。
key 構造¶
binding_name は 1..32 文字、[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,31}) パターン。
主要フィールド¶
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
nat_pool |
leafref → NAT_POOL.name |
yes | — | バインディング対象の NAT pool 名 |
access_list |
文字列 (ACL 名, カンマ区切り可) | no | "" (空) |
対象トラフィックを絞る ACL 名。省略時は全送信元が対象 |
nat_type |
enum snat / dnat |
no | "snat" |
NAT 種別。現時点で dnat は未サポート (CLI が拒否) |
twice_nat_id |
uint16 1..9999 | no | "" → Single NAT |
Twice NAT 用 ID。省略時 Single NAT として動作 |
コード由来の暗黙デフォルト¶
以下のデフォルトはコードレベルで確認済み(YANG / CLI / natmgr 三箇所一致)。
| フィールド | 暗黙デフォルト | 根拠コード |
|---|---|---|
access_list |
"" (空文字列) |
config/nat.py:797 acl_name=None → "" / natmgr.cpp:6879 EMPTY_STRING 初期化 |
nat_type |
"snat" |
YANG default snat / nat.py:821 / natmgr.cpp:7056-7058 empty → SNAT_NAT_TYPE |
twice_nat_id |
"" → Single NAT |
nat.py:823-824 None → "NULL" → DB / natmgr.cpp:6993-6996 "NULL" → EMPTY_STRING |
nat_type が空の場合の natmgr 動作:
// natmgr.cpp:7056-7063
if (nat_type.empty())
{
m_natBindingInfo[key].nat_type = SNAT_NAT_TYPE; // "snat"
}
twice_nat_id の "NULL" 変換:
// natmgr.cpp:6993-6996
if (twice_nat_id == "NULL")
{
twiceNatFound = false;
twice_nat_id = EMPTY_STRING; // "" → Single NAT モード
}
Single NAT / Twice NAT 分岐:
// natmgr.cpp:4663-4679
if (m_natBindingInfo[key].twice_nat_id.empty())
{
// Single NAT: ACL あり/なしで iptables ルール設定
setDynamicAllForwardOrAclbasedRules(ADD, pool_interface, ip_range, port_range, acls_name, key);
}
else
{
// Twice NAT: addDynamicTwiceNatRule() へ
addDynamicTwiceNatRule(key);
}
制約¶
- エントリ数上限: 16 件 (YANG
max-elements 16/ CLInat.py:812でも同チェック) - バインディング名: 最大 32 文字
nat_pool: 存在するNAT_POOLエントリへの leafref (必須)nat_type=dnat: CLI (config nat add binding) が"Ignored, DNAT is not yet supported for Binding"を表示して拒否twice_nat_id有効範囲: 1..9999 (範囲外は YANG / natmgr が拒否)- 同一
twice_nat_idを持てるエントリ: 最大 2 件 (STATIC_NAT・STATIC_NAPT・NAT_BINDINGS合計)
購読者¶
natmgrd(doNatBindingTask): CONFIG_DB のNAT_BINDINGS変更を検知し、NAT pool・ACL の状態確認後に kernel iptables ルールおよび APPL_DB NAT エントリを設定する。orchagent / NatOrch: APPL_DB の NAT エントリを消費して SAI NAT object を作成する。
関連 CONFIG_DB / YANG / CLI¶
- 関連 CONFIG_DB:
NAT_GLOBAL、NAT_POOL、STATIC_NAT、STATIC_NAPT、ACL_TABLE - 関連 CLI:
config nat add binding、config nat remove binding - 関連 YANG:
sonic-nat
関連リファレンス¶
- YANG:
sonic-nat - CLI:
config nat - CONFIG_DB:
NAT_GLOBAL / NAT_POOL
引用元¶
運用ヒント¶
典型設定¶
# Pool + Binding の追加
config nat add pool POOL1 192.168.100.1-192.168.100.10 1024-65535
config nat add binding BIND1 POOL1
# ACL を指定して特定サブネットのみ NAT
config nat add binding BIND2 POOL1 ACL_SRC_SUBNET
# Twice NAT binding
config nat add binding BIND3 POOL1 -twice_nat_id 100
確認コマンド¶
よくある誤設定¶
nat_poolに存在しない pool 名を指定 → natmgr がルールをスキップ ("Pool is not yet enabled"ログ)nat_type=dnatを指定 → CLI が拒否。Binding は SNAT 専用twice_nat_id重複 → 同 ID を持つエントリが 3 件以上になると"Same Twice nat id is not allowed for more than 2 entries!!"エラー
例外条件・特殊挙動¶
- バインディング名が 32 文字超 → スキップ:
"Invalid binding name length - %zu, skipping %s"をログしてエントリを消費 (natmgr.cpp:6899-6904)。 nat_type=dnat→ SWSS_LOG_ERROR + スキップ:"Invalid nat_type %s, skipping %s"をログ (natmgr.cpp:6986-6991)。YANG でも snat がデフォルトで dnat は運用非推奨。twice_nat_id="NULL"→ 空文字列扱い: CLI が省略時に"NULL"を書き込むが、natmgr がEMPTY_STRINGに変換して Single NAT モードで処理 (natmgr.cpp:6993-6996)。- Pool が未登録の状態で Binding 追加 → ルール延期: natmgr はキャッシュに Binding 情報を格納するが
"Pool is not yet enabled, skipping dynamic nat rules addition"としてルール設定をスキップ。Pool が後から登録されると再トリガーされる。 - NAT feature が disabled → ルール延期:
isNatEnabled()=falseの場合、addDynamicNatRule内でスキップし"NAT is not yet enabled"をログ (natmgr.cpp:4632-4636)。 - 重複エントリ (同 pool_name + acl_name) → スキップ:
"Duplicate Binding and it's values, skipping"をログ (natmgr.cpp:7037)。 - エントリ上限 16 件 → CLI が拒否:
"Failed to add binding, as already reached maximum binding limit 16."(nat.py:812-813)。YANG もmax-elements 16で同様に制限。
値依存挙動マトリクス¶
| フィールド | 値 | 挙動 |
|---|---|---|
access_list |
"" (省略時デフォルト) |
全送信元トラフィックを NAT 対象にする (ACL なし full-cone NAT) |
access_list |
ACL 名 (カンマ区切り) | 指定 ACL に一致するトラフィックのみ NAT |
nat_type |
"snat" (デフォルト) |
送信元 IP を pool IP に変換 (内 → 外方向) |
nat_type |
"dnat" |
CLI が拒否。natmgr も SNAT_NAT_TYPE のみ受け付ける |
twice_nat_id |
省略 / "NULL" / "" |
Single NAT モード (setDynamicAllForwardOrAclbasedRules) |
twice_nat_id |
1..9999 | Twice NAT モード (addDynamicTwiceNatRule) |
enum: nat_type=snat/dnat (有効値は snat のみ)。
CDB → 実コンテナ動作トレース¶
段階 1: Consumer 登録¶
- natmgrd (
sonic-swss/cfgmgr/natmgrd.cpp:113):CFG_NAT_BINDINGS_TABLE_NAMEをSubscriberStateTableで購読。
段階 2: CFG → キャッシュ + iptables¶
doNatBindingTaskがフィールドを解析しm_natBindingInfo[key]に格納。nat_type省略時はSNAT_NAT_TYPE ("snat")をキャッシュに設定。twice_nat_id="NULL"はEMPTY_STRINGに変換してから格納。addDynamicNatRuleが NAT 有効状態・pool 存在・L3 インタフェース存在を確認してから iptables ルールを設定。
段階 3: APPL → SAI¶
natmgrdが APP_DB のNAT_DNAT_POOL_TABLE/ iptables 経由で動的 NAT エントリを管理。orchagent / NatOrchが APP_DB エントリを消費して SAI NAT object を作成。
-
YANG 定義 + natmgr 実装:
sonic-nat.yang/sonic-swss/cfgmgr/natmgr.cpp. https://github.com/sonic-net/sonic-swss/blob/master/cfgmgr/natmgr.cpp ↩