2014-02-27

docker exportとdocker importでdockerイメージのサイズを小さくする

Dockerって何かやってくとどんどんディスク圧迫するよね・・・
Dockerは素晴らしいソリューションだし、失敗しても削除すればいいという側面から手軽に使えるのが特に今までの仮想化ソリューションになかったという点が素晴らしいと思う。
でも。でもね。ファイルシステムのレイヤーをどんどん積み上げていくから、ディスクをどんどん圧迫する。

AUFSの仕組みをざっと解説する
幸か不幸か、ずーっと前に仕事でUnionFSを使ったことがあって、一方でDockerで使ってるAUFSは「Another UnionFS」。UnionFSを改良することを目的としたプロダクト。ということで、仕組みは同じだろう。ということで、色々すっ飛ばして実際間違ってる可能性もありますが、UnionFSで使われるオーバーレイと言われる仕組みを説明してみたいと思います。

図内ではベースになるファイルのレイヤーに対して、3つオーバーレイ[1]しているイメージ。一番下のレイヤーは普通にマウントできるファイルシステムで、そこに対して重ねていくような感じでマウントしていくと、ユーザが参照する時には積み重なったところからファイルシステムが見える。これが大雑把なUnionFS(AUFSも同じはず。。)の仕組みです。

実際Dockerのイメージはどうなっているか
AUFSを使っているという触れ込みのDockerですが、作業をしてくとどうなるか。
拙作のDockerイメージを使って確認しようと思います。
Dockerが使える環境で
# docker pull  utimukat55/jessie_20140213
2/13時点のDebian GNU/Linux jessieのDockerイメージです。これは単純に作ったイメージなので、
# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/jessie_20140213   latest              f17806c7b448        12 days ago         464.5 MB
utimukat55/docker_jessie     latest              e07ab3ea414f        4 weeks ago         267.8 MB
464MB!でかい!
んでもって、積み上げられているはずの差分はどこにあるか。
# docker info
Containers: 0
Images: 5
Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 5
WARNING: No memory limit support
WARNING: No swap limit support
Root Dirの下のdiff、/var/lib/docker/aufs/diff/に格納されています。
/var/lib/docker/aufs/diff/
├── 583d969ed337b16b3db6f2e5f7a6583df32ed25d5b03dc0de25e636897b51f15
│   ├── bin
│   ├── boot
│   ├── dev
│   ├── etc
│   ├── home
│   ├── lib
│   ├── lib64
│   ├── media
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── root
│   ├── run
│   ├── sbin
│   ├── srv
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
├── e07ab3ea414f60ee7a8405289e27fa9caa6a5322f2bd4866c28d319b67c9f7de
├── f17806c7b4480783b9c0ddfe08d6c3521f373a93c352657b3903db418adac42d
│   ├── bin
│   ├── dev
│   ├── etc
│   ├── lib
│   ├── sbin
│   ├── usr
│   └── var
├── f4396103dc987caeef469f759dd147cb1bd4761786aa9672108b189a2b19e02e
│   ├── dev
│   ├── tmp
│   └── var
└── f86c3830f454c1ed1e217b86f09c47df41e2ed1bed22038813b478d1514283cc
    ├── bin
    ├── etc
    ├── lib
    ├── run
    ├── sbin
    ├── tmp
    ├── usr
    └── var
でも、元のイメージとか途中のイメージとかは要らないことありますよね。という訳で

docker exportを使ってみる
dockerのリポジトリを他の場所に移動するためのコマンドとして、
  • docker export/import
  • docker save/load
が用意されているみたいです。exportを使ってみる[2]。引数はCONTAINERなので適当に1回コマンドを実行[3]してから
# docker export df293a377639 > shrink.tar
importで戻す。
# cat shrink.tar | docker import - jessie:shrinked
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
jessie              shrinked            b309e7a044ee        46 seconds ago      189.4 MB
189MBまで縮んだよ!
ちなみに、save/loadは差分を差分として持ったまま持ち運ぶ時に使うみたいです。

今回のエントリは、一番上のレイヤーだけほしいなぁと思ってググっていた時に見つけた以下の書き込みがきっかけでした。


[1] 組み込みプロダクトで使う場合、不揮発性のファイルシステムの上にtmpfsみたいな揮発性のファイルシステムを重ねあわせて、電源切ると元に戻る感じにするのが多いですね。
[2] http://docs.docker.io/en/v0.5.3/commandline/command/export/
[3] docker run -t -i f17806c7b448 /bin/echo "hello" とか

2014-02-10

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(4)-DHCPv6サーバの設定再び

前回までのあらすじ

  • DHCPv6サーバはISCのものにパッチを当てたものをパッケージとして作ってインストール
  • DHCPv6クライアントはISCのものを使って、クライアントを手動実行
  • クライアントから送るDHCPv6 soliciteが期待通りにならない(DUIDが)
サーバ側の設定を変更
/etc/dhcp/dhclient.confに記載したDUIDは例のwide_mkduid.plで生成したもので、Hardware typeが6(IEEE802)となっていたのだけど、ISCのdhclientは1(Ethernet)としてDUIDを作るので、こっちに寄せることにしてファイルの内容を変更[1]。最終的には以下。

default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.info-refresh-time 21600;
dhcpv6-lease-file-name "/var/lib/dhcp/dhcpd6.leases";
# RAとか範囲とか(うちの場合はRTX1100で配っているRA)
subnet6 fd00:dead:beef::/64 {
 # 1000からffffまでをDHCPで配る対象にする
 range6 fd00:dead:beef::1000 fd00:dead:beef::ffff;
 # 固定IPアドレス
 host kurobox-t4 {
  host-identifier option dhcp6.client-id 00:03:00:01:00:16:01:xx:yy:zz;
  # 固定で振るIPv6アドレス
  fixed-address6 fd00:dead:beef::100;
 }
}
DHCPサーバを再起動。
# /etc/init.d/isc-dhcp-server restart
DHCPv6クライアント側はDUIDタイプはdhclientのmanを注意深く読んだ結果、引数「-D LL」を指定することでLLを強制的に指定できそうだったので、/var/lib/dhcp/dhclient6.leasesの中身を空にして[2]、起動方法を以下の引数へ変更して実行。
# dhclient -6 -D LL -cf /etc/dhcp/dhclient.conf eth0 -v
一応これで当初望んでいた「fd00:dead:beef::100」は設定されるようになったので「特定のMACアドレスに対して固定IPv6アドレスをDHCPv6で設定する」は達成できたと思いますが、いくつか条件付きなのはここまで記載したとおり。
  • DHCPv6サーバがデフォルトだと扱いづらい
  • dhclientの起動方法が手動
  • DUIDがLLのみ(LL+Tだと対応できない)
サーバ側もクライアント側も結局一筋縄でいかないのは間違いないと思うので、できるだけ早いとここの辺が解決するといいなぁと思っています。

[1] 00:03:00:06から00:03:00:01へ
[2] 空にしないと、取得済みのアドレスを載せたDHCPv6 confirmを送り続けます

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(3)-DHCPv6クライアントの設定

DHCPv6クライアントの設定
クライアント側パッケージはisc-dhcp-clientを使います。サーバ側をisc-dhcp-serverにしたからというだけですが、一応バージョンはdebianの4.2.4-7[1]を使いました。これより前のバージョンでも動くかもしれません。
で、いろんなサイトを見ながら設定を探しつつ…とりあえず[2]の設定がよさげかなぁと思ってこれをベースに。
以下の2行を/etc/dhcp/dhclient.confに書き足して。
send dhcp6.oro 3,23,24,31;
send dhcp6.rapid-commit;
NIC再起動すりゃこの設定したdhclientがDHCPv6 solicite投げるだろjk…
# /etc/init.d/networking restart
……パケット取ってるwiresharkに一向にDHCPv6パケットが流れてこない……

DHCPv6クライアントを手動で実行する
まさかの手動実行ですよ。何か設定が間違ってるのかもしれませんが小職のスキルでは悪いところが見つけられませんでした。

で、とりあえずman dhclientしてみて、dhclient --helpしてみて、それっぽい引数を探します。
# dhclient --help
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Usage: dhclient [-4|-6] [-SNTP1dvrx] [-nw] [-p <port>] [-D LL|LLT]
                [-s server-addr] [-cf config-file] [-lf lease-file]
                [-pf pid-file] [--no-pid] [-e VAR=val]
                [-sf script-file] [interface]
ふむ。とりあえずDHCPv6クライアントとして実行する場合は-6と、最後のinterfaceは指定したほうがよさそう。ついでに一応設定ファイルを-cfで明示的に指定してみよう。あとは動きを確認するために-v(よくあるverbose)。

# dhclient -6 -cf /etc/dhcp/dhclient.conf eth0 -v
実行結果。
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Bound to *:546
Listening on Socket/eth0
Sending on   Socket/eth0
PRC: Soliciting for leases (INIT).
XMT: Forming Solicit, 0 ms elapsed.
'send dhcp6.oro' syntax is deprecated, please use the 'request' syntax ("man dhclient.conf").
XMT:  X-- IA_NA 01:96:49:2b
XMT:  | X-- Request renew in  +3600
XMT:  | X-- Request rebind in +5400
XMT: Solicit on eth0, interval 1060ms.
RCV: Advertise message on eth0 from fe80::213:e8ff:fexx:yyzz.
RCV:  X-- IA_NA 01:96:49:2b
RCV:  | X-- starts 1391264700
RCV:  | X-- t1 - renew  +3600
RCV:  | X-- t2 - rebind +7200
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR fd00:dead:beef::c7e5
RCV:  | | | X-- Preferred lifetime 604800.
RCV:  | | | X-- Max lifetime 2592000.
RCV:  X-- Server ID: 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz
RCV:  Advertisement recorded.
PRC: Selecting best advertised lease.
PRC: Considering best lease.
PRC:  X-- Initial candidate 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz (s: 153, p: 0).
XMT: Forming Request, 0 ms elapsed.
'send dhcp6.oro' syntax is deprecated, please use the 'request' syntax ("man dhclient.conf").
XMT:  X-- IA_NA 01:xx:yy:zz
XMT:  | X-- Requested renew  +3600
XMT:  | X-- Requested rebind +5400
XMT:  | | X-- IAADDR fd00:dead:beef::c7e5
XMT:  | | | X-- Preferred lifetime +7200
XMT:  | | | X-- Max lifetime +7500
XMT:  V IA_NA appended.
XMT: Request on eth0, interval 960ms.
RCV: Reply message on eth0 from fe80::213:e8ff:fexx:yyzz.
RCV:  X-- IA_NA 01:xx:yy:zz
RCV:  | X-- starts 1391264702
RCV:  | X-- t1 - renew  +3600
RCV:  | X-- t2 - rebind +7200
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR fd00:dead:beef::c7e5
RCV:  | | | X-- Preferred lifetime 604800.
RCV:  | | | X-- Max lifetime 2592000.
RCV:  X-- Server ID: 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz
PRC: Bound to lease 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz.
お。動いてる[3]。動いているが。DHCPv6サーバから振られているアドレスが「fd00:dead:beef::c7e5」である。前に書いたとおり動いていれば振られるアドレスは「fd00:dead:beef::100」になるはずなのであるが。一応ifconfigでも確認。
# ifconfig
eth0      Link encap:イーサネット  ハードウェアアドレス 00:16:01:xx:yy:zz
          inetアドレス:192.168.1.33 ブロードキャスト:192.168.1.255  マスク:255.255.255.0
          inet6アドレス: fd00:dead:beef:0:216:1ff:fexx:yyzz/64 範囲:グローバル
          inet6アドレス: fe80::216:1ff:fexx:yyzz/64 範囲:リンク
          inet6アドレス: fd00:dead:beef::c7e5/64 範囲:グローバル
うむやはり。c7e5はDHCPv6サーバからリースする範囲(1000からffff)の範囲には入っているので、DHCPv6サーバ自体は機能してそう。
サーバ側のログを見てみると。
Feb  1 23:25:36 lmdecfy7 dhcpd: Solicit message from fe80::216:1ff:fexx:yyzz port 546, transaction ID 0x792D6600
Feb  1 23:25:36 lmdecfy7 dhcpd: Picking pool address fd00:dead:beef::c7e5
Feb  1 23:25:36 lmdecfy7 dhcpd: Sending Advertise to fe80::216:1ff:fexx:yyzz port 546
Feb  1 23:25:37 lmdecfy7 dhcpd: Request message from fe80::216:1ff:fexx:yyzz port 546, transaction ID 0xA4A60600
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 deleted host decls to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 new dynamic host decls to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 leases to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Sending Reply to fe80::216:1ff:fexx:yyzz port 546
ということで、どうも適当に在庫からアドレスを拾ってきていてそれがc7e5ということらしい。うーむ。色々がんばったつもりなんだが。
パケットを見てみると、どうやらDHCPv6 soliciteの中にクライアントから送られるDUIDが含まれているらしいということを知る。
DUID type: link-layer address plus time (1)
Hardware type: Ethernet (1)
Time: Feb  1, 2014 23:25:00 JST
Link-layer address: 00:16:01:xx:yy:zz
マジかよ。とりあえず2つおかしい。
  1. DUIDタイプがLL+T(MACアドレスと時刻)になっている
  2. Hardware typeがEthernetになっている
DUIDタイプは時刻がいつになるかわからない時点で知ったこっちゃないので、LLになるといいなぁと思っていたので、正直参る。

このエントリはここまで。

[1] http://packages.debian.org/ja/jessie/isc-dhcp-client
[2] https://wikispaces.psu.edu/display/ipv6/DHCPv6#DHCPv6-ISCdhclient4.1.0
[3] MACアドレス該当部はぼかしています

2014-02-05

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(2)-DHCPv6サーバの設定(1)

(今のところ)isc-dhcp-serverはdaemonとしてハンドリングしづらい
いきなりブチ切れに近い感じで。

  • 今回DHCPv6サーバにするのはLinux(Debian GNU/Linux)
  • ざっと持ち合わせてる知識だとwide-dhcpv6-server[1]かisc-dhcp-server[2]が良さそうなのだけど、wideの方はupstreamを見ても最後の更新が2009年なので使うのに気が引けてしまう(今はdibblerなのかな?)
  • かと言ってisc-dhcp-serverがDHCPv6サーバとしてハンドリングしやすいかと言えばそんな事は全くなく、パッチをあてる[3]のが一番てっとり早そうという泥沼
という事で、普通のDHCP(v4)サーバみたくハンドリングできるようにソースパッケージにパッチをあててビルドしますorz。

isc-dhcp-serverをビルド、インストール
まず、当てたいパッチが4.2.4向けなので、現状4.2.4なtesting/jessieまたはsidをapt-get sourceできるように以下の行をapt-lineに追加します。

deb-src http://ftp.jp.debian.org/debian/ jessie main non-free contrib
# apt-get update
# apt-get build-dep isc-dhcp=4.2.4-7
# apt-get install devscripts

# exit
$ mkdir build_isc
$ cd build_isc/
$ apt-get source isc-dhcp=4.2.4-7
で、[3]のMessage142のisc-dhcp-server-ipv6.patchをダウンロードしてきます。ここでは~/Downloadsに保存したものとして、
$ patch -u -p0 < ~/Downloads/isc-dhcp-server-ipv6.patch
(patching file・・・がずらずらーっと出ればOK)

$ cd isc-dhcp-4.2.4/
$ debuild -uc -us
$ su
$ cd ..
# dpkg -i isc-dhcp-server_4.2.4-7_amd64.deb isc-dhcp-common_4.2.4-7_amd64.deb
でビルドしたパッケージのインストールは完了。

isc-dhcp-serverの設定項目
今回はDHCP(v4)サーバは設定せず、DHCPv6サーバだけ動かすので、そのように書き換えます。/etc/default/isc-dhcp-serverの以下の場所を書き換え。
  • V4_ENABLED="true"を"false"へ
  • V6_ENABLED="false"を"true"へ
  • INTERFACES_V6=の行を"wlan0"へ(今回はwlan0でDHCPv6dを動かすので)
# touch /var/lib/dhcp/dhcpd6.leases

/etc/dhcp/dhcpd6.confを必要に応じて書き換える。
default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.info-refresh-time 21600;
dhcpv6-lease-file-name "/var/lib/dhcp/dhcpd6.leases";
# RAとか範囲とか(うちの場合はRTX1100で配っているRA)
subnet6 fd00:dead:beef::/64 {
 # 1000からffffまでをDHCPで配る対象にする
 range6 fd00:dead:beef::1000 fd00:dead:beef::ffff;
 # 固定IPアドレス
 host kurobox-t4 {
  host-identifier option dhcp6.client-id 00:03:00:06:00:16:01:xx:yy:zz;
  # 固定で振るIPv6アドレス
  fixed-address6 fd00:dead:beef::100;
 }
}
ここで固定アドレスを振る対象の行の最後のパラメータですが(最後3オクテットをぼかしてますが)、これが弊ブログの別エントリで触れているDUIDになります。
この時点では生成をミスるとまずいと思ったので、wide_mkduid.plというスクリプトを使って生成しました。端的に書くと、MACアドレスの前に「00:03:00:06:」を付与したDUID-LL(hardware typeは6(IEEE 802 Networks))です。まぁ後々これでも不味かったことを思い知るわけですが。
なお、dhcpd6.confの書き方は[4]を参考にさせていただきました。

このエントリはここまで。


[1] http://packages.qa.debian.org/w/wide-dhcpv6.html
[2] http://packages.qa.debian.org/i/isc-dhcp.html
[3] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=592539

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(1)-序章

やる前は1エントリで済むと思ってたんですが実際やってみるとすげー大変だったのでいくつかに分けます。
現状&やりたいこと
我が家では部分的にIPv6を導入していて、VPN(L2TP)ルータとしてヤマハのRTX1100を使っています。また、RAもRTX1100からLAN側に流していて、ステートレスなIPv6アドレス設定はできている状態です。


ですが、ご存知の通りIPv6アドレスは長い事、ステートレスに生成するIPv6アドレスは128bitぶんのアドレスを使い切る(0ではない)ので、LAN内のサーバにも頻繁にアクセスするには辛いアドレス(手入力したくない)が設定されます。[1]
そこで、IPv4では家庭用のブロードバンドルータでもできるような「特定のMACアドレスに特定のMACアドレスを配布する」をIPv6で実現しようと思いました。よく言うDHCPv6によるステートフルなIPv6アドレス割り振り(しかも固定アドレス)です[2]。

せっかくヤマハルータあるんだからコマンドいくつか流しこめば出来るんじゃないかと思ったんですが、現状のヤマハルータではRTX1100に限らずこの機能が提供されていません。


なので、LAN内のPCをDHCPv6サーバにしてみようというのが今回のスタート地点です。

今回の記事の全容は以下になります。

  1. 序章←今ここ
  2. DHCPv6サーバの設定(1)
  3. DHCPv6クライアントの設定
  4. DHCPv6サーバの設定(2)
RTX1100の設定はこんな感じです。

  • LAN1がLAN
  • 配布するRAのprefixはfd00:dead:beef::/64
  • DHCPv6使うのでRAのMフラグは立てる

具体的には

  • # ipv6 prefix 1 fd00:dead:beef::/64
  • # ipv6 lan1 prefix fd00:dead:beef::/64
  • # ipv6 lan1 rtadv send 1 m_flag=on
このエントリはここまで。


[1] AAAAレコードを返すDNSサーバを置いても解決できる問題ではありますが
[2] ステートフルの定義を理解できてないかもしれないので間違っていたら教えてください

2014-02-01

DHCPv6について(DUID)

DHCPv6で(各ホスト上の手動設定ではなく)静的にアドレスを振る方法について調べていて、DUIDというものに辿り着いた。忘れないように書きだす。

DUIDとは
色々世の中にはIDを振る方法があるのだけど、DHCPの仕組みで使われる(と思われる)IDの振り方。DHCP Unique Identifierの略。

RFC3315で定義されているDUID
RFC3315(DHCP for IPv6)[1]のSection-9で定義されているDUIDは3つ。

  • DUID-LLT(DUID Based on Link-layer Address Plus Time)
  • DUID-EN(DUID Assigned by Vendor Based on Enterprise Number)
  • DUID-LL(DUID Based on Link-layer Address)

DUID-LLTとDUID-LLに書かれている「Link-layer Address」は日本語でいう物理アドレス、いわゆるMACアドレスのことで、LLTの方はMACアドレスと時刻から導出、LLはMACアドレスから導出という事らしい。
一方でDUID-ENはIANAがメンテしているPrivate Enterprise Numberに各ベンダが持っているIDを振っていく形式のようだ。
これら3つのIDのオフセットはRFC3315を参照。

RFC6355で定義されているDUID
それでいて、RFC6355(DUID-UUID)[2]でもDUIDが定義されている。
DUID-UUIDはRFC4122で定義されているUUIDをそのまま使う(正確にはDUID-Typeである4の後ろにDUID128bitを繋げる144bit)ということ。UUIDはあんまり重複しないのでこれの方が手軽という事なんだろうか。

もうちょっとだけ続くんじゃ(2014/02/04追記)
元々あるDUID-LLTとDUID-LLについて、dhclientがデフォルトで投げるDUIDがDUID-LLTになっているので、何で似たようなものが2つあるのかdhclientのデフォルト設定について調べていたらバグとして報告されていた[3]。
その中でComment21に
> So it seems like we all agree that DUID-LL is the way to go...
AFAIK even the RFC agrees :).
と書いてあり、それならと思って改めてRFC3315を読んでみると、まずDUID-LLTがある理由は

  • DHCPv6クライアントとDHCPv6サーバとの間で重複しないIDが必要
  • NICを機器の間で付け替えたとしても、別々のIDになるようにする
ために、MACアドレスと時刻を複合キーのように扱ってIDとして使う。との事。
ではDUID-LLが定義されている理由は。

This type of DUID consists of two octets containing the DUID type 3,
a two octet network hardware type code, followed by the link-layer
address of any one network interface that is permanently connected to
the client or server device.  For example, a host that has a network
interface implemented in a chip that is unlikely to be removed and
used elsewhere could use a DUID-LL.
要は、「NICを取り外し不可能なプロダクトに限ってDUID-LLを使ってもいいよー」的なノリで書かれているので、デフォルトはDUID-LLみたいな事になっているようだ(RFC3315を書いた時のノリでは)。

それと、DUID-LLTとDUID-LLの3〜4オクテット目に使われるhardware typeはIANAでメンテされていて[4]、どういう風に識別されているかはDUIDを生成するDHCPv6クライアント次第であることにも注意が必要である。(DHCPv6サーバ側でDUIDを元にした処理をする場合があるので。)
具体的には、6(IEEE 802 Networks)かと思ったら1(Ethernet (10Mb))だったりするので。

[1] http://tools.ietf.org/html/rfc3315#section-9
[2] http://tools.ietf.org/html/rfc6355
[3] https://bugzilla.redhat.com/show_bug.cgi?id=560361
[4] http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml#arp-parameters-2