IIJlab newsletter

#1: 1998/05/28 「最近のIPv6」
$Id: index.html,v 1.1.1.1 2003/08/28 05:58:03 itojun Exp $

不定期で、「IIJ技術研究所newsletter」というのを書くことにしました。 これが輝ける(?)第1回です。 あまり肩ひじはらず、でも技術的には正確に、 をモットーに細く長く続けていきたいと思っています。 今回は、IPv6の最近の動向について少々。
現在IIJ技術研究所のメンバーの一部は、 IPv6/IPsec関係の研究に没頭しています。 IPv6の動向については、IETF ipng working groupの活動を 追うのがよいと思います。 mailing listベースの活動なので、webpageだけでは血の滴るような最新情報は 得られません。 技術的に興味のある方は、 IETF ipng working groupの mailing listに入ったり、 IETF meeting (次は8月chicagoですね)に 参加したりしてみるとよいと思います。

IPv6に関する最近の動向ですが、あいかわらず各種の標準化活動は続いています。 最近で一番大きな変更は、struct sockaddr_in6の変更と それに関係する IPv6 basic socket API(RFC2133) advanced socket API(RFC2292)の変更でしょう。

IPv6では、IPv4と違いアドレスに「スコープ」の概念が導入されています。 IPv4では、 (RFC1918 で定義されているプライベートアドレスを除けば) 任意のIPv4アドレスは、かならず「世界で唯一」でした。 例えば、ftp.iij.ad.jpは(これを書いてる時点では) 202.232.2.51というIPv4アドレスを持っていますが、 これは世界じゅうでただひとつのもので、他のひとが使ったりしません。 IPv6でもほとんどのIPv6アドレスは「世界でただひとつ」なのですが、 「世界でただひとつ」ではないIPv6アドレスも存在します。 たとえば、IPv6では単一のネットワーク内でしか一意性のないアドレスとして link-local addressというのを定義しています。 link-local addressはfe80::nantara(nantaraは64bit)と いうような形式をしているのですが、アドレスのなかにはどこにも 「どのネットワークのアドレスか」というのを示す識別子が入っていません。 このため、複数のネットワークに接続されたホスト上で 「このパケットはfe80::X行きね」と言われた場合、 どっちにパケットを投げればいいのか判断できません。

	host A
	  |fe80::A
	==+=====
	  |
	router	「fe80::X行きのパケットを
	  |		どっちに投げればいいのだろう?」
	==+=====
	  |fe80::B
	host B
つまり、link-local addressを指定する場合、 「このネットワーク上のアドレス」と指定しないといけません。 ユーザから見える影響としては、例えばping6(IPv6のping)コマンドを 呼び出すときの引数があります。 多くのIPv6実装では、link-local addressへのping6を行うときは ping6 -I de0 fe80::X などとしてインタフェースを指定しないといけません。

今まではRFC2292に 述べられていたように、 sendmsgシステムコールを使って追加の構造体 struct in6_pktinfoを渡し、出力インタフェースを指定していました。 しかし、Tim Hartrickというひとが「これはめんどくさすぎる、やってられん、 sockaddr_in6にインタフェースを指定するフィールドをつけよう」と主張し、 これが受け入れられました。 これまではsockaddr_in6は以下のような定義になっていましたが、

struct sockaddr_in6 {
	u_char		sin6_len;	/* length of this struct(sa_family_t)*/
	u_char		sin6_family;	/* AF_INET6 (sa_family_t) */
	u_int16_t	sin6_port;	/* Transport layer port # (in_port_t)*/
	u_int32_t	sin6_flowinfo;	/* IP6 flow information */
	struct in6_addr	sin6_addr;	/* IP6 address */
};
今度からはこのようになります。赤字部分が増えたところ。
struct sockaddr_in6 {
	u_char		sin6_len;	/* length of this struct(sa_family_t)*/
	u_char		sin6_family;	/* AF_INET6 (sa_family_t) */
	u_int16_t	sin6_port;	/* Transport layer port # (in_port_t)*/
	u_int32_t	sin6_scope_id;
	u_int32_t	sin6_ifindex;
	u_int32_t	sin6_flowinfo;	/* IP6 flow information */
	struct in6_addr	sin6_addr;	/* IP6 address */
};
sin6_ifindexには、ネットワークインタフェースの番号を指定します。 例えば「3番のインタフェースにつながったネットワーク上ののfe80::Aに パケットを投げたい場合、
	struct sockaddr_in6 sin6;

	memset(&sin6, 0, sizeof(sin6));
	sin6.sin6_family = AF_INET6;
	sin6.sin6_len = sizeof(struct sockaddr_in6);
	sin6.sin6_ifindex = 3;
	inet_pton(AF_INET6, "fe80::A", &sin6.sin6_addr);
	/* do what you want */
というようなかんじになります。

まだこの変更を済ませた状態の internet-draftは 発行されていませんが、 この変更はかなり広範囲に影響がありますのではやめの対処が必要です。 ライブラリを直さないといけませんし、 カーネルやツール類も全部makeしなおさないといけません。 僕らが作業をしているKAME projectという BSD unixカーネル改造プロジェクトでは、 以前から似たような機構を違う方法で入れていました。 いい機会なので、sin6_ifindexの処理を 早めに実装して問題点を洗い出し、議論に反映させようと考えています。

いまさらこんな変更が加わったりしているのを見てもわかるように IPv6にはまだまだ決めないといけないこと、作らないといけないことが山もりです。 さらに、IPv4からIPv6にのりかえるためには、 上位層のプロトコルについてもいろいろ考えなければなりません。 また次回以降、こんなはなしについて書いていきたいとおもいます。

NOTE: この件についてはさらに方針変更がありました。 ここ参照


IPv6の入門書としては、とりあえず Christian Huitema著"IPv6: the new internet protocol"(Prentice hall)を おすすめしておきます。 邦訳 もあります。

FreeBSDを入れられるPCが一台あったら、いくつかpublicな実装がありますので インストールして使ってみるのをおすすめします。 ただ、どの実装も開発途上なので、ほとんど毎日毎晩更新されてます。

(IIJ技術研究所 いとうじゅんいちろう)
IIJlab / playground
Copyright(C) 1998 by Internet Initiative Japan Inc. All rights reserved.
Unauthorized reproduction/redistribution is strictly prohibited. Absolutely no warranty.