OpenStack Neutronで、IPv6ネットワーク動作を体験する [slaac編]

Rocky版OpenStack Neutronを活用して、<b>"slaacモードによるIPv6ネットワーク"</b>のデプロイ動作を体験してみます。ただし、デプロイするテナントネットワークは、単一のL3セグメント構成のみです。
外部への通信を想定したルータ環境の配備とか、一切、想定していません。
なお、Neutronでは、オプションとして、<b>Prefix Delegation</b>が利用できるようですが、本記事では、扱いません。
さらに、OpenStack Neutronを活用してIPv6ネットワークをでデプロイする方法は、`slaac`以外に、次の方法もあります。

- [OpenStack Neutronで、IPv6ネットワーク動作を体験する \[dhcpv6-stateful編\]](https://qiita.com/ttsubo/items/3fd451fff1401102af5f)
- [OpenStack Neutronで、IPv6ネットワーク動作を体験する \[dhcpv6-stateless編\]](https://qiita.com/ttsubo/items/dc47e4d37f4df5e140ab)

ちなみに、"[OpenStack Neutronで、IPv4ネットワーク動作を体験する](https://qiita.com/ttsubo/items/a58bafe0bd01831ecc8a)"と比較してみると、理解の助けになるかもしれません。

# ■ どうやって、slaacモードのIPv6ネットワークをデプロイするの？
OpenStack Neutronで、IPv6ネットワークをデプロイする場合、`ipv6_address_mode`と`ipv6_ra_mode`のアトリビュートによって決定されます。
なお、"[OpenStack Documantation: IPv6](https://docs.openstack.org/neutron/pike/admin/config-ipv6.html)"では、次のように記載されています。

> When using SLAAC, the currently supported combinations for ipv6_ra_mode and ipv6_address_mode are as follows.

|ipv6_ra_mode|	ipv6_address_mode|	Result                                      |
|------------|-------------------|--------------------------------------------------|
|Not specified.	|SLAAC	|Addresses are assigned using EUI-64, and an external router will be used for routing.|
|SLAAC	|SLAAC	|Address are assigned using EUI-64, and OpenStack Networking provides routing.|

> Setting <b>ipv6_ra_mode</b> to <b>slaac</b> will result in OpenStack Networking routers being configured to send RA packets, when they are created. This results in the following values set for the address configuration flags in the RA messages:

> - Auto Configuration Flag = 1
- Managed Configuration Flag = 0
- Other Configuration Flag = 0

> New or existing neutron networks that contain a SLAAC enabled IPv6 subnet will result in all neutron ports attached to the network receiving IPv6 addresses. This is because when RA broadcast messages are sent out on a neutron network, they are received by all IPv6 capable ports on the network, and each port will then configure an IPv6 address based on the information contained in the RA packet. In some cases, an IPv6 SLAAC address will be added to a port, in addition to other IPv4 and IPv6 addresses that the port already has been assigned.

## □ ipv6_address_mode / ipv6_ra_mode アトリビュート

- slaac
- dhcpv6-stateful
- dhcpv6-stateless

Neutron標準の機能を使って、IPv6ネットワークをデプロイする場合には、`ipv6_address_mode`と`ipv6_ra_mode`には、同じ値を設定しておけば良いです。

## □ サブネット管理
`"slaac"`で、IPv6アドレスを管理する場合、以下の制約が発生します。

- OpenStack Neutronを使用して、サブネット作成する場合、<b>"cidr"</b>を指定することが可能である
- <b>"cidr"</b>を指定する場合には、サブネット長は、必ず、<b>"/64"</b>とする必要がある
- サブネット長として、<b>"/64"</b>"以外を指定したい場合には、別途、subnetpoolを作成する必要がある
- IPv6アドレスは、`EUI-64`となる


# ■ slaacモードでの想定されるNeutron基本動作
IPv6ネットワークをデプロイすると、Network Node上にテナント専用ルータ環境として<b>radvd</b>が配備されます。
その後、クライアント環境は、ICMPv6 RAメッセージを受信して、RAのフラグオプションにある"Managed address configuration" flag（m-flag）と "Other configuration" flag（o-flag）から、次の振る舞いを判断します。
なお、ICMPv6 RAメッセージには、<b>"Prefix Information"</b>が含まれますので、クライアント側のNICインタフェースには、このPrefixに基づく、`EUI-64`形式のIPv6アドレスが割り当てられます。
（詳細は、[「RFC-4861: Neighbor Discovery for IP version 6 (IPv6)」](https://tools.ietf.org/html/rfc4861)を参照のこと。）

![NeutronによるIPv4:IPv6ネットワーク構築.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103595/60a7acf7-98e0-722e-ccb2-99b705658d98.png)


## □ Routerリソース作成時のデプロイ作業の流れ
ここでのNeutron内部処理のゴールは、Neutron Manager内部で保持するデータベースに、テナントネットワーク用のRouter基本情報を登録する程度でしょう。
この段階では、一切、Compute Node、Network Nodeに対する設定作業は行われません。

## □ Networkリソース作成時のデプロイ作業の流れ
ここでのNeutron内部処理のゴールは、Neutron Manager内部で保持するデータベースに、テナントネットワークの基本情報を登録する程度でしょう。
この段階では、一切、Compute Node、Network Nodeに対する設定作業は行われません。

## □ Subnetリソース作成時のデプロイ作業の流れ
ここでのNeutron内部処理でのゴールは、テナント専用DHCPサーバ環境を配備することです。

![NeutronによるIPv4:IPv6ネットワーク構築.002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103595/9d3eb2e4-19e9-860a-9eac-ce5b5e937f32.png)

- NeutronManagerは、Subnetリソースに応じた<b>IPAM機構</b>を配備する
- Neutron-dhcp-agentは、新たにSubnetリソースが作成されたことを検知する
- Neutron-dhcp-agentは、NeutronManagerに、DHCP専用のPortリソースの作成を依頼する
- NeutronManagerは、DHCP専用のPortリソースを作成する
- NeutronManagerは、DHCPサーバ用Port追加設定を、Neutron-openvswitch-agentに依頼する
- Neutron-openvswitch-agentは、OpenvSwitchの`br-int`ブリッジ上に、DHCPサーバ用Portを追加する
- NeutronManagerは、DHCP環境の配備を、Neutron-dhcp-agentに依頼する
- Neutron-dhcp-agentは、DHCP専用のPortリソースに基づき、DHCPサーバ環境を整備する
  1. Neutron-dhcp-agentは、DHCP用ネームスペースを作成する
  2. Neutron-dhcp-agentは、DHCP用ネームスペース内にdnsmasq環境を整備する

## □ Routerリソース更新時のデプロイ作業の流れ
ここでのNeutron内部処理でのゴールは、別途、Neutronルータがクライアン環境に、ICMPv6 RAメッセージを送信できるように<b>radvd</b>を設定することです。

- NeutronManagerは、Routerリソースへのインタフェース追加処理を開始する
- NeutronManagerは、ROUTER専用のPortリソースを作成する
- NeutronManagerは、ROUTERサーバ用Port追加設定を、Neutron-openvswitch-agentに依頼する
- Neutron-openvswitch-agentは、OpenvSwitchの`br-int`ブリッジ上に、ROUTERサーバ用Portを追加する
- NeutronManagerは、ROUTER環境の配備を、Neutron-l3-agentに依頼する
- Neutron-l3-agentは、ROUTER専用のPortリソースに基づき、ROUTER環境を整備する
  1. Neutron-l3-agentは、ROUTER用ネームスペースを作成する
  2. Neutron-l3-agentは、ROUTER用ネームスペース内にradvd環境を整備する

## □ Portリソース作成時のデプロイ作業の流れ
ここでのNeutron内部処理でのゴールは、別途、クライアン環境から、DHCP取得依頼が発生した場合に、IPv4アドレスを配布できるようDHCPサーバ環境を設定することです。ただし、<b>slaacモードの場合、DHCPサーバを使ったIPv6アドレス等の配布は行われません。</b>

- NeutronManagerは、Portリソースに対応するMACアドレスを割り当てる
- NeutronManagerは、<b>IPAM機構</b>にPortリソース情報のエントリする
- NeutronManagerは、<b>IPAM機構</b>での内部処理に基づき、IPv6アドレスを割り当てる
- NeutronManagerは、DHCPサーバ環境でのIPv6アドレス払い出し設定を、Neutron-dhcp-agentに依頼する
- Neutron-dhcp-agentは、dnsmasq設定ファイルに当該エントリを設定する
- Neutron-dhcp-agentは、dnsmasqプロセスを再起動(kill -HUP)して、エントリ設定を有効化する

### (参考) どうやって、`EUI-64`形式のIPv6アドレスを割り当てているのか？
NeutronManager内部のIPAM機構では、`EUI-64`形式のIPv6アドレスを割り当てるロジックが備わっています。以下、Neutronのソースコードから、関連する部分を抜き出して、サンプルプログラム化してみました。

```python:assign_ip_address.py 
import sys
import random
import netaddr

def is_valid_ipv4(address):
    try:
        return netaddr.valid_ipv4(address)
    except netaddr.AddrFormatError:
        return False

def get_ipv6_addr_by_EUI64(prefix, mac):
    # Check if the prefix is an IPv4 address
    if is_valid_ipv4(prefix):
        msg = _("Unable to generate IP address by EUI64 for IPv4 prefix")
        raise ValueError(msg)
    try:
        eui64 = int(netaddr.EUI(mac).eui64())
        prefix = netaddr.IPNetwork(prefix)
        return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
    except (ValueError, netaddr.AddrFormatError):
        raise ValueError(_('Bad prefix or mac format for generating IPv6 '
                           'address by EUI-64: %(prefix)s, %(mac)s:')
                         % {'prefix': prefix, 'mac': mac})
    except TypeError:
        raise TypeError(_('Bad prefix type for generating IPv6 address by '
                          'EUI-64: %s') % prefix)

def get_random_mac(base_mac):
    mac = [int(base_mac[0], 16), int(base_mac[1], 16),
           int(base_mac[2], 16), random.getrandbits(8),
           random.getrandbits(8), random.getrandbits(8)]
    if base_mac[3] != '00':
        mac[3] = int(base_mac[3], 16)
    return ':'.join(["%02x" % x for x in mac])

if __name__ == '__main__':
    prefix = "2001:db8:1111::/64"
    base_mac = "fa:16:3e:00:00:00"
    if len(sys.argv) == 2:
        mac_address = sys.argv[1]
    elif len(sys.argv) == 1:
        mac_address = get_random_mac(base_mac.split(':'))
    else:
        sys.exit(1)
    ip_address = get_ipv6_addr_by_EUI64(prefix, mac_address)
    print("mac_address:[{0}], ip_address:[{1}]".format(mac_address, ip_address))
```
実際に、動かしてみると、こんな感じです。サンプルプログラムを起動する毎に、Macアドレスを自動割り当て、その後、Macアドレスに応じた、`EUI-64`形式のIPv6アドレスが割り当てられます。
（サンプルプログラムでは、`cidr`は、一律、`"2001:db8:1111::/64"`としています）

```
$ python assign_ip_address.py
mac_address:[fa:16:3e:fc:b4:7c], ip_address:[2001:db8:1111:0:f816:3eff:fefc:b47c]
```
```
$ python assign_ip_address.py
mac_address:[fa:16:3e:63:a9:60], ip_address:[2001:db8:1111:0:f816:3eff:fe63:a960]
```
```
$ python assign_ip_address.py
mac_address:[fa:16:3e:87:ad:43], ip_address:[2001:db8:1111:0:f816:3eff:fe87:ad43]
```
```
$ python assign_ip_address.py
mac_address:[fa:16:3e:74:e8:9f], ip_address:[2001:db8:1111:0:f816:3eff:fe74:e89f]
```


# ■ テナントネットワークのデプロイの作業履歴
Rocky版OpenStack Neutronを使って、Neutron基本動作を、ステップbyステップで確認していきます。

## 1. OpenvSwitch初期構成の確認
OpenvSwitchの初期状態として動作しているbridge構成を確認しておきます
なお、今回は、all_in_one環境で作業しているので、Compute NodeとNetwork Nodeは、同一サーバで動作しています

### (1.1) OpenvSwitchの全体構成を確認する

```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-ex
        Port "eth0"
            Interface "eth0"
        Port br-ex
            Interface br-ex
                type: internal
    Bridge br-tun
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-tun
            Interface br-tun
                type: internal
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

### (1.2) `br-int`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b675f3f6eb45
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 3(patch-tun): addr:ce:e0:2b:eb:f5:41
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:b6:75:f3:f6:eb:45
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

### (1.3) `br-ex`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-ex
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000526d7a08dd4d
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(eth0): addr:52:54:00:2b:07:df
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-ex): addr:52:6d:7a:08:dd:4d
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

## 2. Routerリソース作成の作業履歴
実際に、Routerリソースを作成します

### (2.1) Routerリソースを作成する

```
# openstack router create ipv6-router-slaac
```

### (2.2) Routerリソースを確認しておく

```
# openstack router show ipv6-router-slaac -f json
{
  "external_gateway_info": null, 
  "status": "ACTIVE", 
  "availability_zone_hints": "", 
  "availability_zones": "", 
  "description": "", 
  "admin_state_up": "UP", 
  "created_at": "2020-03-16T02:59:36Z", 
  "tags": "", 
  "distributed": null, 
  "updated_at": "2020-03-16T02:59:36Z", 
  "interfaces_info": "[]", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "flavor_id": null, 
  "revision_number": 0, 
  "routes": "", 
  "ha": null, 
  "id": "10a6a8b9-eb9c-4b32-846f-beb6e87ef160", 
  "name": "ipv6-router-slaac"
}
```

## 3. Networkリソース作成の作業履歴
実際に、Networkリソースを作成します

### (3.1) Networkリソースを作成する

```
# openstack network create ipv6-net-slaac
```
### (3.2) Networkリソースを確認しておく

```
# openstack network show ipv6-net-slaac -f json
{
  "provider:physical_network": null, 
  "ipv6_address_scope": null, 
  "dns_domain": null, 
  "is_vlan_transparent": null, 
  "revision_number": 2, 
  "port_security_enabled": true, 
  "provider:network_type": null, 
  "id": "2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "router:external": "Internal", 
  "availability_zone_hints": "", 
  "availability_zones": "", 
  "segments": null, 
  "name": "ipv6-net-slaac", 
  "ipv4_address_scope": null, 
  "shared": false, 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "status": "ACTIVE", 
  "subnets": "", 
  "description": "", 
  "tags": "", 
  "updated_at": "2020-03-16T03:00:37Z", 
  "is_default": null, 
  "provider:segmentation_id": null, 
  "qos_policy_id": null, 
  "admin_state_up": "UP", 
  "created_at": "2020-03-16T03:00:37Z", 
  "mtu": 1450
}
```



## 4. Subnetリソース作成の作業履歴
Subnetリソースを作成します

### (4.1) Subnetリソースを作成する

```
# openstack subnet create \
--subnet-range 2001:db8:1111::/64 \
--ip-version 6 \
--ipv6-ra-mode slaac \
--ipv6-address-mode slaac \
--network ipv6-net-slaac \
ipv6-subnet-slaac
```

### (4.2) Subnetリソースを確認しておく
```
# openstack subnet show ipv6-subnet-slaac -f json
{
  "service_types": "", 
  "description": "", 
  "enable_dhcp": true, 
  "segment_id": null, 
  "network_id": "2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "created_at": "2020-03-16T03:01:29Z", 
  "tags": "", 
  "dns_nameservers": "", 
  "updated_at": "2020-03-16T03:01:29Z", 
  "ipv6_ra_mode": "slaac", 
  "allocation_pools": "2001:db8:1111::2-2001:db8:1111:0:ffff:ffff:ffff:ffff", 
  "gateway_ip": "2001:db8:1111::1", 
  "revision_number": 0, 
  "ipv6_address_mode": "slaac", 
  "ip_version": 6, 
  "host_routes": "", 
  "cidr": "2001:db8:1111::/64", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "id": "b2da54ca-4d26-44a6-9402-60613c98394e", 
  "subnetpool_id": null, 
  "name": "ipv6-subnet-slaac"
}
```

### (4.3) Portリソース（DHCP）を確認しておく

```
# openstack port list -f json
[
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:1111:0:f816:3eff:fe3d:d6de', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
    "ID": "f48ecb9a-b5dc-4b8b-9a72-740467a058a6", 
    "MAC Address": "fa:16:3e:3d:d6:de", 
    "Name": ""
  }
]
```
```
# openstack port show f48ecb9a-b5dc-4b8b-9a72-740467a058a6 -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-16T03:01:30Z", 
  "dns_domain": null, 
  "device_owner": "network:dhcp", 
  "revision_number": 3, 
  "port_security_enabled": false, 
  "fixed_ips": "ip_address='2001:db8:1111:0:f816:3eff:fe3d:d6de', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
  "id": "f48ecb9a-b5dc-4b8b-9a72-740467a058a6", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:3d:d6:de", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "status": "DOWN", 
  "binding_profile": null, 
  "binding_vif_type": null, 
  "binding_vif_details": null, 
  "tags": "", 
  "dns_assignment": null, 
  "trunk_details": null, 
  "security_group_ids": "", 
  "device_id": "dhcpf4ce2912-1ee5-5084-ac17-a8fe43c4ca19-2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "name": "", 
  "admin_state_up": "UP", 
  "network_id": "2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "dns_name": null, 
  "created_at": "2020-03-16T03:01:29Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```
### (4.4) DHCP用ネームスペースが正しく作成されたことを確認する

```
# ip netns
qdhcp-2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033 (id: 0)
```
```
# ip netns exec qdhcp-2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
11: tapf48ecb9a-b5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:3d:d6:de brd ff:ff:ff:ff:ff:ff
    inet6 2001:db8:1111:0:f816:3eff:fe3d:d6de/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe3d:d6de/64 scope link 
       valid_lft forever preferred_lft forever
```
### (4.5) DHCP用ネームスペースで動作するdnsmasqプロセスを確認する

```
# ps -ef|grep dnsmasq
nobody   21376     1  0 12:01 ?        00:00:00 dnsmasq --no-hosts --no-resolv --pid-file=/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/host --addn-hosts=/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/addn_hosts --dhcp-optsfile=/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/opts --dhcp-leasefile=/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/leases --dhcp-match=set:ipxe,175 --local-service --bind-interfaces --dhcp-option-force=option:mtu,1450 --dhcp-lease-max=0 --conf-file= --domain=openstacklocal
```
### (4.6) dnsmasqの各種設定ファイルを確認する

#### (4.6.1) hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/host 
```
#### (4.6.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/addn_hosts
2001:db8:1111:0:f816:3eff:fe3d:d6de	host-2001-db8-1111-0-f816-3eff-fe3d-d6de.openstacklocal host-2001-db8-1111-0-f816-3eff-fe3d-d6de
```
#### (4.6.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/opts
```
#### (4.6.4) leaseファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/leases
```

### (4.7) OpenvSwitchの構成を確認する

#### (4.7.1) OpenvSwitchの全体構成を確認する

```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true

    ...(snip)

    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "tapf48ecb9a-b5"
            tag: 4095
            Interface "tapf48ecb9a-b5"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

#### (4.7.2) `br-int`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b675f3f6eb45
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 3(patch-tun): addr:ce:e0:2b:eb:f5:41
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 5(tapf48ecb9a-b5): addr:fa:16:3e:3d:d6:de
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:b6:75:f3:f6:eb:45
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

## 5.Routerリソース更新の作業履歴
Routerリソースに、subnetを追加します

### (5.1) Routerリソースを更新する
```
# openstack router add subnet ipv6-router-slaac ipv6-subnet-slaac
```

### (5.2) Routerリソースを確認しておく

```
# openstack router show ipv6-router-slaac -f json
{
  "external_gateway_info": null, 
  "status": "ACTIVE", 
  "availability_zone_hints": "", 
  "availability_zones": "nova", 
  "description": "", 
  "admin_state_up": "UP", 
  "created_at": "2020-03-16T02:59:36Z", 
  "tags": "", 
  "distributed": null, 
  "updated_at": "2020-03-16T03:09:30Z", 
  "interfaces_info": "[{\"subnet_id\": \"b2da54ca-4d26-44a6-9402-60613c98394e\", \"ip_address\": \"2001:db8:1111::1\", \"port_id\": \"ea1a0fb8-6435-42dd-8adc-33bf2bf47a48\"}]", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "flavor_id": null, 
  "revision_number": 1, 
  "routes": "", 
  "ha": null, 
  "id": "10a6a8b9-eb9c-4b32-846f-beb6e87ef160", 
  "name": "ipv6-router-slaac"
}
```
### (5.3) Portリソース（ROUTER）を確認しておく

```
# openstack port list -f json
[
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:1111::1', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
    "ID": "ea1a0fb8-6435-42dd-8adc-33bf2bf47a48", 
    "MAC Address": "fa:16:3e:23:95:f8", 
    "Name": ""
  }, 
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:1111:0:f816:3eff:fe3d:d6de', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
    "ID": "f48ecb9a-b5dc-4b8b-9a72-740467a058a6", 
    "MAC Address": "fa:16:3e:3d:d6:de", 
    "Name": ""
  }
]
```
```
# openstack port show ea1a0fb8-6435-42dd-8adc-33bf2bf47a48 -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-16T03:09:32Z", 
  "dns_domain": null, 
  "device_owner": "network:router_interface", 
  "revision_number": 5, 
  "port_security_enabled": false, 
  "fixed_ips": "ip_address='2001:db8:1111::1', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
  "id": "ea1a0fb8-6435-42dd-8adc-33bf2bf47a48", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:23:95:f8", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "status": "DOWN", 
  "binding_profile": null, 
  "binding_vif_type": null, 
  "binding_vif_details": null, 
  "tags": "", 
  "dns_assignment": null, 
  "trunk_details": null, 
  "security_group_ids": "", 
  "device_id": "10a6a8b9-eb9c-4b32-846f-beb6e87ef160", 
  "name": "", 
  "admin_state_up": "UP", 
  "network_id": "2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "dns_name": null, 
  "created_at": "2020-03-16T03:09:29Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```

### (5.4) ROUTER用ネームスペースが正しく作成されたことを確認する

```
# ip netns
qrouter-10a6a8b9-eb9c-4b32-846f-beb6e87ef160 (id: 2)
qdhcp-2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033 (id: 0)
```
```
# ip netns exec qrouter-10a6a8b9-eb9c-4b32-846f-beb6e87ef160 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
12: qr-ea1a0fb8-64: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:23:95:f8 brd ff:ff:ff:ff:ff:ff
    inet6 2001:db8:1111::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe23:95f8/64 scope link 
       valid_lft forever preferred_lft forever
```
### (5.5) ROUTER用ネームスペースで動作するradvdプロセスを確認する

```
# ps -ef|grep radvd
neutron  22155     1  0 12:09 ?        00:00:00 radvd -C /var/lib/neutron/ra/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.radvd.conf -p /var/lib/neutron/external/pids/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.pid.radvd -u neutron -m syslog
neutron  22156 22155  0 12:09 ?        00:00:00 radvd -C /var/lib/neutron/ra/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.radvd.conf -p /var/lib/neutron/external/pids/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.pid.radvd -u neutron -m syslog
```
### (5.6) radvdの設定ファイルを確認する

```text:/var/lib/neutron/ra/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.radvd.conf
interface qr-ea1a0fb8-64
{
   AdvSendAdvert on;
   MinRtrAdvInterval 30;
   MaxRtrAdvInterval 100;

   
   AdvLinkMTU 1450;
   

   

   

   

   
   prefix 2001:db8:1111::/64
   {
        AdvOnLink on;
        AdvAutonomous on;
   };
   

   
};
```

### (5.7) dnsmasqの各種設定ファイルを確認する

#### (5.7.1) hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/host
```
#### (5.7.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/addn_hosts
2001:db8:1111:0:f816:3eff:fe3d:d6de	host-2001-db8-1111-0-f816-3eff-fe3d-d6de.openstacklocal host-2001-db8-1111-0-f816-3eff-fe3d-d6de
```
#### (5.7.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/opts
```

#### (5.7.4) leaseファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/leases
```

### (5.8) OpenvSwitchの構成を確認する

#### (5.8.1) OpenvSwitchの全体構成を確認する

```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-ex
        Port "eth0"
            Interface "eth0"
        Port br-ex
            Interface br-ex
                type: internal

    ...(snip)

    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "qr-ea1a0fb8-64"
            tag: 4095
            Interface "qr-ea1a0fb8-64"
                type: internal
        Port "tapf48ecb9a-b5"
            tag: 4095
            Interface "tapf48ecb9a-b5"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

#### (5.8.2) `br-int`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b675f3f6eb45
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 3(patch-tun): addr:ce:e0:2b:eb:f5:41
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 5(tapf48ecb9a-b5): addr:fa:16:3e:3d:d6:de
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 6(qr-ea1a0fb8-64): addr:fa:16:3e:23:95:f8
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:b6:75:f3:f6:eb:45
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

#### (5.8.3) `br-ex`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-ex
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000526d7a08dd4d
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(eth0): addr:52:54:00:2b:07:df
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-ex): addr:52:6d:7a:08:dd:4d
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

## 6.Portリソース作成の作業履歴
Portリソースを作成します

### (6.1) Portリソースを作成する
```
# openstack port create --network ipv6-net-slaac ipv6-port-slaac
```

### (6.2) Portリソースを確認しておく
```
# openstack port show ipv6-port-slaac -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-16T03:20:02Z", 
  "dns_domain": null, 
  "device_owner": "", 
  "revision_number": 2, 
  "port_security_enabled": true, 
  "fixed_ips": "ip_address='2001:db8:1111:0:f816:3eff:feef:30f', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'", 
  "id": "212cdf7b-b40c-4214-99d8-5b25614b61aa", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:ef:03:0f", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "status": "DOWN", 
  "binding_profile": null, 
  "binding_vif_type": null, 
  "binding_vif_details": null, 
  "tags": "", 
  "dns_assignment": null, 
  "trunk_details": null, 
  "security_group_ids": "ae012f61-83a5-43e6-9cd8-dfeae6e62110", 
  "device_id": "", 
  "name": "ipv6-port-slaac", 
  "admin_state_up": "UP", 
  "network_id": "2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033", 
  "dns_name": null, 
  "created_at": "2020-03-16T03:20:02Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```

### (6.3) dnsmasqの各種設定ファイルを確認する

#### (6.3.1) hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/host
```
#### (6.3.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/addn_hosts
2001:db8:1111:0:f816:3eff:fe3d:d6de	host-2001-db8-1111-0-f816-3eff-fe3d-d6de.openstacklocal host-2001-db8-1111-0-f816-3eff-fe3d-d6de
2001:db8:1111:0:f816:3eff:feef:30f	host-2001-db8-1111-0-f816-3eff-feef-30f.openstacklocal host-2001-db8-1111-0-f816-3eff-feef-30f
```
#### (6.3.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/opts
```

#### (6.3.4) leaseファイルを確認する

```text:/var/lib/neutron/dhcp/2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033/leases
```

### (6.4) radvdの設定ファイルを確認する

```text:/var/lib/neutron/ra/10a6a8b9-eb9c-4b32-846f-beb6e87ef160.radvd.conf
interface qr-ea1a0fb8-64
{
   AdvSendAdvert on;
   MinRtrAdvInterval 30;
   MaxRtrAdvInterval 100;

   
   AdvLinkMTU 1450;
   

   

   

   

   
   prefix 2001:db8:1111::/64
   {
        AdvOnLink on;
        AdvAutonomous on;
   };
   

   
};
```

### (6.5) OpenvSwitchの構成を確認する

#### (6.5.1) OpenvSwitchの全体構成を確認する

```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-ex
        Port "eth0"
            Interface "eth0"
        Port br-ex
            Interface br-ex
                type: internal

    ...(snip)

    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "qr-ea1a0fb8-64"
            tag: 4095
            Interface "qr-ea1a0fb8-64"
                type: internal
        Port "tapf48ecb9a-b5"
            tag: 4095
            Interface "tapf48ecb9a-b5"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

#### (6.5.2) `br-int`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b675f3f6eb45
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 3(patch-tun): addr:ce:e0:2b:eb:f5:41
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 5(tapf48ecb9a-b5): addr:fa:16:3e:3d:d6:de
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 6(qr-ea1a0fb8-64): addr:fa:16:3e:23:95:f8
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:b6:75:f3:f6:eb:45
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

#### (6.5.3) `br-ex`ブリッジに収容されたPortを確認する

```
# ovs-ofctl show br-ex
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000526d7a08dd4d
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(eth0): addr:52:54:00:2b:07:df
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-ex): addr:52:6d:7a:08:dd:4d
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```

# ■ テナントネットワーク動作確認

クライアント環境のネットワークインタフェースには、事前に、<b>"fa:16:3e:ef:03:0f"</b>のMACアドレスを設定しておき、<b>"2001:db8:1111:0:f816:3eff:feef:30f"</b>のIPv6アドレスを自動で割り当てることが期待値です

```
# openstack port show ipv6-port-slaac -f json
{
  ...(snip)

  "fixed_ips": "ip_address='2001:db8:1111:0:f816:3eff:feef:30f', subnet_id='b2da54ca-4d26-44a6-9402-60613c98394e'",

  ...(snip)

  "mac_address": "fa:16:3e:ef:03:0f",

  ...(snip)
}
```

## 7. クライアント環境整備の作業履歴
IPv6アドレスの割り当てが確認できるよう、クライアント環境を整備します

### (7.1) client用ネームスペースを作成する

```
# ip netns add client
# ip netns
client
qrouter-10a6a8b9-eb9c-4b32-846f-beb6e87ef160 (id: 2)
qdhcp-2d9c8b6d-3390-4f6a-b9c9-fe5cc879e033 (id: 0)
```

### (7.2) vethインターフェイスを作成し、片方の端点をclient用ネームスペースに設定する

```
# ip link add ovs-veth0 type veth peer name client-veth0
# ip link set client-veth0 netns client
```

### (7.3) `OpenvSwitch`の`br-int`構成を確認し、各Port収容で使用している`tag`を把握しておく（この例の場合だと、`"4095"`である）

```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true

    ...(snip)
    
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "qr-ea1a0fb8-64"
            tag: 4095
            Interface "qr-ea1a0fb8-64"
                type: internal
        Port "tapf48ecb9a-b5"
            tag: 4095
            Interface "tapf48ecb9a-b5"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

### (7.4) vethインターフェイスの対向側の端点を`OpenvSwitch`の`br-int`に収容設定する
```
# ovs-vsctl add-port br-int ovs-veth0 tag=4095
```
```
# ovs-vsctl show
3b782d6f-a956-4c33-85fa-527d9eb2a0d5
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true

    ...(snip)

    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "ovs-veth0"
            tag: 4095
            Interface "ovs-veth0"
        Port "qr-ea1a0fb8-64"
            tag: 4095
            Interface "qr-ea1a0fb8-64"
                type: internal
        Port "tapf48ecb9a-b5"
            tag: 4095
            Interface "tapf48ecb9a-b5"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    ovs_version: "2.10.1"
```

### (7.5) client側vethインターフェイスにMACアドレスを設定する

```
# ip netns exec client ip link set dev client-veth0 address fa:16:3e:ef:03:0f
```
```
# ip netns exec client ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: client-veth0@if14: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether fa:16:3e:ef:03:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0
```

### (7.6) vethインターフェイスを`UP`に設定する
```
# ip netns exec client ip link set client-veth0 up
# ip link set ovs-veth0 up
```
```
# ip netns exec client ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: client-veth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:ef:03:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 2001:db8:1111:0:f816:3eff:feef:30f/64 scope global mngtmpaddr dynamic 
       valid_lft 86391sec preferred_lft 14391sec
    inet6 fe80::f816:3eff:feef:30f/64 scope link 
       valid_lft forever preferred_lft forever
```
```
# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b675f3f6eb45
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 3(patch-tun): addr:ce:e0:2b:eb:f5:41
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 5(tapf48ecb9a-b5): addr:fa:16:3e:3d:d6:de
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 6(qr-ea1a0fb8-64): addr:fa:16:3e:23:95:f8
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 7(ovs-veth0): addr:86:ac:db:5e:87:97
     config:     0
     state:      0
     current:    10GB-FD COPPER
     speed: 10000 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:b6:75:f3:f6:eb:45
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
```
### (7.7) IPv6動作を確認する

#### (7.7.1) IPv6アドレスを確認する
クライアント環境に、<b>"2001:db8:1111:0:f816:3eff:feef:30f/64"</b>のIPv6アドレスが割り当てられたことが確認できました

```
# ip netns exec client ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: client-veth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:ef:03:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 2001:db8:1111:0:f816:3eff:feef:30f/64 scope global mngtmpaddr dynamic 
       valid_lft 86388sec preferred_lft 14388sec
    inet6 fe80::f816:3eff:feef:30f/64 scope link 
       valid_lft forever preferred_lft forever
```
#### (7.7.2) ルーティング情報を確認する
radvd環境が動作しているインタフェースのリンクローカルアドレスがデフォルトゲートウェイとして設定されていました

```
# ip netns exec client ip -6 route show
2001:db8:1111::/64 dev client-veth0 proto kernel metric 256 expires 86393sec mtu 1450 pref medium
fe80::/64 dev client-veth0 proto kernel metric 256 mtu 1450 pref medium
default via fe80::f816:3eff:fe23:95f8 dev client-veth0 proto ra metric 1024 expires 293sec mtu 1450 hoplimit 64 pref medium
```

#### (7.7.3) DHCPサーバとの疎通性を確認する
dnsmasq環境が動作しているインタフェースに対して、pingを打ってみましょう

```
# ip netns exec client ping6 2001:db8:1111:0:f816:3eff:fe3d:d6de
PING 2001:db8:1111:0:f816:3eff:fe3d:d6de(2001:db8:1111:0:f816:3eff:fe3d:d6de) 56 data bytes
64 bytes from 2001:db8:1111:0:f816:3eff:fe3d:d6de: icmp_seq=1 ttl=64 time=0.247 ms
64 bytes from 2001:db8:1111:0:f816:3eff:fe3d:d6de: icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from 2001:db8:1111:0:f816:3eff:fe3d:d6de: icmp_seq=3 ttl=64 time=0.116 ms
64 bytes from 2001:db8:1111:0:f816:3eff:fe3d:d6de: icmp_seq=4 ttl=64 time=0.112 ms
^C
--- 2001:db8:1111:0:f816:3eff:fe3d:d6de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.042/0.129/0.247/0.074 ms
```

#### (7.7.4) radvdサーバとの疎通性を確認する
radvd環境が動作しているインタフェースに対して、pingを打ってみましょう

```
# ip netns exec client ping6 2001:db8:1111::1
PING 2001:db8:1111::1(2001:db8:1111::1) 56 data bytes
64 bytes from 2001:db8:1111::1: icmp_seq=1 ttl=64 time=0.903 ms
64 bytes from 2001:db8:1111::1: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 2001:db8:1111::1: icmp_seq=3 ttl=64 time=0.118 ms
64 bytes from 2001:db8:1111::1: icmp_seq=4 ttl=64 time=0.117 ms
^C
--- 2001:db8:1111::1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.114/0.313/0.903/0.340 ms
```

以上です。

# ■ 参考URL
- [OpenStack Neutronで、IPv4ネットワーク動作を体験する](https://qiita.com/ttsubo/items/a58bafe0bd01831ecc8a)
- [どう割り振る？ IPv6でのアドレス設計](https://www.atmarkit.co.jp/ait/articles/1109/06/news122.html)
- [OpenStack Documantation: IPv6](https://docs.openstack.org/neutron/pike/admin/config-ipv6.html)
- [OpenStack Neutron IPv6 Lessons](https://www.slideshare.net/ritchey98/openstack-neutron-ipv6-lessons)