NetworkManagerからOpen vSwitchを作成する

Open vSwitchを作成する時は、ovsコマンドを使用することが一般的だと思いますが、NetworkManagerが稼働している環境だとNetworkManagerから全部設定したいなあと思うことがあります。
というのも、ovsコマンドから作成したinterfaceにIPを設定するためには、NetworkManagerからでなく別途ifcfgファイルを手動で作成して適用する必要があるからです。(私の知見不足で他に方法があるかもしれませんが) よって、nmcliからovsの作成・設定をする方法を調べたのでメモとして残しておきます。

インストール

nmcliからovsを作成するには、openvswitchの他に、NetworkManager-ovsをインストールする必要があります。
※openvswitchは既にinstall済み

dnf install NetworkManager-ovs

インストール後、NetworkManagerを再起動します。再起動しないと私の環境では正常に動作しませんでした。

systemctl restart NetworkManager

設定

NetworkManagerからovsを作成する場合、bridge, port, interfaceをそれぞれ作成しなければなりません。
ovs-vsctlコマンドとは異なり、自動的には作成してもらえないようです。
最初に、bridge作成します。

nmcli con add type ovs-bridge ifname br-data

次に、port, interfaceを作成します。 masterは、portの場合はbridge名、interfaceの場合は、port名を入力します。
全部同じ名前でもいいですが、紛らわしかったので今回はport名だけ変更しました。
また、interfaceを作成する際に、IPの無効化の設定をしています。
この設定をしないと、接続プロファイルがactiveにならないので、しばらくすると自動的にovsがdownします。

nmcli con add type ovs-port ifname br-data-p01 master br-data
nmcli con add type ovs-interface slave-type ovs-port ifname br-data master br-data-p01 \
 ipv4.method disabled \
 ipv6.method disabled

IPを設定する場合は下記のように設定します。
tag設定する場合は、ovs-port.tag のように記載します。

nmcli con add type ovs-port ifname ovs-vlan10 master br-data ovs-port.tag 10
nmcli con add type ovs-interface slave-type ovs-port ifname vlan10 master ovs-vlan10 \
 ipv4.method manual ipv4.address 192.168.10.1/24 \
 ipv4.gateway 192.168.10.254 \
 ipv4.dns 8.8.8.8 \
 ipv4.never-default no \
 ipv6.method disabled

nmcli con add type ovs-port ifname ovs-vlan20 master br-data ovs-port.tag 20
nmcli con add type ovs-interface slave-type ovs-port ifname vlan20 master ovs-vlan20 \
 ipv4.method manual ipv4.address 192.168.20.1/24 \
 ipv4.gateway 192.168.20.254 \
 ipv4.never-default yes \
 ipv6.method disabled

最後に、物理IFをovs-interfaceとしてbridgeに組み込みます。
この際にportも作成する必要があります。 下記例では、ovs-port.vlan-mode <vlan-mode名> でportに設定するvlan-modeをnative-untaggedに変更しています。
併せてtag 20を設定しているので、tag無pktを受信すると、vlan20のpktとして扱うという動きになります。 (送信時もtagを付けない)

nmcli con add type ovs-port ifname ovs-ens19 master br-data \
 ovs-port.vlan-mode native-untagged \
 ovs-port.tag 20
nmcli con add type ethernet ifname ens19 master ovs-ens19

これで 設定ができたので、確認してみます。
まずは、openvswitchから見てみます。

[root@test ~]# ovs-vsctl show
02cadfc2-10dd-441b-8fa7-ed1861a84a4d
    Bridge br-data
        Port ovs-vlan10
            tag: 10
            Interface vlan10
                type: internal
        Port ovs-vlan20
            tag: 20
            Interface vlan20
                type: internal
        Port br-data-p01
            Interface br-data
                type: internal
        Port ovs-ens19
            tag: 20
            Interface ens19
                type: system
    ovs_version: "2.15.3"

[root@test ~]# ovs-vsctl list port ovs-ens19
_uuid               : adc42cb6-aa53-4efd-ab6e-e2de791fa075
bond_active_slave   : []
bond_downdelay      : 0
bond_fake_iface     : false
bond_mode           : []
bond_updelay        : 0
cvlans              : []
external_ids        : {NM.connection.uuid="5a3bc8ff-b87b-451d-a4c8-05b8c8736570"}
fake_bridge         : false
interfaces          : [de7bfab3-b883-4b76-89fe-2014179f8eff]
lacp                : []
mac                 : []
name                : ovs-ens19
other_config        : {}
protected           : false
qos                 : []
rstp_statistics     : {}
rstp_status         : {}
statistics          : {}
status              : {}
tag                 : 20
trunks              : []
vlan_mode           : native-untagged

正常に作成されているようです。

次にnmcliの接続プロファイル とデバイスを見てみます。
作成時にcon-name でプロファイル名を指定していないので、少し分かり難いですね。

[root@test ~]# nmcli con show --active
NAME                   UUID                                  TYPE           DEVICE
ovs-slave-vlan10       2b96a544-042e-4b08-b83d-a967c8ff8a85  ovs-interface  vlan10
ovs-slave-vlan20       08bf6c74-931f-4a49-b292-eaf3e92c4043  ovs-interface  vlan20
ovs-bridge-br-data     02cfc6ed-7642-4355-9d11-92505aa84fa0  ovs-bridge     br-data
ovs-slave-br-data      95a93f76-4bca-4062-812a-d1d357b72a97  ovs-interface  br-data
ovs-slave-br-data-p01  15d1690e-6df4-4a1f-b0b4-391ba9fd4ca9  ovs-port       br-data-p01
ovs-slave-ens19        80e4dcaa-a75b-4108-8063-52699eeccc44  ethernet       ens19
ovs-slave-ovs-ens19    5a3bc8ff-b87b-451d-a4c8-05b8c8736570  ovs-port       ovs-ens19
ovs-slave-ovs-vlan10   3c9f7b44-9272-4520-b7bc-f51e1428daa7  ovs-port       ovs-vlan10
ovs-slave-ovs-vlan20   101c0c92-577a-466a-8777-a2eb16ffe714  ovs-port       ovs-vlan20

[root@test ~]# nmcli dev
DEVICE       TYPE           STATE                   CONNECTION
vlan10       ovs-interface  connected               ovs-slave-vlan10
vlan20       ovs-interface  connected               ovs-slave-vlan20
ens19        ethernet       connected               ovs-slave-ens19
br-data      ovs-bridge     connected               ovs-bridge-br-data
br-data      ovs-interface  connected               ovs-slave-br-data
br-data-p01  ovs-port       connected               ovs-slave-br-data-p01
ovs-ens19    ovs-port       connected               ovs-slave-ovs-ens19
ovs-vlan10   ovs-port       connected               ovs-slave-ovs-vlan10
ovs-vlan20   ovs-port       connected               ovs-slave-ovs-vlan20
lo           loopback       unmanaged               --

最後にデバイスの状態とルート情報を確認します。

[root@test ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master ovs-system state UP group default qlen 1000
    link/ether 5e:51:07:e8:5e:77 brd ff:ff:ff:ff:ff:ff
17: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ce:ec:57:ab:6c:ec brd ff:ff:ff:ff:ff:ff
18: br-data: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 12:4b:c8:a3:f0:4a brd ff:ff:ff:ff:ff:ff
19: vlan10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 72:e9:5a:79:65:55 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.1/24 brd 192.168.10.255 scope global noprefixroute vlan10
       valid_lft forever preferred_lft forever
20: vlan20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 4e:e4:59:08:94:3e brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.1/24 brd 192.168.20.255 scope global noprefixroute vlan20
       valid_lft forever preferred_lft forever

[root@test ~]# ip r
default via 192.168.10.254 dev vlan10 proto static metric 801
192.168.10.0/24 dev vlan10 proto kernel scope link src 192.168.10.1 metric 801
192.168.20.0/24 dev vlan20 proto kernel scope link src 192.168.20.1 metric 802

問題ないようですね。
疎通確認は面倒臭いので省略します。
今回は上手くできましたが、下記参考文献にある通りovsの機能を全てサポートしているわけではないようなので、使用する機能が対応しているか事前に確認する必要がありそうです。

参考文献

https://manpages.debian.org/testing/network-manager/nm-settings.5.en.html#ovs-port_setting
https://manpages.debian.org/testing/openvswitch-common/ovs-vsctl.8.en.html
https://man.archlinux.org/man/extra/networkmanager/nm-openvswitch.7.en
http://www.openvswitch.org//ovs-vswitchd.conf.db.5.pdf