...
Intel ixgbe系NICにおいては、10G SFP+を使用するにあたり、ドライバ内でSFP+のベンダーコード(OUI)を確認し、ホワイトリストに載っていないSFP+が挿入されている場合にエラーを出力し、NICのポートをドライバの再読込が実施されるまで無効にするロジックが実装されている。が挿入されている場合にエラーを出力し、ドライバの再読込が実施されるまでNICのポートを無効にするロジックが実装されている。
このロジックを回避する方法として、ドライバのオプションに"allow_unsupported_sfp=1"を渡すというものがあるが、これはあくまでLinux等ドライバオプションを指定できるOS上でしか使用することができず、Windows等においてはSFP+のベンダーロックを回避することは困難である。
...
以下にLinux用ixgbeドライバにおけるSFP+ベンダーロックのロジック概要を記載する。
SFP+ベンダーロックの実装は、ixgbeベンダーロック機構は、ixgbe_phy.cのixgbe_identify_sfp_module_generic関数内で実装されている。
...
- SFP/SFP+のEEPROMを取得し、サポート対象外のSFP/SFP+でないことを確認する
- サポートされるOpticsはチップごとに異なるためここには記載しないが、必要に応じてコードを確認のこと
- 10G DACの場合、ベンダーによらずすべてのOpticsを許可する
- 1G SFPのうち、サポート指定ないものが挿入されている場合はエラーとするSFPのうち、サポートしていないものが挿入されている場合はエラーとする
- 82598EBベースのNICの場合、OpticsのベンダーによらずすべてのOpticsを許可する
- NICのEEPROM内に記録されているDEVICE_CAPS(Device Capabilities)を確認し、"IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP" (0x01)のフラグが立っていない場合、以下のチェックを実行する。
- 1G SFPの場合、ベンダーによらずサポートしている種類のトランシーバであれば許可する
- 10G SFP+の場合、SFP+のベンダーコードがIntelのものであれば許可する
- SFP+のベンダーコードがIntelでない場合、ドライバの"allow_unsupported_sfp"オプションを確認し、有効であれば警告メッセージを表示した上で許可する
- 上記の条件にマッチしない場合、エラーとする
- IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP (0x01)のフラグが立っている場合、すべてのトランシーバを許可する
...
また、ixgbe_type.h内のIXGBE_DEVICE_CAPS_ALLOW_ANY_SFP定数によると、このフラグは0x01、すなわち最下位ビットであることがわかる。によると、このフラグは0x01とのANDで取り出されており、すなわち最下位ビットであることがわかる。
IXGBE_DEVICE_CAPSは2bytesの長さをもつが、EEPROM上ではリトルエンディアンで格納されているため、バイト単位でみるとEEPROMの0x58番地の最下位ビットがこのフラグになる。
...
上記の例では、IXGBE_DEVICE_CAPS(の下位バイト)として0xFE(0b11111110)が記録されており、IXGBE_DEVICE_CAPS_ALLOW_ANY_SFPのビットは立っていないことがわかる。この値を0xFF(0b11111111)に書き換えることができれば、SFP+のベンダーロックを根本的に回避できることになる。のベンダーロックを根本的に回避できることになる。なお、この値はNICの種類等によって内容が異なる可能性があるため、必ず自身の環境において値を確認することを推奨する。
ethtoolコマンドでは、-Eオプションを使用することでNICのEEPROMを書き換えることが可能となっている。
...
Linuxにおいては、IXGBE_DEVICE_CAPSはSFPのチェックを実行するたびに読み込まれるため、書き換えを完了したら動作に即時反映され、無事にSFP+のベンダーロックを回避することができる。この変更は永続的なものとなり、Windows等ドライバのオプションでは回避が難しいOS上においても動作するものと考えられる。
なお、デュアルポートNIC等では複数のポートが認識されるが、1つのポートに対して書き換えを実施すればすべてのポートで変更が有効となる。
確認
筆者の環境において上記手法を用いた際のログを以下に記載する。
$ sudo ethtool -e eth1 offset 0x58 length 1
Offset Values
------ ------
0x0058: fe
>>> SFP+の抜挿
$ dmesg | tail -n 2
[ 2790.220891] ixgbe 0000:0a:00.0 eth1: WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.
[ 2790.220896] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
$ sudo ethtool -E eth1 magic 0x15c48086 offset 0x58 value 0xff
$ sudo ethtool -e eth1 offset 0x58 length 1
Offset Values
------ ------
0x0058: ff
>>> SFP+の抜挿
$ dmesg | tail -n 2
[ 2790.220896] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
[ 3097.967617] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
IXGBE_DEVICE_CAPSの最下位ビット(IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)が0の際はWARNINGとしてOpticsがサポートされていない旨が出力されているが、IXGBE_DEVICE_CAPSの最下位ビット(IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)を1にすることでWARNINGの出力がなくなっていることがわかる。(筆者の環境においてはallow_unsupported_sfpが有効になっているためWARNINGメッセージの出力にとどまっているが、allow_unsupported_sfpが無効の場合はNICのポートの動作が停止する)