連載 / v6 の実装ー 0 図 2 mip6-prefix 構〕本の生成 105 106 107 111 112 113 114 115 116 117 118 119 120 121 122 124 131 132 133 134 135 } MALLOC(mpfx, struct mip6-prefix * , M_TEMP , M_NOWAIT) ; if (mpfx = = NULL) { return (NULL) ; bzero(mpfx, sizeof (*mpfx) ) ; sizeof (struct mip6_prefix) , in6—prefix1en2mask (&mask , prefixlen) ; LIST_INIT(&mpfx—>mpfx-ha-1ist) ; / * XXX mpfx->mpfx-haddr ; * / mpfx—>mpfx—prefixlen = prefixlen ; mpfx->mpfx—prefix. s6—addr32 [ 3 ] & = mask. s6-addr32 [ 3 ] ; mpfx->mpfx—prefix. s6—addr32 [ 2 ] & = mask. s6—addr32 [ 2 ] ; mpfx->mpfx-prefix. s6—addr32 [ 1 ] & = mask. s6-addr32 [ 1 ] ; mpfx->mpfx-prefix. s6—addr32 [ 0 ] & = mask. s6-addr32 [ 0 ] ; mpfx—>mpfx—prefix *prefix; callout—init (&mpfx—>mpfx—timer—ch, NULL) ; / * set initial timeout . * / mip6—prefix—update—Iifetime (mpfx , vltime , return (mpfx) ; 構造体に関連づけられている mip6-prefix-ha 構造体を 検索する。 ・ mip6-prefix-ha 」 ist-find-withmha() 才帛した mip6-ha 構造体に関連づけられた mip6-pre- fix-ha 構造体を検索する。 以下、それぞれの関数を解説します。引用するコードは fix-ha 構造体が定義されています。 カ夏数の mip6-ha 橢告体の情報をもてるよう、 mip6-pre- から広告されている場合もあるので、 mip6-prefix 構造体 ス情報を広告したり、あるプレフィックスカ夏数のルータ けて保持しています。 1 つのルータが複数のプレフィック 構造体 ) と、その情報を広告したルータのあいだを関連づ 移動ノードでは、各プレフィックス情報 (mip6-prefix 連しています。図 1 に、これらの構造体の関係を示します。 構造体は、ルータ情報を表す mip6-ha 構造体と密接に関 移動ノードでプレフィックス情報を表す mip6-prefix mip6-prefix 構造体の生成 mip6-prefix. c のものです。 UNIX MAGAZINE 2005.9 れます。 mip6-prefix 構造体は mip6-prefix-create() で作成さ 95 96 97 98 99 100 101 pltime) ; struct mip6—prefix * mip6—prefix-create(prefix, prefixlen, u—int32—t pltime ; u_int32_t vltime ; u—int8—t prefixlen; struct in6—addr *prefix ; vltime , pltime) mip6-prefix-create() の引数は 4 つです。 prefix と prefixlen は作成する mip6-prefix 構造体に本内されるプ レフィックスとプレフィックス長、 vltime と pltime はプ レフィックスの有効時間と推奨有効時間です。 図 2 の 105 ~ 112 行目で mip6-prefix 構造体を十内す るためのメモリ領域を確保し、 113 ~ 120 行目でプレフィ ックス情報 (prefix と prefixlen) を設定します。メモリ 確保に失敗した場合は NULL カります ( 111 行目 ) 。 122 行目で、 mip6-prefix-ha 構造体を保持するための リスト構造体を初期化します。図 1 に示したとおり、 mip6 -prefix 構造体はプレフィックス情報を広告しているルー タへのポインタを mip6-prefix-ha 構造イ釜由で保持しま す。 124 行目でこの mip6-prefix 構造体のタイマーを初期 化し、 132 行目の mip6-prefix-update 」 ifetime() で有 効時間を設定するとともに、次のタイマー呼出しを設定し 73
図 14 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 図 15 520 521 522 523 524 525 526 527 528 529 530 531 532 533 500 連載 / 旧 v6 の実装ー 0 mip6-prefix-ha 」 ist-find-withaddr() 関数び里 struct mip6—prefix—ha * mip6—prefix—ha—Iist—find—withaddr (mpfxha_list , addr) struct mip6—prefix—ha—1ist *mpfxha—list ; struct in6_addr *addr ; struct mip6—prefix—ha *mpfxha ; for (mpfxha = LIST—FIRST (mpfxha-list) ; mpfxha; mpfxha = LIST—NEXT (mpfxha , mpfxha_entry) ) { if (mpfxha—>mpfxha-mha = = NULL) C011ti11Ue ; if (IN6_ARE_ADDR_EQUAL (&mpfxha—>mpfxha_mha—>mha—addr , addr) ) return (mpfxha) ; mip6-prefix-ha-list-find-withmha() 関数のタ里 struct mip6—prefix—ha * mip6—prefix—ha—Iist—find—withmha(mpfxha list , mha) struct mip6—prefix—ha—Iist *mpfxha—list ; struct mip6—ha *mha ; return (NULL) ; struct mip6—prefix—ha *mpfxha; for (mpfxha = LIST-FIRST(mpfxha_1ist) ; mpfxha; mpfxha = LIST-NEXT (mpfxha , mpfxha_entry) ) { if (mpfxha—>mpfxha mha & & (mpfxha->mpfxha mha return (mpfxha) ; return (NULL) ; = mha) ) mip6-prefix-ha 」 ist-remove() は mip6-prefix-ha 構 造体のエントリを mip6-prefix 構造体の mpfxha 」 ist か ら削除します。この構造体は mip6-ha 構造体へのポイン タをオ内しているだけなので、単純に LIST-REMOVE() でリストから取り除いたあと、 mip6_prefix-ha 構造体用 に確保されていたメモリ領域を解放するだけです。 mip6-prefix-ha 」 ist-find-withaddr() は、第 2 引数 addr で指定したアドレスをもつ mip6 ー ha 構造体を、第 1 引数 (mpfxha 」 ist) で指定した mip6-prefix-ha 構造体 のリストから検索する関数です。図 14 の 509 ~ 516 行目 で、 mpfxha 」 ist で指定された mip6-prefix-ha 構造体リ ストのエントリをたどり、それぞれのエントリが示してい る mip6-ha 構造体のアドレスを調べます。 addr で指定さ れたアドレスをもつ mip6-ha 構造体がみつかれば、その UNIX MAGAZ 工 NE 2005.9 時点での mip6-prefix-ha 構造体のポインタを返します。 mip6-prefix-ha 」 ist-find-withmha() は、第 2 引数 mha で指定した mip6-ha 構造体へのポインタをもつ mip6-prefix-ha 構造体を、第 1 引数 mpfxha 」 ist で指定 したリストから検索します。図 15 の 527 ~ 531 行目で、リ ストに含まれる mip6-prefix-ha 構造体をたどり、構造体 に保持されている mip6-ha 構造体へのポインタが、 mha で指定されたアドレスと同じものを探します。該当するも のがあれば、その時点での mip6-prefix-ha 構造体へのポ します。 インタが返されます。 81 ( しま・けいいち IIJ) 次回も引き続き移動ノードのプレフィックス管理を解説 ☆
連載 / v6 の実装 図 1 mip6-prefix 、 mip6-ha 、 mip6-prefix mip6 prefix—list mip6_ha list mip6_prefix{} m pfx_entry m pfx_ha list mip6_prefix_ha{} mpfxha_entry mpfxha_mha mip6—prefix—ha{} mpfxha_entry mpfxha—mha mip6_ha{} mha_entry -ha 構本の系 mip6_prefix{} mpfx—entry mpfx_ha list mip6_prefix_ha{} mpfxha—entry mpfxha_mha mi p6—p refix—ha{} mpfxha_entry mpfxha_mha rn i p6_ha{} mha_entry mip6—prefix{} mpfx—entry mpfx_ha list mip6—prefix_ha{} mpfxha—entry mpfxha_mha mip6_ha{} mha_entry プレフィックス管理関数 72 ・ mip6-prefix 」 ist-find-withprefix() mip6-prefix 構造体のエントリをリストから削除する。 ・ mip6-prefix-list-remove mip6-prefix 構造体のエントリをリストに登録する。 ・ mip6-prefix-list-insert() 生成する。 移動ノードのホームアドレスをプレフィックス情報から ・ mip6-prefix-haddr-assign() プレフィックス情報の有効時間を更新する。 ・ mip6-prefix-update 」 ifetime 造体 ) のエントリを作成する。 プレフィックス情報を内する構造体 (mip6-prefix 構 ・ mip6-prefix-create() として、以下のものが用意されています。 移動ノードがプレフィックス情報を管理するための関数 指定したプレフィックス情報をもつ mip6-prefix 構造 体のエントリを検索する。 ・ mip6-prefix 」 ist-find-withhaddr() 指定したホームアドレスをもつ mip6-prefix 構造体の 工ントリを検索する。 ・ mip6-prefix-settimer mip6-prefix 構造体のタイマー処理関乎出し時刻を設 定する。 ・ mip6-prefix-timer タイマー処理関 ・ mip6-prefix-ha 」 ist-insert() ホーム・エージェント構造体 (mip6-ha 構造体 ) と mip6 -prefix 構造体を関連づける構造体 (mip6-prefix-ha 構 造体 ) をリストに追加する。 ・ mip6-prefix-ha 」 ist-remove mip6-prefix-ha 構造体をリストから削除する。 ・ mip6-prefix-ha 」 ist-find-withaddr() 指定したホームエージェント・アドレスをもつ mip6 ー ha UNIX MAGAZ 工 NE 2005.9
図 10 400 401 402 403 404 405 406 407 408 409 410 411 412 413 連載 / 旧 v6 の実装ー 0 hif-softc 構本からの参照を肖郎余する処理 if ( (mpfx-list = NULL) Ⅱ (mpfx return (EINVAL) ; = NULL) ) { / * remove a11 references from hif interfaces . * / for (hif = LIST—FIRST(&hif_softc_1ist) ; hif ; LIST_NEXT(hif , hif_entry)) { hif hif-prefix—list—remove(&hif->hif-prefix-list-home, hif—prefix—list—find—withmpfx(&hif—>hif—prefix—list—home , mpfx) ) ; hif—prefix—list—remove(&hif—>hif—prefix—list—foreign, hif—prefix—list—find—withmpfx(&hif—>hif—prefix—list—foreign, mpfx) ) ; ックス情報を取得するまで、繰り返しモバイル・プレフィ ックス要求メッセージを送信します。 まず、図 9 の 351 ~ 354 行目で有効時間が切れる時刻 (mpfx-vlexpire) を過ぎていないかどうかを確認します。 有効時間が切れていたら、 mip6-prefix 」 ist-remove() で mip6-prefix 構造体のエントリを削除します。 続いて、 356 行目で mip6-prefix-send-mps() を呼び 出し、モバイル・プレフィックス要求メッセージを送信し ます。 363 ~ 370 行目では、次のタイマー呼出しを予約します。 MIP6-MOBILE-PREFIX-SOL-INTERVAL 時間後 にまだ有効時間カ長っていれば、 MIP6-MOBILE-PRE- FIX-SOL-INTERVAL 時間後にタイマー関数の呼出し を予約し、そうでなければ有効時間が切れる時刻に最後の 呼出しを予約します。 mip6-prefix 構造体の月た態は EXPIRING のままです。 この : 犬態は、ルータ通知やモノヾイル・プレフィックス応答 メッセージを受信することで PREFERRED : 犬態に戻り ます。 プレフィックス情報の追加と削除 mip6-prefix 構造体は mip6-prefix 」 ist を先頭とする リスト構造として管理されています。移動ノードが入手し たプレフィックス情報は、すべて mip6-prefix 」 ist にイ寺 されます。 mip6-prefix 構造体をリストに追加 / 削除するための関 数が、 mip6-prefix 」 ist-insert() と mip6-prefix 」 ist-re- move ( ) です。 378 int 78 379 380 381 382 383 384 385 386 387 388 389 390 mip6—prefix—Iist—insert(mpfx—Iist , mpfx) return ( 0 ) ; mpfx-entry) ; LIST_INSERT_HEAD (mpfx_list , mpfx , return (EINVAL) ; (mpfx = = NULL) ) { = NULL ) Ⅱ if ( (mpfx—list struct mip6—prefix *mpfx; struct mip6—prefix—1ist *mpfx-list ; mip6-prefix 」 istänsert() は 2 つの引数をもちます。 mpfx 」 ist はリスト構造体 (mip6-prefix 」 ist) へのポイン 夕、 mpfx はリストに追加する mip6-prefix 構造体へのポ インタです。関数内は、たんに LIST-INSERT-HEAD() マクロでエントリを追加するだけの単純な内容となってい ます。 392 393 394 395 396 int mip6—prefix—1ist—remove (mpfx—list , mpfx) struct mip6—prefix—1ist *mpfx—list ; struct mip6—prefix *mpfx ; mip6-prefix 」 ist-remove() は 2 つの引数をもちます。 mpfx 」 ist はリスト構造体 (mip6-prefix 」 ist) へのポイン 夕、 mpfx はリストから削除する mip6-prefix 構造体への ポインタです。 追加時とは異なり、 mip6-prefix 構造体の削除は注意が 必要です。 mip6-prefix 構造体は、 hif-softc 構造体から ポインタ参照されている可能性があります。また、 mip6- prefix 構造体は mip6-ha 構造体への参照をイ尉寺していま UNIX MAGAZINE 2005.9
図 11 415 416 417 418 419 図 12 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 連載 / 旧 v6 の実装ー 0 mip6-ha 構冒本への参照を肖畭するタ里 / * remove a11 refernces t0 advertising routers . * / while ( !L 工 ST-EMPTY(&mpfx->mpfx—ha-1ist) ) { mpfxha = LIST-FIRST(&mpfx—>mpfx-ha—1ist) ; mip6-prefix-ha-1ist-remove(&mpfx->mpfx—ha—1ist , mpfxha) ; mip6-prefix 」 ist-find-withprefix() によるプレフィックス・情報の本 struct mip6—prefix * mip6—prefix—Iist—find—withprefix(prefix, prefixlen) mpfx—>mpfx-prefixlen) ) { & & (prefixlen if (in6—are—prefix—equa1 (prefix , &mpfx—>mpfx—prefix , prefixlen) mpfx = LIST—NEXT (mpfx , mpfx-entry) ) { for (mpfx = LIST—FIRST(&mip6_prefix—Iist) ; mpfx; struct mip6-prefix *mpfx ; int prefixlen ; struct in6—addr *prefix; return (NULL) ; / * not found. * / return (mpfx) ; / * found. * / す。実際にエントリを削除する前に、ほかの構造体との参 照情報を削除します。 図 10 の 405 ~ 413 行目は、 hif-softc 構造体から mip6- prefix 構造体への参照を削除する処理です。 hif-softc 構 造体は、 hif-prefix 」 ist-home と hif-prefix 」 ist-foreign 変数にそれぞれ、ホーム・プレフィックスと出先プレフィ ックスの情報を内しています。これらの変数に保持され ているプレフィックス情報が mip6-prefix 構造体を参照し ているので、 hif-prefix-list-remove() 関数を用いて参昭 を削除します。 図 11 の 416 ~ 419 行目は、 mip6-ha 構造体への参照 を削除する処理です。 mip6-prefix 構造体が参照している mip6-ha 構造体は、 mpfx-ha 」 ist に保持されています。 mpfx-ha 」 ist をたどりながら、 mip6-prefix-ha 」 ist-re- move() で mip6-ha 構造体への参照を削除します。 421 422 423 424 425 426 } LIST_REMOVE (mpfx , mpfx_entry) ; mip6—prefix—settimer(mpfx, ー 1 ) ; FREE (mpfx , M_TEMP) ; return ( 0 ) ; すべての参照清報を削除したら、 LIST-REMOVE() で UNIX MAGAZINE 2005.9 工ントリをリストから外し、 FREE ( ) でメモリ領域を解放 します ( 421 ~ 423 行目 ) 。 プレフィックス情報の検索 mip6-prefix 構造体は 2 種類の方法で検索できます。 1 つはプレフィックスとプレフィックス長の情報をもとに検 索する方法で、 mip6-prefix 」 ist-find-withprefix() で実 装されています。もう 1 つはホームアドレスをもとに検索 する方法で、 mip6-prefix 」 ist-find-withhaddr() で実装 されています。 mip6-prefix 」 ist-find-withprefix() はプレフィックス を表す in6-addr 構造体へのポインタ (prefix) とプレフィ ックス長 (prefixlen) を引数にとります。 すべてのプレフィックス情報は mip6-prefix 」 ist に保 持されているので、リストをたどりながら、引数で渡され たプレフィックス情報をもつ mip6-prefix 構造体を検索し ます。該当するエントリがあればそのポインタを返し、な ければ NULL を返します ( 図 12 の 435 ~ 445 行目 ) 。 mip6-prefix-list-find-withhaddr() の引数は 2 つで す ( 図 13 ) 。 mpfx 」 ist は mip6-prefix 」 ist へのポイン 夕、 haddr は検索対象のホームアドレスへのポインタです。 79
図 13 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 連載 / 旧 v6 の実装ー 0 mip6-prefix 」 ist-find-withhaddr() 関数によるプレフィックス情報の検索 struct mip6—prefix * mip6—prefix—Iist—find—withhaddr(mpfx—Iist, haddr) if (IN6_ARE_ADDR_EQUAL (haddr , &mpfx—>mpfx_haddr) ) { mpfx = LIST—NEXT(mpfx, mpfx-entry) ) { for (mpfx = LIST-FIRST(mpfx_1ist) ; mpfx; struct mip6—prefix *mpfx; struct in6_addr *haddr ; struct mip6—prefix—1ist *mpfx—list ; return (NULL) ; / * not found . * / return (mpfx) ; / * found . * / すべての mip6-prefix 構造体は mip6-prefix 」 ist に f 尉寺 されるので本来第 1 引数は不要 ( つねに同じ値が指定され る ) ですが、開発初期のコードのままになっています。 図 13 の 455 ~ 461 行目で mip6-prefix 」 ist の各工ント リを調べ、 mpfx-haddr に常内されているホームアドレス と、引数で渡されたアドレスが等しいエントリのポインタ を返します。 mip6-ha 構造体との関連づけ mip6-prefix 構造体は、プレフィックス情報をアナウン スしているルータへのポインタ情報を保持しています。ポ インタ情報は mip6-prefix-ha 構造体で表され、 mip6- prefix 構造体の mpfx-prefix-ha-list メンバー変数にリ ストとしてイ尉寺されます。 467 struct mip6_prefix—ha * 468 mip6—prefix—ha—1ist—insert(mpfxha—Iist , 478 479 480 481 482 483 486 487 if (mpfxha ! = NULL) return (mpfxha) ; MALLOC(mpfxha, struct mip6—prefix—ha * , sizeof (struct mip6—prefix—ha) , M_TEMP , M_NOWA 工 T) ; if (mpfxha = = NULL) { return (NULL) ; 477 ~ 479 行目では、指定された mip6-ha 構造体への ポインタがリストに登録されていないかどうかを調べます。 登録済みなら、そのエントリへのポインタを返して終了し ます。未登録であれば、 481 ~ 487 行目で新しく作成する mip6-prefix-ha 構造体のメモリを確保します。 488 489 490 491 } mpfxha—>mpfxha—mha = mha ; LIST_INSERT_HEAD (mpfxha_list , mpfxha , mpfxha—entry) ; return (mpfxha) ; 469 470 471 { mha) struct mip6—prefix—ha—1ist *mpfxha—list ; struct mip6—ha *mha ; 488 行目で mpfxha-mha に引数で渡された mip6-ha 構造体のポインタを設疋し、 mip6-prefix 構造体の mpfx- ha 」 ist にエントリを挿入します。 mip6-prefix-ha 」 ist-insert() は mip6-prefix-ha 構 造体をリストに追加します。 mpfxha 」 ist は追加するリス トへのポインタ、 mha は関連する mip6-ha 構造体へのポ インタです。 472 struct mip6—prefix—ha *mpfxha ; 477 mpfxha = mip6—prefix—ha—1ist—find—withmha( mpfxha—list , mha) ; 80 493 494 495 496 497 498 499 VOid mip6—pref ix—ha—list—remove (mpfxha—list , mpfxha) struct mip6—prefix—ha—1ist *mpfxha—list ; struct mip6—prefix—ha *mpfxha ; LIST_REMOVE (mpfxha , mpfxha-entry) ; FREE (mpfxha , M_TEMP) ; UNIX MAGAZINE 2005 . 9
連載 / v6 の実装ー 0 図 5 ホームアドレスの生成 183 184 185 186 187 200 201 202 203 204 205 206 207 208 209 210 211 212 int mip6-prefix—haddr-assign(mpfx, sc) error = get—ifid( (struct ifnet * ) sc, struct hif_softc *sc ; struct mip6—prefix *mpfx ; return (error) ; if (error) NULL , &ifid) ; mpfx—>mpfx—haddr mpfx—>mpfx— return ( 0 ) ; mpfx—>mpfx—prefix ; haddr . s6_addr32 [ 2 ] ifid. s6—addr32 [ 2 ] ; ifid. s6—addr32 [ 3 ] ; mpfx—>mpfx—haddr. s6—addr32 [ 3 ] て、 mpfx-vltime が無期限に設疋されていなければ、効 時間 (mpfx-vltime) が切れる前にタイマー呼出しを設定 します。 mpfx-pltime 、 mpfx-vltime ともに無期限の場 合、タイマー呼出しは設定されません。 ホームアドレスの計算 mip6-prefix-haddr-assign() は mip6-prefix 構造体 に設疋されているプレフィックス情報をもとにホームアド レスを生成します。 mip6-prefix-haddr-assign() は 2 つの引数をもちま す ( 図 5 ) 。 mpfx はホームアドレスを生成するプレフィッ クス情報が内された mip6-prefix 構造体へのポインタ、 sc はそのプレフィックスが割り当てられているホームネッ トワーク・インターフェイス (hif-softc 構造体 ) へのポイ ンタです。 図 5 の 201 ~ 204 行目で get-ifid() を呼び出し、イン ターフェイス識別子を取得します。 get-ifid() は第 1 引数 と第 2 引数にインターフェイスへのポインタをとり、それ らのインターフェイスに設疋されているインターフェイス 識別子を第 3 引数に十翻村します。取得する識別子は第 1 引 数で指定したインターフェイスの情報が優先されます。ど ちらのインターフェイスからも識別子を取得できなければ、 ノードが保持しているほかのインターフェイスから識別子 を取得します。それも不可能な場合には、乱数で生成され た識別子となります。乱数を使った場合、一意性は保証さ れません。 UNIX MAGAZINE 2005 . 9 ホームアドレスの情報は mpfx-haddr に内されます。 上位 64 ビットをプレフィックス情報からコピーし、下位 64 ビットを get 」 fid ( ) で取得したインターフェイス識別 子からコピーします ( 207 ~ 209 行目 ) 。 タイマー関数呼出し時刻の言 mip6-prefix-settimer() は mip6-prefix 構造体のタイ マー関乎出し時刻を誌定します。 237 void 238 mip6—prefix—settimer(mpfx, tick) 239 240 241 { struct mip6—prefix *mpfx; 10 Ⅱ g tick; mip6-prefix-settimer() の引数は 2 つです。 mpfx は タイマー呼出しを設疋する mip6-prefix 構造体へのポイン 夕、 tick は呼出しまでの時間を示します。 257 if (tick く 0 ) { 258 259 261 mpfx—>mpfx—timeout = 0 ; mpfx->mpfx-ntick = 0 ; callout—stop(&mpfx—> mpfx—timer—ch) ; 257 ~ 261 行目はタイマー呼出しのキャンセル処理です。 tick に負数を指定された場合、タイマー関連の変数を初期 化し、 callout-stop() でタイマーを停止します。 図 6 の 268 行目で、タイマーが起動する時刻を mpfx- timeout に設疋します。 269 ~ 289 行目では、指定された 75
連載 / v6 の実装 図 8 PREFERRED 状態でび里 330 331 332 337 338 339 340 341 342 343 344 345 346 347 348 switch (mpfx->mpfx-state) { case MIP6_PREFIX_STATE_PREFERRED : if (mip6-prefix-send-mps (mpfx) ) { if (mpfx—>mpfx—vlexpire > mono—time . tv-sec + MIP6-MOBILE-PREFIX_SOL_INTERVAL) { mip6—prefix—settimer (mpfx , MIP6_MOBILE_PREFIX_SOL_INTERVAL * (z) ; } else { mip6—prefix—settimer (mpfx , (mpfx->mpfx—vlexpire ー mono—time. tv-sec) * (z) ; break ; mpfx->mpfx-state = MIP6-PREFIX—STATE-EXPIRING; 図 9 EXPIRING 状態で 0 里 350 351 352 353 354 355 356 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 } case MIP6_PREFIX_STATE_EXPIRING : if (mpfx—>mpfx—vlexpire く mono—time . tv—sec) { mip6—prefix—1ist—remove (&mip6—prefix—1ist , mpfx) ; break; if (mip6—prefix—send—mps(mpfx) ) { if (mpfx—>mpfx-vlexpire > } else { mpfx->mpfx-state = MIP6-PREFIX—STATE_EXPIRING ; (mpfx—>mpfx—vlexpire ー mono—time . tv—sec) * (z) ; mip6—prefix-settimer(mpfx, MIP6_MOBILE_PREFIX_SOL_ 工 NTERVAL * (z) ; mip6—prefix—settimer (mpfx , mono—time . tv—sec + MIP6—MOBILE—PREFIX_SOL_INTERVAL) { splx(s) ; break ; と EXPIRING) をもっています。 PREFERRED は推 奨肩効期限がまだ残っている状態です。この状態のときに タイマー関数カ呼ばれた場合、推奨肩効時間の期限が迫っ ていることを未します。 図 8 の 332 行目の mip6-prefix-send-mps() でモバイ ル・プレフィックス要求メッセージを送信し、最新のプレ フィックス情報の取得を試みます。 339 ~ 346 行目では、次のタイマー呼出しの時刻を設 定します。現在の実装では、推奨有効時間が切れた状態 UNIX MAGAZINE 2005 . 9 の mip6-prefix 構造体は MIP6-MOBILE-PREFIX- SOL-INTERVAL 時間ごとにタイマー関数を呼び出し、 モバイル・プレフィックス要求メッセージを送信します。 MIP6-MOBILE-PREFIX-SOL-INTERVAL の値は 10 秒に設定されています。 推奨肩効時間が切れた場合、 mip6-prefix 構造体の状態 は EXPIRING に遷移します ( 347 行目 ) 。 EXPIRING は、より新しいプレフィックス情報を入手 する必要がある状態です。この状態では、新しいプレフィ 77
表 1 アドレスの番頁と構造 1111 1111 連載 / 旧ルーティング 種類 Unspecified グローノヾル・ユニキャスト 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て 未割当て IPv4 マップ IPv4 互換 ループバック マルチキャスト 未割当て リンクローカル・ユニキャスト 未割当て ユニークローカル・ユニキャスト 0000 0000 0000 0001 0000 001 0000 01 プレフィックス ( 2 週 1111 110 1111 10 1111 0 1110 110 101 100 011 010 001 0001 0000 1 1111 1110 11 1111 1110 10 1111 1110 0 : : / 128 ・ : 1 / 128 記 : : 仕仕 : 0.0.0.0 / 96 : :. 0.0.0.0 / 96 備考 : / 8 : / 3 : / 3 : / 3 : / 3 : / 4 : / 6 : / 7 : / 10 fec(): fe80. fe00. fc00: f800 : f000. e000 : C000 : a000 : 8000. 6000 : 4000. 2000 : 1000. 0800 ・ 0400. 0200 0100. 0000 : 冊 0 : : / 8 います。アドレスは、先頭の何ビットかを見ると、それが 46 ると、自ホストの TCP 2601 番ポートに IPv6 で telnet telnet : : 1 2601 " とす ドレスカ坏リ用できます。つまり、 通信のバケットの終点 IP アドレスにはループバック・ア いる Zebra デーモンに telnet 接続する場合、その telnet じる通信に用いられます。たとえば、自ホストで動作して ループバック (Loopback) アドレスは、自ホスト内で閉 ループバック・アドレス ( : : 1 / 128 ) 実際には利用される機会はめったにありません。 リンクローカル・ユニキャストアドレスカ坏リ用可能なので、 ています。アドレスが設疋されていない場合でも、後述の あり、、、アドレスがない ( 設疋されていない ) " ことを示し Unspecified アドレス ( : : / 128 ) は未定義のアドレスで Unspecified アドレス ( : : / 128 ) 示します。 す。現在規定されているアドレスの種類と構造を、表 1 に どの種類のアドレスであるか判断できる構造になっていま 接続することができます。 IPv4 における 127.0.0.1 のア ドレスと同じ意床をもっています。 IPv4 互換アドレスと IPv4 マップアドレス インターネットが IPv4 から IPv6 へ移行するシナリオ として、 IPv6 ホストカ働的に IPv4 ネットワークの上に トンネルを張るという技術が考案されました [ 2 ] 。 IPv4 互 換 IPv6 アドレスはこの動的トンネリングの際に利用され ます。また、 IPv4 マップアドレスは、 IPv4 アドレスを IPv6 アドレスで表現するためのアドレス空間です。どち らも下位 32 ビットに IPv4 アドレスがオ内されます。な お、この連載では動的トンネリングは扱いません。 グローバル・ユニキャストアドレス グローバル・ユニキャスト (Global unicast) のアドレ ス空間が、通常のインターネット通信に用いられる IPv6 アドレス空間です。この範囲のアドレスは、 IANA (ln- ternet Assigned Nurnbers Authority)2 が RIR (Re- 2 http://www.iana.org/ 上記 4 つのアドレス空間を除く 割当て廃 1E (OSI NSAP 互換アドレス [ 3 ] ) IANA から割当て中 開発中。現在はまだ利用されていない 割当て廃 . に ( サイトローカル・ユニキャストアドレス [ 4 ] ) UNIX MAGAZ 工 NE 2005.9
連載 / 旧 v6 の実装ー 0 図 6 タイマー乎出し時刻の言聢 267 268 269 270 272 2 73 279 280 282 283 289 290 291 292 293 } } else { mpfx—>mpfx—timeout = mono—time. tv—sec 十 tick / hz; if (tick > INT—MAX) { else mpfx—>mpfx—ntick = tick ー INT—MAX ; callout—reset(&mpfx—>mpfx—timer—ch, mip6—prefix—timer, mpfx) ; mpfx—>mpfx—ntick = 0 ; callout—reset(&mpfx—>mpfx—timer—ch, mip6-prefix—timer, mpfx) ; INT_MAX , tick, SPIX(S) ; 図 7 mip6-prefix-settimer() で INT-MAX を超える日か指定されていた場合のタ里 316 mpfx = (struct mip6-prefix *)arg; 317 318 if (mpfx—>mpfx—ntick > 0 ) { 319 320 321 322 323 324 325 326 327 328 } if (mpfx->mpfx—ntick > INT-MAX) { } else { SPIX(S) ; return ; INT_MAX ; mpfx—>mpfx—ntick mip6—prefix—settimer(mpfx, INT—MAX) ; mpfx—>mpfx—ntick = 0 ; mip6—prefix—settimer (mpfx , mpfx—>mpfx—ntick) ; タイムアウトまでの時間 (tick) が、整数変数 (int 型 ) の上 er() で実装されます。 実際のタイマー処理は次に解説する mip6-prefix-tim- 間後にタイマーを起動するように設定します。 イ寺しておきます。そうでない場合は、 282 行目で tick 時 定し、 tick から INT-MAX を引いた値を mpfx-ntick に 行目で INT-MAX 時間後にタイマーを起動するように設 の値が int 型の上限値 (INT-MAX) を超えていたら、 272 上限が int 型変数の上限に制限されているからです。 tick を調整しています。 callout-reset() で指定できる時間の 限値を超えているかどうかに応じてタイマー呼出しの時間 295 296 297 298 76 #def ine MIP6_MOBILE_PREFIX_SOL_INTERVAL VOid mip6-prefix-timer(arg) static void 10 / * XXX * / 299 { mip6-prefix-timer() は void 型のポインタを引数にも ちます。実際には、ポインタに mip6-prefix 構造体へのポ インタカス疋されています。 図 7 の 318 ~ 328 行目は、 mip6-prefix-settimer() で INT-MAX を超える時間を指定されていた場合の処理で す。 mpfx-ntick に 0 以上の値か轂定されている場合、ま だ実際にタイマー関数を呼び出す時刻にはなっていないこ とを未します。ふたたび mip6-prefix-settimer() を呼 び出し、次のタイマー呼出しを予約します。 mip6-prefix- timer() が呼ばれるたびに mpfx-ntick の数は減ってい き、最終的に INT-MAX より小さくなったときに mpfx- ntick が 0 に設疋されます。 mip6-prefix 構造体は 2 種類の状態 (PREFERRED UNIX MAGAZ 工 NE 2005 . 9