コンテンツにスキップ

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 構造

NAT_BINDINGS|<binding_name>

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 / CLI nat.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_NATSTATIC_NAPTNAT_BINDINGS 合計)

購読者

  • natmgrd (doNatBindingTask): CONFIG_DBNAT_BINDINGS 変更を検知し、NAT pool・ACL の状態確認後に kernel iptables ルールおよび APPL_DB NAT エントリを設定する。
  • orchagent / NatOrch: APPL_DB の NAT エントリを消費して SAI NAT object を作成する。

関連 CONFIG_DB / YANG / CLI

  • 関連 CONFIG_DB: NAT_GLOBALNAT_POOLSTATIC_NATSTATIC_NAPTACL_TABLE
  • 関連 CLI: config nat add bindingconfig nat remove binding
  • 関連 YANG: sonic-nat

関連リファレンス

引用元

運用ヒント

典型設定

# 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

確認コマンド

sonic-db-cli CONFIG_DB hgetall 'NAT_BINDINGS|BIND1'
show nat config bindings
show nat translations

よくある誤設定

  • 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_NAMESubscriberStateTable で購読。

段階 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 を作成。

  1. YANG 定義 + natmgr 実装: sonic-nat.yang / sonic-swss/cfgmgr/natmgr.cpp. https://github.com/sonic-net/sonic-swss/blob/master/cfgmgr/natmgr.cpp