8. 上向きルート
本セクションでは、RPL がどのように上向きルートを発見し、維持するかについて説明します。これらのルートを発見し維持するために使用されるメッセージである DODAG Information Objects (DIO) の使用について説明します。RPL がどのように DIO を生成し、応答するかを規定します。また、DIO 送信をトリガーするために使用される DODAG Information Solicitation (DIS) メッセージについても説明します。
セクション 3.2.8 で述べたように、DODAG への参加を決定したノードは、関連するインスタンスのデフォルトルートとして少なくとも 1 つの DODAG 親をプロビジョニングしなければなりません (MUST)。このデフォルトルートにより、パケットは、最終的に共通の祖先に到達するまで上向きに転送され、そこから宛先へと下向きにルーティングされます。宛先が DODAG 内にない場合、DODAG ルートは DODAG 外部への接続を使用してパケットを転送できる可能性があります。外部へパケットを転送できない場合、DODAG ルートはそれを破棄しなければなりません。
DIO メッセージは、明示的なルーティング情報も転送できます。
-
DODAGID: DODAGID は、ルートのグローバルまたはユニークローカル IPv6 アドレスです。DODAG に参加するノードは、ルートが DODAGID として使用するアドレスへのホストルートを、DODAG 親を介してプロビジョニングすべきです (SHOULD)。
-
RIO プレフィックス: ルートは、DIO メッセージに 1 つ以上の Route Information Option (RIO) を配置してもかまいません (MAY)。RIO は、ルートを介して到達可能な外部ルートを、[RFC4191] からの RIO を組み込んだセクション 6.7.5 で提示されているように、優先度に関連付けてアドバタイズするために使用されます。これはルーティングアドバタイズメントではなくルートの機能として解釈され、別のルーティングプロトコルで再配布してはなりませんが (MUST NOT)、入力 RPL ルータに接続されたノードから RPL ドメインにパケットが注入される際に、入力 RPL ルータが DODAG を選択するために使用すべきです (SHOULD)。目的関数 (Objective Function) は、同一インスタンスに対してある DODAG を別の DODAG よりも優先するために、RIO でアドバタイズされたルートまたはそれらのルートの優先度を使用してもかまいません (MAY)。
8.1. DIO 基本ルール
-
以下の DIO Base フィールドについて、DODAG ルートではないノードは、その優先 DODAG 親(セクション 8.2.1 で定義)と同じ値をアドバタイズしなければなりません (MUST)。このようにして、これらの値は DODAG を下流に変更されずに伝播し、その DODAG ルートへのルートを持つすべてのノードによってアドバタイズされます。これらのフィールドは以下の通りです。
- Grounded (G)
- Mode of Operation (MOP)
- DAGPreference (Prf)
- Version
- RPLInstanceID
- DODAGID
-
ノードは、各ホップで以下のフィールドを更新してもかまいません (MAY)。
- Rank
- DTSN
-
各ルートが設定する DODAGID フィールドは、RPL インスタンス内で一意でなければならず (MUST)、ルートに属するルーティング可能な IPv6 アドレスでなければなりません (MUST)。
8.2. 上向きルートの発見と維持
上向きルートの発見により、ノードは関心のある DODAG のメンバーである近隣ノードを発見し、親のセットを特定することによって、DODAG に参加できます。近隣ノードと親を選択するための正確なポリシーは実装依存であり、OF によって駆動されます。本セクションでは、相互運用性のためにそれらのポリシーが従わなければならないルールのセットを規定します。
8.2.1. DODAG バージョン内の近隣ノードと親
RPL の上向きルート発見アルゴリズムと処理は、リンクローカルノードの 3 つの論理セットの観点から行われます。第一に、候補近隣ノードセットは、リンクローカルマルチキャストを介して到達可能なノードのサブセットです。このセットの選択は実装および OF に依存します。第二に、親セットは、候補近隣ノードセットの制限されたサブセットです。最後に、優先親は、上向きルートにおける優先ネクストホップである親セットのメンバーです。概念的には、優先親は単一の親ですが、それらの親が等しく優先され、同一のランクを持つ場合、複数の親のセットである可能性があります。
より正確には:
-
DODAG 親セットは、候補近隣ノードセットのサブセットでなければなりません (MUST)。
-
DODAG ルートは、サイズゼロの DODAG 親セットを持たなければなりません (MUST)。
-
DODAG ルートではないノードは、1 以上のサイズの DODAG 親セットを維持してもかまいません (MAY)。
-
ノードの優先 DODAG 親は、その DODAG 親セットのメンバーでなければなりません (MUST)。
-
ノードのランクは、その DODAG 親セットのすべての要素よりも大きくなければなりません (MUST)。
-
近隣不到達検出 (NUD) [RFC4861] または同等のメカニズムが、近隣ノードに到達できなくなったと判断した場合、RPL ノードは、再び到達可能であると判断するまで、ルートの計算およびアドバタイズ時にこのノードを候補近隣ノードセットに含めてはなりません (MUST NOT)。到達不能な近隣ノードを介するルートは、ルーティングテーブルから削除しなければなりません (MUST)。
これらのルールにより、DODAG 内のノードに一貫した半順序が存在することが保証されます。ノードのランクが変更されない限り、上記のルールに従うことで、ランクはルートへの各ホップで減少するため、DODAG ルートへのすべてのノードのルートがループフリーであることが保証されます。
[RFC6552] で議論されているように、OF は候補近隣ノードセットと親セットの選択を導くことができます。
8.2.2. DODAG バージョン間の近隣ノードと親
上記のルールは、単一の DODAG バージョンを管理します。本セクションのルールは、複数の DODAG バージョンが存在する場合に RPL がどのように動作するかを定義します。
8.2.2.1. DODAG バージョン
-
タプル (RPLInstanceID, DODAGID, DODAGVersionNumber) は、DODAG バージョンを一意に定義します。各 DODAG 親から最後に聞こえた DIO メッセージによって伝えられる、ノードの DODAG 親セットのすべての要素は、同じ DODAG バージョンに属さなければなりません (MUST)。ノードの候補近隣ノードセットの要素は、異なる DODAG バージョンに属してもかまいません (MAY)。
-
ノードの DODAG 親セットのすべての要素がその DODAG バージョンに属している場合、またはそのノードが対応する DODAG のルートである場合、そのノードは DODAG バージョンのメンバーです。
-
ノードは、自身がメンバーではない DODAG バージョンの DIO を送信してはなりません (MUST NOT)。
-
DODAG ルートは、アドバタイズする DODAGVersionNumber をインクリメントして、新しい DODAG バージョンに移行してもかまいません (MAY)。DODAG ルートが DODAGVersionNumber をインクリメントする場合、セクション 7 で説明されているシリアル番号演算の規則に従わなければなりません (MUST)。DODAGVersionNumber のインクリメントをトリガーするイベントについては、本セクションの後半とセクション 18 で説明します。
-
特定の DODAG 内では、ルートではないノードは、自身が聞いた最高の DODAGVersionNumber よりも高い DODAGVersionNumber をアドバタイズしてはなりません (MUST NOT)。高いとは、セクション 7 の「より大きい」演算子として定義されます。
-
ノードが DIO を送信して DODAG バージョンをアドバタイズした後は、同じ DODAG の以前の DODAG バージョン(つまり、同じ RPLInstanceID、同じ DODAGID、およびより低い DODAGVersionNumber を持つ)のメンバーであってはなりません (MUST NOT)。低いとは、セクション 7 の「より小さい」演算子として定義されます。
ルートではないノードで DODAG 親セットが空になった場合(つまり、最後の親が削除され、ノードがその DODAG に関連付けられなくなった場合)、実装固有のローカルタイマーが満了するまで DODAG 情報を抑制すべきではありません。 「古い」DODAG 状態が抑制される前の期間中、ノードは、新しい親が現れた場合に DODAGVersionNumber がインクリメントされたかどうかを観察できます。これは、そのノードが自身の以前のサブ DODAG 内で誤って古い DODAG バージョンに再参加した場合に発生する可能性のあるループの可能性を防ぐのに役立ちます。
DODAGVersionNumber がインクリメントされると、新しい DODAG バージョンは DODAG ルートから外側に向かって広がります。新しい DODAGVersionNumber をアドバタイズする親は、古い DODAGVersionNumber をアドバタイズするノードのサブ DODAG に属することはできません。したがって、ノードは、ループを形成することなく、新しい DODAGVersionNumber を持つ任意のランクの親を安全に追加できます。
例えば、あるノードが DODAGVersionNumber N の DODAG を離れたとします。あるノードがサブ DODAG を持っており、INFINITE_RANK のランクをアドバタイズしてそのサブ DODAG を毒そうと試みたが、それらのアドバタイズメントが LLN で失われた可能性があるとします。その場合、ノードがその元の DODAG 内の位置を DODAGVersionNumber N でアドバタイズしている候補近隣ノードを観察した場合、その候補近隣ノードはノードの以前のサブ DODAG 内にあった可能性があり、その候補近隣ノードを親として追加するとループが発生する可能性があります。この場合、その候補近隣ノードが DODAGVersionNumber N+1 をアドバタイズしていることが観察されれば、その候補近隣ノードは安全であることが確実です。なぜなら、その候補近隣ノードは、元のノードが分離している間に DODAG ルートから聞くことによって DODAGVersionNumber をインクリメントできたため、元のノードのサブ DODAG 内にないことが確実だからです。このため、分離されたノードにとって、DODAGVersionNumber N を含む元の DODAG 情報を記憶しておくことは有用です。
DODAG ルートがいつ DODAGVersionNumber をインクリメントするかは実装依存であり、本仕様の範囲外です。例としては、定期的に、管理上の介入により、または接続の損失や DODAG の非効率性のアプリケーションレベルの検出時に、DODAGVersionNumber をインクリメントすることが挙げられます。
ノードが新しい DODAG バージョンに移行してアドバタイズした後、上記のルールにより、新しい DODAG バージョンをアドバタイズすることをコミットすると、以前の DODAG バージョン(以前の DODAGVersionNumber)をアドバタイズできなくなります。
8.2.2.2. DODAG ルート
-
アプリケーション定義の目標を満たす可能性のない DODAG ルートは、Grounded ビットを設定してはなりません (MUST NOT)。
-
DODAG ルートは、ROOT_RANK のランクをアドバタイズしなければなりません (MUST)。
-
DODAG 親セットが空のノードは、フローティング DODAG の DODAG ルートになってもかまいません (MAY)。また、DAGPreference を設定して、優先度を低くしてもかまいません (MAY)。
非 LLN リンクを使用して多数の LLN ルートを連携させる展開では、それらの非 RPL リンク上で RPL を実行し、1 つのルータを「バックボーンルート」として使用することが可能です。バックボーンルートは DODAG の仮想ルートであり、バックボーン上で BASE_RANK のランクを公開します。そのバックボーンルートを親とするすべての LLN ルート(バックボーンルート自体が LLN ルートとしても機能する場合を含む)は、LLN に対して ROOT_RANK のランクを公開します。これらの仮想ルートは同じ DODAG の一部であり、同じ DODAGID をアドバタイズします。これらは、バックボーン上の仮想ルートと DODAGVersionNumber およびその他の DODAG パラメータを調整します。調整方法は、本仕様の範囲外です(将来の関連仕様で定義される予定)。
8.2.2.3. DODAG 選択
目的関数および DAG のアドバタイズされたルーティングメトリックと制約のセットによって、ノードが近隣ノードセット、親セット、および優先親を選択する方法が決まります。この選択は、暗黙的に DAG 内の DODAG も決定します。このような選択には、メトリックやその他の考慮事項だけでなく、管理上の優先順位 (Prf) も含めることができます。
ノードが他の最適化目標を満たしながら、より優先度の高い DODAG に参加するオプションがある場合、ノードは通常、OF によって決定される、より優先度の高い DODAG への参加を求めます。他のすべてが等しい場合、どの DODAG が最も優先されるかを決定するのは実装に委ねられます(リマインダーとして、ノードは RPL インスタンスごとに 1 つの DODAG にのみ参加しなければならないため)。
8.2.2.4. DODAG バージョン内のランクと移動
-
ノードは、DODAG バージョン内の親セットのメンバー以下のランクをアドバタイズしてはなりません (MUST NOT)。
-
ノードは、DODAG バージョン内の以前のアドバタイズメントよりも低いランクをアドバタイズしてもかまいません (MAY)。
-
L を、特定のノードがアドバタイズした DODAG バージョン内の最低ランクとします。同じ DODAG バージョン内で、そのノードは L + DAGMaxRankIncrease よりも高い有効ランクをアドバタイズしてはなりません (MUST NOT)。INFINITE_RANK はこのルールの例外です。ノードは、制限なしに DODAG バージョン内で INFINITE_RANK をアドバタイズしてもかまいません (MAY)。ノードのランクが L + DAGMaxRankIncrease で許可されているよりも高くなる場合、ランクをアドバタイズするとき、ランクを INFINITE_RANK としてアドバタイズしなければなりません (MUST)。
-
ノードは、いつでも、RPL インスタンス内の別の DODAG に参加することを選択してもかまいません (MAY)。そのような参加にはランクの制限はありません。ただし、その別の DODAG が、このノードが以前にメンバーであった DODAG バージョンである場合を除きます。その場合、前の箇条書き (3) のルールに従わなければなりません。ノードは、新しい DODAG メンバーシップを示す DIO を送信するまで、以前の DODAG に沿ってパケットを転送しなければなりません (MUST)。
-
ノードは、適切な DODAG 親から次の DODAGVersionNumber がアドバタイズされたのを聞いた後いつでも、DODAG 内の次の DODAG バージョンに移行することを選択してもかまいません (MAY)。
概念的には、実装は DODAG バージョン内で DODAG 親セットを維持しています。移動には、DODAG 親セットの変更が伴います。上への移動はループを作成するリスクはありませんが、下への移動はリスクがある可能性があるため、その操作には追加の制約が適用されます。
ノードが次の DODAG バージョンに移行する場合、新しいバージョンのために DODAG 親セットを再構築する必要があります。実装は、潜在的により良いメトリックを持つがランクが高い他の近隣ノードが自分自身をアナウンスするかどうかを確認するために、妥当な時間だけ移行を延期することができます。同様に、ノードが新しい DODAG にジャンプする場合、この新しい DODAG のために新しい DODAG 親セットを構築する必要があります。
ノードが接続されている DODAG を下に移動し、ランクを上げる必要がある場合、セクション 8.2.2.5 で説明されているように、ルートを毒し、移動する前に遅延してもかまいません (MAY)。
ノードは、制限なしに、以前にメンバーであったことのない任意の DODAG バージョンに参加することが許可されていますが、ノードが DODAG バージョンの以前のメンバーであった場合、DODAG バージョンの存続期間中のどの時点でも L+DAGMaxRankIncrease よりも高いランクをアドバタイズしてはならないというルールを引き続き遵守しなければなりません。ノードが事実上ランクを INFINITE_RANK までずっとインクリメントできるようにする抜け穴を作成しないように、このルールを遵守する必要があります。これは、他のノードに影響を与え、リソースを浪費するカウント・トゥ・インフィニティ(無限カウント)シナリオを作成する可能性があります。
8.2.2.5. ポイズニング(毒入れ)
-
ノードは、INFINITE_RANK のランクをアドバタイズすることによってルートを毒します。
-
ノードは、親セットに INFINITE_RANK のランクを持つノードを持ってはなりません (MUST NOT)。
実装はポイズニングの目的で INFINITE_RANK をアドバタイズするかもしれませんが、そうすることはランクを INFINITE_RANK に設定することと同じではありません。例えば、ノードは、RPL パケット情報に INFINITE_RANK ではないランクが含まれるデータパケットを送信し続けながら、DIO で INFINITE_RANK をアドバタイズする場合があります。
(以前の)親が INFINITE_RANK のランクをアドバタイズしていることが観察された場合、その(以前の)親は DODAG から分離しており、もはや親として機能することはできず、別のノードが INFINITE_RANK よりも大きいランクを持つと見なされる方法もありません。したがって、その(以前の)親はもはや親として機能できず、親セットから削除されます。
8.2.2.6. 分離 (Detaching)
- 特定の DODAG バージョン内で DODAG に接続し続けることができない、つまり、本仕様のルールに違反せずに空でない親セットを保持できないノードは、この DODAG バージョンから分離してもかまいません (MAY)。分離したノードは、独自のフローティング DODAG のルートとなり、ポイズニングの代替として、DIO でこの新しい状況を直ちにアドバタイズすべきです (SHOULD)。
8.2.2.7. 親への追従
- ノードが DODAG 親の 1 つから、親が DODAG を離れたことを示す DIO を受信した場合、そのノードは、可能であれば、代替の DODAG 親を介して現在の DODAG に留まるべきです (SHOULD)。離れる親に追従してもかまいません (MAY)。
DODAG 親が移動したか、次の DODAG バージョンに移行したか、または別の DODAG にジャンプした可能性があります。ノードは、代替の親を介して可能であれば、現在の DODAG に留まることを優先すべきですが、他に選択肢がない場合は親に追従すべきです。
8.2.3. DIO メッセージ通信
DIO メッセージが受信されると、受信ノードはまず、DIO メッセージがさらなる処理のために受け入れられるべきかどうかを判断し、適格であれば、その後 DIO メッセージをさらなる処理のために提示しなければなりません。
-
DIO メッセージが不正な形式である場合、DIO メッセージはさらなる処理の対象ではなく、ノードはそれを黙って破棄しなければなりません (MUST)。 (エラーログについてはセクション 18 を参照)。
-
DIO メッセージの送信者が候補近隣ノードセットのメンバーであり、DIO メッセージが不正な形式でない場合、ノードは DIO を処理しなければなりません (MUST)。
8.2.3.1. DIO メッセージ処理
候補近隣ノードから DIO メッセージを受信すると、セクション 8.2 で説明されている DODAG 発見のルールに従って、近隣ノードが DODAG 親に昇格される場合があります。ノードが近隣ノードを DODAG 親セットに入れると、ノードは新しい DODAG 親ノードを介して DODAG に接続されます。
最も優先される親を使用して、他のどのノードが DODAG 親になることができるかを制限すべきです。DODAG 親セット内の一部のノードは、最も優先される DODAG 親以下のランクである可能性があります。(このケースは、例えば、エネルギー制約のあるデバイスがより低いランクにあるが、最適化目標に従って回避されるべきであり、その結果、より高いランクでより優先される親が存在する場合に発生する可能性があります。)
8.3. DIO 送信
RPL ノードは、Trickle タイマー [RFC6206] を使用して DIO を送信します。受信者の親セット、優先親、またはランクに変更を引き起こさない、より小さい DAGRank を持つ送信者からの DIO は、Trickle タイマーに関して一貫していると見なされるべきです (SHOULD)。
以下のパケットおよびイベントは、Trickle タイマーに関して不整合と見なされなければならず (MUST)、Trickle タイマーをリセットさせます。
-
セクション 11.2 で詳述されているように、パケットを転送するときにノードが不整合を検出した場合。
-
ノードが Solicited Information オプションなしでマルチキャスト DIS メッセージを受信した場合。ただし、DIS フラグがこの動作を制限している場合を除きます。
-
ノードが Solicited Information オプション付きのマルチキャスト DIS を受信し、ノードが Solicited Information オプション内のすべての述語に一致する場合。ただし、DIS フラグがこの動作を制限している場合を除きます。
-
ノードが新しい DODAG バージョンに参加した場合(例:DODAGVersionNumber の更新、新しい RPL インスタンスへの参加など)。
このリストは網羅的ではなく、実装は他のメッセージまたはイベントを不整合と見なしてもかまいません (MAY)。
ノードは、ユニキャスト DIS メッセージに応答して DIO Trickle タイマーをリセットすべきではありません (SHOULD NOT)。ノードが Solicited Information オプションなしでユニキャスト DIS を受信した場合、応答として送信者に DIO をユニキャストしなければなりません (MUST)。この DIO には、DODAG Configuration オプションを含めなければなりません (MUST)。ノードが Solicited Information オプション付きのユニキャスト DIS メッセージを受信し、その Solicited Information オプションの述語に一致する場合、応答として送信者に DIO をユニキャストしなければなりません (MUST)。このユニキャスト DIO には、DODAG Configuration オプションを含めなければなりません (MUST)。したがって、ノードは、DODAG 構成およびその他のパラメータをプローブするために、潜在的な DODAG 親にユニキャスト DIS メッセージを送信してもかまいません (MAY)。
8.3.1. Trickle パラメータ
Trickle タイマーの構成パラメータは、以下のように規定されています。
-
Imin: DIO メッセージから (2^DIOIntervalMin) ms として学習されます。DIOIntervalMin のデフォルト値は DEFAULT_DIO_INTERVAL_MIN です。
-
Imax: DIO メッセージから DIOIntervalDoublings として学習されます。DIOIntervalDoublings のデフォルト値は DEFAULT_DIO_INTERVAL_DOUBLINGS です。
-
k: DIO メッセージから DIORedundancyConstant として学習されます。DIORedundancyConstant のデフォルト値は DEFAULT_DIO_REDUNDANCY_CONSTANT です。RPL では、k の値が 0x00 の場合、これは RPL における無限大の冗長定数、つまり Trickle がメッセージを抑制しないこととして扱われます。
8.4. DODAG 選択
DODAG 選択は実装および OF に依存します。不安定な動きを制限するために、すべてのメトリックが等しい場合、ノードは以前の選択を維持すべきです (SHOULD)。また、ノードは、少なくともより安定した選択肢が利用可能な場合に、可用性が変動していると検出された親をフィルタリングする手段を提供すべきです (SHOULD)。
セキュリティまたはその他の理由で、接地された (grounded) DODAG への接続が可能でないか望ましくない場合、分散した DODAG は、LLN 内の接続を可能にするために、可能な限り大きな DODAG に集約してもかまいません (MAY)。
ノードは、候補近隣ノードを DODAG 親として検討する前に、その候補近隣ノードとの双方向接続と適切なリンク品質が利用可能であることを確認すべきです (SHOULD)。
8.5. リーフノードとしての動作
場合によっては、RPL ノードはリーフノードとしてのみ DODAG に接続することがあります。そのようなケースの一例は、ノードが RPL インスタンスの OF またはアドバタイズされたメトリック/制約を理解していないか、サポートしていない(ポリシー)場合です。ポリシー機能に関連するセクション 18.6 で規定されているように、ノードはリーフノードとして DODAG に参加するか、DODAG に参加しないことができます。セクション 18.5 で述べたように、その場合は障害をログに記録することが推奨されます。
リーフノードは DODAG 接続を拡張しません。ただし、場合によっては、リーフノードは依然として時折 DIO を送信する必要があるかもしれません。特に、リーフノードが常にリーフノードとして動作していたわけではなく、不整合が検出された場合などです。
リーフノードとして動作するノードは、以下のルールに従わなければなりません。
-
DAG Metric Container を含む DIO を送信してはなりません (MUST NOT)。
-
その DIO は、INFINITE_RANK の DAGRank をアドバタイズしなければなりません (MUST)。
-
DIO 送信を抑制してもかまいません (MAY)。ただし、パケットが転送されているときの不整合の検出、またはユニキャスト DIS メッセージへの応答として DIO 送信がトリガーされた場合を除き、その場合、DIO 送信を抑制してはなりません (MUST NOT)。
-
セクション 9.2 で説明されているように、ユニキャスト DAO を送信してもかまいません (MAY)。
-
セクション 9.10 で説明されているように、「1 ホップ」近隣へのマルチキャスト DAO を送信してもかまいません (MAY)。
リーフノードが DIO を送信する必要がある特定のケースは、そのリーフノードが別の DODAG の以前のメンバーであり、別のノードが古いトポロジを想定してメッセージを転送し、不整合をトリガーした場合です。リーフノードは、不整合を修復するために DIO を送信する必要があります。LLN の損失の多い性質により、リーフノードがリーフノードになる前に古い DODAG で INFINITE_RANK のランクをアドバタイズすることによって楽観的にルートを毒したとしても、そのアドバタイズメントが失われた可能性があり、リーフノードは不整合を修復するために後で DIO を送信できなければならないことに注意してください。
一般的なケースでは、リーフノードは自身をルータとしてアドバタイズ(つまり、DIO を送信)してはなりません (MUST NOT)。
8.6. 管理ランク
場合によっては、実装固有のポリシーやノードのプロパティに基づいて、OF によって計算されたランクを超えてノードによってアドバタイズされるランクを調整することが有益な場合があります。例えば、バッテリーが限られているノードは、他に選択肢がない限りリーフであるべきであり、誇張されたランクを公開するために OF によって規定されたランク計算を増強する場合があります。