OSPF(Open Shortest Path First)は、実際のネットワークでもよく使われるダイナミックルーティングプロトコルです。この記事では、OSPF の概要と、ネイバーを見つけて隣接関係になり、経路を計算するまでの流れをまとめます。
- OSPF のエリア、バックボーンルータ、ABR
- Hello で確かめる項目と、ルータ ID の決まり方
- ネイバーの状態(Down から Full まで)の移り方と、debug での見え方
OSPF の概要
OSPF は、RFC 2328「OSPF Version 2」で決められているリンクステート型のルーティングプロトコルです。ダイクストラのアルゴリズム(SPF:Shortest Path First)を使い、帯域幅から決まるコストをもとに最短の経路を計算します。
OSPF にはエリアという考え方があります。同じエリアのルータは、エリアの中のトポロジーの情報(LSDB)を共有し、それぞれが SPF で最短の経路を計算します。全員が同じ情報から計算するので、エリアの中ではルーティングループが起きません。エリア0(0.0.0.0)は、OSPF のネットワークの中心になるバックボーンエリアです。エリアが1つだけの構成では、エリア0を使うのが一般的です。
エリア0に属しているルータを、バックボーンルータと呼びます。
エリア0以外のエリア(エリア1、エリア2など)は、エリア0に直接つながっている必要があります。エリア0とエリア1のように、複数のエリアに属しているルータを、エリアボーダールータ(ABR)と呼びます。ABR は、あるエリアの経路情報をまとめ、サマリー LSA(タイプ3)としてほかのエリアへ広告します。エリアの中の細かいトポロジーは、ほかのエリアには伝えません。
OSPF の動作の流れ
ルータ同士が OSPF でトポロジーの情報を交換し、ルーティングテーブルができるまでの流れを、次の構成で見ていきます。R2 と R3 を 192.168.23.0/24 でつなぎ、エリア0にしています。
Hello でネイバーを見つける
OSPF が有効なインターフェースからは、マルチキャストアドレス 224.0.0.5(AllSPFRouters)宛てに Hello パケットが送られます。このマルチキャストで、同じセグメントにいる OSPF のルータを自動で見つけます。
Hello にはいくつかのパラメータ(エリア、ルータ ID など)が入っていて、ルータ同士でパラメータが合っているかを確かめます。
この記事の画面は、実際の画面ではなく、検証時の画面から見るポイントを抜き出して描いたイメージです。バージョンによって、項目の並びや表記は変わります。
1▸ Internet Protocol Version 4, Src: 192.168.23.2, Dst: 224.0.0.5▾ Open Shortest Path First ▾ OSPF Header Version: 22 Message Type: Hello Packet (1) Packet Length: 483 Source OSPF Router: 2.2.2.24 Area ID: 0.0.0.0 (Backbone) Checksum: 0x333a [correct] Auth Type: Null (0) Auth Data (none): 0000000000000000 ▾ OSPF Hello Packet5 Network Mask: 255.255.255.06 Hello Interval [sec]: 10 ▸ Options: 0x12, (L) LLS Data block, (E) External Routing Router Priority: 17 Router Dead Interval [sec]: 40 Designated Router: 192.168.23.3 Backup Designated Router: 192.168.23.2 Active Neighbor: 3.3.3.3 ▸ OSPF LLS Data Block
| No. | 項目 | 内容 |
|---|---|---|
| 1 | 宛先 224.0.0.5 | OSPF ルータすべて宛てのマルチキャスト |
| 2 | Hello パケット | OSPF のパケットの種類(タイプ1) |
| 3 | ルータ ID | ルータを見分ける ID(ここでは 2.2.2.2) |
| 4 | エリア番号 | 自分のエリア。ネイバー同士で一致している必要がある |
| 5 | サブネットマスク | インターフェースのマスク。ブロードキャストなどのネットワークでは、ネイバー同士で一致している必要がある |
| 6 | Hello インターバル | Hello を送る間隔。既定値は10秒。ネイバー同士で一致している必要がある |
| 7 | Dead インターバル | この間 Hello が届かないと、ネイバーをダウンにする。既定値は Hello の4倍の40秒。ネイバー同士で一致している必要がある |
ほかに、認証の設定やスタブエリアかどうか(Options の E ビットなど)も、ネイバー同士で合っている必要があります。
ルータ ID は、次の順番で決まります。
| 順番 | ルータ ID になるもの |
|---|---|
| 1 | router-id コマンドで設定した値 |
| 2 | ループバックインターフェースの IP アドレス。複数あるときは最も大きいもの(ほかのインターフェースのアドレスのほうが大きくても、ループバックが優先される) |
| 3 | 動いているインターフェースの中で、最も大きい IP アドレス |
一度決まったルータ ID は、OSPF のプロセスを再起動するかルータを再起動するまで変わりません。
隣接関係になるまでの状態
パラメータが合っていることを確かめたあと、ルータ同士はトポロジーの情報を交換して、隣接関係(Full)になります。ネイバーの状態は、次のように移ります。
| 状態 | 内容 |
|---|---|
| Down | 最初の状態。相手からの Hello をまだ受け取っていない。自分から Hello を送ることはできる |
| Init | 相手の Hello を受け取ったが、その Hello の Active Neighbor に自分のルータ ID が入っていない |
| 2-Way | 受け取った Hello の Active Neighbor に自分のルータ ID が入っていて、双方向で Hello が届いている。マルチアクセスのネットワークでは、ここで DR/BDR を選ぶ |
| ExStart | DBD(Database Description)パケットのやり取りを始める準備。どちらが主(マスター)になるかと、DBD の番号の初めの値を決める。ルータ ID が大きいほうがマスターになる |
| Exchange | DBD パケットを交換する。DBD には、自分の LSDB にある LSA のヘッダ(要約)が入っている |
| Loading | DBD でわかった足りない LSA を LSR(Link State Request)で要求し、LSU(Link State Update)で受け取る |
| Full | ルータ同士の LSDB が完全に同期し、隣接関係ができた状態 |
次は、R2 の debug ip ospf adj の出力です(時刻の表示は省いています)。前半は R2 のインターフェースが一度ダウンしたときの動きで、Interface going Up からがネイバーを作り直す流れです。2-Way になり、DR/BDR を選び(DR は 3.3.3.3、BDR は 2.2.2.2)、ExStart と Exchange で DBD を交換し、LS REQ と LS UPD のやり取りを経て Full になっています。R3 のルータ ID のほうが大きいので、R2 はスレーブになっています。
R2
R2#debug ip ospf adj OSPF adjacency debugging is on OSPF-1 ADJ Fa0/0.23: Nbr 3.3.3.3: Clean-up dbase exchange OSPF-1 ADJ Fa0/0.23: Neighbor change event OSPF-1 ADJ Fa0/0.23: DR/BDR election OSPF-1 ADJ Fa0/0.23: Elect BDR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: Elect DR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: Elect BDR 0.0.0.0 OSPF-1 ADJ Fa0/0.23: Elect DR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: DR: 2.2.2.2 (Id) BDR: none OSPF-1 ADJ Fa0/0.23: Remember old DR 3.3.3.3 (id) OSPF-1 ADJ Fa0/0.23: 2.2.2.2 address 192.168.23.2 is dead, state DOWN OSPF-1 ADJ Fa0/0.23: Neighbor change event OSPF-1 ADJ Fa0/0.23: DR/BDR election OSPF-1 ADJ Fa0/0.23: Elect BDR 0.0.0.0 OSPF-1 ADJ Fa0/0.23: Elect DR 0.0.0.0 OSPF-1 ADJ Fa0/0.23: Elect BDR 0.0.0.0 OSPF-1 ADJ Fa0/0.23: Elect DR 0.0.0.0 OSPF-1 ADJ Fa0/0.23: DR: none BDR: none OSPF-1 ADJ Fa0/0.23: Flush network LSA immediately OSPF-1 ADJ Fa0/0.23: Remember old DR 2.2.2.2 (id) OSPF-1 ADJ Lo0: Interface going Up OSPF-1 ADJ Fa0/0.23: Interface going Up OSPF-1 ADJ Fa0/0.23: 2 Way Communication to 3.3.3.3, state 2WAY OSPF-1 ADJ Fa0/0.23: Backup seen event before WAIT timer OSPF-1 ADJ Fa0/0.23: DR/BDR election OSPF-1 ADJ Fa0/0.23: Elect BDR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: Elect DR 3.3.3.3 OSPF-1 ADJ Fa0/0.23: Elect BDR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: Elect DR 3.3.3.3 OSPF-1 ADJ Fa0/0.23: DR: 3.3.3.3 (Id) BDR: 2.2.2.2 (Id) OSPF-1 ADJ Fa0/0.23: Nbr 3.3.3.3: Prepare dbase exchange OSPF-1 ADJ Fa0/0.23: Send DBD to 3.3.3.3 seq 0x61 opt 0x52 flag 0x7 len 32 OSPF-1 ADJ Fa0/0.23: Rcv DBD from 3.3.3.3 seq 0xDC3 opt 0x52 flag 0x7 len 32 mtu 1500 state EXSTART OSPF-1 ADJ Fa0/0.23: NBR Negotiation Done. We are the SLAVE OSPF-1 ADJ Fa0/0.23: Nbr 3.3.3.3: Summary list built, size 0 OSPF-1 ADJ Fa0/0.23: Send DBD to 3.3.3.3 seq 0xDC3 opt 0x52 flag 0x0 len 32 OSPF-1 ADJ Fa0/0.23: Rcv DBD from 3.3.3.3 seq 0xDC4 opt 0x52 flag 0x1 len 72 mtu 1500 state EXCHANGE OSPF-1 ADJ Fa0/0.23: Exchange Done with 3.3.3.3 OSPF-1 ADJ Fa0/0.23: Send LS REQ to 3.3.3.3 length 48 LSA count 2 OSPF-1 ADJ Fa0/0.23: Send DBD to 3.3.3.3 seq 0xDC4 opt 0x52 flag 0x0 len 32 OSPF-1 ADJ Fa0/0.23: Rcv LS UPD from 3.3.3.3 length 144 LSA count 2 OSPF-1 ADJ Fa0/0.23: Synchronized with 3.3.3.3, state FULL %OSPF-5-ADJCHG: Process 1, Nbr 3.3.3.3 on FastEthernet0/0.23 from LOADING to FULL, Loading Done OSPF-1 ADJ Fa0/0.23: Neighbor change event OSPF-1 ADJ Fa0/0.23: DR/BDR election OSPF-1 ADJ Fa0/0.23: Elect BDR 2.2.2.2 OSPF-1 ADJ Fa0/0.23: Elect DR 3.3.3.3 OSPF-1 ADJ Fa0/0.23: DR: 3.3.3.3 (Id) BDR: 2.2.2.2 (Id)
SPF で最短の経路を計算する
ルータ同士で共有したトポロジーの情報をもとに、SPF のアルゴリズムで最短の経路を計算し、ルーティングテーブルに入れます。R2 は、R3 のループバック 3.3.3.3 をコスト 2(リンクのコスト 1 とループバックのコスト 1)で学習しています。
R2
R2#sh ip route ospf
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
+ - replicated route, % - next hop override
Gateway of last resort is not set
3.0.0.0/32 is subnetted, 1 subnets
O 3.3.3.3 [110/2] via 192.168.23.3, 00:03:07, FastEthernet0/0.23
Hello で隣接関係を保つ
隣接関係を保つため、ルータ同士は Hello を定期的に送り続けます。debug ip ospf hello を見ると、R2 の Hello の送信(Send hello)と R3 からの受信(Rcv hello)が、それぞれ約10秒ごとに出ています。
R2
R2#debug ip ospf hello OSPF hello debugging is on *Jun 13 12:21:22.007: OSPF-1 HELLO Fa0/0.23: Send hello to 224.0.0.5 area 0 from 192.168.23.2 *Jun 13 12:21:27.491: OSPF-1 HELLO Fa0/0.23: Rcv hello from 3.3.3.3 area 0 192.168.23.3 *Jun 13 12:21:31.615: OSPF-1 HELLO Fa0/0.23: Send hello to 224.0.0.5 area 0 from 192.168.23.2 *Jun 13 12:21:36.799: OSPF-1 HELLO Fa0/0.23: Rcv hello from 3.3.3.3 area 0 192.168.23.3 *Jun 13 12:21:40.791: OSPF-1 HELLO Fa0/0.23: Send hello to 224.0.0.5 area 0 from 192.168.23.2 *Jun 13 12:21:45.815: OSPF-1 HELLO Fa0/0.23: Rcv hello from 3.3.3.3 area 0 192.168.23.3
まとめ
| 流れ | 使うパケット | 状態 |
|---|---|---|
| ネイバーを見つけ、パラメータを確かめる | Hello(224.0.0.5) | Down → Init → 2-Way |
| LSDB の中身を伝え合う | DBD | ExStart → Exchange |
| 足りない LSA を受け取る | LSR/LSU | Loading → Full |
| 最短の経路を計算する | ― | SPF でルーティングテーブルを作る |
| 隣接関係を保つ | Hello(既定10秒ごと) | Dead インターバルの間 Hello がなければダウン |
コメント