キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 
cancel
告知

JTAC-Mid-Career-Recruitment-2021.3

CSC-campaign-v2.JPG

 

IOS/IOS-XE: BGP Keepalive Retransmission に起因するネイバーダウン

1272
閲覧回数
0
いいね!
0
コメント

はじめに

本ドキュメントでは、「IGP として OSPF を使用した BGP 環境にて、リンクダウンに伴う OSPF の経路変更時に、想定していない BGP ネイバーダウンが発生した」という事例について記載します。
この事例は少し特殊なケースではありますが、ルーティングプロトコルのタイマーを変更する際には、各ルーティングプロトコルだけではなく、その他のプロトコルや様々な状況を想定して設定する必要があることを理解できる良い事例であると思います。
 

Topology

<Physical Topology>

 

topology.png

 <Routing Protocol>

topology2.png

 

Config

!--- R1 ---
interface e0/0 ip ospf cost 1 ! interface e0/1 ip ospf cost 100 ! router ospf 1
router-id 1.1.1.1 network 1.1.1.1 0.0.0.0 area 0 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 ! router bgp 65000
bgp router-id 1.1.1.1 timers bgp 30 90 neighbor 3.3.3.3 remote-as 65000 neighbor 3.3.3.3 update-source Loopback0 !
 
!--- R2 ---
router ospf 1 router-id 2.2.2.2
network 2.2.2.2 0.0.0.0 area 0
network 10.0.0.0 0.0.0.255 area 0 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 !

 

!--- R3 ---
router ospf
router-id 3.3.3.3
network 3.3.3.3 0.0.0.0 area 0
network 10.0.0.0 0.0.0.255 area 0
!
router bgp 65000
bgp router-id 3.3.3.3
timers bgp 30 90
neighbor 1.1.1.1 remote-as 65000
neighbor 1.1.1.1 update-source Loopback0
!

 

事象

SW1 - SW2 間のリンクをダウンさせた際に R1 と R3 の BGP ネイバーがダウンしてしまい、直後にアップするという事象となります。ダウン時には以下のようなログが出力されます。

R1#
*Aug 30 08:23:53.950: %BGP-3-NOTIFICATION: received from neighbor 3.3.3.3 4/0 (hold time expired) 0 bytes 

なお、OSPF の Hello / Dead タイマーはデフォルトであり、BGP の keepalive / Hold タイマーは 30 / 90 秒に設定しています。

このようなタイマー設定の場合、SW1 - SW3 間のリンクをダウンさせても最大40秒(OSPF の Dead timer の満了に伴う経路切り替え) で SW3 経由のリンクに切り替わるため、BGP の Hold タイマーは 期限切れにならず、BGP のネイバーはダウンしない想定でした。

なぜ R1 と R3 のネイバー関係がダウンしてしまったのでしょうか。

 

解説

この事象における想定動作をフロー図にすると以下のようになります。

flow1.png

※ 図のフローはあくまでも一例であり、タイミングによってはパケットの順番が異なる場合があります。

 

時刻7秒から44秒までが R1-R3 間で通信できない時間となります。この間に BGP keepalive-2 が R1 から R3 に送信されますが、リンクダウンしているので R3 へは到達しません。

その後 OSPF の収束により SW3 経由の経路に切り替わるため、 R1 が送信した BGP keepalive-3 が R3 に到達し、 BGP Holdtimer がクリアされ、BGP のネイバーダウンは発生しないことになります。

また、 リンクダウンの時刻によっては BGP keepalive を2回分ドロップしてしまうことも考えられます。時刻20秒から30秒の間にリンクダウンが発生した場合、時刻30秒、時刻60秒に送信される BGP keepalive がドロップされますが、時刻90秒に送信される BGP keepalive が R3 に到達するため、BGP ネイバーはダウンしないはずです。

なぜ BGP ネイバーがダウンしてしまうのでしょうか。

 

上記の想定には、考慮されていない点があります。それが BGP keepalive の 再送です。BGP は TCP を利用してネイバーを確立することは周知のとおりですが、 BGP の keepalive の再送も TCP の Retransmission メカニズムを使用しています。R1 が送信した BGP keepalive (これをkeepalive-1(0)とします) が R2 に到達しなかった場合( 正確に言えば R2 から Ack が返信されてこない場合)、1秒後に BGP keepalive を再送します(この1回目の再送のkeepaliveを keepalive-1(1)とします)。この keepalive-1(1) が到達しなかった場合には 2秒後に keepalive-1(2)を、それでも到達しなければ 4秒後にkeepalive-1(3)を送信します。 このように、再送時間は 2の n 乗ずつ増加し、最大 32  秒まで増加します。

 

(注意) 本ドキュメントでは再送時間を単純化していますが、 実際再送時間は RTT や RTT の偏差、平滑化などの値を考慮して算出されます。詳細については RFC6928 を参照して下さい。

 

つまり、以下の図のように再送が行われます。

flow2.pngこの図では1回分の BGP Keepalive のみの再送について記載していますが、BGP Keepalive-1(0) の送信後30秒で BGP は(再送ではない) BGP Keepalive-2(0) を送信することに注意してください。

 

ここで、上記の図において Keepalive-1(4) の再送失敗後(例えば時刻 20 秒)に経路が SW3 経由に切り替わり、R1 と R3 の疎通が復旧した場合を考えます。このとき、Keepalive-1(5)がR3に到達する前に (再送ではない) BGP Keepalive-2(0) がR3に先に到達します。このパケットを R3 はどのように扱うのでしょうか。以下に R3 でのパケットキャプチャを示します。

cap1.png

 Wireshark 上では [TCP Previous segment not captured] と表示されていることが確認できます。

このメッセージは TCP Sequence 番号を参照し、この TCP セッション上での1つ前のパケットが正しく受信できていないことを示します。実際にこのパケットキャプチャを確認すると、Keepalive-1(4)は Seq=3862, Ack=3824, Len=19で送信されており、Keepalive-2(0)は Seq=3881, Ack=3824, Len=19で送信されています。

R3から見れば、次に受信する TCP パケットの Sequence 番号は 3862 であるはずなのに、 Seq=3881 である Keepalive-2(0) を受信していることから、1つ前のパケットが到達していないことを検知し、このKeepalive-2(0) をドロップします。TCP のレイヤで Keepalive-2(0) をドロップしてしまうため、 BGP がHoldtimer をリセットするのは Keepalive-1(4) を受信したタイミングとなります。この動作が本事象に大きく関わってきます。

この TCP Retransmission を考慮して再度本事象発生時のフローを以下に示します。

 

flow3.png

Keepalive-1(5)が送信されてから Keepalive-1(6)を再送するまでの時間は32秒であり、実際に R3 に到達したのが時刻 93 秒となりますので、 BGP Holdtimer expired により BGP ネイバーがダウンしています。この間に Keepalive-2(1) や Keepalive-3(0) が R3 に到達していますが、TCP Sequence 番号が期待されたものではないため、TCP レイヤでドロップされています。

つまり、リンクダウンのタイミングによってはこのような問題が発生しうるということが言えます。

 

回避策

この事象の回避策としては、タイマーを適切なものに変更する、またはIP SLA を使用してリンクダウンの検知を早める、などが考えられます。

BGP のタイマーを変更するのであれば、遅延を考慮せず、TCP の再配送が解説の項で示したタイミングで行われると考えた場合、 BGP Holdtimer を94秒以上に設定することで回避可能です。

また OSPF のタイマーを変更するのであれば Dead タイマーを 30秒以下にすることで回避できます。

 

なお、BGP / OSPF のタイマーがデフォルトであればこのような問題は発生しません。

まとめ

この事象は、ルーティングプロトコルのタイマーを変更する際には他のプロトコルとの関連性を深く考慮する必要があることを示す良い例だと思います。

また、BGP を使用する際にはルーティングプロトコル自体の動作だけでなく、 TCP の動作にも注意することが大切です。

ネットワーク設計の際にタイマーの変更を検討している場合には参考にしていただければと思います。