仮想マシンを外部ネットワークへ接続させる方法はいくつかあるみたいです。

NATモード
初期状態だとこのモードです。仮想マシンはIPマスカレードされてホストのIPアドレスとして外へ出ていきます。外から仮想マシンへはアクセスするときは、一工夫必要になります。
Routedモード
ホストがルータとして動作します。仮想マシンは自身のIPアドレスで外へ出ていきます。外から仮想マシンへアクセスするときは、なんらかのルーティングが必要になります。
ブリッジ
libvirtの外側で設定されたブリッジデバイスに仮想マシンを接続します。
ダイレクト-ブリッジ
macvtapのbridgeモードを利用して直接ホストネットワークへ接続します。 @takehironet さんに教えてもらいました。Thanks :smile: 同一ホスト上の仮想マシン同士でやりとりする場合は、両方とも同じモードである必要があります。
ダイレクト-プライベート
macvtapのprivateモードを利用して直接ホストネットワークへ接続します。
ダイレクト-vepa
macvtapのvepaモードを利用して直接ホストネットワークへ接続します。vepa(Virtual Ethernet Port Aggregator)が使えるスイッチがないと使えません。
ダイレクト-パススルー
macvtapを利用して直接ホストネットワークへ接続します。物理インターフェースは一度に一つの仮装インターフェースからしか使えません。物理インターフェースに空きがないときはエラーが記録されます。
ホストデバイス
PCIネットワークデバイスを仮想マシンへ直接割り当てます。

ここではブリッジとダイレクト-プライベート、そしてダイレクト-ブリッジを試してみます。

やり方その1「ブリッジ」接続するときの作業手順

ここでは、物理デバイス名は「ens32」です。

(ステップ1) ブリッジコネクションを作成

「br0」というインターフェースに対してブリッジコネクションを作成します。

# nmcli con add type bridge ifname br0
Connection 'bridge-br0' (2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd) successfully added.

こんなんできました。

# nmcli con show
NAME        UUID                                  TYPE            DEVICE
vnet0       66568803-1d59-4dcf-b241-ff6cab294715  generic         vnet0
ens32       461d3edc-1e6e-4334-b8dc-1ff3d691c03e  802-3-ethernet  ens32
virbr0-nic  8d33a0ef-019a-4ce1-a8e8-71dc0c9bbe1e  generic         virbr0-nic
virbr0      4094d785-3de6-4acc-86bb-64cafc4d3deb  bridge          virbr0
bridge-br0  2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd  bridge          br0
# nmcli dev
DEVICE      TYPE      STATE                                  CONNECTION
virbr0      bridge    connected                              virbr0
ens32       ethernet  connected                              ens32
virbr0-nic  tap       connected                              virbr0-nic
vnet0       tap       connected                              vnet0
br0         bridge    connecting (getting IP configuration)  bridge-br0
lo          loopback  unmanaged                              --

(ステップ2) ブリッジスレーブコネクションを作成

「bridge-br0」コネクションをマスターとして、「ens32」インターフェースをスレーブとするコネクションを作成します。

# nmcli con add type bridge-slave ifname ens32 master bridge-br0
Connection 'bridge-slave-ens32' (59ea6a01-af71-4f55-8433-eb7c49117578) successfully added.

こんなんできました。

# nmcli con
NAME                UUID                                  TYPE            DEVICE
bridge-slave-ens32  59ea6a01-af71-4f55-8433-eb7c49117578  802-3-ethernet  --    
vnet0               66568803-1d59-4dcf-b241-ff6cab294715  generic         vnet0 
ens32               461d3edc-1e6e-4334-b8dc-1ff3d691c03e  802-3-ethernet  ens32 
virbr0-nic          8d33a0ef-019a-4ce1-a8e8-71dc0c9bbe1e  generic         virbr0-nic
virbr0              4094d785-3de6-4acc-86bb-64cafc4d3deb  bridge          virbr0
bridge-br0          2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd  bridge          br0
# nmcli dev
DEVICE      TYPE      STATE                                  CONNECTION
virbr0      bridge    connected                              virbr0
ens32       ethernet  connected                              ens32
virbr0-nic  tap       connected                              virbr0-nic
vnet0       tap       connected                              vnet0
br0         bridge    connecting (getting IP configuration)  bridge-br0
lo          loopback  unmanaged                              --

(ステップ3) 既存コネクションを削除して再起動

ネットワーク接続が切れてしまうので、すかさず再起動してます。

# nmcli con delete ens32 && reboot
Connection 'ens32' (461d3edc-1e6e-4334-b8dc-1ff3d691c03e) successfully deleted.

うまくいけばこんな結果に。

# nmcli con
NAME                UUID                                  TYPE            DEVICE
virbr0              89597488-c27c-4038-aeb9-ab426c19cfbe  bridge          virbr0
bridge-br0          2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd  bridge          br0   
bridge-slave-ens32  59ea6a01-af71-4f55-8433-eb7c49117578  802-3-ethernet  ens32 
virbr0-nic          9125d953-43f0-44c1-90a1-91db218a27b5  generic         virbr0-nic
# nmcli dev
DEVICE      TYPE      STATE      CONNECTION
br0         bridge    connected  bridge-br0
virbr0      bridge    connected  virbr0
ens32       ethernet  connected  bridge-slave-ens32
virbr0-nic  tap       connected  virbr0-nic
lo          loopback  unmanaged  --
# ip addr show br0
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 10:78:d2:e3:56:12 brd ff:ff:ff:ff:ff:ff
    inet 172.27.51.121/24 brd 172.27.51.255 scope global dynamic br0
       valid_lft 690988sec preferred_lft 690988sec
    inet6 fe80::1278:d2ff:fee3:5612/64 scope link
       valid_lft forever preferred_lft forever

(ステップ4) libvirtのネットワーク設定を作成

こんな内容のXMLファイルを作成します。

host-bridge.xml

<network>
  <name>host-bridge</name>
  <forward mode="bridge" />
  <bridge name="br0"/>
</network>

XMLの書式についてはこちら → http://libvirt.org/formatnetwork.html

virshコマンドで読み込みます。

# virsh net-define --file host-bridge.xml
Network host-bridge defined from host-bridge.xml

自動開始するようにします。

# virsh net-autostart host-bridge
Network host-bridge marked as autostarted

こんなんできました。

# virsh net-list --all
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     yes           yes
 host-bridge          inactive   yes           yes

(ステップ5) 既存仮想マシンのネットワーク接続を変更

<interface type='network'>要素中身を変更します。

変更前

      <source network='default'/>

変更後

      <source network='host-bridge'/>

やり方その2「プライベート」接続するときの作業手順

(ステップ1) macvtapリンクを作成

# ip link add link ens32 name macvtap0 type macvtap mode private

状態がDOWNになっているので上げます。

# ip link set macvtap0 up

こんなんできました。

23: macvtap0@ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500
    link/ether 7e:f3:46:9c:f0:c1 brd ff:ff:ff:ff:ff:ff

(ステップ2) libvirtのネットワーク設定を作成

こんな内容のXMLファイルを作成します。

net-private.xml

<network>
  <name>vtap</name>
  <forward mode="private">
    <interface dev="macvtap0" />
  </forward>
</network>

virshコマンドで読み込みます。

# virsh net-define --file net-private.xml
Network vtap defined from net-private.xml

自動開始するようにします。

# virsh net-autostart vtap
Network vtap marked as autostarted

こんなんできました。

# virsh net-list --all
 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     yes           yes
 vtap                 inactive   yes           yes

(ステップ3) 既存仮想マシンのネットワーク接続を変更

<interface type='network'>要素の中身を変更します。

変更前

      <source network='default'/>

変更後

      <source network='vtap'/>

落穂拾(えない)

この方法だとホスト-VM間の通信ができません。VMにホストと通信するための別NICを追加する等の解決策があります。

作成したmacvtap0は再起動すると消えてしまいます。永続化の方法模索中。。。

やり方その3 「ダイレクト-ブリッジ」接続するときの作業手順

ここでは、物理デバイス名は「ens32」です。

既存仮想マシンのネットワーク接続を変更

<interface type='network'>要素の中身を変更します。

変更前

      <source network='default'/>

変更後

      <source dev='ens32' mode='bridge'/>

新規インストール時にvirt-installで指定する場合

ネットワークのオプションを次のようにします。

--network type=direct,source=ens32,source_mode=bridge

source_modeを指定しないと、デフォルトのvepaになります。

参考情報