SONiCが動きそうで動かないスイッチを動かした話

# このスイッチでSONiC動きますか?
ホワイトボックススイッチは端的に言えばパケット転送用ハードウェアをPCIeスロットにぶっさしたPCのようなもの、といえる。形状が1Uラックマウントで正面にたくさんのLANポートが並んでいるため、外観はPCとはかけ離れているし、実際利用する段になるとPC的な使われ方をするのは珍しい。

このホワイトボックススイッチだが、実際のところいろんなスイッチベンダーからいろんなモデルが発売されていて、その中のごく一部はAmazonやNTT-X Storeから個人で購入することも不可能ではない。ずばり買えると書かなかったのは単純に価格の問題である。売ってるからと言って80万円とか100万円とかポンと出せる人はなかなかいないだろう。(さっき割引後価格だけど[35万円のホワイトボックススイッチ](https://www.dell.com/ja-jp/work/shop/%E8%A3%BD%E5%93%81%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%8A%E3%83%83%E3%83%97/s%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-25g%E5%AF%BE%E5%BF%9Csfp28-12%E3%83%9D%E3%83%BC%E3%83%88-l3%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81-s5212f-on/spd/networking-s-series-25-100gbe/s5212fn0201jp)を見つけて少し動揺している)

SONiCはホワイトボックススイッチで動作するOSだが、どのスイッチに入れても動くというわけではない。幸い、公式から[対応しているデバイス・プラットフォームの一覧](https://github.com/Azure/SONiC/wiki/Supported-Devices-and-Platforms)が公開されている。ここに載ってれば動くよ! と言いたいところなのだが、実は動かないスイッチが載っている。正確には、対応する設定ファイルが用意されそれに基づいてインストールイメージが作成されていて、実際インストールできるし起動もするけれど、パケット転送機能が動作しないスイッチがあるのだ。

# 表に載っているのに動かない経緯
自分の知る限り、少なくとも表に載っている中で2つのスイッチはそのままでは動作しない。
- Accton [AS7326-56X](https://www.edge-core.com/productsInfo.php?cls=1&cls2=154&cls3=155&id=544)
- Accton [AS7726-32X](https://www.edge-core.com/productsInfo.php?cls=1&cls2=5&cls3=15&id=545)
これらはいずれも、スイッチASICとしてBroadcom Trident3を採用している。

Accton以外にもTrident3を採用しているスイッチはいくつかあり、例えば
- DELL EMC S5232F-ON
- Delta AG9032v2a
これらについては、表に記載されていて、かつパケット転送動作を確認できている。この差はどこからきているのだろうか。

答えを先に書いてしまうと、BroadcomのスイッチASICの基本設定を記述するconfig.bcmというファイルがあるのだが、Acctonの2モデルはこのファイルの内容に不足があり、またファイルのパスを正しく指定していないため、Trident3の初期化ができていないことが原因である。

ただし、これは単なるAcctonのミスというわけではない。時系列を追って説明する。
1. 前提としてconfig.bcmに記述できるキーワードには制限があり、自由に制限を緩めることはできない。ASICベンダーであるBroadcomから了解を得る必要がある。
2. Acctonが対応コードとconfig.bcmをPRする。config.bcmに関して、Trident3を動作させるのに必要なキーワードは書けない(書くとビルドに失敗する)ため、それを省いた差分となっている。
3. AcctonのPRがマージされる。
4. DELL EMC S5232F-ON対応コードがcommitされる。config.bcmにはTrident3に必要な設定が含まれている。このときconfig.bcm用キーワードにも追加があり、またBroadcom SAIもTrident3対応のものに更新されたため、S5232F-ONではこの時点で問題なく動作している。
5. Delta AG9032v2a対応コードがcommitされる。こちらのconfig.bcmにもTrident3の動作に必要なキーワードが加えられていた。こちらも問題なく動作している。
6. 現在に至る。

つまるところ、Acctonは対応が早すぎたのだ。

# 動かすには?
config.bcmの中身に設定を追加し、そのファイルを参照するようsai.profileの中身を書き換えればよい。AS7326-56XおよびAS7726-32Xの対応差分が下記である。ソースコードをcloneしてパッチを当てるもよし、変更内容をなぞってインストール済みのSONiCの設定ファイルを書き換えるもよし。思想や感情を創作的に表現したものじゃないので著作権フリーでどうぞ。

なお、sai.profileの中に書くパスはSONiCにログインしても見えない。syncd dockerの中で参照するパスとなっている。

```diff
diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile
index 0e465ce1..47e31074 100644
--- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile
+++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/sai.profile
@@ -1 +1 @@
-SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7326-48x25G+8x100G.config.bcm
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm
diff --git a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm
index 2b7b6fb0..35a79836 100755
--- a/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm
+++ b/device/accton/x86_64-accton_as7326_56x-r0/Accton-AS7326-56X/td3-as7326-48x25G+8x100G.config.bcm
@@ -30,6 +30,9 @@ tdma_timeout_usec=3000000
 skip_L2_USER_ENTRY=0
 bcm_tunnel_term_compatible_mode=1

+ifp_inports_support_enable=1
+port_flex_enable=1
+
 dport_map_port_1=6
 dport_map_port_2=2
 dport_map_port_3=1
diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile
index 46f5cb3b..461cdd76 100644
--- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile
+++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/sai.profile
@@ -1 +1 @@
-SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7726-32x100G.config.bcm
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7726-32x100G.config.bcm
diff --git a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm
index 16cbb8d3..2fe2c1d3 100755
--- a/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm
+++ b/device/accton/x86_64-accton_as7726_32x-r0/Accton-AS7726-32X/td3-as7726-32x100G.config.bcm
@@ -33,6 +33,9 @@ bcm_tunnel_term_compatible_mode=1

 phy_an_c73=1

+ifp_inports_support_enable=1
+port_flex_enable=1
+
 dport_map_port_1=1
 dport_map_port_5=2
 dport_map_port_9=3
```
なお、config.bcmへの追加内容については[PR#2482](https://github.com/Azure/sonic-buildimage/pull/2482)を参考にしている。

# 終わりに
わかってしまえば数行いじくるだけではあるが、動かないときはログにも`not supported`などと出るだけでしばらくのあいだ原因がわからず、ずっと頭を抱えていたことを思い出す。自力で解決できたのは偶々であり、このレイヤーについては基本的にスイッチベンダーが対応すべきものだと考える。