コンテンツにスキップ

内部実装

ここでは SRv6 / MPLS / Path Tracing の主要 daemon・ファイル・SAI 属性のうち、設計を理解する上で欠かせない部分を集約します。コード位置は元 HLD ページに紐付いており、verifier が裏取り済みです。

srv6orch の構造

sonic-swss/orchagent/srv6orch.cpp / srv6orch.h が中核です。

  • end_behavior_mapend / end.dt4 / end.dt6 / end.dt46 / un / ua / udt4 / udt6 / udt46 / udx4 / udx6 等の文字列を、SAI の SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_* に対応付けます。uSID 拡張で uN / uA / uDT* / uDX* が追加されています。
  • MY_SID_ENTRY 作成createUpdateMysidEntry(my_sid_string, vrf, adj, end_action) が SAI への投入入口です。L3 隣接が必要な behavior では adj から nexthop を解決し、SAI_MY_SID_ENTRY_ATTR_NEXT_HOP_ID に渡します。
  • pending queuem_pendingSRv6MySIDEntries: map<NextHopKey, set<tuple<...>>> が Neighbor 未解決の SID を保留します。Neighbor 確定時の updateNeighbor 系コールバックで pending を flush します。
  • VPNsrv6_prefix_agg_id_table_ が Prefix を AGG_ID に集約、createSrv6Vpn / deleteSrv6Vpn が VPN encap mapper と vpn_sid を route nexthop に紐付けます。
  • SID listSAI_OBJECT_TYPE_SRV6_SIDLIST で SID 列を 1 オブジェクト化し、policy で参照します。

bgpcfgd の SRv6Mgr

Static SID / Locator は src/sonic-bgpcfgd/bgpcfgd/managers_srv6.pySRv6Mgr が処理します。

  • locators_set_handler / sids_set_handlerCONFIG_DB の subscribe ハンドラ。
  • locator 不在のまま SID が来ても、SRV6_MY_LOCATORS を subscribe して deferred 解決する経路を持ちます。
  • 最終的に vtysh -c "segment-routing" -c "srv6" -c "static-sids" -c "sid {} locator {} behavior {} vrf {}" を発行して FRR に流し込みます。

frrcfgd 側では SRV6_MY_LOCATORSzebraSRV6_MY_SIDSmgmtd に向けるターゲット daemon 設定があります。CONFIG_DB → FRR の中継経路が二重化されているわけではなく、各テーブルで担当 daemon が異なる構造です。

MPLS データパス

sonic-swss/fpmsyncd/routesync.cpp が MPLS netlink を APP_DB に変換する入口です。

  • APP_LABEL_ROUTE_TABLE_NAMEProducerStateTable として開きます。
  • AF_MPLS の netlink route を受け取り、RTA_NEWDST から MPLS NH label stack、LWTUNNEL_ENCAP_MPLS から encap label を取り出して APP_DB に書きます。
  • APP_DB の LABEL_ROUTE_TABLEorchagent 側が消費し、SAI INSEG_ENTRY を bulk で programming します。

per-RIF の MPLS 有効化(INTERFACE.<intf>.mpls = enable)は intfmgrd / IntfMgr が SAI の RIF 属性として渡し、ASIC が MPLS フレームを受理するかどうかを切り替えます。

QoS との接続

sonic-swss/orchagent/qosorch.cppm_qos_handler_mapCFG_MPLS_TC_TO_TC_MAP_TABLE_NAME が登録され、mpls_tc_to_tc_field_namePORT_QOS_MAP のフィールド名として参照されます。ハンドラは QosOrch::handleMplsTcToTcTable です。DSCP / TC / PG マップと同じ枠組みで MPLS TC が扱われるため、QoS 側の運用知識がそのまま使えます。

Path Tracing の SAI 属性

Path Tracing Midpoint は SAI 側で port 属性として実装されています。

  • SAI_PORT_ATTR_PATH_TRACING_INTFpt_interface_id に対応。
  • SAI_PORT_ATTR_PATH_TRACING_TIMESTAMP_TYPEpt_timestamp_template に対応。値は SAI_PORT_PATH_TRACING_TIMESTAMP_TYPE_12_19 のようにビット切り出し位置で命名されます。

orchagent 側の処理は port 系で、sonic-swss/tests/test_port.pytest_PortPathTracing として単体テストが存在します。

SAI MY_SID_ENTRY の使い分け

SAI 視点では、SRv6 endpoint は SAI_OBJECT_TYPE_MY_SID_ENTRY 1 種類でほぼ表現されます。違いは behavior 属性と、cross-connect 系での NEXT_HOP_ID の有無です。uSID も SAI レベルでは behavior 値が増えただけで、データ構造の追加はありません。HLD レベルで複数に見えるものが SAI レベルで同じ object なのは、設定や運用で「同じ場所を見ればよい」という指針につながります。

データフロー(SRv6 / MPLS)

flowchart LR
  CFG[(CONFIG_DB<br/>SRV6_MY_LOCATORS / SRV6_MY_SIDS / MPLS_TC_TO_TC_MAP)] --> BGP[bgpcfgd / SRv6Mgr]
  BGP --> FRR[FRR<br/>zebra / mgmtd]
  FRR -->|FPM| FPM[fpmsyncd<br/>RouteSync]
  FPM --> APPL[(APPL_DB<br/>ROUTE_TABLE / LABEL_ROUTE_TABLE)]
  APPL --> SRV6ORCH[Srv6Orch / RouteOrch]
  SRV6ORCH --> ASIC[(ASIC_DB<br/>MY_SID_ENTRY / INSEG_ENTRY / SIDLIST)]

主要 Orch / daemon の責務

コンポーネント 主実体 責務
Srv6Orch (orchagent/srv6orch.cpp) Srv6Orch::doTaskcreateUpdateMysidEntrycreateSrv6Vpn MY_SID_ENTRY、SID list、VPN encap mapper
MplsRouteOrch (orchagent/routeorch.cpp 内) label route 処理 INSEG_ENTRY 作成、bulk programming
bgpcfgd::SRv6Mgr python static SID/Locator を vtysh で FRR に投入
fpmsyncd::RouteSync C++ AF_MPLS netlink を LABEL_ROUTE_TABLE に変換
IntfMgr C++ per-RIF MPLS 有効化
QosOrch::handleMplsTcToTcTable C++ MPLS TC ↔ internal TC map

SAI 属性使用一覧

object 主属性
SAI_OBJECT_TYPE_MY_SID_ENTRY SAI_MY_SID_ENTRY_ATTR_ENDPOINT_BEHAVIOR = END / END_X / END_DT4 / END_DT6 / END_DT46 / UN / UA / UDT4 / UDT6 / UDT46 / UDX4 / UDX6PACKET_ACTIONNEXT_HOP_IDVRF
SAI_OBJECT_TYPE_SRV6_SIDLIST SAI_SRV6_SIDLIST_ATTR_TYPESEGMENT_LIST
SAI_OBJECT_TYPE_NEXT_HOP SAI_NEXT_HOP_ATTR_TYPE = SRV6_SIDLISTSRV6_SIDLIST_ID
SAI_OBJECT_TYPE_INSEG_ENTRY SAI_INSEG_ENTRY_ATTR_NUM_OF_POPPACKET_ACTIONNEXT_HOP_ID
SAI_OBJECT_TYPE_PORT SAI_PORT_ATTR_PATH_TRACING_INTFSAI_PORT_ATTR_PATH_TRACING_TIMESTAMP_TYPE
SAI_OBJECT_TYPE_ROUTER_INTERFACE SAI_ROUTER_INTERFACE_ATTR_ADMIN_MPLS_STATE

Redis テーブル参照関係

CONFIG_DB:
  SRV6_MY_LOCATORS, SRV6_MY_SIDS,
  MPLS_TC_TO_TC_MAP, TC_TO_DSCP_MAP_MPLS,
  INTERFACE (mpls = enable)
APPL_DB:
  ROUTE_TABLE (SRv6 encap / decap route),
  LABEL_ROUTE_TABLE (MPLS),
  SRV6_MY_SID_TABLE, SRV6_SID_LIST_TABLE
STATE_DB:
  SRV6_*_STATUS (限定的)
ASIC_DB:
  MY_SID_ENTRY, SRV6_SIDLIST, INSEG_ENTRY, NEXT_HOP (TYPE=SRV6_SIDLIST)

ZMQ / Redis pub/sub

  • ZMQ は使わない。
  • bgpcfgd ↔ FRR は vtysh execve(プロセス起動)で config を流し込む経路。Redis pub/sub も間接的にしか使われない。
  • fpmsyncdFPM netlink を受け、ProducerStateTable で LABEL_ROUTE_TABLE に書く。

既知の実装上の制約

  • SRv6 endpoint behavior の SAI mapping は ベンダ実装で対応が分かれる。特に END_DT46UDT* は未実装の ASIC がある。
  • SID list は SAI で 1 オブジェクト化されるが、SID 数の上限が ASIC TCAM サイズに律速される。HLD 上の数字より実機が低いケースが多い。
  • MPLS は SONiC core では機能的に古く、fpmsyncd の MPLS label 解析は 限定的な netlink encoding にしか対応していない。L3VPN(VPNv4/VPNv6 over MPLS)の完全サポートは無く、SRv6 経由を推奨。
  • per-port MPLS 有効化は RIF 属性で行うが、SAI_ROUTER_INTERFACE_ATTR_ADMIN_MPLS_STATE 未対応の ASIC では「kernel は受理するが ASIC が drop」する silent な動作になる。
  • Path Tracing Midpoint は data plane の OAM 拡張で、SONiC では SAI_PORT_ATTR_PATH_TRACING_* を介して port 単位設定。midpoint だけで end-to-end が完結するわけではない点に注意。
  • SRv6 VPN の prefix-agg-id は orchagent の内部最適化で、SAI 側では複数 prefix が同じ nexthop (= 同じ vpn_sid)を共有する形になる。CRM の prefix 数とは別の集計が必要。

関連ページ