RESTCONF APIを使ってフローを書き換えてみる

2016年6月9日(木)
安座間 勇二(あざま ゆうじ)

※記事内で一部のソースコードが突き抜けて表示されている箇所があります。マウスオーバーするとSyntaxHighlighterというツールがポップアップされますので、別ウィンドウで表示させたりクリップボードにコピーしたりしてご活用ください。

OpenDaylightの特徴の一つとして、多くのNorthbound Inrerface(NBI)が用意されている点があげられます。MD-SALがインターフェースを抽象化することで、OpenDaylightを利用するさまざまなアプリケーションからのAPI呼び出しを容易にできるようになっています。第2回と第3回ではOpenDaylightとOpenStackを連携させた環境の構築を行いましたが、OpenStackにおいてもNeutronプラグイン経由でOpenDaylightに用意されているAPIを呼び出すことで、ネットワークに関する様々なコントロールができるようになっています。

そこで、今回はOpenDaylightのRESTCONF APIに注目します。RESTCONF APIを利用して、OpenDaylightのデータストアに登録されているフローの取得と更新を行ってみます。

RESTCONF API

そもそもRESTCONF APIとは、NETCONFデータストア内のYANGで定義されたデータにアクセスするためのHTTPを使ったRESTライクなプロトコルのことです。OpenDaylightでもRESTCONF APIを使えば、OpenDaylightのデータストアに登録されたフローをコントロールできます。

OpenDaylight RESTCONF API Documentation

OpenDaylightを起動すると、RESTCONF API ExplorerがOSGi bundleとして実行されるようになっています。RESTCONF API ExplorerはAPIドキュメントなのですが、Swaggerの仕様に基づいており、レンダリングされてSwagger UIとして表示されます。OpenDaylightを実行しているノードに対して、ブラウザから以下の様にアクセスすると、APIの一覧を表示したり、テストリクエストを投げたりすることができます。

http://192.168.0.10:8181/apidoc/explorer/index.html

RESTCONF API Explorer

RESTCONF APIを使ってみる

それでは、RESTCONF APIを試してみます。環境は第2回で構築したOpenDaylight+OpenStack環境を使います。

フローの取得

RESTCONFのHTTPリクエストとレスポンスの内容は、非常に長くなる場合があり記述するのが面倒です。そこで、ここではクライアントコマンドでオペレーションしていきます。まず、python-odlclientをインストールします。

~$ sudo pip install python-odlclient

フローを取得するためには、取得したいノードのノードIDを知る必要があります。そこで、まず最初にノード一覧を取得してコンピュートノードのノードIDを確認します。

~$ export ODL_HOST=192.168.0.10
~$ odl node list
+--------------------------+--------------+-----------------+-------------+--------------+----------+
| id                       | ip_address   | connector_count | table_count | hardware     | software |
+--------------------------+--------------+-----------------+-------------+--------------+----------+
| openflow:267140174830659 | 192.168.0.11 | 4               | 11          | Open vSwitch | 2.0.2    | # コンピュートノード
| openflow:235547676672585 | 192.168.0.10 | 5               | 11          | Open vSwitch | 2.0.2    | # コントローラノード
+--------------------------+--------------+-----------------+-------------+--------------+----------+

ちなみに、ノード一覧を取得するためにcurlコマンドを使ってリクエストすると、以下の様に膨大な量のレスポンスが返ってくるため、うまく加工しない限り人間が読めたものではありません。

~$ curl -s -H "Accept: application/json" -u "admin:admin" -X GET http://192.168.0.10:8181/restconf/operational/opendaylight-inventory:nodes
{"nodes":{"node":[{"id":"openflow:267140174830659","node-connector":[{"id":"openflow:267140174830659:1","flow-node-inventory:hardware-address":"76:6B:A2:F5:73:75",‥‥‥‥}

ノードごとのノードIDがわかったので、コンピュートノードのフローを取得してみます。

~/devstack$ odl flow list openflow:267140174830659
+---------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id                                                | table_id | priority | match                                                                                                                                                                                                                                                                                                                                                                                   | instructions                                                                                                                                                                                                      |
+---------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| LLDP                                              | 0        | 32768    | ethernet-match: {"ethernet-type": {"type": 35020}}                                                                                                                                                                                                                                                                                                                                      | output-action: {"max-length": 65535, "output-node-connector": "CONTROLLER"}                                                                                                                                       |
| LocalMac_1056_7_fa:16:3e:db:c3:fd                 | 0        | 32768    | in-port: "openflow:267140174830659:7", ethernet-match: {"ethernet-source": {"address": "FA:16:3E:DB:C3:FD"}}                                                                                                                                                                                                                                                                            | set-field: {"tunnel": {"tunnel-id": 1056}}, openflowplugin-extension-nicira-action:nx-reg-load: {"dst": {"start": 0, "end": 31, "nx-reg": "nicira-match:nxm-nx-reg0"}, "value": 1}, go-to-table: {"table_id": 20} |
| LocalMac_1056_6_fa:16:3e:c5:8b:b9                 | 0        | 32768    | in-port: "openflow:267140174830659:6", ethernet-match: {"ethernet-source": {"address": "FA:16:3E:C5:8B:B9"}}                                                                                                                                                                                                                                                                            | set-field: {"tunnel": {"tunnel-id": 1056}}, openflowplugin-extension-nicira-action:nx-reg-load: {"dst": {"start": 0, "end": 31, "nx-reg": "nicira-match:nxm-nx-reg0"}, "value": 1}, go-to-table: {"table_id": 20} |
| TunnelIn_1056_1                                   | 0        | 32768    | tunnel: {"tunnel-id": 1056}, in-port: "openflow:267140174830659:1"                                                                                                                                                                                                                                                                                                                      | openflowplugin-extension-nicira-action:nx-reg-load: {"dst": {"start": 0, "end": 31, "nx-reg": "nicira-match:nxm-nx-reg0"}, "value": 2}, go-to-table: {"table_id": 20}                                             |
| DropFilter_7                                      | 0        | 8192     | in-port: "openflow:267140174830659:7"                                                                                                                                                                                                                                                                                                                                                   | Drop                                                                                                                                                                                                              |
| DropFilter_6                                      | 0        | 8192     | in-port: "openflow:267140174830659:6"                                                                                                                                                                                                                                                                                                                                                   | Drop                                                                                                                                                                                                              |
| DEFAULT_PIPELINE_FLOW_0                           | 0        | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 20}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_20                          | 20       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 30}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_30                          | 30       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 40}                                                                                                                                                                                     |
| Egress_DHCP_Client_Permit_                        | 40       | 61012    | udp-destination-port: 67, ip-match: {"ip-protocol": 17}, udp-source-port: 68, ethernet-match: {"ethernet-type": {"type": 2048}}                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| Egress_DHCP_Server_7_DROP_                        | 40       | 61011    | in-port: "openflow:267140174830659:7", udp-destination-port: 68, ethernet-match: {"ethernet-type": {"type": 2048}}, udp-source-port: 67, ip-match: {"ip-protocol": 17}                                                                                                                                                                                                                  | Drop                                                                                                                                                                                                              |
| Egress_DHCP_Server_6_DROP_                        | 40       | 61011    | in-port: "openflow:267140174830659:6", udp-destination-port: 68, ethernet-match: {"ethernet-type": {"type": 2048}}, udp-source-port: 67, ip-match: {"ip-protocol": 17}                                                                                                                                                                                                                  | Drop                                                                                                                                                                                                              |
| #UF$TABLE*40-9                                    | 40       | 61010    | arp-source-hardware-address: {"address": "FA:16:3E:C5:8B:B9"}, ethernet-match: {"ethernet-type": {"type": 2054}}                                                                                                                                                                                                                                                                        | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| #UF$TABLE*40-11                                   | 40       | 61010    | arp-source-hardware-address: {"address": "FA:16:3E:DB:C3:FD"}, ethernet-match: {"ethernet-type": {"type": 2054}}                                                                                                                                                                                                                                                                        | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| Egress_IP1056_fa:16:3e:c5:8b:b9_Permit_           | 40       | 61007    | ethernet-match: {"ethernet-source": {"address": "FA:16:3E:C5:8B:B9"}, "ethernet-type": {"type": 2048}}                                                                                                                                                                                                                                                                                  | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| Egress_IP1056_fa:16:3e:db:c3:fd_Permit_           | 40       | 61007    | ethernet-match: {"ethernet-source": {"address": "FA:16:3E:DB:C3:FD"}, "ethernet-type": {"type": 2048}}                                                                                                                                                                                                                                                                                  | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| Egress_Allow_VM_IP_MAC_6fa:16:3e:c5:8b:b9_Permit_ | 40       | 36001    | in-port: "openflow:267140174830659:6", ipv4-source: "10.11.12.7/32", ethernet-match: {"ethernet-source": {"address": "FA:16:3E:C5:8B:B9"}, "ethernet-type": {"type": 2048}}                                                                                                                                                                                                             | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| Egress_Allow_VM_IP_MAC_7fa:16:3e:db:c3:fd_Permit_ | 40       | 36001    | in-port: "openflow:267140174830659:7", ipv4-source: "10.11.12.8/32", ethernet-match: {"ethernet-source": {"address": "FA:16:3E:DB:C3:FD"}, "ethernet-type": {"type": 2048}}                                                                                                                                                                                                             | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_40                          | 40       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 50}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_50                          | 50       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 60}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_60                          | 60       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 70}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_70                          | 70       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 80}                                                                                                                                                                                     |
| DEFAULT_PIPELINE_FLOW_80                          | 80       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 90}                                                                                                                                                                                     |
| #UF$TABLE*90-10                                   | 90       | 61010    | arp-target-hardware-address: {"address": "FA:16:3E:C5:8B:B9"}, ethernet-match: {"ethernet-type": {"type": 2054}}                                                                                                                                                                                                                                                                        | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| #UF$TABLE*90-12                                   | 90       | 61010    | arp-target-hardware-address: {"address": "FA:16:3E:DB:C3:FD"}, ethernet-match: {"ethernet-type": {"type": 2054}}                                                                                                                                                                                                                                                                        | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| Ingress_IP1056_fa:16:3e:c5:8b:b9_Permit_          | 90       | 61007    | ethernet-match: {"ethernet-type": {"type": 2048}, "ethernet-destination": {"address": "FA:16:3E:C5:8B:B9"}}                                                                                                                                                                                                                                                                             | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| Ingress_IP1056_fa:16:3e:db:c3:fd_Permit_          | 90       | 61007    | ethernet-match: {"ethernet-type": {"type": 2048}, "ethernet-destination": {"address": "FA:16:3E:DB:C3:FD"}}                                                                                                                                                                                                                                                                             | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| Ingress_DHCP_Server1056_fa:16:3e:57:9e:07_Permit_ | 90       | 61006    | udp-destination-port: 68, ip-match: {"ip-protocol": 17}, udp-source-port: 67, ethernet-match: {"ethernet-source": {"address": "FA:16:3E:57:9E:07"}, "ethernet-type": {"type": 2048}}                                                                                                                                                                                                    | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| DEFAULT_PIPELINE_FLOW_90                          | 90       | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 100}                                                                                                                                                                                    |
| DEFAULT_PIPELINE_FLOW_100                         | 100      | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | go-to-table: {"table_id": 110}                                                                                                                                                                                    |
| UcastOut_1056_7_fa:16:3e:db:c3:fd                 | 110      | 32768    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"address": "FA:16:3E:DB:C3:FD"}}                                                                                                                                                                                                                                                                                 | output-action: {"max-length": 0, "output-node-connector": "7"}                                                                                                                                                    |
| UcastOut_1056_6_fa:16:3e:c5:8b:b9                 | 110      | 32768    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"address": "FA:16:3E:C5:8B:B9"}}                                                                                                                                                                                                                                                                                 | output-action: {"max-length": 0, "output-node-connector": "6"}                                                                                                                                                    |
| TunnelOut_1056_1_fa:16:3e:57:9e:07                | 110      | 32768    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"address": "FA:16:3E:57:9E:07"}}                                                                                                                                                                                                                                                                                 | output-action: {"max-length": 0, "output-node-connector": "1"}                                                                                                                                                    |
| TunnelOut_1056_1_fa:16:3e:da:ac:59                | 110      | 32768    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"address": "FA:16:3E:DA:AC:59"}}                                                                                                                                                                                                                                                                                 | output-action: {"max-length": 0, "output-node-connector": "1"}                                                                                                                                                    |
| BcastOut_1056                                     | 110      | 16384    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"mask": "01:00:00:00:00:00", "address": "01:00:00:00:00:00"}}, openflowplugin-extension-general:extension-list: [{"extension-key": "openflowplugin-extension-nicira-match:nxm-nx-reg0-key", "extension": {"openflowplugin-extension-nicira-match:nxm-nx-reg": {"reg": "nicira-match:nxm-nx-reg0", "value": 2}}}] | output-action: {"max-length": 0, "output-node-connector": "6"}, output-action: {"max-length": 0, "output-node-connector": "7"}                                                                                    |
| TunnelFloodOut_1056                               | 110      | 16383    | tunnel: {"tunnel-id": 1056}, ethernet-match: {"ethernet-destination": {"mask": "01:00:00:00:00:00", "address": "01:00:00:00:00:00"}}, openflowplugin-extension-general:extension-list: [{"extension-key": "openflowplugin-extension-nicira-match:nxm-nx-reg0-key", "extension": {"openflowplugin-extension-nicira-match:nxm-nx-reg": {"reg": "nicira-match:nxm-nx-reg0", "value": 1}}}] | output-action: {"max-length": 0, "output-node-connector": "6"}, output-action: {"max-length": 0, "output-node-connector": "1"}, output-action: {"max-length": 0, "output-node-connector": "7"}                    |
| LocalTableMiss_1056                               | 110      | 8192     | tunnel: {"tunnel-id": 1056}                                                                                                                                                                                                                                                                                                                                                             | Drop                                                                                                                                                                                                              |
| DEFAULT_PIPELINE_FLOW_110                         | 110      | 0        |                                                                                                                                                                                                                                                                                                                                                                                         | Drop                                                                                                                                                                                                              |
+---------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

フローの変更

今回は2台のインスタンス(vm01、vm-mirror)を使って、パケットのミラーリングをRESTCONF APIから行ってみます。インスタンスvm01宛のパケットをインスタンスvm-mirrorにミラーリングするためフローの設定をします。

パケットミラーリング

まず、外部ネットワークとテナントネットワークを作成します。

~/devstack$ source openrc admin admin
~/devstack$ neutron net-create ext-net --router:external
~/devstack$ neutron subnet-create ext-net 172.16.1.0/24
~/devstack$ sudo ip addr add 172.16.1.1/24 dev br-ex
~/devstack$ source openrc demo demo
~/devstack$ neutron net-create net01
~/devstack$ neutron subnet-create net01 10.11.12.0/24 --name net01-subnet
~/devstack$ neutron router-create router1
~/devstack$ neutron router-interface-add router1 net01-subnet
~/devstack$ neutron router-gateway-set router1 ext-net

ネットワーク上のパケットをキャプチャーするツールとしてtcpdumpをよく利用すると思います。今回もtcpdumpを利用しますが、現在Glanceイメージとして登録されているcirrosは非常にミニマムなクラウドOSであるためtcpdumpコマンドがインストールされていません。そこで、Ubuntuのイメージを新規に登録することにします。

~/devstack$ wget https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img  # Ubuntuのイメージをダウンロード
~/devstack$ source openrc admin admin
~/devstack$ glance image-create --name ubuntu --disk-format=qcow2 --container-format=bare \
--visibility public --file ./trusty-server-cloudimg-amd64-disk1.img                                     # Ubuntuイメージの登録

Ubuntuのインスタンスを起動し、Floating IPを割り当てます。

~/devstack$ source openrc demo demo
~/devstack$ nova keypair-add mykey > mykey                                    # インスタンスへのSSH用のキーペアの作成と公開鍵の登録
~/devstack$ nova boot --image ubuntu --flavor m1.small --key mykey vm01       # vm01を作成
~/devstack$ nova boot --image ubuntu --flavor m1.small --key mykey vm-mirror  # vm-mirrorを作成
~/devstack$ neutron floatingip-create ext-net                                 # フローティングIPの作成
Created a new floatingip:
+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| fixed_ip_address    |                                      |
| floating_ip_address | 172.16.1.4                           |
| floating_network_id | ad490f39-82b9-4164-8526-d47ae379dd49 |
| id                  | 101351bd-3044-4da2-bf36-72a193adc976 |
| port_id             |                                      |
| router_id           |                                      |
| status              | DOWN                                 |
| tenant_id           | 48e3c8d0688c4ccfac7126060ec550c0     |
+---------------------+--------------------------------------+
~/devstack$ neutron floatingip-create ext-net                                 # フローティングIPの作成
Created a new floatingip:
+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| fixed_ip_address    |                                      |
| floating_ip_address | 172.16.1.5                           |
| floating_network_id | ad490f39-82b9-4164-8526-d47ae379dd49 |
| id                  | f75ba7ed-3796-4f97-a0b9-e39d77baafca |
| port_id             |                                      |
| router_id           |                                      |
| status              | DOWN                                 |
| tenant_id           | 48e3c8d0688c4ccfac7126060ec550c0     |
+---------------------+--------------------------------------+
~/devstack$ neutron port-list                                                 # インスタンスのポートを確認
+--------------------------------------+------+-------------------+-----------------------------------------------------------------------------------+
| id                                   | name | mac_address       | fixed_ips                                                                         |
+--------------------------------------+------+-------------------+-----------------------------------------------------------------------------------+
| 18173079-b4b1-44f8-85cc-a8bdd2a9ebe4 |      | fa:16:3e:db:c3:fd | {"subnet_id": "565fdfc0-d215-46c1-88da-fdd938c3aebd", "ip_address": "10.11.12.8"} |
| 470bbdfe-4be4-49c0-8a0b-71a75f664e9c |      | fa:16:3e:57:9e:07 | {"subnet_id": "565fdfc0-d215-46c1-88da-fdd938c3aebd", "ip_address": "10.11.12.2"} |
| c22dc6bc-d575-4100-a825-c64ef3a2fac4 |      | fa:16:3e:da:ac:59 | {"subnet_id": "565fdfc0-d215-46c1-88da-fdd938c3aebd", "ip_address": "10.11.12.1"} |
| d151ef5d-5954-4c35-ac88-b047f6bda2b1 |      | fa:16:3e:c5:8b:b9 | {"subnet_id": "565fdfc0-d215-46c1-88da-fdd938c3aebd", "ip_address": "10.11.12.7"} |
+--------------------------------------+------+-------------------+-----------------------------------------------------------------------------------+
~/devstack$ neutron floatingip-associate 101351bd-3044-4da2-bf36-72a193adc976 d151ef5d-5954-4c35-ac88-b047f6bda2b1  # vm01へフローティングIPを割り当てる
~/devstack$ neutron floatingip-associate f75ba7ed-3796-4f97-a0b9-e39d77baafca 18173079-b4b1-44f8-85cc-a8bdd2a9ebe4  # vm-mirrorへフローティングIPを割り当てる

コンピュートノードのCLIを2つ開き、Floating IPでvm01とvm-mirrorにSSHログインします。各インスタンスでeth0へのICMPパケットをtcpdumpで監視します。

[vm01]

~/devstack$ ssh 172.16.1.4 -i mykey
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-85-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

 System information disabled due to load higher than 1.0

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ubuntu@vm01:~$ sudo tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

[vm-mirror]

~/devstack$ ssh 172.16.1.5 -i mykey
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-85-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

 System information disabled due to load higher than 1.0

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ubuntu@vm-mirror:~$ sudo tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

コントローラノードからvm01のFloating IPに対してpingを実行します。

~/devstack$ ping 172.16.1.4
PING 172.16.1.4 (172.16.1.4) 56(84) bytes of data.
64 bytes from 172.16.1.4: icmp_seq=1 ttl=63 time=4.01 ms
64 bytes from 172.16.1.4: icmp_seq=2 ttl=63 time=5.66 ms
64 bytes from 172.16.1.4: icmp_seq=3 ttl=63 time=1.04 ms
64 bytes from 172.16.1.4: icmp_seq=4 ttl=63 time=1.00 ms
  :

vm01のtcpdumpでicmpリクエストが届いている事がわかると思います。

ubuntu@vm01:~$ sudo tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
08:58:25.002574 IP 172.16.1.1 > host-10-11-12-3.openstacklocal: ICMP echo request, id 9565, seq 1, length 64
08:58:25.004569 IP host-10-11-12-3.openstacklocal > 172.16.1.1: ICMP echo reply, id 9565, seq 1, length 64
08:58:26.018485 IP 172.16.1.1 > host-10-11-12-3.openstacklocal: ICMP echo request, id 9565, seq 2, length 64
08:58:26.018673 IP host-10-11-12-3.openstacklocal > 172.16.1.1: ICMP echo reply, id 9565, seq 2, length 64
08:58:27.017110 IP 172.16.1.1 > host-10-11-12-3.openstacklocal: ICMP echo request, id 9565, seq 3, length 64
08:58:27.017286 IP host-10-11-12-3.openstacklocal > 172.16.1.1: ICMP echo reply, id 9565, seq 3, length 64
08:58:28.018369 IP 172.16.1.1 > host-10-11-12-3.openstacklocal: ICMP echo request, id 9565, seq 4, length 64
08:58:28.018548 IP host-10-11-12-3.openstacklocal > 172.16.1.1: ICMP echo reply, id 9565, seq 4, length 64
  :

それでは、vm01宛のパケットをvm-mirrorへミラーリングためのフローを設定します。

~/devstack$ odl flow create openflow:267140174830659 110 flow_mirror --tun-id 0x420 --dl-dst fa:16:3e:c5:8b:b9 --instructions output:2,output:3
True

curlでリクエストを投げると以下の様になります。

~/devstack$ curl -i -H "Content-Type: application/xml" -H "Accept: application/json" -u "admin:admin" -X PUT "http://192.168.0.11:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:267140174830659/flow-node-inventory:table/110/flow/flow_mirror" -d '<?xml version="1.0" encoding="utf-8"?><flow xmlns="urn:opendaylight:flow:inventory"><table_id>110</table_id><id>flow_mirror</id><match><tunnel><tunnel-id>0x420</tunnel-id></tunnel><ethernet-match><ethernet-destination><mask>ff:ff:ff:ff:ff:ff</mask><address>fa:16:3e:c5:8b:b9</address></ethernet-destination></ethernet-match></match><instructions><instruction><order>0</order><apply-actions><action><output-action><output-node-connector>2</output-node-connector></output-action><order>0</order></action><action><output-action><output-node-connector>3</output-node-connector></output-action><order>1</order></action></apply-actions></instruction></instructions></flow>'

vm-mirrorのtcpdumpを見てみるとミラーリングされたパケットが届くようになったことが確認できます。

[vm-mirror]

ubuntu@vm-mirror:~$ sudo tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
09:07:04.530341 IP 172.16.1.1 > 10.11.12.3: ICMP echo request, id 9788, seq 1, length 64
09:07:05.533755 IP 172.16.1.1 > 10.11.12.3: ICMP echo request, id 9788, seq 2, length 64
09:07:06.531791 IP 172.16.1.1 > 10.11.12.3: ICMP echo request, id 9788, seq 3, length 64
  :

RESTCONF APIを使ってミラーリングのフローを設定する例を紹介しました。OpenDaylightがMD-SALという抽象化レイヤーを採用していることによって、OpenDaylightを利用する様々なアプリケーションからのリクエストをNBIから受け取れる仕組みになっています。今回はRESTCONF APIをご紹介しましたが、この他にも様々なNBIが用意されているので、ぜひ使ってみてください。

著者
安座間 勇二(あざま ゆうじ)
NECソリューションイノベータ株式会社
1991年、沖縄県生まれ。2014年の入社以来、ソフトウェアエンジニアとしてOpenStackでのSFC(Service Function Chaining)やOpenDaylightを使ったSDN/NFVを中心とした開発や検証などに携わる。OpenStack Neutronを中心にコントリビューションしており、OpenStack Summit Tokyo 2015においてSFCのR&Dについて発表。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています