詳解ホワイトボックススイッチNOSMPLS Japan 20202020年11月9日
NTTエレクトロニクスアメリカ 石田 渉

アジェンダ• ホワイトボックススイッチの近況• ホワイトボックススイッチNOSのアーキテクチャ• OSとEthernetASICの連携方法• まとめ

ホワイトボックススイッチの近況• ホワイトボックススイッチとそれ以外の境界が曖昧になってきた• Arista, Cisco, JuniperのハードでホワイトボックススイッチNOSのSONiCが動く• Cisco ASIC Silicon OneのプレスリリースでSONiC/SAIが言及される• 一方ホワイトボックススイッチ+OSS NOSの商用サポート提供も進んでいる• Cumulus, MellanoxはNVIDIAに買収される• データセンタネットワーク以外にも適用しようとする動きが広がっている• DCSG(セルサイトゲートウェイ) - TIP, AT&T
• シャーシ型ルータ - OCP, AT&T
• 伝送装置 - TIP, ONF ODTN• OLT - ONF VOLTHA• Enterprise Edge : DENT (Amazon, NVIDIA etc..)

ホワイトボックススイッチNOSの近況• OSS: SONiC, DANOS, Stratum, DENT
• SONiCの開発が活発 / OSSの中での趨勢は決まった？
• Microsoft, Broadcom, Dell, NVIDIA(Mellanox)等が開発に参加• とはいえ誰でも簡単に安心して使えるレベルにはまだまだ達していない• IPInfusion, Edgecore等が商用サポートを開始• FBOSS(Facebook)がSAIの利用を開始• ONL(Open Network Linux)が多くのNOSで使われながらもBigSwitchがAristaに買収されて先行きが不透明• FBOSS, ArcOS, DENT, StractumはONLベース

ホワイトボックススイッチNOSのアーキテクチャ
CLI, SNMP, NETCONF, gNMI etc..

L2/L3プロトコル
EthernetASICとOSのネットワークスタックとの協調動作

Network Application
Hardware Control
EthernetASICの抽象化,マルチベンダ化
ペリフェラル(プラガブルトランシーバ)等の制御

Application
Management

Management死活監視
ログ
パッケージング
アップグレードホワイトボックススイッチNOSのアーキテクチャ
CLI, SNMP, NETCONF, gNMI etc..

L2/L3プロトコル
EthernetASICとOSのネットワークスタックとの協調動作

Network Application
Hardware Control

今日の話の中心EthernetASICの抽象化,マルチベンダ化
ペリフェラル(プラガブルトランシーバ)等の制御

Application
Management

Management

死活監視
ログ
パッケージング
アップグレードHardware Control

EthernetASICの抽象化• OSからはPCIeデバイスとして見える• 制御はチップベンダが提供するユーザランドで動くSDKで行うのが一般的• NOSは複数ベンダのEthernetASICの制御を抽象化するため、HAL(Hardware Abstraction Layer)をベンダのSDK上に載せることが一般的• SONiCではSAI(Switch Abstraction Interface)というオープンなHALを利用している• Broadcom/NVIDIA(Mellanox)を始め多くのEthernetASICが対応しており、オープンソースのHALでは一番成功している• Cisco Silicon ONEもSAIへの対応を発表している• 最近ではFBOSSもSAIをHALとして利用、今後デファクトスタンダードになっていく？

Hardware Control

ペリフェラルの制御• ネットワーク機器はサーバ寄りではあるが、組み込み機器の要素もある• BMC/IPMIの利用も広がっているが、まだ温度モニタリング, ファン制御はOS上で行わなければいけないことが一般的• トランシーバの制御• サーバではethtoolを使いNICのドライバがPCIeを経由してトランシーバにアクセス• ホワイトボックススイッチではトランシーバのi2cバスが直接CPUに接続されているため、接続方法が異なる• ethtoolはそのまま使えない• ピザボックス型だけではなく、シャーシ型/モジュール型のホワイトボックス製品も増えており、ペリフェラルを統一して扱える仕組みが必要とされている• Cumulusが提唱したACPIベースのAPDは支持が得られなかった様子• ONLのONLPが現状有力解だがSONiCが使っていない + ONLの今後の開発動向が不透明コントロールプレーンのパケットのみOSで処理を行う

ほとんどのパケット処理はCPUを介さず行う( Broadcom Tomahawk4/ Innovium TERALYNX8 = 25.6Tbps )Hardware Control

SAI (Switch Abstraction Interface)• オープンなEthernetASICの制御API• https://github.com/opencomputeproject/SAI• Cのヘッダファイルの集合 + ユーティリティライブラリ• CRUDベースのAPI : オブジェクトの作成/削除 + アトリビュートの読み書き• notification/callbackもアトリビュートとして関数ポインタを登録するようになっている• SAIの実装は各EthernetASICベンダが行い、OSS化する必要はない• Barefoot, Broadcom, Cavium, Centec, Innovium, Marvell, Mellanox,Nephosが実装を公表

ホワイトボックススイッチNOSのアーキテクチャ
CLI, SNMP, NETCONF, gNMI etc..

L2/L3プロトコル
EthernetASICとOSのネットワークスタックとの協調動作Network Application
Hardware Control

今日の話の中心EthernetASICの抽象化,マルチベンダ化
ペリフェラル(プラガブルトランシーバ)等の制御

Application
Management

Management

死活監視
ログ
パッケージング
アップグレードNetwork Application• NOSではEthernetASICとOSのネットワークスタックをどのように連携させるかが肝• なぜ連携させる必要があるのか？

• サーバサイドのソフト資産をそのまま流用したいから• 流用しないとTCPスタックに始まり、ping, tcpdump, ルーティングデーモン等々全てに修正が必要になる• スイッチ上で適当なLinuxディストリビューションを立ち上げればマネジメントポートは普通のネットワー
クインターフェイスとして見え、サーバと同じように管理できる• しかしEthernetASICのフロントパネルポートはそのままでは見えない• ip link showでフロントパネルポートは見えない• またEthernetASICの状態とOSのネットワークスタックを同期させないといけない• FDB(L2), FIB(L3)等々OSのネットワークスタックとの連携例
1. EthernetASICのフロントパネルポートに対応するネットワークインターフ
ェイスの作成2. インターフェイスへのIPアドレスの設定
3. Neighborテーブル(ARP/ND)の同期
4. ルーティングプロトコルとの連携
これらをSONiC/SAIではどのように実現しているかをSAIに対してどのようなAPIを発行するか、を中心に見ていく1. ネットワークインターフェイスの作成• SAIではhostifというオブジェクトがOS内のインターフェイスに対応する• hostifを作ると、SAIライブラリがOS内にnetdevを生やしてくれる

https://github.com/opencomputeproject/SAI/blob/master/inc/saihostif.h#L20-L30

Host Interfaceの作成

スイッチIDとアトリビュートのリストを受け取り、OIDを返す( スイッチID = ASICの通し番号, ピザボックスタイプのスイッチでは通常ASICは1つのみ搭載なのでスイッチIDは常に同じ )https://github.com/opencomputeproject/SAI/blob/master/inc/saihostif.h#L1347

Host Interfaceのアトリビュート (1/2)
Host Interfaceのアトリビュートの定義

コメントにアトリビュートの型とどのような使いかたが出来るかを示すフラグ等が記載されている
SONiCではこれらを機械的にパースして制約を満たしているかチェックする仕組みを利用している (metaライブラリ)

OSにインターフェイスを生やすにはNETDEVを選択

Host Interfaceのアトリビュート (2/2)

Hostifを作るには、対応するPort(フロントパネルポート)のOIDを指定することが必須であることがわかる
HostifはPort以外にもLAG, VLAN, SYSTEM_PORT(シャーシ型の装置で利用)に対して作成することもできる。Portと同様対応するOIDを指定する。
またフラグにより、 このアトリビュートは作成時には必須かつ作成時にのみ利用できる(後から変更できない)、とわかる。

https://github.com/opencomputeproject/SAI/blob/master/inc/saihostif.h#L816

Portの作成
Hostifを作るためには、事前にPortを作らなければいけない
Portの作成にはcreate_port APIを利用する

スイッチIDとアトリビュートのリストを受け取り、OIDを返す

https://github.com/opencomputeproject/SAI/blob/master/inc/saiport.h#L3083

Portのアトリビュート

Portの作成ではHW_LANE_LISTとSPEEDを必ず設定しなければいけない
HW_LANE_LISTにはプラットフォーム固有のSERDESレーン番号のリストを渡す
QSFP28/100GbEの場合、電気レーンは4本なので4要素のリストになる
SONiCではport_config.iniというプラットフォーム固有のファイルにレーン番号の情報が格納される ( ただしdynamic port breakoutのサポートが進んでおり、これが完了するとport_config.iniは使われなくなる予定.
https://github.com/Azure/SONiC/blob/master/doc/dynamic-port-breakout/sonic-dynamicport-breakout-HLD.md )OSのネットワークスタックとの連携
1. EthernetASICのフロントパネルポートに対応するネットワークインターフ
ェイスの作成• PortとHost Interfaceオブジェクトを作成する

2. インターフェイスへのIPアドレスの設定
3. Neighborテーブル(ARP/ND)の同期
4. ルーティングプロトコルとの連携

2. インターフェイスへのIPアドレスの設定• LinuxではnetlinkというAPIを使って、インターフェイスへのIPアドレスを設定する ( ipコ
マンドはnetlinkを内部で利用している )• ip address add 192.168.0.1/24 dev Ethernet1 ← 1.で作成したnetdev• しかしkernelはEthernetASICの制御に関与しないので、上記コマンドではソフト(OS)にはIPアドレスを設定できても、ハード(EthernetASIC)にはIPアドレスが設定できていない• EthernetASICに対しては自身のIPアドレスをCPU側に転送するように設定する必要がある• LinuxのネットワークスタックとEthernetASICの制御をどちらともアトミックに行う必要がある

OS/EthernetASIC両者への操作の実現方法
1. 普通のLinuxサーバと同じように操作出来るようにする
2. 専用CLI/マネジメントシステムを用意する

OS/EthernetASIC両者への操作の実現方法

1. 普通のLinuxサーバと同じように操作出来るようにする• netlinkはユーザ空間からモニタリングすることができる ( ip monitor )• ユーザのipコマンドによる変更をnetlink listenerで検知して、その内容を元にEthernetASIC SDKを介して、EthernetASICを制御する• ipコマンドの変更はKernelへの処理が完了したら成功してしまうので、EthernetASIC SDKがエラーを返したときのエラーハンドリングができない
iproute2
netlink

netlink
listener

EthernetASIC
SDK

netlinkuser
kernelKernelEthernetASICOS/EthernetASIC両者への操作の実現方法

2. 専用CLI/マネジメントシステムを用意する• Kernelの設定とEthernetASICの設定どちらとも成功してはじめて、ユーザに成功した、と返すCLIを用意する• ユーザがNET_ADMIN権限がある場合、簡単にシステムを壊せてしまう• ip address addコマンドのユーザによる実行でKernelとEthenetASICの状態が不一致• SONiCはこの方式

CLI
iproute2
運用で禁止?

EthernetASIC
SDK

netlinkuser
kernelKernelEthernetASIC

インターフェイスへのIPアドレスの設定

EthernetASICに対して必要な操作
1. routerinterfaceの作成• 主な用途

1. directly connectedな経路のnexthopとして
2. それ以外の経路のnexthopが使うインターフェイスとして

2. L3経路の作成

1. 自分自身への経路作成• nexthopはCPUに設定

2. directly connectedな経路の作成• nexthopは上で作成したrouterinterfaceに設定

Router Interfaceの作成

スイッチIDとアトリビュートのリストを受け取り、OIDを返す

https://github.com/opencomputeproject/SAI/blob/master/inc/sairouterinterface.h#L437

Router Interfaceのアトリビュート

ルーティングインスタンス(VR)の指定(VRFの実装で利用)対応するポートのOIDを指定

https://github.com/opencomputeproject/SAI/blob/master/inc/sairouterinterface.h#L42

Routeの作成

RouteはOIDを作らず(switch_id, vr_id, destination)のタプルをOIDの代わりに使う(経路は他のオブジェクトに比べて数が多くなるため)

Routeのアトリビュート

nexthopをOIDで指定する指定できるオブジェクトとして- NEXT_HOP- NEXT_HOP_GROUP- ROUTER_INTERFACE- PORTが指定できる

右のどれにも該当しない普通のL3経路

ECMP/複数のnexthopを同時利用する場合

connected経路

自分への経路CPUポートを指定

OSのネットワークスタックとの連携
1. EthernetASICのフロントパネルポートに対応するネットワークインターフ
ェイスの作成• PortとHost Interfaceオブジェクトを作成する

2. インターフェイスへのIPアドレスの設定• OSとEthernetASIC両者への操作が必要• RouterInterfaceとRouteオブジェクトを作成する

3. Neighborテーブル(ARP/ND)の同期
4. ルーティングプロトコルとの連携

3. Neighborテーブル(ARP/ND)の同期• EthernetASICではARPの処理は行わず、OSのARP解決の結果をEthernetASICに反映する
netlinklistenerping1

4. netlink (RTM_NEWNEIGH)

hostif

5. SAI call

KernelARP

EthernetASIC
2. ARP request

EthernetASIC
SDK

3.ARP reply

Neighbor
Table

userkernel

Neithborテーブル(ARP/ND)の同期

EthernetASICに対して必要な操作
1. ARP/NDパケットのCPU側へのコピー• SONiCではCOPP(Control Plane Policing)の一環で設定される• 本日は詳細は割愛、概要を次に説明

2. Neighborテーブルにエントリーを追加

COPPの設定ファイル

ARP_REQ/ARP_RESP/NDはCPUにコピーする設定
これらがSAIのhostif_table_entry, hostif_trap_group, hostif_trap,
policierオブジェクトの作成に変換され、EthernetASICに設定される
https://github.com/Azure/sonic-buildimage/blob/master/dockers/docker-orchagent/copp.json.j2

NeighborEntryの作成
Routeは (switch_id, vr_id, destination(prefix))だった
NeighborEntryはOIDを作らず(switch_id, rif_id,ip_address)のタプルをOIDの代わりに使う(NeighborEntryは他のオブジェクトより数が多くなるため)

https://github.com/opencomputeproject/SAI/blob/master/inc/saineighbor.h#L264

NeighborEntryのアトリビュート

あるNeighbor(IPアドレス)に対応するMACアドレス
OSがARP/ND解決を行い、その結果をASICに格納する( ASICはARP/ND処理はしない )CREATE_AND_SETなので、後から対応するMACアドレスを変更することも可能

https://github.com/opencomputeproject/SAI/blob/master/inc/saineighbor.h#L58

OSのネットワークスタックとの連携
1. EthernetASICのフロントパネルポートに対応するネットワークインターフ
ェイスの作成• PortとHost Interfaceオブジェクトを作成する

2. インターフェイスへのIPアドレスの設定• OSとEthernetASIC両者への操作が必要• RouterInterfaceとRouteオブジェクトを作成する

3. Neighborテーブル(ARP/ND)の同期• COPPを使ったARP/NDパケットのCPUへのコピー• OSにARP/ND処理を任せ、NeighborEntryオブジェクトを作成する

4. ルーティングプロトコルとの連携

4. ルーティングプロトコルとの連携• SONiCではルーティングプロトコル実装としてFRR(Quaggaのfork)を利用• FRRのFPM(Forwarding Plane Manager)という仕組みを利用し、FRRが経路をOSのFIBに注入する際に、その経路に関する通知をもらいEthernetASICに対して必要な操作を行う
bgpd

zapi

zebra

fpm EthernetASIC

SDK

netlink

hostifhostifuser

SAI callKernelEthernetASIC

FIB

nexthoptablekernelルーティングプロトコルとの連携

EthernetASICに対して必要な操作
1. Nexthopオブジェクトの作成• ECMPの場合はNexthopGroupを作りNexthopをグループ化(本日は割愛)

2. Routeオブジェクトの作成• “2. IPアドレス設定”でも作ったRouteオブジェクトだが、今回はNexthopにNexthopオブジェクトを設定する

Nexthopの作成

スイッチIDとアトリビュートのリストを受け取り、OIDを返す

Nexthopのアトリビュート

IPアドレスとRouterInterfaceのOIDでNexthopを表現する
どちらもCREATE_ONLYで変更不可。
NeighborEntryのキーは(switch_id, rif_id, ip_address)だったので、この2つの情報でEthernetASICは使うべきMACアドレスを知ることができる

OSのネットワークスタックとの連携
1. EthernetASICのフロントパネルポートに対応するネットワークインターフ
ェイスの作成• PortとHost Interfaceオブジェクトを作成する

2. インターフェイスへのIPアドレスの設定• OSとEthernetASIC両者への操作が必要• RouterInterfaceとRouteオブジェクトを作成する

3. Neighborテーブル(ARP/ND)の同期• COPPを使ったARP/NDパケットのCPUへのコピー• OSにARP/ND処理を任せ、NeighborEntryオブジェクトを作成する

4. ルーティングプロトコルとの連携• FRRのFPM機能を使って経路情報を得る• NexthopオブジェクトとRouteオブジェクトを作成する

まとめ• ホワイトボックススイッチNOSではOSのネットワークスタックとEthernetASICをどのように連携させるかが肝• SONiC/SAIによりオープンにNOSの内部実装に関する議論が出来るようになった• 実際に手を動かして触れる実装があることで、より深くネットワーク機器を理解できるようになってきている