対象とするNICを以下で定義

export NIC=enp130s0f0

 

NICのEEPROM内の設定変更を行い、SR-IOVの有効化、最大VF数の決定を行う

MFT TOOLが必要なので、以下のページで取得。

https://www.mellanox.com/products/adapter-software/firmware-tools

 

firmwareサービスの起動

mst start

 

ステータス取得

[root@localhost ~]# mst status -v
MST modules:
------------
    MST PCI module loaded
    MST PCI configuration module loaded
PCI devices:
------------
DEVICE_TYPE             MST                           PCI       RDMA            NET                       NUMA  
ConnectX5(rev:0)        /dev/mst/mt4119_pciconf0.1    82:00.1   mlx5_1          net-enp130s0f1            1     

ConnectX5(rev:0)        /dev/mst/mt4119_pciconf0      82:00.0   mlx5_0,mlx5_4,mlx5_5net-enp130s0f0            1     

ConnectX4(rev:0)        /dev/mst/mt4115_pciconf0.1    83:00.1   mlx5_3          net-enp131s0f1            1     

ConnectX4(rev:0)        /dev/mst/mt4115_pciconf0      83:00.0   mlx5_2          net-enp131s0f0            1     

ConnectX3(rev:1)        /dev/mst/mt4099_pciconf0      
ConnectX3(rev:1)        /dev/mst/mt4099_pci_cr0       07:00.0   mlx4_0          net-enp7s0d1,net-enp7s0   0     
 

使用するNICを決定して、そのMSTデバイス名を確認する。今回はCOnnectX-5を使う予定なので、デバイス名は/dev/mst/mt4119_pciconf0

 

設定値確認

mlxconfig -d /dev/mst/mt4119_pciconf0 q | grep NUM_OF_VFS

          NUM_OF_VFS                          0
mlxconfig -d /dev/mst/mt4119_pciconf0 q | grep SRIOV_EN

          SRIOV_EN                            False(0)

 

設定

mlxconfig -d /dev/mst/mt4119_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=2

反映のため再起動

reboot

ここまでは、一回やればOK.

 

次からの手順は、起動毎に実行する必要がある。

 

VF数を決定

export NIC=enp130s0f0

echo 2 > /sys/class/net/${NIC}/device/sriov_numvfs

 

以下の3行をコピペして、VFが出現していることを確認。

export NIC_PCI=`mst status -v | grep ${NIC} | tr -s " " | cut -f 3 -d " "`

export NIC_PCI_DEV=`echo ${NIC_PCI} | cut -f 1 -d "."`

lspci | grep ${NIC_PCI_DEV} | grep "Virtual Function"
 

結果

82:00.2 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]
82:00.3 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]

COnnectX-5のeswitchデバイスの設定値をswitchdevに変更する。

echo 0000:82:00.2 > /sys/bus/pci/drivers/mlx5_core/unbind
echo 0000:82:00.3 > /sys/bus/pci/drivers/mlx5_core/unbind
devlink dev eswitch set pci/0000:${NIC_PCI} mode switchdev
ethtool -K ${NIC} hw-tc-offload on
echo 0000:82:00.2 > /sys/bus/pci/drivers/mlx5_core/bind
echo 0000:82:00.3 > /sys/bus/pci/drivers/mlx5_core/bind

 

上のコマンドをもう少し一般化すると、以下のようになる。

lspci | grep ${NIC_PCI_DEV} | grep "Virtual Function" | cut -f 1 -d " " | sed -e "s/.*/echo 0000:& > \/sys\/bus\/pci\/drivers\/mlx5_core\/unbind/e"

devlink dev eswitch set pci/0000:${NIC_PCI} mode switchdev
ethtool -K ${NIC} hw-tc-offload on

 

lspci | grep ${NIC_PCI_DEV} | grep "Virtual Function" | cut -f 1 -d " " | sed -e "s/.*/echo 0000:& > \/sys\/bus\/pci\/drivers\/mlx5_core\/bind/e"

 

 

 

VFにMACアドレスを設定

 

ip link set ${NIC} vf 0 mac e4:11:22:33:44:50
ip link set ${NIC} vf 1 mac e4:11:22:33:44:51

 

一旦EEPROMの内容を書き換えてSR-IOVを有効化したら、次の再起動からは以下のコピペでとりあえずOK。

export NIC=enp130s0f0

echo 2 > /sys/class/net/${NIC}/device/sriov_numvfs

export NIC_PCI=`mst status -v | grep ${NIC} | tr -s " " | cut -f 3 -d " "`

export NIC_PCI_DEV=`echo ${NIC_PCI} | cut -f 1 -d "."`

lspci | grep ${NIC_PCI_DEV} | grep "Virtual Function" | cut -f 1 -d " " | sed -e "s/.*/echo 0000:& > \/sys\/bus\/pci\/drivers\/mlx5_core\/unbind/e"

devlink dev eswitch set pci/0000:${NIC_PCI} mode switchdev
ethtool -K ${NIC} hw-tc-offload on

lspci | grep ${NIC_PCI_DEV} | grep "Virtual Function" | cut -f 1 -d " " | sed -e "s/.*/echo 0000:& > \/sys\/bus\/pci\/drivers\/mlx5_core\/bind/e"

これすると、VFのRepresenterであるethxが出現する。この場合VFが2つなので、eth0、eth1が出てきた。

それらを使用して、BridgeなりOVSなりにRepresenterを放り込んであげると、SR-IOVで接続された仮想マシンとの通信を接続してあげることができます。

 

次はハードウェアオフロード。

 

VMを2つ作成し、以下のようにPCIデバイスを追加する設定を行う。それぞれ、0000:82:00:2と0000:82:00:3を設定する。

VMはCentOS7.6を使用してインストールした。

VFを設定すると、NICとして認識されるので、IPアドレスを付与してとりあえず放置。

 

open vSwitchを起動する

 

バージョン2.12.0をダウンロードし、ビルド(手順割愛)

そして起動。

export PATH=$PATH:$HOME/bin:/usr/share/openvswitch/scripts
ovs-ctl --system-id=random start

 

オフロード設定

ovs-vsctl set Open_vSwitch . other_config:hw-offload=true other_config:tc-policy=none

 

export NIC=enp130s0f0

ovs-vsctl --may-exist add-br ovsbr

ovs-vsctl --may-exist add-port ovsbr eth0

ovs-vsctl --may-exist add-port ovsbr eth1

ovs-vsctl --may-exist add-port ovsbr ${NIC}

 

[root@localhost ~]# ovs-vsctl show
53c81b57-a23f-485d-aee5-54d43e04d417
    Bridge ovsbr
        Port "eth0"
            Interface "eth0"
        Port "eth1"
            Interface "eth1"
        Port "enp130s0f0"
            Interface "enp130s0f0"
        Port ovsbr
            Interface ovsbr
                type: internal
    ovs_version: "2.12.0"
 

この状態で、VM同士が通信し始めると思います。

 

ここでオフロードの試験を行います。

使うのはまずPINGです。

 

本当にオフロードしているのか?一番わかり易いのは、PINGの一発目だけがovsbrインタフェースにtcpdumpで確認できますが、次からはNICのハードウェアが転送を行うためtcpdumpに現れなくなります。動画を撮って、Youtubeにあげていますので、見てください。

 

PING

 

iperf3