PR

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のWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

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