コンテンツにスキップ

内部実装

VXLAN / EVPN / VNET の内部実装は「FRR (bgpd) が EVPN type-2/type-5 を学習し、zebra が kernel/fpmsyncd に渡し、orchagent が VxlanOrch / VNetOrch / VRFOrch / NeighOrch を通じて SAI tunnel 系オブジェクトを ASIC_DB に投入する」という縦の流れと「外部 controller が VNET_TUNNEL / VNET_ROUTE_TUNNEL を直接 APPL_DB に書く」という横の流れに分かれます。HLD の章をまたいで読むときは、この二経路をまず分離します。

データフロー

flowchart LR
  subgraph control[制御プレーン]
    BGPD[bgpd<br/>EVPN type-2/5]
    ZEBRA[zebra]
    CTRL[VNET controller<br/>外部から swssconfig 等]
  end
  subgraph swss[swss コンテナ]
    FPMSYNCD[fpmsyncd]
    BGPCFGD[bgpcfgd]
    ORCH[orchagent<br/>VxlanOrch / VNetOrch / VxlanTunnelOrch]
  end
  subgraph redis[Redis]
    CFG[(CONFIG_DB<br/>VXLAN_TUNNEL / VNET)]
    APP[(APPL_DB<br/>VNET_TUNNEL_TABLE / VNET_ROUTE_TUNNEL_TABLE)]
    ASIC[(ASIC_DB<br/>SAI_OBJECT_TYPE_TUNNEL)]
  end
  BGPD --> ZEBRA --> FPMSYNCD --> APP
  BGPCFGD --> CFG
  CTRL --> APP
  CFG --> ORCH
  APP --> ORCH
  ORCH --> ASIC

EVPN 学習経路と VNET API 経路は orchagent の中で同じ tunnel / encap オブジェクトに合流します。重複作成を避けるため、VxlanTunnelOrch は tunnel 名を key とした参照カウントを内部で持ちます。

主要 Orch / daemon の責務

コンポーネント 主なクラス / 実体 責務
VxlanTunnelOrch (orchagent/vxlanorch.cpp) VxlanTunnelOrch::doTaskcreateVxlanTunnel VXLAN_TUNNEL から SAI tunnel / tunnel-map を生成、underlay/overlay router interface を関連付け
VxlanTunnelMapOrch VxlanTunnelMapOrch::doTask VNI ↔ VLAN / VRF の tunnel-map entry を管理
VNetOrch (orchagent/vnetorch.cpp) VNetOrch::doTaskVNetBitmapObject / VNetVrfObject VNET テーブルから vrf 実体(または bitmap 方式)を作成
VNetRouteOrch addRouteaddTunnelRoute VNET_ROUTE_TABLE / VNET_ROUTE_TUNNEL_TABLE を SAI nexthop / nexthop group へ
EvpnRemoteVnipOrch / EvpnNvoOrch orchagent/vxlanorch.cpp type-2 で学んだ remote VTEP を tunnel decap 側に登録
VRFOrch orchagent/vrforch.cpp EVPN type-5 受信 vrf の作成・参照管理
IntfsOrch orchagent/intfsorch.cpp overlay SVI / router interface の作成
bgpcfgd (dockers/docker-fpm-frr/bgpcfgd/) jinja2 + bgpcfgd CONFIG_DBBGP_* / DEVICE_METADATA から FRR の vtysh config を生成
fpmsyncd (fpmsyncd/fpmlink.cpp) FpmLink::processFpmMessage zebra の FPM netlink を ROUTE_TABLE / LABEL_ROUTE_TABLE に書き込み

SAI 属性の使用一覧

ステップ SAI object 主要属性
tunnel 作成 SAI_OBJECT_TYPE_TUNNEL SAI_TUNNEL_ATTR_TYPE = VXLANSAI_TUNNEL_ATTR_ENCAP_SRC_IPSAI_TUNNEL_ATTR_DECAP_MAPPERSSAI_TUNNEL_ATTR_ENCAP_MAPPERS
tunnel map SAI_OBJECT_TYPE_TUNNEL_MAP SAI_TUNNEL_MAP_ATTR_TYPE = VNI_TO_VLAN_ID / VNI_TO_VIRTUAL_ROUTER_ID
tunnel map entry SAI_OBJECT_TYPE_TUNNEL_MAP_ENTRY SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEYSAI_TUNNEL_MAP_ENTRY_ATTR_VLAN_ID_VALUE / VIRTUAL_ROUTER_ID_VALUE
decap term SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TUNNEL_TYPE = VXLANDST_IPSRC_IP(P2P 時)
overlay nexthop SAI_OBJECT_TYPE_NEXT_HOP SAI_NEXT_HOP_ATTR_TYPE = TUNNEL_ENCAPSAI_NEXT_HOP_ATTR_TUNNEL_IDSAI_NEXT_HOP_ATTR_TUNNEL_VNISAI_NEXT_HOP_ATTR_TUNNEL_MAC

これら属性のうち SAI_NEXT_HOP_ATTR_TUNNEL_MAC は EVPN type-2 由来の inner DMAC を渡すために使われ、ベンダ実装で missing になりやすい点が discrepancy として上がりやすい箇所です。

Redis テーブル参照関係

CONFIG_DB:
  VXLAN_TUNNEL ─┬─> VxlanTunnelOrch
  VXLAN_TUNNEL_MAP ─> VxlanTunnelMapOrch
  VNET ─────────> VNetOrch
  VLAN_INTERFACE / VLAN  ─> IntfsOrch (overlay SVI)
  BGP_NEIGHBOR (l2vpn evpn AF)  ─> bgpcfgd → FRR

APPL_DB:
  VNET_TUNNEL_TABLE / VNET_ROUTE_TABLE / VNET_ROUTE_TUNNEL_TABLE ─> VNetOrch / VNetRouteOrch
  EVPN_REMOTE_VNI_TABLE ─> EvpnRemoteVnipOrch
  NEIGH_TABLE (type-2) ─> NeighOrch

STATE_DB:
  VXLAN_TUNNEL_TABLE / EVPN_REMOTE_VNI_TABLE / BFD_SESSION_TABLE
ASIC_DB:
  SAI_OBJECT_TYPE_TUNNEL / TUNNEL_MAP / TUNNEL_TERM_TABLE_ENTRY / NEXT_HOP / ROUTE_ENTRY

VNET monitoring / BFDBFD_SESSION_TABLE 経由で BfdOrch に届き、ECMP nexthop の up/down 判定にフィードバックされます。

ZMQ / pub-sub の使用

  • VNET_ROUTE_TUNNEL_TABLE は外部 controller からの大量 push を想定し、ZMQ producer/consumer 経路で APPL_DB を経由せずに orchagent に直接渡す経路があります(zmq_server_addressORCHAGENT 設定)。SDN コントローラ統合 HLD で導入された経路で、Redis pub/sub のスループット限界回避のためです。
  • 通常 EVPN 経路は ProducerStateTable / SubscriberStateTable を使う Redis pub/sub のみで、ZMQ は使いません。
  • BfdOrch から VNetOrch への通知は orchagent 内 Observer パターン(プロセス内 callback)で、Redis を経由しません。

既知の実装上の制約

  • VxLAN encap source IP は loopback IP をひとつ選ぶ設計で、複数 source を SAI 側で同時に持つことは tunnel object 単位では未対応です(HLD で明記)。
  • ベンダ ASIC によっては SAI_TUNNEL_MAP_TYPE_VNI_TO_VIRTUAL_ROUTER_ID(type-5 用)が未実装で、EVPN type-5 を MAC-VRF + IRB で代替する実装に倒れることがあります。これは discrepancy として記録する典型例です。
  • VNET BGP(VNET 内 BGP セッション)は BGP route の VNET 帰属を nexthop で識別する設計で、同一 nexthop が複数 VNET から指される構成は HLD では除外されています。
  • type-2 で学んだ ARP/ND の老化は kernel ではなく orchagent の NeighOrch が tunnel route と一緒に管理するため、tcpdump で aging を観測しても挙動が一致しないことがあります。

VNI ↔ VRF / VLAN マッピング

EVPN は VNI を L2(type-2)と L3(type-5)の両方で使うため、VNI の意味を文脈で分ける必要があります。

種別 用途 SONiC 実装
L2 VNI type-2(MAC / MAC+IP)broadcast domain VLANVXLAN_TUNNEL_MAP で VLAN にバインド
L3 VNI type-5(IP prefix)受信側で route lookup VRFVXLAN_EVPN_NVO で VRF にバインド
Symmetric IRB type-2 でも L3 VNI を経由して inter-subnet ルーティング type-2 の RT に L3 VNI を含めて広告

fpmsyncd は FRR からの EVPN route を EVPN_REMOTE_VNI_TABLE 系で受け、VnetOrch がそれを SAI tunnel / FDB / route に変換します。VNI が L2 と L3 で衝突する設定は CONFIG_DB の整合性チェックで拒否される設計ですが、bgpcfgd 経由でない手動の vtysh 投入では拒否されない既知の隙があります。

tunnel decap term の使い分け

SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY には P2P / P2MP / MP2MP の 3 種があり、SONiC は EVPN の挙動に合わせて切り替えます。

type 用途 SAI 属性
P2P 特定 remote VTEP からの decap DST_IP(local VTEP IP)+ SRC_IP(remote VTEP IP)
P2MP 任意 remote からの decap、特定 local IP DST_IP のみ
MP2MP DCI 用、任意 source / 任意 destination DST/SRC とも IP range

EvpnRemoteVnipOrch は remote VTEP を学習するごとに P2P term を追加する実装と、初回に P2MP を 1 件作って共有する実装が SONiC のバージョンによって混在します。VxlanTunnelOrch::createTunneldip 引数が空かどうかで分岐します。

EVPN GR / fast convergence

EVPN の障害収束は FRR の bgp graceful-restart と SONiC の EVPN_REMOTE_VNI_TABLE の TTL に依存します。FRR 側が下流 advertise を止めた後、VxlanTunnelOrch が remote VTEP を保持する期間(HOLD time)に traffic を blackhole しないようにする restart-time 系のパラメータが BGP_NEIGHBOR.graceful_restart_helper_only で制御されます。

関連ページ