YAMAHA ルータで DHCP 固定割当できない問題と Client Identifier

YAMAHA 製のルータ内で DHCP サーバが動いている状況で、特定のクライアントに対して DHCP サーバから固定の IP アドレスを払い出すように設定したい。

```
dhcp scope bind 1 192.168.0.2 XX:XX:XX:XX:XX:XX
```

とりあえず「IP アドレスと MAC アドレスを紐付けたらいいでしょ」と考えてこのようなコマンドを実行したが、IP アドレスは固定できなかった。

## 3行まとめ
- DHCP の仕様 (RFC2131) で定義されている Client Identifier という機能があり、DHCP クライアントは任意の識別子を DHCP サーバに伝えることができる
- YAMAHA ルータの DHCP サーバは初期設定では Client Identifier を用いた固定割当 (use-clientid 機能) を優先するようになっており、その場合は MAC アドレスで固定割当を設定しても動作しないことがある
- YAMAHA ルータの設定で use-clientid 機能を無効にすることで MAC アドレスによる固定割り当て設定を動作させることができる

## 原因調査をする
[15.1.5 DHCP 予約アドレスの設定 - RTpro - ヤマハ](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/dhcp/dhcp_scope_bind.html)

公式ドキュメントを読むと、こう書いてある。

> [書式]
> dhcp scope bind scope_num ip_address [type] id
> dhcp scope bind scope_num ip_address mac_address
> ...

DHCP 固定割当をするコマンドには複数のフォーマットがあるらしい。
さきほど実行してうまくいかなかったのは第2書式に当たる。

> コマンドの第 2 書式による MAC アドレスでの予約は、クライアントの識別に DHCP パケットの chaddr フィールドを用いる。この形の予約機能は、RT の設定が dhcp server rfc2131 compliant off あるいは use-clientid 機能を使用しない設定になっているか、もしくは DHCP クライアントが DHCP パケット中に Client-Identifier オプションを付けてこない場合でないと動作しない。

つまり、**「設定で use-clientid 機能が有効になっている」かつ「DHCP パケット中に Client-Identifier オプションが付いている」場合は、第2書式で指定した固定割当は動作しない。**

[15.1.2 RFC2131 対応動作の設定 - RTpro - ヤマハ](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/dhcp/dhcp_server_rfc2131_compliant.html)

公式ドキュメントを読むと、use-clientid 機能は初期状態で有効になっていることがわかる。

また、`show status dhcp` を実行した結果を見ると、ほとんどのクライアントで `(タイプ) クライアントID: (01) xx xx xx xx xx xx` と表示されることから、ほとんどの DHCP クライアントのパケットに「Client-Identifier オプションが付いている」ことがわかる。

## DHCP の Client Identifier とは何か
以下のサイトが詳しかった。

[DHCPのクライアントIDオプション：プログラマー社長のブログ：オルタナティブ・ブログ](https://blogs.itmedia.co.jp/komata/2014/10/dhcpid-c2e1.html)

要点を抜粋すると、

- Client Identifier は DHCP の仕様 (RFC2131) に記載されている仕様で「クライアントからクライアント ID が送られてきたら MAC アドレスの代わりにクライアント IDでクライアントを識別せよ」という機能のこと
    - この仕様の趣旨は「ネットワークボードを交換しても同じ払い出しを受けられるようにする」ため
- 実際の DHCP クライアントは、ほとんどがクライアント ID として「0x01 + MAC アドレス」を指定してくる
    - 先頭の 0x01 は種別が MAC アドレスだという意味で、事実上 MAC アドレスで識別しているのと変わらない
- macOS ではネットワーク設定画面から簡単にこのクライアント ID を任意の値に設定できる
    - 同一セグメント内で「クライアント ID」が重複するように設定できてしまう
- 上記サイトの筆者 (長年 DHCP 製品を開発) は、クライアント ID による識別が必要なケースに出会ったことがない

**クライアント ID による識別、やらないほうがいいのではないか？？？**

## クライアント ID による識別を無効にする
YAMAHA ルータでは、以下のコマンドでクライアント ID による識別を無効にすることができる。

```
dhcp server rfc2131 compliant except use-clientid
```

これを設定しておけば、冒頭の

```
dhcp scope bind 1 192.168.0.2 XX:XX:XX:XX:XX:XX
```

このようなコマンド (第2書式) で MAC アドレスによる固定割当が動作するようになる。

## 補足： use-clientid を有効にしたまま固定割当する方法
何らかの事情で use-clientid を無効にできない場合かつクライアントからクライアント ID が送られてくる場合は、第2書式は使えないので第1書式で指定するほかないが、第1書式での指定方法もいくつかある。

(クライアントからクライアント ID が送られてくるかどうかは、一度 IP を払い出してみて `show status dhcp` したらわかる。)
(use-clientid が有効であっても、クライアント ID が送られてこないクライアントに対しては第2書式は使える)

### クライアント ID を指定する方法
MAC アドレスではなくクライアント ID を指定することで固定割当できる。

```
dhcp scope bind 1 192.168.0.2 <クライアントID>
```

`<クライアントID>` はたいてい `01 XX XX XX XX XX XX` (01 + MAC アドレスをスペース区切りにしたもの) が送られてくるが、クライアントが変則的なフォーマットでクライアント ID を指定してくる場合はそれに対応しなければならない。


### type `ethernet` を指定する方法
type `ethernet` を明示することで、クライアント ID が送られてくる場合であっても MAC アドレスによる固定割当ができる。

```
dhcp scope bind 1 192.168.0.2 ethernet <MACアドレス>
```

## 3行まとめ (再掲)
- DHCP の仕様 (RFC2131) で定義されている Client Identifier という機能があり、DHCP クライアントは任意の識別子を DHCP サーバに伝えることができる
- YAMAHA ルータの DHCP サーバは初期設定では Client Identifier を用いた固定割当 (use-clientid 機能) を優先するようになっており、その場合は MAC アドレスで固定割当を設定しても動作しないことがある
- YAMAHA ルータの設定で use-clientid 機能を無効にすることで MAC アドレスによる固定割り当て設定を動作させることができる