コンテンツにスキップ

内部実装

NAT / DHCP / DNS の内部実装は「SONiC は何を ASIC に任せ、何を Linux user space daemon に任せているか」の切り分けを意識すると整理しやすいです。NAT は SAI で hardware offload する path と conntrack で kernel に任せる path があり、DHCP は relay agent / server agent の二種類、DNS は基本 systemd-resolved + /etc/resolv.conf です。

データフロー

NAT

flowchart LR
  CFG[(CONFIG_DB<br/>NAT_POOL/NAT_BINDINGS/STATIC_NAT)] --> NATMGR[natmgrd]
  NATMGR --> APPL[(APPL_DB<br/>NAT_TABLE/NAPT_TABLE)]
  NATMGR --> KERNEL[iptables / conntrack]
  APPL --> NATORCH[NatOrch]
  NATORCH --> ASIC[(ASIC_DB<br/>SAI_NAT_ENTRY)]
  KERNEL -->|netlink conntrack| NATSYNCD[natsyncd]
  NATSYNCD --> APPL

DHCP relay / DHCP server

flowchart LR
  CFG[(CONFIG_DB<br/>DHCP_RELAY/DHCP_SERVER_IPV4)] --> DHCPRELAY[dhcprelay<br/>isc-dhcp-relay or dhcpmon]
  CFG --> DHCPSRV[dhcp_server_ipv4<br/>kea-dhcp4]
  DHCPRELAY --> CLIENT[client]
  DHCPSRV --> LEASE[(STATE_DB<br/>DHCP_SERVER_IPV4_LEASE)]

主要 daemon の責務

NAT

コンポーネント 主実体 責務
natmgrd (cfgmgr/natmgr.cpp) NatMgr::doTask STATIC_NAT / STATIC_NAPT / NAT_POOL / NAT_BINDINGSiptablesAPPL_DB に展開
NatOrch (orchagent/natorch.cpp) NatOrch::doTaskaddNatEntryremoveNatEntry APPL_DB を読み SAI NAT entry に投入
natsyncd (natsyncd/natsync.cpp) conntrack netlink listener kernel conntrack イベントを APPL_DB:NAT_TABLE に sync(ダイナミック NAT の hardware offload)
iptables rules (NAT/MANGLE) natmgrd が生成 初回パケットを kernel で NAT してから ASIC に load する

DHCP

コンポーネント 主実体 責務
dhcprelay (dockers/docker-dhcp-relay) isc-dhcp-relay + dhcpmon DHCPv4 / DHCPv6 relay。dhcpmon がカウンタを STATE_DB に書く
dhcp_server_ipv4 (src/sonic-dhcp-server) kea-dhcp4 based フル DHCP server。DHCP_SERVER_IPV4* 系テーブルから設定生成、lease を Redis に書く
dhcp6relay isc-dhcp-relay -6 DHCPv6 relay

DNS

コンポーネント 主実体 責務
resolv.conf 管理 hostcfgd の DNS task CONFIG_DB:DNS_NAMESERVER から /etc/resolv.conf 生成

SAI 属性使用一覧

NAT 関連:

object 属性
SAI_OBJECT_TYPE_NAT_ENTRY SAI_NAT_ENTRY_ATTR_NAT_TYPE = SOURCE_NAT/DESTINATION_NAT/DOUBLE_NATSAI_NAT_ENTRY_ATTR_SRC_IPSAI_NAT_ENTRY_ATTR_DST_IPSAI_NAT_ENTRY_ATTR_HIT_BITSAI_NAT_ENTRY_ATTR_AGING_TIME
SAI_OBJECT_TYPE_ROUTER_INTERFACE SAI_ROUTER_INTERFACE_ATTR_NAT_ZONE_ID(NAT zone を rif に紐付け)
SAI_OBJECT_TYPE_SWITCH SAI_SWITCH_ATTR_NAT_ENABLE(NAT 機能の全体スイッチ)

DHCP / DNS には SAI 属性は使われません(kernel で完結)。

Redis テーブル参照関係

CONFIG_DB:
  NAT_POOL, NAT_BINDINGS, STATIC_NAT, STATIC_NAPT, NAT_GLOBAL,
  DHCP_RELAY, DHCP_SERVER_IPV4, DHCP_SERVER_IPV4_*,
  DNS_NAMESERVER
APPL_DB:
  NAT_TABLE, NAPT_TABLE, NAT_TWICE_TABLE, NAPT_TWICE_TABLE
STATE_DB:
  NAT_TABLE, NAPT_TABLE, NAT_RESTORE_TABLE,
  DHCP_SERVER_IPV4_LEASE,
  DHCPv4_COUNTERS_TABLE, DHCPv6_COUNTERS_TABLE
ASIC_DB:
  NAT_ENTRY

ZMQ / Redis pub/sub

  • NAT: 通常の ProducerStateTable / SubscriberStateTable のみ。
  • natsyncdconntrack-tools の netlink を直接 listen し、Redis に書く片方向経路。conntrack 自体が pub/sub ではない点に注意。
  • DHCP: dhcpmon が pcap または syslog をパースする実装で、Redis 経由ではなく直接 counter を STATE_DB に書く。
  • DNS: pub/sub 経路はありません。

既知の実装上の制約

  • NAT の hardware offload は ASIC によって対応・非対応が分かれます。SAI_SWITCH_ATTR_NAT_ENABLE がサポートされていない ASIC では NAT は kernel のみ動作し、large flow のスループットが極端に落ちます。
  • natsyncd は conntrack の age を SAI に正確に反映できないことがあり、SAI_NAT_ENTRY_ATTR_HIT_BIT を polling して timeout を判断する設計に依存します。これがベンダ SAI で未対応だと NAT entry が枯渇しやすいです。
  • DHCP server (kea-dhcp4) はまだ全機能を網羅しておらず、特に option 82 周辺と高可用構成は限定的です。
  • DHCP relay の counter は dhcpmon が pcap-based で kernel iptables NFLOG を見ている実装で、高負荷時にパケットを取りこぼします。「relay packets 」を SLA に使うのは避けてください。
  • DNS は SONiC で独自設定はなく、hostcfgd/etc/resolv.conf を上書きする単純な実装。DNS-over-TLS や split-DNS は未対応。
  • IPv6 NAT(NAT66 / NPTv6)は SAI で属性は定義されているが、SONiC orchagent の対応が partial で、HLD と実装の discrepancy が出やすい部分です。

DHCP relay の packet path

DHCP relay (dhcprelayd および kea-dhcp4/kea-dhcp6 relay モード) は CoPP 経由で trap された DHCP パケットを処理します。

flowchart LR
  CLIENT[DHCP client] -->|broadcast / multicast| PORT[ingress port]
  PORT -->|CoPP trap| CPU[CPU queue]
  CPU --> KERNEL[Linux kernel]
  KERNEL --> RELAY[dhcprelayd / kea]
  RELAY -->|unicast to server_vip| EGRESS[egress port]
  RELAY -->|stats| DHCPMON[dhcpmon NFLOG]
  DHCPMON --> STATE[(STATE_DB<br/>DHCP_COUNTER_TABLE)]

CoPP の trap group dhcp / dhcpv6 がデフォルトで設定され、レート制限は COPP_TABLEcir/cbs で調整されます。dhcpmon の counter は NFLOG ベースで参考値扱いが妥当です。

関連ページ