ovs-tcpdumpでOpen vSwitchをお手軽packet capture

#はじめに
OpenStack環境で色々テストしていると頻繁にOpen vSwitchでmirror portを切りたくなりますが
ovs-vsctl set でmirrorの登録をしようとするとコマンドが長すぎて鳥頭では覚えきれません。

解説してくださっている方のサイトに行って毎回コピペ&修正していましたがovs-tcpdumpを使えば簡単にキャプチャが出来るのでご紹介したいと思います。


#環境条件
- OS: ubuntu 16.04
- ovs ver: 2.6.1


# 作業手順
ovs-vsctl show なり ovs-vsctl list-ports *bridge-name*なりでmirrorしたいport名を確認

```
# ovs-vsctl show
<<省略>>
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "qvo57f459bb-44"
            tag: 6
            Interface "qvo57f459bb-44"
<<省略>>
```

ovs-tcpdumpでキャプチャ実施

```
# ovs-tcpdump -i qvo57f459bb-44
ERROR: Please create an interface called `miqvo57f459bb-44`
See your OS guide for how to do this.
Ex: ip link add miqvo57f459bb-44 type veth peer name miqvo57f459bb-442
#
```

はい、errorになりました...
mirror portとして作成しようとしたport名が長すぎて失敗しているので--mirror-toオプションで適当なport名を指定してあげます。

```
# ovs-tcpdump -i qvo57f459bb-44 --mirror-to hoge
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hoge, link-type EN10MB (Ethernet), capture size 262144 bytes
23:25:26.429571 IP6 :: > ff02::1:ff16:28f4: ICMP6, neighbor solicitation, who has fe80::10ee:8fff:fe16:28f4, length 24

23:25:26.437448 IP6 :: > ff02::16: HBH ICMP6, multicast listener report v2, 1 group record(s), length 28

23:25:27.429494 IP6 fe80::10ee:8fff:fe16:28f4 > ff02::16: HBH ICMP6, multicast listener report v2, 1 group record(s), length 28
```
無事キャプチャが出来ました。これなら調べなくてもその場でコマンド打てますね。
ちなみにファイルに出力したい等tcpdumpのオプションを付ける場合は後ろにオプションを指定してやります。

```
# ovs-tcpdump -i qvo57f459bb-44 --mirror-to hoge -c 100 -w /tmp/hoge.pcap
```


別terminalでキャプチャ中のbridgeを見てみると interface: hogeが追加されており、bridgeテーブルのmirrorsカラムにも情報が追記されています。

```
# ovs-vsctl show
<<省略>>
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port hoge
            Interface hoge
<<省略>>

# ovs-vsctl list bridge
_uuid               : f599472d-7afa-480d-96e4-bfc27b3c3fd3
auto_attach         : []
controller          : [c17faf47-5a67-43cd-b19f-1111c774eaa1]
datapath_id         : "00002e4799f50d48"
datapath_type       : system
datapath_version    : "<unknown>"
external_ids        : {}
fail_mode           : secure
flood_vlans         : []
flow_tables         : {}
ipfix               : []
mcast_snooping_enable: false
mirrors             : [d9a098a2-a339-469e-b0c9-3cb150249a85]
name                : br-int
netflow             : []
other_config        : {}
ports               : [07d1fb41-b321-4e3e-bf6c-0448c579ec71, 313aaa66-4def-4fdb-ac7e-96b049d25987, 84d909b6-441c-40f7-88c0-8b1408abe0c4, d894b527-20a6-402b-970d-c4451c185d25, ebd45a4d-a141-47c7-a7a8-3677ea0b7a8e, f553205b-ea2c-4f15-b9b7-3d5f42cef989]
protocols           : ["OpenFlow10", "OpenFlow13"]
rstp_enable         : false
rstp_status         : {}
sflow               : []
status              : {}
stp_enable          : false
<<省略>>
```

ただしこのovs-tcpdumpですがbugなのかよく分かりませんがキャプチャを終了させるとmirrorポートは対象bridgeから削除されるのですが、bridgeデータベースのmirrorsカラムの情報を消してくれないという行儀の悪い状態となっています(ver.2.6.1の場合)

ovs-vsctl list mirrorで見てもがっつり残っています

```
# ovs-vsctl list mirror
_uuid               : d9a098a2-a339-469e-b0c9-3cb150249a85
external_ids        : {}
name                : "m_qvo57f459bb-44"
output_port         : []
output_vlan         : []
select_all          : false
select_dst_port     : [313aaa66-4def-4fdb-ac7e-96b049d25987]
select_src_port     : [313aaa66-4def-4fdb-ac7e-96b049d25987]
select_vlan         : []
snaplen             : []
statistics          : {tx_bytes=0, tx_packets=0}
#
```

しょうがないので手動で消してやります。
対象bridgeの全てのmirror情報を削除

```
# ovs-vsctl clear bridge ブリッジ名 mirrors
```

複数mirrorを使用していて特定のmirror情報だけ削除する場合

```
# ovs-vsctl remove bridge ブリッジ名 mirror 対象uuid
```

行儀の悪さは少し残念ですが便利なコマンドですね。