libvirtd で作成される tap デバイスについて

#概要
libvirtd で作成される tap デバイスについてまとめてみました。
#tap デバイスについて
## wikipedia より
\# つたない訳ですがお許し下さい。。orz
\# ツッコミ大歓迎です...(震
> In computer networking, TUN and TAP are virtual-network kernel devices. Being network devices supported entirely in software, they differ from ordinary network devices which are backed up by hardware network adapters.

> TUN と TAP は仮想ネットワークのカーネルデバイスである。ハードウェアネットワークアダプタによってバックアップされている通常のネットワークデバイスと異なり、ソフトウェアで完全にサポートされているネットワークデバイスである。

> TUN (namely network TUNnel) simulates a network layer device and it operates with layer 3 packets like IP packets. TAP (namely network tap) simulates a link layer device and it operates with layer 2 packets like Ethernet frames. TUN is used with routing, while TAP is used for creating a network bridge.

> TUN(ネットワークトンネル)は、ネットワーク機器をシュミレートし、IPパケットのようにL3で動作する。
TAP(ネットワークタップ)はリンクレイヤをシュミレートし、イーサフレームのようにL2で動作する。
TAP がネットワーク・ブリッジの作成のために使用されている一方、TUN はルーティングと共に使用されます。

> Packets sent by an operating system via a TUN/TAP device are delivered to a user-space program which attaches itself to the device. A user-space program may also pass packets into a TUN/TAP device. In this case the TUN/TAP device delivers (or "injects") these packets to the operating-system network stack thus emulating their reception from an external source.

> TUN, TAP デバイスを経由して、オペレーティング·システムから送信されたパケットは、デバイスに自分自身を添付し、ユーザスペースのプログラムに配信されます。ユーザスペースプログラムは、TUN/ TAPデバイスにパケットを渡すことができます。この場合、TUN, TAP デバイスは外部ソースからそれらの受信をこのようにエミュレートし OS のネットワークスタックへ配送(あるいは注入) する。

## libvirt における tap デバイスについて
* KVM では libvirtd によって作成される仮想スイッチ(br)を介してゲストOS とホストOS が通信できるようになっている。ゲストOS -> 外部ネットワークについても必ずホストOS を介する。tap デバイスはこの仮想ブリッジに作成されるゲストOS の仮想 NIC と繋がるデバイスである。

* ということで、tap デバイスはホストOS に作成される。
	* ゲストOS を作成した際にホストOS 側に作成されている ```vnet0``` というデバイスが tap デバイスである。
	* 環境によって名前は異なります。合わせて読み替えてください。
* [参考: Stray Penguin - KVM] (http://www.asahi-net.or.jp/~aa4t-nngk/kvm.html)
	* *仮想ネットワークの構築* の図を参照のこと

## br インターフェースと tap デバイスの関係
これを見たからといって理解できるというわけではないと思いますが、私の場合色々と tap デバイスや br インターフェースについての記事や資料を読み、最終的に下記の出力を見て「あぁ、なるほど」と思えるようになりました。

```
# brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.6cf049ae192e	no		bond0
							        vnet0
br1		8000.6cf049ae192e	no		bond0.1
							        vnet1
br2		8000.6cf049ae192e	no		bond0.2
							        vnet2
```

このホストOSには事前に br0, br1, br2 を作成済みでゲストOSが1台稼働しているという状況です。
br0 には bond0 , vnet0 が所属していることがわかります。
br1, br2 も同様ですね。

ゲストOS の eth0 は tap デバイスである vnet0 と紐付いていて、vnet0 は br0 に接続している。
bond0 も同様であることからゲストOS から外部への通信は　
```ゲストOS eth0 → vnet0(tapデバイス) → br0 → bond0 → eth0 → 外部``` 
という順で経由していることが分かります。

参考までに bond0 , eth0 の設定を載せておきます。

```bash:/etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE="bond0"
BOOTPROTO="static"
ONBOOT="yes"
BONDING_OPTS="mode=1 miimon=200"
BRIDGE="br0"
TYPE="Ethernet"
```

```bash:/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="static"
ONBOOT="yes"
MASTER="bond0"
SLAVE="yes"
```

```ゲストOS eth0 → vnet0(tapデバイス)``` ここの対応はどうなっているんだという疑問もあるかと思うので ```virsh edit hostname```  で設定を覗いて見ます。

```
    <interface type='bridge'>
      <mac address='52:54:00:6e:64:cd'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <interface type='bridge'>
      <mac address='52:54:00:3d:3f:e1'/>
      <source bridge='br1'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </interface>
    <interface type='bridge'>
      <mac address='52:54:00:27:c2:4b'/>
      <source bridge='br2'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </interface>
```
注目するべきは、```<source bridge=``` です。この項目でこのゲストOS がどの br I/F と紐づくかが定義されます。

ここまでで、```ゲストOS eth0 → vnet0(tapデバイス) → br0 → bond0 → eth0 → 外部``` の流れがはっきりとしたはず。。

以上、備忘録です。
\# 文字ばかりの説明ですが誰かのためになれば幸いです。