STUDY · NETWORK GUIDE

3-14 NDP と SLAAC — 近隣探索とアドレス自動設定

IPv6 の近隣探索 NDP とアドレス自動設定 SLAAC を扱う。NS / NA / RS / RA の 4 メッセージ、EUI-64、重複検出 DAD、DHCPv6 との対比を、CML2.9 IOS-XE 17.x の debug ipv6 nd で実機確認する。

1. 前節の振り返りと本節の内容

3-13 では、IPv6 のアドレス体系を扱いました。128 ビットを 16 進数 8 グループで表記すること、/64 を基本単位としてプレフィックスとインタフェース ID (IID = Interface ID) に分かれること、アドレス種別 (GUA / LLA / ULA / マルチキャスト / anycast) が先頭プレフィックスで決まること、そして 1 つのインタフェースが LLA + GUA + ULA + anycast を同時に持つことを、show ipv6 interface / show ipv6 route で確認しました。

3-13 では、いくつかの事実を「結果」として示すにとどめ、その仕組みを次節へ送りました。LLA (Link-Local Address) が ipv6 enable だけで MAC アドレスから生成されること、ホストが手動設定なしに RA (Router Advertisement) を受けて GUA / ULA を自動取得したこと、show ipv6 neighbors にアドレスが state 付きで現れること、各ユニキャストアドレスが対応する solicited-node マルチキャストに自動参加すること。これらの仕組みそのものが、本節 3-14 の主題です。

本節 3-14 では、IPv6 が近隣のノードを探し当てる NDP (Neighbor Discovery Protocol) と、ホストが自分でアドレスを決める SLAAC (StateLess Address AutoConfiguration) を扱います。NDP の NS / NA / RS / RA という 4 種類のメッセージ、MAC アドレスから IID を作る EUI-64 (Extended Unique Identifier 64) のフル展開、重複アドレスを検出する DAD (Duplicate Address Detection)、そして RA を受けてホストがアドレスを自動生成する SLAAC と DHCPv6 (Dynamic Host Configuration Protocol for IPv6) との対比を、CML2.9 IOS-XE 17.x の R1 と HOST を使い、debug ipv6 nd / show ipv6 interface / show ipv6 neighbors の出力で裏付けます。


2. NDP とは — ICMPv6 上で動く近隣探索

NDP (Neighbor Discovery Protocol) は、同一リンク上のノード同士が、相手の存在・MAC アドレス・ルータの所在を知るための仕組みです。RFC 4861 で規定され、すべて ICMPv6 (Internet Control Message Protocol for IPv6) のメッセージとして動きます。IPv6 でアドレス解決・ルータ探索・アドレス自動設定の起点になる、L3 の基盤プロトコルです。

NDP の役割は、IPv4 では複数の別々の仕組みが分担していました。RFC 4861 §3.1 は NDP の対応物を、隣接ノードの MAC アドレス解決の ARP (Address Resolution Protocol)、ルータ探索の ICMP Router Discovery、経路の最適化案内の ICMP Redirect の組み合わせとして整理しています。IPv6 ではこれらをすべて NDP が ICMPv6 上で統合します (なお、MAC から IP を逆引きする古い RARP は NDP の対応物には含まれません。SLAAC / RA はホストが自分でアドレスを決める仕組みで、RARP の直接の置き換えではありません)。ARP のように L2 と L3 の間 (L2.5) に独立したプロトコルを置くのではなく、ICMPv6 という L3 の枠組みに一本化した点が、IPv4 との設計上の大きな違いです。

NDP が使う ICMPv6 のメッセージは、Type 133 から 137 の 5 種類です。本節では、このうちアドレス解決とアドレス自動設定で中心となる NS / NA / RS / RA の 4 つを詳しく扱い、5 番目の Redirect (Type 137) は概念のみ触れます。


3. 本ラボのトポロジ — R1 が RA を送り HOST が SLAAC でアドレス取得

検証ラボは、2001:db8:0:14::/64 (GUA) と fd00:14::/64 (ULA) の 2 つのプレフィックスを持つ 1 つの IPv6 セグメント上に、RA を送出するルータ R1 と、アドレス取得を観察する HOST を 2 台置いた構成です。SW (unmanaged_switch) が 3 ノードを同一リンクに収めます。R1 は ipv6 unicast-routing で RA 送出を有効にし、Gi2 に GUA 2001:db8:0:14::1/64 と ULA fd00:14::1/64 を設定して、両プレフィックスを RA で広告します。

2 台の HOST は、アドレスの取得方法を意図的に分けています。HOST1 は day0 で IPv6 アドレスを 1 つも設定せず、eth0 を up にするだけで R1 の RA を受けて SLAAC でアドレスを自動取得します。HOST2 は、R1 と重複する GUA 2001:db8:0:14::1/64 を手動で設定し、DAD で重複が検出される様子を観察します。HOST1 が「正常な SLAAC」、HOST2 が「DAD 衝突」を担い、1 つのラボで両方を対比できます。

各ノードに割り当てたアドレスは以下のとおりです。本節で使うアドレスはすべて小文字で表記しますが、後で引用する show / debug 出力では IOS-XE が大文字 (2001:DB8) で表示します。表記の大小は同じアドレスを指します。

ノード種別アドレス取得方法
R1 Gi2GUA2001:db8:0:14::1/64手動設定 (RA でこのプレフィックスを広告)
R1 Gi2ULAfd00:14::1/64手動設定 (RA で広告)
R1 Gi2LLAfe80::5054:ff:fe69:1bd8ipv6 enable で自動生成 (RA の送信元)
HOST1SLAAC GUA2001:db8:0:14:5054:ff:fe62:92cd/64RA プレフィックス + EUI-64 で自動取得
HOST1SLAAC ULAfd00:14::5054:ff:fe62:92cd/64RA プレフィックス + EUI-64 で自動取得
HOST1LLAfe80::5054:ff:fe62:92cd/64起動時に自動生成
HOST2手動 GUA2001:db8:0:14::1/64手動設定 (R1 と重複 → DAD で DUPLICATE)

トポロジ全体は以下のとおりです。図に描かれた HOST1 の GUA 2001:db8:0:14:5054:ff:fe86:f81d は、EUI-64 の説明で使う MAC 52:54:00:86:f8:1d に基づく例です。実機の HOST1 は MAC 52:54:00:62:92:cd を持つため、実機の SLAAC GUA は 2001:db8:0:14:5054:ff:fe62:92cd になります。生成の仕組みは同じで、もとにする MAC が異なる点に注意してください。

3-14 NDP + SLAAC ラボトポロジ。R1 が 2001:db8:0:14::/64 (GUA) と fd00:14::/64 (ULA) のプレフィックスを RA で広告する。HOST1 は手動設定なしで RA を受けて SLAAC でアドレスを自動取得し、図では EUI-64 例 (MAC 52:54:00:86:f8:1d) の GUA 2001:db8:0:14:5054:ff:fe86:f81d を示す。HOST2 は R1 と重複する 2001:db8:0:14::1 を手動設定し、DAD で DUPLICATE 検出される

4. NDP の 4 メッセージ — NS / NA / RS / RA

NDP の中心となるメッセージは、NS / NA / RS / RA の 4 つです。それぞれ ICMPv6 の Type 番号を持ち、アドレス解決とアドレス自動設定という 2 つの目的のために、送信元と宛先を使い分けます。

NS (Neighbor Solicitation、Type 135) は、相手の MAC アドレスを知るためのアドレス解決と、後述の DAD で使われます。送信元は通常自分の LLA (DAD では unspecified ::)、宛先は相手の solicited-node マルチキャストです。NA (Neighbor Advertisement、Type 136) は NS への応答で、自分の MAC アドレスを通知します。送信元は広告を送るインタフェースのアドレス (本ラボの観察では LLA。RFC 4861 §4.4 上は「そのインタフェースに割り当てられたアドレス」であり必ずしも LLA とは限りません)、宛先は要請元 (要請元が :: のときなど一部条件では all-nodes ff02::1) です。この NS / NA のペアが、IPv4 の ARP に相当する役割を果たします。

RS (Router Solicitation、Type 133) は、ホストが起動時にルータを探すメッセージで、宛先は all-routers ff02::2 です。RA (Router Advertisement、Type 134) は、ルータがプレフィックスや既定ゲートウェイを広告するメッセージです。宛先は、トリガとなった RS の送信元 (ユニキャスト) か all-nodes ff02::1 で、ルータが周期送出する RA は all-nodes 宛になります (RFC 4861 §4.2)。RA は RS への応答として送られるほか、ルータが周期的にも送出します。この RS / RA のペアが、ホストのアドレス自動設定の起点になります。4 メッセージの役割と ICMPv6 Type、送信元と宛先は以下のとおりです。

NDP の 4 メッセージは ICMPv6 で動く (Type 133-136)。RS (Type 133) はホストがルータを探し all-routers ff02::2 宛、RA (Type 134) はルータがプレフィックス・既定 GW を広告し all-nodes ff02::1 宛、NS (Type 135) は相手の MAC を要請 (アドレス解決) / DAD で相手の solicited-node 宛、NA (Type 136) は NS への応答で要請元宛。IPv4 では ARP / ICMP Router Discovery / ICMP Redirect が別々に担っていた役割を NDP が ICMPv6 上で統合する

5. アドレス解決 — NS / NA と neighbor state

アドレス解決は、通信相手の IPv6 アドレスは分かっているが MAC アドレスが不明なときに、NS で問い合わせ NA で答えを得る手順です。IPv4 の ARP に相当しますが、宛先がブロードキャストではなく solicited-node マルチキャストである点が異なります。これにより、リンク上の無関係なノードへの負荷を抑えられます。

実機では、HOST1 から R1 のアドレスへ通信が発生した瞬間に、R1 の debug ipv6 nd でアドレス解決の一連の流れを捕捉できます。R1 が相手 (HOST1 の LLA FE80::5054:FF:FE62:92CD) を解決する過程で、neighbor の状態が DELETE → INCMP → REACH と遷移します。Resolution request で解決を始め、Sending NS で問い合わせ、Received NA で応答を受け取り、相手の MAC (5254.0062.92cd) を学習します。出力は以下のとおりです。

snippet
*Jun  4 13:29:10.120: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) Resolution request
*Jun  4 13:29:10.120: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) DELETE -> INCMP
*Jun  4 13:29:10.131: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) Sending NS
*Jun  4 13:29:10.133: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) Received NA from FE80::5054:FF:FE62:92CD
*Jun  4 13:29:10.133: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) LLA 5254.0062.92cd
*Jun  4 13:29:10.133: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE62:92CD) INCMP -> REACH
*Jun  4 13:29:15.121: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE69:1BD8) Received NS from FE80::5054:FF:FE62:92CD
*Jun  4 13:29:15.121: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE69:1BD8) Sending NA to FE80::5054:FF:FE62:92CD

この出力の後半は、逆方向のアドレス解決です。R1 (LLA FE80::5054:FF:FE69:1BD8) が HOST1 から Received NS を受け取り、Sending NA で自分の MAC を応答しています。NS / NA は片方向の手順ではなく、互いに相手を解決し合う双方向のやり取りである点が読み取れます。

解決の結果は neighbor 表に記録されます。show ipv6 neighbors を見ると、HOST1 の LLA FE80::5054:FF:FE62:92CD が、その MAC 5254.0062.92cd と state REACH、インタフェース Gi2 に対応付けられて現れます。この neighbor 表が、IPv4 の ARP テーブルに相当します。

snippet
show ipv6 neighbors
IPv6 Address                              Age Link-layer Addr State Interface
FE80::5054:FF:FE62:92CD                     0 5254.0062.92cd  REACH Gi2

neighbor の state は、その相手がどれだけ確実に到達できるかを表します。代表的な値は、debug ipv6 nd で見た解決中の INCMP (Incomplete、解決待ち)、応答を得た REACH (Reachable、到達確認済み)、そして一定時間使われずに古くなった STALE です。実際、同じ neighbor は時間が経つと REACH -> STALE へ遷移します。show ipv6 neighbors の state 列は省略形の REACH / STALE で表示され、debug の出力では INCMP / REACH のように内部状態が現れます。アドレス解決の流れは以下のとおりです。

アドレス解決: NS を solicited-node 宛に送り、NA で MAC を得る。① HOST1 が R1 の MAC を知りたいとき、NS (Type 135) を R1 の solicited-node マルチキャスト ff02::1:ff00:1 宛に送る。② R1 は NA (Type 136) で自分の MAC を応答する。③ 解決結果は neighbor 表に記録され、state が INCMP → REACH → STALE と遷移する。IPv4 ARP がリンク全体へブロードキャストするのに対し、NDP の NS は solicited-node マルチキャスト宛なので関係するノードだけが受け取る

solicited-node マルチキャストは、ターゲットアドレスの下位 24 ビットを使って算出するマルチキャストアドレスです。プレフィックス ff02::1:ff00:0/104 にターゲットの下位 24 ビットを付けて作ります。R1 の GUA 2001:db8:0:14::1 のように下位がほぼ 0 のアドレスなら、solicited-node は ff02::1:ff00:1 になります。HOST1 の LLA fe80::5054:ff:fe62:92cd であれば、下位 24 ビット 62:92cd から ff02::1:ff62:92cd になります。3-13 §7 で show ipv6 interface の “Joined group address(es)” に各アドレスの solicited-node が並んでいた理由が、この NS の宛先として使われるためです。


6. EUI-64 — MAC からインタフェース ID を作る

EUI-64 (Extended Unique Identifier 64) は、48 ビットの MAC アドレスから 64 ビットのインタフェース ID (IID) を作る規則です。LLA も SLAAC で生成する GUA / ULA も、この IID を MAC アドレスから EUI-64 で組み立てます。3-13 §4 では LLA の出所として 1 段だけ示しましたが、本節では SLAAC のアドレス生成と絡めてフルに展開します。

EUI-64 の手順は次の 3 段階です。図と合わせるため、MAC 52:54:00:86:f8:1d を例に説明します。

  1. MAC を 2 分割する: MAC を上位 3 オクテット 52:54:00 (OUI = ベンダ識別子) と下位 3 オクテット 86:f8:1d (NIC 固有部) に分けます。
  2. 中央に ff:fe を挿入する: 上位 3 オクテットと下位 3 オクテットの間に ff:fe を挟み、52:54:00:ff:fe:86:f8:1d という 64 ビットにします。
  3. 先頭オクテットの U/L ビットを反転する: 先頭オクテット 0x52 (0101 0010) の下位から 2 番目のビット (U/L ビット) を反転し、0x50 (0101 0000) にします。

この結果、IID は 5054:00ff:fe86:f81d となり、省略表記では 5054:ff:fe86:f81d です。LLA はプレフィックス fe80::/64 と結合して fe80::5054:ff:fe86:f81d、SLAAC GUA は RA のプレフィックス 2001:db8:0:14::/64 と結合して 2001:db8:0:14:5054:ff:fe86:f81d になります。手順 3 の U/L ビットは「グローバル一意 (0) かローカル管理 (1) か」を示すビットで、EUI-64 (RFC 4291) の規約は このビットを反転する ことです (常に 1 にするわけではありません)。本例の MAC 先頭オクテット 0x52 (0101 0010) は U/L ビットが既に 1 のローカル管理アドレスなので、反転すると 0 になり 0x50 (0101 0000) となります。逆に、ベンダ割り当てのグローバル一意 MAC (U/L ビット 0) を変換した場合は反転で 1 になります。

実機の HOST1 で、この生成規則が成り立つことを検算できます。HOST1 の MAC は ip link show eth052:54:00:62:92:cd でした。同じ手順を適用すると、IID は 5054:ff:fe62:92cd になり、HOST1 が実際に持つ LLA fe80::5054:ff:fe62:92cd と SLAAC GUA 2001:db8:0:14:5054:ff:fe62:92cd に一致します。

snippet
HOST1:~$ ip link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:62:92:cd brd ff:ff:ff:ff:ff:ff

このように、MAC アドレスさえ分かれば LLA も SLAAC アドレスの IID も計算で再現できます。EUI-64 で IID を作るフローは以下のとおりです。

SLAAC: RA のプレフィックス + EUI-64 の IID = 自動生成アドレス。① HOST が起動時に RS (Type 133) を送り、② R1 が RA (Type 134) でプレフィックス 2001:db8:0:14::/64 を広告する。HOST は自分の MAC 52:54:00:86:f8:1d を EUI-64 で IID 化する。MAC を 52:54:00 と 86:f8:1d に 2 分割し、中央に ff:fe を挿入して 52:54:00:ff:fe:86:f8:1d、先頭オクテットの U/L ビットを反転して 52 → 50、IID は 5054:00ff:fe86:f81d となる。プレフィックスと IID を結合して SLAAC GUA 2001:db8:0:14:5054:ff:fe86:f81d を生成し、DAD で重複が無いことを確かめて valid になる

7. SLAAC — RA のプレフィックスからアドレスを自動生成

SLAAC (StateLess Address AutoConfiguration) は、ホストが DHCP サーバを使わず、ルータの RA とプレフィックスだけを使ってアドレスを自分で決める仕組みです。「ステートレス」とは、どのホストにどのアドレスを割り当てたかを集中管理するサーバ (= ステートを持つ装置) が不要であることを意味します。ホストは RA で受け取ったプレフィックスに、IID (インタフェース ID) を結合してアドレスを生成します。本ラボの HOST は IID を MAC から EUI-64 で作る方式で動いていますが、IID の生成方式は実装依存であり、現在は RFC 8064 が RFC 7217 のセキュア・安定プライバシー IID を既定として推奨しています (リンク層アドレスを埋め込む EUI-64 を既定にしないことを推奨)。本節では「本ラボの設定 / 実装では EUI-64 を使う」前提で読み進めてください。

SLAAC の起点は RA です。R1 は周期的に RA を all-nodes FF02::1 宛に送り、その中にプレフィックス情報オプション (PIO = Prefix Information Option) を含めます。debug ipv6 nd で RA の送出を捕捉すると、Sending RA の後にプレフィックス 2001:DB8:0:14::/64FD00:14::/64[LA] フラグ付きで広告されているのが分かります。

snippet
*Jun  4 13:23:28.225: ICMPv6-ND: (GigabitEthernet2,FE80::5054:FF:FE69:1BD8) Sending RA (1800) to FF02::1
*Jun  4 13:23:28.225: ICMPv6-ND:   MTU = 1500
*Jun  4 13:23:28.225: ICMPv6-ND:   prefix 2001:DB8:0:14::/64 [LA] 2592000/604800
*Jun  4 13:23:28.225: ICMPv6-ND:   prefix FD00:14::/64 [LA] 2592000/604800

[LA]AAutonomous フラグで、「このプレフィックスを SLAAC のアドレス生成に使ってよい」ことを示します。L は on-link フラグです。A フラグが立っているため、ホストはこの 2 つのプレフィックスから SLAAC でアドレスを作ります。末尾の 2592000/604800 は、アドレスの valid lifetime (2592000 秒 = 30 日) と preferred lifetime (604800 秒 = 7 日) です。RA (1800)1800 は、このルータを既定ゲートウェイとして使ってよい有効期間 (1800 秒) を示します。

ホスト側で結果を見ると、SLAAC がアドレスを生成したことが確認できます。HOST1 は day0 で IPv6 アドレスを 1 つも設定していませんが、ip -6 addr show eth0 には GUA 2001:db8:0:14:5054:ff:fe62:92cd、ULA fd00:14::5054:ff:fe62:92cd、LLA fe80::5054:ff:fe62:92cd の 3 つが並びます。GUA と ULA は scope global dynamic で、RA を受けて動的に取得したことを示します。

snippet
HOST1:~$ ip -6 addr show eth0
    inet6 fd00:14::5054:ff:fe62:92cd/64 scope global dynamic flags 100
    inet6 2001:db8:0:14:5054:ff:fe62:92cd/64 scope global dynamic flags 100
    inet6 fe80::5054:ff:fe62:92cd/64 scope link
HOST1:~$ ip -6 route show
default via fe80::5054:ff:fe69:1bd8 dev eth0  metric 1024  expires 0sec

SLAAC がホストに与えるのは、アドレスだけではありません。ip -6 route showdefault via fe80::5054:ff:fe69:1bd8 が示すとおり、既定ゲートウェイも RA から学習します。このゲートウェイは R1 の LLA で、RA の送信元アドレスがそのまま既定ゲートウェイになります。RA を受けてプレフィックスからアドレスを作り、RA の送信元を既定ゲートウェイにする。この 2 つで、ホストは DHCP サーバなしに L3 で通信できる状態になります。

なお、R1 は RA をデフォルトでは 200 秒周期で送出します。show ipv6 interfaceND router advertisements are sent every ... seconds がその周期です。本ラボでは観察に時間がかかるのを避けるため、ipv6 nd ra interval 30 で周期を 30 秒に短縮しています。後述の show ipv6 interface の出力に every 30 seconds と出るのはこの設定によるもので、デフォルトは 200 秒です。


8. DAD — 重複アドレス検出

DAD (Duplicate Address Detection) は、新しいアドレスを使い始める前に、同一リンク上に同じアドレスが既に存在しないかを確認する手順です。LLA であれ SLAAC で生成した GUA であれ手動設定したアドレスであれ、IPv6 のアドレスは付与された直後は tentative (仮) という状態で、DAD を通過するまで通信に使われません。

DAD は NS を DupAddrDetectTransmits 回 (IOS-XE / Linux の既定では 1 回) 打って確認します (この値を 0 にすると DAD を行いません)。このときの NS は、アドレス解決の NS とは送信元が異なります。送信元は unspecified :: で、宛先は tentative アドレスの solicited-node マルチキャストです。送信元を :: にするのは、まだそのアドレスが自分のものとして確定していないためです。同じアドレスを既に使っているノードがいれば NA が返って重複と判定され、また 2 ノードが同時に同じアドレスで DAD を行った場合は相手の NS を受信することでも重複を検出します。誰も応答せず重複も無ければ、そのアドレスは valid になり通信に使えます。

実機では、R1 にテスト用のアドレス 2001:DB8:0:14::DAD を追加した瞬間の DAD NS を捕捉できました。DAD request でアドレスが tentative になり、Sending DAD NS で確認の NS を送出しています。

snippet
*Jun  4 13:29:57.904: IPv6-Addrmgr-ND: DAD request for 2001:DB8:0:14::DAD on GigabitEthernet2
*Jun  4 13:29:57.920: ICMPv6-ND: (GigabitEthernet2,2001:DB8:0:14::DAD) Sending DAD NS [Nonce: 3e68.b21e.1549]

末尾の Nonce は、自分が送った NS を自分で受信してしまうループ (同一ノードでの誤検出) を防ぐための乱数で、RFC 7527 で規定された拡張です。

DAD が重複を検出すると、そのアドレスは使えなくなります。本ラボでは、HOST2 が R1 と同じ 2001:db8:0:14::1 を手動設定したことで重複が発生しました。結果は、R1 側の show ipv6 interface に現れます。GUA 2001:DB8:0:14::1[DUP] マークが付き、syslog に %IPV6_ND-4-DUPLICATE が記録されました。

snippet
*Jun  4 13:19:24.596: %IPV6_ND-4-DUPLICATE: Duplicate address 2001:DB8:0:14::1 on GigabitEthernet2
snippet
show ipv6 interface GigabitEthernet2
  Global unicast address(es):
    2001:DB8:0:14::1, subnet is 2001:DB8:0:14::/64 [DUP]
    FD00:14::1, subnet is FD00:14::/64

ここで注意したいのは、重複の影響を受けたのが後から設定した HOST2 ではなく、先に設定していたルータ R1 だった点です。HOST2 (alpine) 側の ip -6 addr show eth0 を見ると、重複した 2001:db8:0:14::1scope global のまま保持され、使い続けられています。

snippet
HOST2:~$ ip -6 addr show eth0
    inet6 fd00:14::5054:ff:fee7:495b/64 scope global dynamic flags 100
    inet6 2001:db8:0:14:5054:ff:fee7:495b/64 scope global dynamic flags 100
    inet6 2001:db8:0:14::1/64 scope global
    inet6 fe80::5054:ff:fee7:495b/64 scope link

「重複すると後から来た方が負ける」と単純化されがちですが、本ラボではこのとおり R1 が自分の ::1 を失い、HOST2 が保持しました。DAD で重複が検出されたとき、どちらが使用不可になるかは実装やタイミングに依存します。確実に言えるのは、重複は両者にとって危険であり、手動で固定アドレスを割り当てるときは重複を避けなければならないという点です。DAD のフローは以下のとおりです。

DAD は :: 送信元で重複を確認。SLAAC するかは PIO の A フラグ、DHCPv6 が使えるかは M/O フラグが案内する。上段の DAD (Duplicate Address Detection) は、① 新アドレスが tentative (仮) の段階で、② 送信元 :: (unspecified)・宛先 solicited-node マルチキャスト ff02::1:ff00:1 宛に NS を打ち、③ 応答が無ければ valid、NA が返れば DUPLICATE 検出となる。下段はアドレスの配り方で、A=1 のプレフィックスがあれば SLAAC でアドレス生成、M=0/O=0 が純 SLAAC、M=0/O=1 がステートレス DHCPv6 (補助情報のみ)、M=1 がステートフル DHCPv6 (アドレスも DHCPv6 から。A=1 が残れば SLAAC と併存し得る)

なお、HOST2 は手動設定した 2001:db8:0:14::1 とは別に、SLAAC で 2001:db8:0:14:5054:ff:fee7:495b も自動取得しています (MAC 52:54:00:e7:49:5b の EUI-64)。手動アドレスの重複と、SLAAC による自動取得は独立して動くため、片方が重複してももう片方は正常に付与されます。


9. SLAAC と DHCPv6 — ステートレスとステートフル

ホストにアドレスを配る方法は、SLAAC と DHCPv6 の 2 系統があります。ここで正確に押さえたいのは、「SLAAC でアドレスを作るかどうか」を本質的に決めるのは、RA の各プレフィックス情報オプション (PIO) に立つ A (Autonomous) フラグ だという点です (RFC 4862 §5.5.3)。A=1 のプレフィックスがあれば、ホストはそこから SLAAC でアドレスを生成します。

一方、RA ヘッダの M フラグ (Managed) と O フラグ (Other) は「DHCPv6 が利用可能かどうか」を案内するフラグ です (RFC 4861 §4.2)。M=1 は「アドレスを DHCPv6 から取得してよい」、O=1 は「アドレス以外の補助情報 (DNS など) を DHCPv6 から取得してよい」を示します。M/O は SLAAC を直接 ON/OFF するスイッチではない ため、たとえば M=1 でも A=1 のプレフィックスが広告されていれば SLAAC と DHCPv6 アドレスが併存し得ます (SLAAC を止めたいなら、そのプレフィックスを ipv6 nd prefix ... no-autoconfig で A=0 にします)。

代表的な運用上の組み合わせは次の 3 つです。純 SLAAC (M=0 / O=0 + A=1 プレフィックス) は、アドレスも補助情報もすべて RA から得るステートレス方式。ステートレス DHCPv6 (M=0 / O=1) は、アドレスは SLAAC、DNS などの補助情報だけを DHCPv6 から得る方式。ステートフル DHCPv6 (M=1、SLAAC を併用しない場合は A=0) は、アドレスを DHCPv6 サーバが割り当てる方式で、IPv4 の DHCP に最も近い動作です。対比は以下の表のとおりです (「アドレスの出所」は代表的な構成での挙動)。

方式M / O フラグPIO の A フラグアドレスの出所補助情報の出所
純 SLAACM=0 / O=0A=1SLAAC (RA + EUI-64 等)RA
ステートレス DHCPv6M=0 / O=1A=1SLAAC (RA + EUI-64 等)DHCPv6
ステートフル DHCPv6M=1A=0 (SLAAC 併用なら A=1)DHCPv6 サーバDHCPv6

実機で M / O フラグを切り替えると、show ipv6 interface の表示が変わります。ただし IOS-XE 17.x は、M=1O=1 という数値を直接は表示せず、人間が読める文で表します。デフォルト (純 SLAAC) では Hosts use stateless autoconfig for addresses. の 1 行だけが出ます。

snippet
show ipv6 interface GigabitEthernet2
  ...
  ND router advertisements are sent every 30 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.

R1 に ipv6 nd other-config-flag を設定して O=1 にすると、上の行に加えて Hosts use DHCP to obtain other configuration. の行が追加されます。アドレスは引き続き SLAAC、補助情報のみ DHCPv6 という状態です。

snippet
  Hosts use stateless autoconfig for addresses.
  Hosts use DHCP to obtain other configuration.

さらに ipv6 nd managed-config-flag で M=1 にすると、Hosts use stateless autoconfig for addresses. の行が消え、代わりに Hosts use DHCP to obtain routable addresses. が出ます。アドレスそのものを DHCPv6 が配るステートフル DHCPv6 の状態です。

snippet
  Hosts use DHCP to obtain routable addresses.
  Hosts use DHCP to obtain other configuration.

本ラボは、これら 3 つの表示差を確認した後、デフォルト (純 SLAAC) に戻しています。DHCPv6 サーバの構築 (アドレスプール・プレフィックス委任など) は、本節では概念中心とし深追いしません。重要なのは、IPv6 ではアドレス配布が SLAAC か DHCPv6 かを RA の M / O フラグが決め、その状態が show ipv6 interface で確認できるという点です。


10. 落とし穴・補足

本節で押さえておきたい論点と、教科書 / 実装の挙動との差を 5 件まとめます。3-3 から 3-13 と同じ「正直記録」枠で、CML2.9 IOS-XE 17.x (csr1000v) の実装の振る舞いと python での検算を優先します。

落とし穴 1: NDP の主証跡はルータ側の debug / show

本ラボの HOST は alpine の非特権シェルで、3-12 / 3-13 と同様に ip neigh flush のような権限を要する操作が Operation not permitted で実行できません。そのため、NDP / SLAAC の挙動を厳密に追う主証跡は、ルータ側の debug ipv6 ndshow ipv6 neighbors / show ipv6 interface に置いています。HOST 側の ip -6 addr / ip -6 route は、SLAAC の結果や DAD の保持状態を補足的に確認する用途です。「HOST から NDP を能動的に観察できない」と感じたら、観察点をルータ側へ移すのが定石です。

落とし穴 2: debug ipv6 nd は Mgmt-vrf 経由 SSH では terminal monitor が要る

debug ipv6 nd の出力は、デフォルトでは console にしか出ません。本ラボのように Mgmt-vrf 経由の SSH (vty セッション) で debug を観察するには、terminal monitor を実行して debug 出力を vty に転送する必要があります。これを忘れると、debug を有効にしたのに何も流れてこないように見え、capture できません。「debug を有効にしたのにログが出ない」ときは、まず terminal monitor の実行漏れを疑います。

落とし穴 3: RA の周期はデフォルト 200 秒

RA はデフォルトで 200 秒周期で送出されます。debug ipv6 nd を仕掛けてから RA の送出を待つと、最大で 200 秒近くかかることがあります。本ラボでは観察に時間がかかるのを避けるため、ipv6 nd ra interval 30 で周期を 30 秒に短縮しました。show ipv6 interfaceND router advertisements are sent every 30 seconds と出るのはこの設定によるもので、何も設定しない素のデフォルトは 200 秒です。RA の周期を変えても、SLAAC や RA の中身そのものは変わりません。

落とし穴 4: DAD の重複で先に設定した側が負けることがある

DAD で重複が検出されたとき、「後から設定した側が負ける」とは限りません (§8)。本ラボでは、HOST2 が R1 と同じ 2001:db8:0:14::1 を後から手動設定したにもかかわらず、%IPV6_ND-4-DUPLICATE[DUP] マークが付いたのは先に設定していた R1 側でした。HOST2 は重複アドレスを scope global で保持し続けました。どちらが使用不可になるかは実装やタイミングに依存するため、運用上は「重複は両者にとって危険」と捉え、手動の固定アドレスは重複しないよう設計時に管理するのが確実です。

落とし穴 5: M / O フラグは IOS-XE で数値表示されない

教科書で「M フラグ」「O フラグ」と説明される設定は、IOS-XE 17.x の show ipv6 interface では M=1 / O=1 という数値で表示されません (§9)。代わりに、Hosts use stateless autoconfig for addresses. (純 SLAAC)、Hosts use DHCP to obtain other configuration. (O=1)、Hosts use DHCP to obtain routable addresses. (M=1) という人間可読な文で表されます。M=1 にすると stateless autoconfig の行が消える挙動も合わせて、show 出力で M / O の数値を探しても見つからない点に注意します。フラグの状態は、これらの文の有無で読み取ります。


11. 次節

本節 3-14 では、NDP と SLAAC を扱いました。NDP が ICMPv6 上で動く近隣探索の仕組みであること、NS / NA / RS / RA の 4 メッセージ (ICMPv6 Type 133-136) がアドレス解決とアドレス自動設定を担うこと、アドレス解決で neighbor state が INCMP → REACH → STALE と遷移すること、MAC アドレスから EUI-64 で IID を作ること、ホストが RA のプレフィックスと EUI-64 で SLAAC アドレスを自動生成すること、DAD で重複アドレスを検出すること、そしてアドレス配布が RA の M / O フラグで SLAAC か DHCPv6 かに分かれることを、CML2.9 IOS-XE 17.x の debug ipv6 nd / show ipv6 interface / show ipv6 neighbors で裏付けました。3-13 で結果のみ示した EUI-64・neighbor state・solicited-node・SLAAC の仕組みを、本節で回収しました。

ここまでの 3-13 と 3-14 で、IPv6 のアドレス体系とアドレス自動設定を扱いました。残るのは、IPv6 の経路をルータ間でどう交換するかです。次節 3-15 IPv6 ルーティングでは、IPv4 の OSPFv2 / BGP に対応する IPv6 のルーティングプロトコル、すなわち OSPFv3 (Open Shortest Path First version 3) と MP-BGP (Multiprotocol BGP) を扱います。OSPFv3 が OSPFv2 と異なる点 (address-family による IPv4 / IPv6 の分離、LLA でのネイバーピアリング)、MP-BGP が address-family ipv6 unicast で IPv6 経路を運ぶ仕組みを、CML2.9 の実機検証とともに見ていきましょう。


次節