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

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

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

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


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

> For DHCPv6, the currently supported combinations are as follows:

|ipv6_ra_mode|	ipv6_address_mode|	Result                                      |
|------------|-------------------|--------------------------------------------------|
|DHCPv6-stateless	|DHCPv6-stateless	|Addresses are assigned through RAs (see SLAAC above) and optional information is delivered through DHCPv6.|
|DHCPv6-stateful	|DHCPv6-stateful	|Addresses and optional information are assigned using DHCPv6.|

> Setting DHCPv6-stateless for <b>ipv6_ra_mode</b> configures the neutron router with radvd agent to send RAs. The list below captures the values set for the address configuration flags in the RA packet in this scenario. Similarly, setting DHCPv6-stateless for <b>ipv6_address_mode</b> configures neutron DHCP implementation to provide the additional network information.

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


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

- slaac
- dhcpv6-stateful
- dhcpv6-stateless

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

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

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

# ■ dhcpv6-statelessモードでの想定される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/6528bdc9-2b76-c34c-9db1-071393ecb023.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サーバ環境を設定することです。

- 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:3333::/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:3333::/64"`としています）

```
$ python assign_ip_address.py 
mac_address:[fa:16:3e:6b:ba:76], ip_address:[2001:db8:3333:0:f816:3eff:fe6b:ba76]
```
```
$ python assign_ip_address.py 
mac_address:[fa:16:3e:c3:40:2e], ip_address:[2001:db8:3333:0:f816:3eff:fec3:402e]
```
```
$ python assign_ip_address.py 
mac_address:[fa:16:3e:74:6e:af], ip_address:[2001:db8:3333:0:f816:3eff:fe74:6eaf]
```
```
$ python assign_ip_address.py 
mac_address:[fa:16:3e:aa:06:f9], ip_address:[2001:db8:3333:0:f816:3eff:feaa:6f9]
```


# ■ テナントネットワークのデプロイの作業履歴
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-dhcpv6-stateless
```

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

```
# openstack router show ipv6-router-dhcpv6-stateless -f json
{
  "external_gateway_info": null, 
  "status": "ACTIVE", 
  "availability_zone_hints": "", 
  "availability_zones": "", 
  "description": "", 
  "admin_state_up": "UP", 
  "created_at": "2020-03-17T23:42:42Z", 
  "tags": "", 
  "distributed": null, 
  "updated_at": "2020-03-17T23:42:42Z", 
  "interfaces_info": "[]", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "flavor_id": null, 
  "revision_number": 0, 
  "routes": "", 
  "ha": null, 
  "id": "b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc", 
  "name": "ipv6-router-dhcpv6-stateless"
}
```

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

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

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

```
# openstack network show ipv6-net-dhcpv6-stateless -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": "3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "router:external": "Internal", 
  "availability_zone_hints": "", 
  "availability_zones": "", 
  "segments": null, 
  "name": "ipv6-net-dhcpv6-stateless", 
  "ipv4_address_scope": null, 
  "shared": false, 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "status": "ACTIVE", 
  "subnets": "", 
  "description": "", 
  "tags": "", 
  "updated_at": "2020-03-17T23:43:35Z", 
  "is_default": null, 
  "provider:segmentation_id": null, 
  "qos_policy_id": null, 
  "admin_state_up": "UP", 
  "created_at": "2020-03-17T23:43:35Z", 
  "mtu": 1450
}
```



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

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

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

### (4.2) Subnetリソースを確認しておく
```
# openstack subnet show ipv6-subnet-dhcpv6-stateless -f json
{
  "service_types": "", 
  "description": "", 
  "enable_dhcp": true, 
  "segment_id": null, 
  "network_id": "3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "created_at": "2020-03-17T23:44:26Z", 
  "tags": "", 
  "dns_nameservers": "", 
  "updated_at": "2020-03-17T23:44:26Z", 
  "ipv6_ra_mode": "dhcpv6-stateless", 
  "allocation_pools": "2001:db8:3333::2-2001:db8:3333:0:ffff:ffff:ffff:ffff", 
  "gateway_ip": "2001:db8:3333::1", 
  "revision_number": 0, 
  "ipv6_address_mode": "dhcpv6-stateless", 
  "ip_version": 6, 
  "host_routes": "", 
  "cidr": "2001:db8:3333::/64", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "id": "4858fea0-4484-4b61-b4b2-d186fabf2496", 
  "subnetpool_id": null, 
  "name": "ipv6-subnet-dhcpv6-stateless"
}
```

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

```
# openstack port list -f json
[
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:3333:0:f816:3eff:fe2c:1d48', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
    "ID": "04567bd3-616a-471c-a997-c102bd18ca8a", 
    "MAC Address": "fa:16:3e:2c:1d:48", 
    "Name": ""
  }
]
```
```
# openstack port show 04567bd3-616a-471c-a997-c102bd18ca8a -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-17T23:44:27Z", 
  "dns_domain": null, 
  "device_owner": "network:dhcp", 
  "revision_number": 3, 
  "port_security_enabled": false, 
  "fixed_ips": "ip_address='2001:db8:3333:0:f816:3eff:fe2c:1d48', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
  "id": "04567bd3-616a-471c-a997-c102bd18ca8a", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:2c:1d:48", 
  "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-3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "name": "", 
  "admin_state_up": "UP", 
  "network_id": "3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "dns_name": null, 
  "created_at": "2020-03-17T23:44:27Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```
### (4.4) DHCP用ネームスペースが正しく作成されたことを確認する

```
# ip netns
qdhcp-3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9 (id: 0)
```
```
# ip netns exec qdhcp-3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9 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
20: tap04567bd3-61: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:2c:1d:48 brd ff:ff:ff:ff:ff:ff
    inet6 2001:db8:3333:0:f816:3eff:fe2c:1d48/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe2c:1d48/64 scope link 
       valid_lft forever preferred_lft forever
```
### (4.5) DHCP用ネームスペースで動作するdnsmasqプロセスを確認する

```
# ps -ef|grep dnsmasq
nobody    2992     1  0 08:44 ?        00:00:00 dnsmasq --no-hosts --no-resolv --pid-file=/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/host --addn-hosts=/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/addn_hosts --dhcp-optsfile=/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/opts --dhcp-leasefile=/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/leases --dhcp-match=set:ipxe,175 --local-service --bind-interfaces --dhcp-range=set:tag0,2001:db8:3333::,static,64,86400s --dhcp-option-force=option:mtu,1450 --dhcp-lease-max=16777216 --conf-file= --domain=openstacklocal
```
### (4.6) dnsmasqの各種設定ファイルを確認する

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/host
```
#### (4.6.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/addn_hosts
2001:db8:3333:0:f816:3eff:fe2c:1d48	host-2001-db8-3333-0-f816-3eff-fe2c-1d48.openstacklocal host-2001-db8-3333-0-f816-3eff-fe2c-1d48
```
#### (4.6.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/opts
tag:tag0,option6:domain-search,openstacklocal
```
#### (4.6.4) leaseファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/leases
duid 00:01:00:01:26:04:1d:77:fa:16:3e:2c:1d:48
```

### (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 "tap04567bd3-61"
            tag: 4095
            Interface "tap04567bd3-61"
                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
 12(tap04567bd3-61): addr:fa:16:3e:2c:1d:48
     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-dhcpv6-stateless ipv6-subnet-dhcpv6-stateless
```

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

```
# openstack router show ipv6-router-dhcpv6-stateless -f json
{
  "external_gateway_info": null, 
  "status": "ACTIVE", 
  "availability_zone_hints": "", 
  "availability_zones": "nova", 
  "description": "", 
  "admin_state_up": "UP", 
  "created_at": "2020-03-17T23:42:42Z", 
  "tags": "", 
  "distributed": null, 
  "updated_at": "2020-03-17T23:49:55Z", 
  "interfaces_info": "[{\"subnet_id\": \"4858fea0-4484-4b61-b4b2-d186fabf2496\", \"ip_address\": \"2001:db8:3333::1\", \"port_id\": \"1a323388-0625-418c-92e8-20b38e197d85\"}]", 
  "project_id": "f2de30617f9d4ac495035a6cf44ad7b9", 
  "flavor_id": null, 
  "revision_number": 1, 
  "routes": "", 
  "ha": null, 
  "id": "b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc", 
  "name": "ipv6-router-dhcpv6-stateless"
}
```
### (5.3) Portリソース（ROUTER）を確認しておく

```
# openstack port list -f json
[
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:3333:0:f816:3eff:fe2c:1d48', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
    "ID": "04567bd3-616a-471c-a997-c102bd18ca8a", 
    "MAC Address": "fa:16:3e:2c:1d:48", 
    "Name": ""
  }, 
  {
    "Status": "DOWN", 
    "Fixed IP Addresses": "ip_address='2001:db8:3333::1', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
    "ID": "1a323388-0625-418c-92e8-20b38e197d85", 
    "MAC Address": "fa:16:3e:06:30:86", 
    "Name": ""
  }
]
```
```
# openstack port show 1a323388-0625-418c-92e8-20b38e197d85 -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-17T23:49:56Z", 
  "dns_domain": null, 
  "device_owner": "network:router_interface", 
  "revision_number": 5, 
  "port_security_enabled": false, 
  "fixed_ips": "ip_address='2001:db8:3333::1', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
  "id": "1a323388-0625-418c-92e8-20b38e197d85", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:06:30:86", 
  "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": "b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc", 
  "name": "", 
  "admin_state_up": "UP", 
  "network_id": "3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "dns_name": null, 
  "created_at": "2020-03-17T23:49:54Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```

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

```
# ip netns
qrouter-b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc (id: 5)
qdhcp-3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9 (id: 0)
```
```
# ip netns exec qrouter-b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc 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
21: qr-1a323388-06: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:06:30:86 brd ff:ff:ff:ff:ff:ff
    inet6 2001:db8:3333::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe06:3086/64 scope link 
       valid_lft forever preferred_lft forever
```
### (5.5) ROUTER用ネームスペースで動作するradvdプロセスを確認する

```
# ps -ef|grep radvd
neutron   3637     1  0 08:49 ?        00:00:00 radvd -C /var/lib/neutron/ra/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.radvd.conf -p /var/lib/neutron/external/pids/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.pid.radvd -u neutron -m syslog
neutron   3638  3637  0 08:49 ?        00:00:00 radvd -C /var/lib/neutron/ra/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.radvd.conf -p /var/lib/neutron/external/pids/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.pid.radvd -u neutron -m syslog
```
### (5.6) radvdの設定ファイルを確認する

```text:/var/lib/neutron/ra/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.radvd.conf
interface qr-1a323388-06
{
   AdvSendAdvert on;
   MinRtrAdvInterval 30;
   MaxRtrAdvInterval 100;

   
   AdvLinkMTU 1450;
   

   
   AdvOtherConfigFlag on;
   

   

   

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

   
};
```

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

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/host
```
#### (5.7.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/addn_hosts
2001:db8:3333:0:f816:3eff:fe2c:1d48	host-2001-db8-3333-0-f816-3eff-fe2c-1d48.openstacklocal host-2001-db8-3333-0-f816-3eff-fe2c-1d48
2001:db8:3333::1	host-2001-db8-3333--1.openstacklocal host-2001-db8-3333--1
```
#### (5.7.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/opts
tag:tag0,option6:domain-search,openstacklocal
```

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/leases
duid 00:01:00:01:26:04:1e:c1:fa:16:3e:2c:1d:48
```

### (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-1a323388-06"
            tag: 4095
            Interface "qr-1a323388-06"
                type: internal
        Port "tap04567bd3-61"
            tag: 4095
            Interface "tap04567bd3-61"
                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
 12(tap04567bd3-61): addr:fa:16:3e:2c:1d:48
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 13(qr-1a323388-06): addr:fa:16:3e:06:30:86
     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-dhcpv6-stateless ipv6-port-dhcpv6-stateless
```

### (6.2) Portリソースを確認しておく
```
# openstack port show ipv6-port-dhcpv6-stateless -f json
{
  "allowed_address_pairs": "", 
  "extra_dhcp_opts": "", 
  "updated_at": "2020-03-17T23:57:18Z", 
  "dns_domain": null, 
  "device_owner": "", 
  "revision_number": 2, 
  "port_security_enabled": true, 
  "fixed_ips": "ip_address='2001:db8:3333:0:f816:3eff:fe1e:63c1', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'", 
  "id": "bdd5ce99-8ed2-4941-9e12-703355901f19", 
  "description": "", 
  "binding_vnic_type": "normal", 
  "qos_policy_id": null, 
  "mac_address": "fa:16:3e:1e:63:c1", 
  "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-dhcpv6-stateless", 
  "admin_state_up": "UP", 
  "network_id": "3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9", 
  "dns_name": null, 
  "created_at": "2020-03-17T23:57:18Z", 
  "data_plane_status": null, 
  "binding_host_id": null
}
```

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

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/host
```
#### (6.3.2) add_hostファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/addn_hosts
2001:db8:3333:0:f816:3eff:fe2c:1d48	host-2001-db8-3333-0-f816-3eff-fe2c-1d48.openstacklocal host-2001-db8-3333-0-f816-3eff-fe2c-1d48
2001:db8:3333::1	host-2001-db8-3333--1.openstacklocal host-2001-db8-3333--1
2001:db8:3333:0:f816:3eff:fe1e:63c1	host-2001-db8-3333-0-f816-3eff-fe1e-63c1.openstacklocal host-2001-db8-3333-0-f816-3eff-fe1e-63c1
```
#### (6.3.3) optファイルを確認する

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/opts
tag:tag0,option6:domain-search,openstacklocal
```

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/leases
duid 00:01:00:01:26:04:1e:c1:fa:16:3e:2c:1d:48
```

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

```text:/var/lib/neutron/ra/b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc.radvd.conf
interface qr-1a323388-06
{
   AdvSendAdvert on;
   MinRtrAdvInterval 30;
   MaxRtrAdvInterval 100;

   
   AdvLinkMTU 1450;
   

   
   AdvOtherConfigFlag on;
   

   

   

   
   prefix 2001:db8:3333::/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-1a323388-06"
            tag: 4095
            Interface "qr-1a323388-06"
                type: internal
        Port "tap04567bd3-61"
            tag: 4095
            Interface "tap04567bd3-61"
                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
 12(tap04567bd3-61): addr:fa:16:3e:2c:1d:48
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 13(qr-1a323388-06): addr:fa:16:3e:06:30:86
     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:1e:63:c1"</b>のMACアドレスを設定しておき、<b>"2001:db8:3333:0:f816:3eff:fe1e:63c1"</b>のIPv6アドレスを自動で割り当てることが期待値です

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

  "fixed_ips": "ip_address='2001:db8:3333:0:f816:3eff:fe1e:63c1', subnet_id='4858fea0-4484-4b61-b4b2-d186fabf2496'",

  ...(snip)

  "mac_address": "fa:16:3e:1e:63:c1",

  ...(snip)
}
```

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

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

```
# ip netns add client
# ip netns
client
qrouter-b7858c74-b29f-44b7-bc9a-cb75f7c5b9dc (id: 5)
qdhcp-3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9 (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-1a323388-06"
            tag: 4095
            Interface "qr-1a323388-06"
                type: internal
        Port "tap04567bd3-61"
            tag: 4095
            Interface "tap04567bd3-61"
                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 "qr-1a323388-06"
            tag: 4095
            Interface "qr-1a323388-06"
                type: internal
        Port "tap04567bd3-61"
            tag: 4095
            Interface "tap04567bd3-61"
                type: internal
        Port "ovs-veth0"
            tag: 4095
            Interface "ovs-veth0"
        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:1e:63:c1
```
```
# 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
22: client-veth0@if23: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether fa:16:3e:1e:63:c1 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
22: client-veth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:1e:63:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 2001:db8:3333:0:f816:3eff:fe1e:63c1/64 scope global mngtmpaddr dynamic 
       valid_lft 86396sec preferred_lft 14396sec
    inet6 fe80::f816:3eff:fe1e:63c1/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
 12(tap04567bd3-61): addr:fa:16:3e:2c:1d:48
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 13(qr-1a323388-06): addr:fa:16:3e:06:30:86
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 14(ovs-veth0): addr:da:81:10:ad:4d:10
     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:3333:0:f816:3eff:fe1e:63c1/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
22: client-veth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:1e:63:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 2001:db8:3333:0:f816:3eff:fe1e:63c1/64 scope global mngtmpaddr dynamic 
       valid_lft 86387sec preferred_lft 14387sec
    inet6 fe80::f816:3eff:fe1e:63c1/64 scope link 
       valid_lft forever preferred_lft forever
```
#### (7.7.2) ルーティング情報を確認する
radvd環境が動作しているインタフェースのリンクローカルアドレスがデフォルトゲートウェイとして設定されていました

```
# ip netns exec client ip -6 route show
2001:db8:3333::/64 dev client-veth0 proto kernel metric 256 expires 86382sec mtu 1450 pref medium
fe80::/64 dev client-veth0 proto kernel metric 256 mtu 1450 pref medium
default via fe80::f816:3eff:fe06:3086 dev client-veth0 proto ra metric 1024 expires 282sec mtu 1450 hoplimit 64 pref medium
```

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

```
# ip netns exec client ping6 2001:db8:3333:0:f816:3eff:fe2c:1d48
PING 2001:db8:3333:0:f816:3eff:fe2c:1d48(2001:db8:3333:0:f816:3eff:fe2c:1d48) 56 data bytes
64 bytes from 2001:db8:3333:0:f816:3eff:fe2c:1d48: icmp_seq=1 ttl=64 time=1.13 ms
64 bytes from 2001:db8:3333:0:f816:3eff:fe2c:1d48: icmp_seq=2 ttl=64 time=0.123 ms
64 bytes from 2001:db8:3333:0:f816:3eff:fe2c:1d48: icmp_seq=3 ttl=64 time=0.113 ms
64 bytes from 2001:db8:3333:0:f816:3eff:fe2c:1d48: icmp_seq=4 ttl=64 time=0.119 ms
^C
--- 2001:db8:3333:0:f816:3eff:fe2c:1d48 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.113/0.373/1.138/0.441 ms
```

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

```
# ip netns exec client ping6 2001:db8:3333::1
PING 2001:db8:3333::1(2001:db8:3333::1) 56 data bytes
64 bytes from 2001:db8:3333::1: icmp_seq=1 ttl=64 time=0.890 ms
64 bytes from 2001:db8:3333::1: icmp_seq=2 ttl=64 time=0.174 ms
64 bytes from 2001:db8:3333::1: icmp_seq=3 ttl=64 time=0.124 ms
64 bytes from 2001:db8:3333::1: icmp_seq=4 ttl=64 time=0.164 ms
^C
--- 2001:db8:3333::1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.124/0.338/0.890/0.319 ms
```

## 8. dhclient動作確認の作業履歴
実際に、DHCPv6プロトコルを使用して、dhclient動作結果を確認します

### (8.1) dhclientを起動する

```
# ip netns exec client dhclient -v -6 -S client-veth0
Internet Systems Consortium DHCP Client 4.2.5
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on Socket/client-veth0
Sending on   Socket/client-veth0
PRC: Requesting information (INIT).
XMT: Forming Info-Request, 0 ms elapsed.
XMT: Info-Request on client-veth0, interval 1020ms.
RCV: Reply message on client-veth0 from fe80::f816:3eff:fe2c:1d48.
PRC: Done.
```

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

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/host
```

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

```text:/var/lib/neutron/dhcp/3f5d8a65-5f14-4df2-b91e-ef0fd92a5cb9/leases
duid 00:01:00:01:26:04:1e:c1:fa:16:3e:2c:1d:48
```

#### (8.2.3) DHCPクライアントでのlease情報を確認する

```text:/var/lib/dhclient/dhclient6.leases
```
`dhclient6.leases`ファイルには、何も書き込まれないんですね
以上です。

# ■ 参考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)