BGPのSoOを真面目に考えてみる

この記事は約42分で読めます。
スポンサーリンク

CCIEのBlueprintにMPLS/MP-BGP/VPNv4がありまして、その中にBGPのSite of Origin(SoO)の概念があります。

この記事では、このBGPのSoOについて考察していきます。自分の備忘録も兼ねて(こういうパケットの流れとかが重要な設定は覚えるのが難しい。STP/RSTPとかも・・・)

EIGRPのSoOじゃなくて、BGPのSoOです。EIGRPのSoOについて理解を深めたい方は以下のINEのPDFを読んでください。非常に有用です。

INEのEIGRPのSoO資料

ちなみに、この記事は私がCiscoPressやINEなどの情報をもとに結論付けたものなので、仮に間違っていた場合は是非教えてください。記載しているファクトは全て実機検証しましたが、そもそもユースケースから間違っていたとかあったら教えてください。

この記事は、出来るだけ文章を冗長に書いています。テクニカルな説明をするときに・・・・がとか・・・をの部分を省略すると、具体的なフローとか本質がぼやけてしまうので。なので、少しうざったいくらい冗長に書いてるかもですけど、お許しください。

はじめに:BGPのSoOって詳しいドキュメントがほとんどない

最近、CCIEの復習のために、MP-BGP関係を集中的にやっています。INEのビデオとかCertGuideを読み直すことによって、RDとかRTとか、CCIEの勉強をしている時よりもさらに理解が深まってきました。やっぱり復習って重要です。ITの知識って、ドキュメントを読み直すほど理解が深まります。

で、今回のトピックのSoOですが、前述の通りEIGRPのではなくて、BGPのSoOです。

BGPのSoOってドキュメントがほとんどないんですよね。EIGRPのSoOはINEのブログ(PDF)でそれなりに分かりやすいのがあるのですが(上のやつ)、BGPのSoOで本質的な用途の記載がされているものがほとんど見つかりませんでした。

殆どのドキュメントは「BGPのSoOはCEのallowas-inを使っている時に、PE側で設定することによって、プレフィックスのループを防ぐ」とかのレベルしか書いていません。そんなことは分かっているんですけど・・・もう少し、どんなケースで利用するかが知りたいんですけど。

見つからなかったので、自分で検証してみました。

BGPのCE-PEプレフィックス交換についてのおさらい

念のため、おさらいしておきます。

今回の話は、CE-PE間のプレフィックス交換の話です。PE-PE間のiBGPによるプレフィックス交換の話ではありません。MP-BGPのトピックを話す時、この2つの違いを理解する事は非常に重要ですし、基本です。

CE-PE間のプレフィックス交換をBGP(原則eBGP)で行う時の課題を説明します。

具体的にどんな時かと言うと。

CEとPE間のプレフィックス交換をBGP(原則eBGP)を使って行います。さらに、Customerの拠点が複数あるなどの場合、かつ各拠点のBGPのASが同一だった場合。この条件が合致したとします。

文章で書くと分かりにくいと思いますので、絵で描いてみます。こんな場合です。

IMG_0052

 

この時、特に特別な設定をしなければ、A拠点のプレフィックスはB拠点のCE2で受け取りません。なぜなら、PE2にA拠点のプレフィックスが到着した時点で、A拠点のプレフィックスには既にCustomerのAS(65000)が属性として付与されているので、BGPのループ防止(自ASの属性が付与されているプレフィックスは受け取らない)メカニズムによってCE2のBGPがA拠点のプレフィックスを拒否するからです。

IMG_0053

CE2で「debug ip bgp update」を入力しプレフィックスのアップデートが見えるようにして、「clear ip bgp * in」とかでPE2からのアップデートを再度要求すれば、以下のメッセージが表示されます。こんな感じで既に自分のASが付与されたプレフィックスは受信を拒否します。

BGP(0): 155.1.58.5 rcv UPDATE about 155.1.37.0/24 -- DENIED due to: AS-PATH contains our own AS;
BGP(0): no valid path for 155.1.37.0/24

じゃあ、どうやってCE2(もしくはその逆)でA拠点のプレフィックスを受け入れるのか?ですが、大きく2つの方法があります。

CE側にてallowas-inする

CE側のルーター(今回はCE1/CE2)でallowas-inをPEへのneighborステートメントで設定します(neighbor x.x.x.x allowas-inみたいな感じ)。これを設定すると、設定したネイバーから受け取ったプレフィックスの属性に自ASが含まれていても、気にせずBGP-Tableに入れてくれます

IMG_0054

つまり、allowas-inはCustomer側で行う設定です。

PE側にてas-overrideする

PE側のルーター(今回はPE1/PE2)でas-overrideを設定します。これを設定すると、CE側にプレフィックスを送信するときに、まず送信するプレフィックスのAS群を見ます。仮に、AS群の中に送信するCE側のAS番号が含まれていたら、その番号をPEのASに置換(Replace/Override)します。

IMG_0055

つまり、as-overrideはISP側で行う設定です。

allowas-inとas-overrideはどちらか1つでよい

上記のコンセプトが理解出来たら、どちらかの設定だけでよい(拠点間でのBGPを利用したプレフィックスのやりとりができる)ことがわかるはずです。

私のSoOの勘違い

ここまでは、多分CCIEを勉強していると誰でも知っている事かと思います。私もここまではすんなりと理解できました。

でも、SoOの理解が難しかった。SoOの理解というよりも、どんな時にSoOを使うか?が分からなかったので、本質的なコンセプトを理解出来なかったのです。

殆どのドキュメントには「CE側でallowas-inするときに、PE側でSoO設定をすることによって、ループを防ぐことが出来る」と書いています。

でも、ループってプレフィックスループの事?データループの事?どんなときにそんな状況が発生するの?ってところを具体的にかいている資料がない(見つからなかった)。

SoOはPE-PE間でプレフィックスをやり取り数と気のVPNv4プレフィックスに含める事によって、対向側PEで同一SoOプレフィックスをCE側に送りません。でも、そもそも、CEはプレフィックスを別拠点から受け取りたいのに、そのミッションが達成できないではないか。とか考えていました。

その時に私が頭の中に想像していたトポロジは、これです。

IMG_0056

ドキュメントによっては、「拠点間を別のリンクでバックドアを持っている場合」とか書いていました。iBGPとかIGPとかで。でも、実際にそういうトポロジを作ってみたのですが、どうしてもルーティングループを作り出すことが出来ませんでした。

その時のトポロジが、これです。

IMG_0057

で、さらに色々調べた結果、以下のリンクを見つけました。

上記のモハメドさんの発言

The BGP- SOO is a loop prevention mechanism for MULTIHOMED Site to the MPLS backbone, or for a sites that are single homed to the MPLS Backbone but share a backdoor link between them.

ふむふむ、なるほど!拠点内でマルチホームをしているケースか。と、閃いたわけです。

マルチホームでのVPNの場合に利用する・・らしい

つまり、以下のようなトポロジです。INEのトポロジを拝借してます。GNS3での再現なので、G1/XXはG1/0.XXに読み替えてください。

IMG_0061

また、通常のINEトポロジに以下のループバックを加えています。

  • R10:lo10(10.10.10.10/32)
  • R2:lo2(2.2.2.2/32)
  • R9:lo9(9.9.9.9/32)

上記はCustomer内のIGP(OSPF)に含めています。このループバック間での通信で検証して行きます。

念のため、全RTのコンフィグを残しておきますね。(今回の内容に関連するところだけ。なので、DMVPNとかは除く)

R1:

hostname R1

!
vrf definition CUST_A
 rd 1:1
 !
 address-family ipv4
  route-target export 100:100
  route-target import 100:100
  route-target import 600:600
  route-target import 500:500
 exit-address-family
!
!
!
!
interface Loopback0
 ip address 150.1.1.1 255.255.255.255
 ipv6 address 2001:150:1:1::1/128
!
!
interface GigabitEthernet1/0.13
 encapsulation dot1Q 13
 vrf forwarding CUST_A
 ip address 155.1.13.1 255.255.255.0
!
interface GigabitEthernet1/0.146
 encapsulation dot1Q 146
 ip address 155.1.146.1 255.255.255.0
 ipv6 address 2001:155:1:146::1/64
!
router ospf 1
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.146.0 0.0.0.255 area 0
 mpls ldp autoconfig
!
router bgp 100
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 150.1.4.4 remote-as 100
 !
 address-family ipv4
 exit-address-family
 !
 address-family vpnv4
  neighbor 150.1.4.4 activate
  neighbor 150.1.4.4 send-community extended
 exit-address-family
 !
 address-family ipv4 vrf CUST_A
  neighbor 155.1.13.3 remote-as 65000
  neighbor 155.1.13.3 activate
 exit-address-family
!

 

R2:

hostname R2
!
!
interface Loopback0
 ip address 150.1.2.2 255.255.255.255
 ipv6 address 2001:150:2:2::2/128
!
interface Loopback2
 ip address 2.2.2.2 255.255.255.255
!
interface GigabitEthernet1/0.23
 encapsulation dot1Q 23
 ip address 155.1.23.2 255.255.255.0
 ipv6 address 2001:155:1:23::2/64
!
router ospf 1
 network 2.2.2.2 0.0.0.0 area 0
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.23.0 0.0.0.255 area 0
!

 

R3:

hostname R3
!
interface Loopback0
 ip address 150.1.3.3 255.255.255.255
 ipv6 address 2001:150:3:3::3/128
!
interface GigabitEthernet1/0.13
 encapsulation dot1Q 13
 ip address 155.1.13.3 255.255.255.0
 ipv6 address 2001:155:1:13::3/64
!
interface GigabitEthernet1/0.23
 encapsulation dot1Q 23
 ip address 155.1.23.3 255.255.255.0
 ipv6 address 2001:155:1:23::3/64
!
interface GigabitEthernet1/0.37
 encapsulation dot1Q 37
 ip address 155.1.37.3 255.255.255.0
 ipv6 address 2001:155:1:37::3/64
!
router ospf 1
 redistribute bgp 65000 subnets
 network 155.1.23.0 0.0.0.255 area 0
 network 155.1.37.0 0.0.0.255 area 0
!
router bgp 65000
 bgp log-neighbor-changes
 redistribute ospf 1
 neighbor 155.1.13.1 remote-as 100
 neighbor 155.1.13.1 allowas-in
!

 

R4:

hostname R4
!
interface Loopback0
 ip address 150.1.4.4 255.255.255.255
 ipv6 address 2001:150:4:4::4/128
!
interface GigabitEthernet1/0.45
 encapsulation dot1Q 45
 ip address 155.1.45.4 255.255.255.0
 ipv6 address 2001:155:1:45::4/64
!
interface GigabitEthernet1/0.146
 encapsulation dot1Q 146
 ip address 155.1.146.4 255.255.255.0
 ipv6 address 2001:155:1:146::4/64
!
router ospf 1
 router-id 150.1.4.4
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.0.0 0.0.255.255 area 0
 mpls ldp autoconfig
!
router bgp 100
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 150.1.1.1 remote-as 100
 neighbor 150.1.1.1 update-source Loopback0
 neighbor 150.1.5.5 remote-as 100
 neighbor 150.1.5.5 update-source Loopback0
 neighbor 150.1.6.6 remote-as 100
 neighbor 150.1.6.6 update-source Loopback0
 !
 address-family ipv4
 exit-address-family
 !
 address-family vpnv4
  neighbor 150.1.1.1 activate
  neighbor 150.1.1.1 send-community extended
  neighbor 150.1.1.1 route-reflector-client
  neighbor 150.1.5.5 activate
  neighbor 150.1.5.5 send-community extended
  neighbor 150.1.5.5 route-reflector-client
  neighbor 150.1.6.6 activate
  neighbor 150.1.6.6 send-community extended
  neighbor 150.1.6.6 route-reflector-client
 exit-address-family
!

 

R5:

hostname R5
!
vrf definition CUST_A
 rd 5:5
 !
 address-family ipv4
  route-target export 500:500
  route-target import 500:500
  route-target import 100:100
  route-target import 600:600
 exit-address-family
!
!
!
interface Loopback0
 ip address 150.1.5.5 255.255.255.255
 ipv6 address 2001:150:5:5::5/128
!
interface GigabitEthernet1/0.5
 encapsulation dot1Q 5
 ip address 155.1.5.5 255.255.255.0
 ipv6 address 2001:155:1:5::5/64
!
interface GigabitEthernet1/0.45
 encapsulation dot1Q 45
 ip address 155.1.45.5 255.255.255.0
 ipv6 address 2001:155:1:45::5/64
!
interface GigabitEthernet1/0.58
 encapsulation dot1Q 58
 vrf forwarding CUST_A
 ip address 155.1.58.5 255.255.255.0
!
router ospf 1
 router-id 150.1.5.5
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.0.0 0.0.255.255 area 0
 mpls ldp autoconfig
!
router bgp 100
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 150.1.4.4 remote-as 100
 !
 address-family ipv4
 exit-address-family
 !
 address-family vpnv4
  neighbor 150.1.4.4 activate
  neighbor 150.1.4.4 send-community extended
 exit-address-family
 !
 address-family ipv4 vrf CUST_A
  neighbor 155.1.58.8 remote-as 65000
  neighbor 155.1.58.8 activate
 exit-address-family
!

 

R6:

hostname R6
!
vrf definition CUST_A
 rd 6:6
 !
 address-family ipv4
  route-target export 600:600
  route-target import 600:600
  route-target import 100:100
  route-target import 500:500
 exit-address-family
!
!
!
interface Loopback0
 ip address 150.1.6.6 255.255.255.255
 ipv6 address 2001:150:6:6::6/128
!
!
interface GigabitEthernet1/0.67
 encapsulation dot1Q 67
 vrf forwarding CUST_A
 ip address 155.1.67.6 255.255.255.0
!
interface GigabitEthernet1/0.146
 encapsulation dot1Q 146
 ip address 155.1.146.6 255.255.255.0
 ipv6 address 2001:155:1:146::6/64
!
router ospf 1
 router-id 150.1.6.6
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.0.0 0.0.255.255 area 0
 mpls ldp autoconfig
!
router bgp 100
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 150.1.4.4 remote-as 100
 !
 address-family ipv4
 exit-address-family
 !
 address-family vpnv4
  neighbor 150.1.4.4 activate
  neighbor 150.1.4.4 send-community extended
 exit-address-family
 !
 address-family ipv4 vrf CUST_A
  neighbor 155.1.67.7 remote-as 65000
  neighbor 155.1.67.7 activate
 exit-address-family
!

 

R7:

hostname R7
!
interface Loopback0
 ip address 150.1.7.7 255.255.255.255
 ipv6 address 2001:150:7:7::7/128
!
!
interface GigabitEthernet1/0.7
 encapsulation dot1Q 7
 ip address 155.1.7.7 255.255.255.0
 ipv6 address 2001:155:1:7::7/64
!
interface GigabitEthernet1/0.37
 encapsulation dot1Q 37
 ip address 155.1.37.7 255.255.255.0
 ipv6 address 2001:155:1:37::7/64
!
interface GigabitEthernet1/0.67
 encapsulation dot1Q 67
 ip address 155.1.67.7 255.255.255.0
 ipv6 address 2001:155:1:67::7/64
!
interface GigabitEthernet1/0.79
 encapsulation dot1Q 79
 ip address 155.1.79.7 255.255.255.0
 ipv6 address 2001:155:1:79::7/64
!
router ospf 1
 redistribute bgp 65000 subnets
 network 155.1.37.0 0.0.0.255 area 0
 network 155.1.79.0 0.0.0.255 area 0
!
router bgp 65000
 bgp log-neighbor-changes
 redistribute ospf 1
 neighbor 155.1.67.6 remote-as 100
 neighbor 155.1.67.6 allowas-in
!

 

R8:

hostname R8
!
!
interface Loopback0
 ip address 150.1.8.8 255.255.255.255
 ipv6 address 2001:150:8:8::8/128
!
interface GigabitEthernet1/0.8
 encapsulation dot1Q 8
 ip address 155.1.8.8 255.255.255.0
 ipv6 address 2001:155:1:8::8/64
!
interface GigabitEthernet1/0.58
 encapsulation dot1Q 58
 ip address 155.1.58.8 255.255.255.0
 ipv6 address 2001:155:1:58::8/64
!
interface GigabitEthernet1/0.108
 encapsulation dot1Q 108
 ip address 155.1.108.8 255.255.255.0
 ipv6 address 2001:155:1:108::8/64
!
router ospf 1
 redistribute bgp 65000 subnets
 network 155.1.108.0 0.0.0.255 area 0
!
router bgp 65000
 bgp log-neighbor-changes
 redistribute ospf 1
 neighbor 155.1.58.5 remote-as 100
 neighbor 155.1.58.5 allowas-in
!

 

R9:

hostname R9
!
!
interface Loopback0
 ip address 150.1.9.9 255.255.255.255
 ipv6 address 2001:150:9:9::9/128
!
interface Loopback9
 ip address 9.9.9.9 255.255.255.255
!
interface GigabitEthernet1/0.9
 encapsulation dot1Q 9
 ip address 155.1.9.9 255.255.255.0
 ipv6 address 2001:155:1:9::9/64
!
interface GigabitEthernet1/0.79
 encapsulation dot1Q 79
 ip address 155.1.79.9 255.255.255.0
 ipv6 address 2001:155:1:79::9/64
!
router ospf 1
 network 9.9.9.9 0.0.0.0 area 0
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.79.0 0.0.0.255 area 0
!

 

R10:

hostname R10
!
!
interface Loopback0
 ip address 150.1.10.10 255.255.255.255
 ipv6 address 2001:150:10:10::10/128
!
interface Loopback10
 ip address 10.10.10.10 255.255.255.255
!
interface GigabitEthernet1/0.10
 encapsulation dot1Q 10
 ip address 155.1.10.10 255.255.255.0
 ipv6 address 2001:155:1:10::10/64
!
interface GigabitEthernet1/0.108
 encapsulation dot1Q 108
 ip address 155.1.108.10 255.255.255.0
 ipv6 address 2001:155:1:108::10/64
!
router ospf 1
 network 10.10.10.10 0.0.0.0 area 0
 network 150.1.0.0 0.0.255.255 area 0
 network 155.1.108.0 0.0.0.255 area 0
!

CE(R7,R3,R8)は全てallowas-inしています。

試しに、R9(lo9)からR10(lo10)にtraceしてみます。これは、MPLSコアを通って拠点2のPE(R5)経由でR10に届くはず。

R9#
R9#trace 10.10.10.10 source lo9
Type escape sequence to abort.
Tracing the route to 10.10.10.10
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 136 msec 348 msec 160 msec
  2 155.1.67.6 336 msec 164 msec 136 msec
  3 155.1.146.4 [MPLS: Labels 16/22 Exp 0] 276 msec 324 msec 132 msec
  4 155.1.58.5 [MPLS: Label 22 Exp 0] 612 msec 248 msec 456 msec
  5 155.1.58.8 612 msec 404 msec 244 msec
  6 155.1.108.10 340 msec *  656 msec
R9#

美しいですね!

次に、R9(lo9)からR2(lo2)へtraceしてみます。これは、同じ拠点内(R9-R7-R3-R2)を通るはず。通るはず?

R9#trace 2.2.2.2 source lo9
Type escape sequence to abort.
Tracing the route to 2.2.2.2
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 112 msec 240 msec 384 msec
  2 155.1.37.3 428 msec 664 msec 336 msec
  3 155.1.13.1 356 msec 372 msec 380 msec
  4 155.1.67.6 [MPLS: Label 25 Exp 0] 132 msec 128 msec 140 msec
  5 155.1.67.7 176 msec 388 msec 532 msec
  6 155.1.37.3 584 msec 284 msec 696 msec
  7 155.1.13.1 276 msec 608 msec 384 msec
  8 155.1.67.6 [MPLS: Label 25 Exp 0] 172 msec 240 msec 168 msec
  9 155.1.67.7 312 msec 540 msec 596 msec
 10 155.1.37.3 436 msec 624 msec 256 msec
 11 155.1.13.1 428 msec 332 msec 308 msec
 12 155.1.67.6 [MPLS: Label 25 Exp 0] 296 msec 312 msec 180 msec
 13 155.1.67.7 424 msec 708 msec 536 msec
 14 155.1.37.3 336 msec 320 msec 316 msec
 15 155.1.13.1 388 msec 388 msec 268 msec
 16 155.1.67.6 [MPLS: Label 25 Exp 0] 568 msec 452 msec 344 msec
 17 155.1.67.7 500 msec

残念ながら、ループしました。ループしたので最後は切りました。でも、ついにループを作ることに成功しました!現実だと怖いけど、問題を再現出来たのでまずは一歩前進です。

では、なぜループしたのか?です。

traceの結果を見たところ、R9-R7-R3までのルーティングは正しく見えます。そのあとに、R1にルーティングしているのがおかしいです。R3はR2にルーティングしないと。

では、なぜR3はR1にルーティングしているのか?

それを確認する為に、R3の情報を見てみます。

R3#sh ip bgp
BGP table version is 25, local router ID is 150.1.3.3
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>  2.2.2.2/32       155.1.13.1                             0 100 65000 ?
 *>  9.9.9.9/32       155.1.13.1                             0 100 65000 ?
 *>  10.10.10.10/32   155.1.13.1                             0 100 65000 ?
 *>  150.1.2.2/32     155.1.13.1                             0 100 65000 ?
 *>  150.1.9.9/32     155.1.13.1                             0 100 65000 ?
 *>  150.1.10.10/32   155.1.13.1                             0 100 65000 ?
 *>  155.1.23.0/24    0.0.0.0                  0         32768 ?
 *>  155.1.37.0/24    0.0.0.0                  0         32768 ?
 *>  155.1.79.0/24    155.1.13.1                             0 100 65000 ?
 *>  155.1.108.0/24   155.1.13.1                             0 100 65000 ?
R3#sh ip route 2.2.2.2
Routing entry for 2.2.2.2/32
  Known via "bgp 65000", distance 20, metric 0
  Tag 100, type external
  Redistributing via ospf 1
  Advertised by ospf 1 subnets
  Last update from 155.1.13.1 00:06:52 ago
  Routing Descriptor Blocks:
  * 155.1.13.1, from 155.1.13.1, 00:06:52 ago
      Route metric is 0, traffic share count is 1
      AS Hops 2
      Route tag 100
      MPLS label: none
R3#

初めの出力は、R3のBGP-Tableです。結果は明らかですね。R3からみたR2(2.2.2.2)の向きがR1側になっていますね!

つまり、プレフィックス(R2の2.2.2.2/32)の交換が以下の流れで行われました。データじゃないですよ。プレフィックスの交換です。
・(OSPF)R2->R3
・(OSPF)R3->R7
(OSPF redistribute to BGP)R7->R6
・(BGP)R6-R1。厳密にはRoute reflector経由だけど今回のトピックの本質じゃないので割愛。
・(BGP)R1-R3

つまり、R7がIGP経由でR3からR2のプレフィックス(R2の2.2.2.2/32)を受信し、BGP-Tableに入れちゃった。これは、自分でBGP-Tableに挿入したルートだからWeightが32768になってベストパスになる。R7はベストパスのR2プレフィックスをピアであるR6に広報する。回り回ってそのプレフィックスがR6経由でR3に到達した。

絵的にはこんな感じ?(どんどん汚くなってきた)

IMG_0062

ちなみに、これはR7やR3がプレフィックスを受信するタイミングによって挙動が変わります。例えば、R7のOSPFをリセットすると、R7はR3からOSPFで受信するR2の経路より先にR6からBGPで受信するR2の経路をBGP-Tableに入れます。そして、Routing-TableにもR6経由のR2プレフィックス(2.2.2.2/32)が入ります。

この後に、R7でOSPFが有効化されたとします。OSPFがR3経由のR2プレフィックスをRouting-Tableに入れようとします。しかし、すでに上述のとおりeBGP経由(R6経由)のR2のプレフィックスがRouting-Tableに入っています。OSPFとeBGPだと、eBGPの方がAD値が低い(20<110)。なので、OSPFのプレフィックスはRouting-Tableに入れれません。R7はR2の経路としてR6をルーティングテーブル上示すようになります。すると、今度はISP経由でパケット(データ)が流れます。

以下は、R7のOSPFをリセットした後のR7のBGP-TableとR9からTraceを実行した結果です。

R7(config-router)#do sh ip bgp
BGP table version is 38, local router ID is 150.1.7.7
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>  2.2.2.2/32       155.1.67.6                             0 100 65000 ?
 *>  9.9.9.9/32       155.1.79.9               2         32768 ?
 *>  10.10.10.10/32   155.1.67.6                             0 100 65000 ?
 *>  150.1.2.2/32     155.1.67.6                             0 100 65000 ?
 *>  150.1.9.9/32     155.1.79.9               2         32768 ?
 *>  150.1.10.10/32   155.1.67.6                             0 100 65000 ?
 *>  155.1.23.0/24    155.1.67.6                             0 100 65000 ?
 *>  155.1.37.0/24    0.0.0.0                  0         32768 ?
 *                    155.1.67.6                             0 100 65000 ?
 *>  155.1.79.0/24    0.0.0.0                  0         32768 ?
 *>  155.1.108.0/24   155.1.67.6                             0 100 65000 ?

R9#trace 2.2.2.2 source lo9
Type escape sequence to abort.
Tracing the route to 2.2.2.2
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 120 msec 148 msec 144 msec
  2 155.1.67.6 148 msec 216 msec 392 msec
  3 155.1.13.1 [MPLS: Label 24 Exp 0] 480 msec 436 msec 528 msec
  4 155.1.13.3 264 msec 428 msec 308 msec
  5 155.1.23.2 364 msec *  180 msec

結果的に、Traceは成功していますが、これは期待した結果ではありません。期待した結果はIGPを利用した拠点内ルーティングですから。

他にもBGP/OSPFの動作でどちらが先にRouting-Tableにルートを入れるかによってさまざまなケースが考えられます。が、要するに上記の通りループが発生するケースがあります。Brian的に言うと、unexpected conditionってとこでしょうか。

では、本質的な問題が何かと言うと、そもそもR7がR6経由でR2の経路(2.2.2.2/32)を受信すること自体がおかしいんです。R7とR3は拠点Aのデュアルホーム目的でPEに繋がっています。

R7はISP経由でR10のプレフィックスは欲しいです。R2のプレフィックスは貰ってはいけないです。

それを実現するためにSoOがある(はず・・)です。考えてみたら名前も「Site of Origin」ですからね。Customer of Originでもなく、Site(拠点)ですから。

後は、どこにでも書いているSoOの内容です。

SoOを付ける方法ですが、これは「拠点ごと」にユニークなSoO値をPEに設定します。こんな感じです。

R6:

R6(config)#router bgp 100
R6(config-router)#add ipv4 vrf CUST_A
R6(config-router-af)#nei 155.1.67.7 soo 65000:37
R6(config-router-af)#

R1:

R1(config)#router bgp 100
R1(config-router)#add ipv4 vrf CUST_A
R1(config-router-af)#neighbor 155.1.13.3 soo 65000:37

R5:

R5(config)#router bgp 100
R5(config-router)#add ipv4 vrf CUST_A
R5(config-router-af)#neighbor 155.1.58.8 soo 65000:8

 

R5の方(拠点B)はデュアルホームではないので、SoOは設定不要ですが、方針を合わせるという意味で設定しておきました。

これを設定する事で、PEであるR1はR6から来た拠点Aの経路(主にR9のプレフィックス9.9.9.9/32)をCEであるR3側に送りません。また、PEであるR6はR1から来た拠点Aの経路(主にR2のプレフィックス2.2.2.2/32)をCEであるR7に送りません。でも、R1とR6はR5から来た拠点Bの経路(主にR10)は受信して後ろのCE(R3/R7)に送ります。

SoOは以下のコマンドで確認できます。

R6#sh bgp vpnv4 uni all 2.2.2.2
BGP routing table entry for 1:1:2.2.2.2/32, version 9
Paths: (1 available, best #1, no table)
  Not advertised to any peer
  Refresh Epoch 2
  65000
    150.1.1.1 (metric 2) from 150.1.4.4 (150.1.4.4)
      Origin incomplete, metric 2, localpref 100, valid, internal, best
      Extended Community: SoO:65000:37 RT:100:100
      Originator: 150.1.1.1, Cluster list: 150.1.4.4
      mpls labels in/out nolabel/20
      rx pathid: 0, tx pathid: 0x0
BGP routing table entry for 6:6:2.2.2.2/32, version 16
Paths: (2 available, best #1, table CUST_A)
  Not advertised to any peer
  Refresh Epoch 2
  65000, imported path from 1:1:2.2.2.2/32 (global)
    150.1.1.1 (metric 2) from 150.1.4.4 (150.1.4.4)
      Origin incomplete, metric 2, localpref 100, valid, internal, best
      Extended Community: SoO:65000:37 RT:100:100
      Originator: 150.1.1.1, Cluster list: 150.1.4.4
      mpls labels in/out nolabel/20
      rx pathid: 0, tx pathid: 0x0
  Refresh Epoch 1
  65000
    155.1.67.7 from 155.1.67.7 (150.1.7.7)
      Origin incomplete, metric 3, localpref 100, valid, external
      Extended Community: SoO:65000:37 RT:600:600
      rx pathid: 0, tx pathid: 0
R6#

Extended Communityの個所にSoOがありますね。

SoOを設定した後(念のため、clear ip bgp * をするとなお良し。本番ではダメですよ。)、R7のBGP-Tableを見てみます。

R7#sh ip bgp
BGP table version is 20, local router ID is 150.1.7.7
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>  2.2.2.2/32       155.1.37.3               3         32768 ?
 *>  9.9.9.9/32       155.1.79.9               2         32768 ?
 *>  10.10.10.10/32   155.1.67.6                             0 100 65000 ?
 *>  150.1.2.2/32     155.1.37.3               3         32768 ?
 *>  150.1.9.9/32     155.1.79.9               2         32768 ?
 *>  150.1.10.10/32   155.1.67.6                             0 100 65000 ?
 *>  155.1.23.0/24    155.1.37.3               2         32768 ?
 *>  155.1.37.0/24    0.0.0.0                  0         32768 ?
 *>  155.1.79.0/24    0.0.0.0                  0         32768 ?
 *>  155.1.108.0/24   155.1.67.6                             0 100 65000 ?

R2のプレフィックス(2.2.2.2/32)はR3から(IGPのプレフィックスを挿入)しかありませんね。つまり、R6から回り回って届いたR2のプレフィックスはなくなりました。

では、R9からR2へ、再度Traceをかけてみます。

R9#trace 2.2.2.2 source lo9
Type escape sequence to abort.
Tracing the route to 2.2.2.2
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 140 msec 156 msec 232 msec
  2 155.1.37.3 164 msec 304 msec 216 msec
  3 155.1.23.2 220 msec *  512 msec

OKです!拠点AのIGPでルーティングが完結しました。

デュアルホームを設定している目的は、CEであるR7かR3のどちらかがISP(PE)に繋がらなくなった時に、別の経路から別拠点と通信できる事です。SoOを設定していても、もちろんこれは実現されます。R9から再度R10へtraceかけてみます

R9#trace 10.10.10.10 source lo9
Type escape sequence to abort.
Tracing the route to 10.10.10.10
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 148 msec 96 msec 144 msec
  2 155.1.67.6 396 msec 200 msec 292 msec
  3 155.1.146.4 [MPLS: Labels 16/22 Exp 0] 500 msec *  340 msec
  4 155.1.58.5 [MPLS: Label 22 Exp 0] 268 msec 372 msec 340 msec
  5 155.1.58.8 192 msec 348 msec 300 msec
  6 155.1.108.10 292 msec 528 msec 932 msec

R7のR6向きのインターフェース(g1/0.67)をshutしてみます。これで、CEであるR7はPEであるR6との経路がなくなりました。

R7#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R7(config)#int g1/0.67
R7(config-subif)#shut
R7(config-subif)#
%BGP-5-NBR_RESET: Neighbor 155.1.67.6 reset (Interface flap)
%BGP-5-ADJCHANGE: neighbor 155.1.67.6 Down Interface flap
%BGP_SESSION-5-ADJCHANGE: neighbor 155.1.67.6 IPv4 Unicast topology base removed from session  Interface flap

BGPタイマーを調整していないので3分待ちます。3分後再度traceしてみると・・・

R9#trace 10.10.10.10 source lo9
Type escape sequence to abort.
Tracing the route to 10.10.10.10
VRF info: (vrf in name/id, vrf out name/id)
  1 155.1.79.7 124 msec 204 msec 112 msec
  2 155.1.37.3 484 msec 228 msec 192 msec
  3 155.1.13.1 356 msec 216 msec 200 msec
  4 155.1.146.4 [MPLS: Labels 16/23 Exp 0] 264 msec 276 msec 300 msec
  5 155.1.58.5 [MPLS: Label 23 Exp 0] 380 msec 224 msec 160 msec
  6 155.1.58.8 268 msec 352 msec 600 msec
  7 155.1.108.10 256 msec *  892 msec

もともとはR7->R6経由でR10へルーティングされていたのが、R7->R3->R1->コア->以下省略の流れになりました。成功です。

IMG_0063

結論:SoOは拠点毎にマルチホームするときに有用

マルチホーム構成だと、拠点内のプレフィックスがISP経由で周ってくる可能性があります。SoOを設定するとこの課題のワークアラウンドになります。

詳しい人、教えて欲しいのですが、これってつまり、例えばR7-R3間の経路が切れたとして、するとR9->R2の通信はできなくなると思うのですが、それは仕方ない(コア間を経由出来ない)ということですよね?

何度も言いますが、これ以外にSoOが有効なユースケースや、私の検証で間違っていることが合ったら教えてくださいね。

あ、あと「お前のこの記事良かったよ!」って感想があればコメントください。久しぶりにCCIEネタを気合い入れて書いてみたので・・・

コメント

  1. antares01 より:

    > 例えばR7-R3間の経路が切れたとして、するとR9->R2の通信はできなくなると思うのですが、それは仕方ない(コア間を経由出来ない)ということですよね?

    これはもう仕方無しですね。ループ防止のためにSoOでPEからCEへの広報を止めてもLAN側がつながっているんだから問題ないよね、という考えなので、これでLAN側が切れた場合まではケアできません。この構成でR7-R3が切れた時にR9-R2を救済したいのであれば、別途、R9-R2を接続するなり、LAN内の設計で何とかするしかありません。

    • CCIE_TOZAI より:

      コメント誠にありがとうございます。
      やはり、SoOのコンセプトとして、同一サイト・マルチホームでの片方のCEからのプレフィックス戻りを防ぐ事だから、LANが切れたときは仕方ないのですね。
      実際の世界では、LAN内のルータの数、冗長経路の作成は、今回のラボに比較にならない程検討事項に挙げられると思うので、その中でLAN内の冗長構成として考えるべきですね。
      少なくとも私の考えていた想定が正しそうで安心しました。SoOのコンセプトは一歩間違えると180度違う風に思い込む事があるので・・・
      また見にきてください(間違ってる事が合ったら指摘して頂ければ)

  2. student より:

    初歩的な質問でこんなことを聞くのも恐縮ですが
    プレフィクスの交換は下記を見て判断されているのでしょうか?
    Last update from 155.1.13.1 00:06:52 ago

    こちらはデータ(ICMP?)の交換なのでしょうか?
    Routing Descriptor Blocks:
    * 155.1.13.1, from 155.1.13.1, 00:06:52 ago

    また、
    * 155.1.13.1 と from 155.1.13.1 はそれぞれの違いがあれば教えて頂けると幸いです。
    調べ方が悪かったのか、分かりませんでした。お手数ですが、よろしくお願いします。

    R3#sh ip route 2.2.2.2
    Routing entry for 2.2.2.2/32
    Known via “bgp 65000”, distance 20, metric 0
    Tag 100, type external
    Redistributing via ospf 1
    Advertised by ospf 1 subnets
    Last update from 155.1.13.1 00:06:52 ago
    Routing Descriptor Blocks:
    * 155.1.13.1, from 155.1.13.1, 00:06:52 ago
    Route metric is 0, traffic share count is 1
    AS Hops 2
    Route tag 100
    MPLS label: none

    • CCIE_TOZAI より:

      コメントありがとうございます。
      >プレフィクスの交換は下記を見て判断されているのでしょうか?
      >Last update from 155.1.13.1 00:06:52 ago
      プレフィックス交換は、人によって確認方法がまちまちだと思うのですが、私は初めに「sh ip route」をみて、結果に含まれていたらとりあえず交換されたとみています。
      仮に、そこに表示されていなかったら、使用しているルーティングプロトコルの細かいところをみていきます。例えば、EIGRPだったら「sh ip eigrp topology」とかですね。

      >* 155.1.13.1 と from 155.1.13.1 はそれぞれの違いがあれば教えて頂けると幸いです。
      自分もshow ip routeの情報はCisco Doc含む複数の情報が見つかったのですが、show ip route XX.XX.XX.XXの詳細ドキュメントが見つかりませんでした。ソースで知っている方がいたら教えて欲しいです。
      私の見解ですが、「* 155.1.13.1」つまり初めの箇所はNext Hopです。
      「from XX」の箇所は、そのプレフィックス情報が誰から取得したかです。
      基本的にこの2つは同じところの場合が多いです。今回は同じで155.1.13.1ですよね。

      でも、複雑な環境だと違う場合もあります。

      考えてみたら、Next Hopはそのプレフィックス宛のパケットを次に何処に転送すればよいか?という話ですよね。この情報は必ずしも同じルーター(つまりNext Hop)が教えなくても言い訳です。
      この考え方をひらめく事は、非常に重要だと思っています。Control PlaneとData Planeは分けて考えれると言うことですから。

      具体的にはBGPのRouteReflectorとかOSPFのLSA5(Forward Address)などになります。

      • antares01 より:

        > ソースで知っている方がいたら教えて欲しいです。

        ソースというほどではありませんが、例えば、http://www.cisco.com/c/en/us/td/docs/ios/iproute_pi/command/reference/iri_book/iri_pi2.html#wp1042302
        の中に次の箇所が参考になるかもしれません。
        —-
        The preceding example shows the output from the show ip route command for an IP route generated by IS-IS. Each path that is shown under the Routing Descriptor Blocks report displays two IP addresses. The first address (10.22.22.2) is the next hop address. The second is the originator IP address from the advertising IS-IS router.
        —-

        • CCIE_TOZAI より:

          いつも、ご指摘誠にありがとうございます。
          頂いたリンクの情報、非常に参考になります。自分が間違っていない事が分かったので良かったです。

  3. student より:

    ありがとうございます。
    学生の身ではCCIEホルダーの方々と話せる機会がなかったので非常に貴重な意見を頂けて助かりました。

    >具体的にはBGPのRouteReflectorとか
    RRも同様の考え方でできるのですね。ルーティングテーブルで経路が表示されていたら必ずそのルートにたどり着くものだと思ってました。

    INEworkbookにあるBGPのbasic.bgp.routingをGNS上で再現すると、R1とR3の間で似たようなループが発生する等いろんなトラブルに遭遇して
    ルーティングテーブル上では sh ip route で目的通りの宛先を示しておりながら、全くpingを打つと全く異なる経路に飛んで行くことがあり原因がさっぱり分かりませんでした。

    私自身トラブルシュートする際にデータの交換とプレフィックスの交換を別々で考える発想がなかったため非常に参考になりました。
    ありがとうございます。

    • CCIE_TOZAI より:

      こちらこそ、コメントありがとうございます。
      少しは参考になったみたいで嬉しいです。
      勉強しているときはCCIE取得者ってめっちゃ遠い存在と思うかもしれませんが、地道に真面目に勉強したら絶対に取得出来ますよ。学生さんでも可能です。

      むしろ、CCIEを取得して初めて「もっと自分の知らない知識が沢山ある」と感じることがあるくらいです。

      >INEworkbookにあるBGPのbasic.bgp.routingをGNS上で再現すると、R1とR3の間で似たようなループが発生する等いろんなトラブルに遭遇して
      >ルーティングテーブル上では sh ip route で目的通りの宛先を示しておりながら、全くpingを打つと全く異なる経路に飛んで行くことがあり原因がさっぱり分かりませんでした。
      これ少し気になりますね。私は今までGNS3で何百回と検証を繰り返してきましたが、一度も上記の様な自分の想定外の箇所にPINGが行ったり、明らかにバグと見られるループはありませんでした。
      全く異なる経路とは、[sh ip route xx.xx.xx.xx]と打って出てくる経路と違う経路なのでしょうか。それだったら確かに腑に落ちませんが・・・

  4. student より:

    お返事が遅くなり申し訳ありません。
    頂いた情報を元に試行錯誤したところ少しずつ分かってきました。

    >全く異なる経路とは、[sh ip route xx.xx.xx.xx]と打って出てくる経路と違う経路
    そうですね、 traceroute すると、routing table とは全く異なる経路に進みます…。

    >自分の想定外の箇所にPINGが行ったり、明らかにバグと見られるループはありませんでした。
    ということは、configの誤りではないということですね。今までconfigの誤りや手順等ばかり調べていました…。

    そこで、GNSのversionを1.2.3 -> 1.4.1 へバージョンアップしたところ問題があっさり解決しました…。
    記事のタイトルとはかけ離れた内容で申し訳ありませんでした。

    >地道に真面目に勉強したら絶対に取得出来ますよ。学生さんでも可能です。
    ありがとうございます。死ぬ気で頑張り続けます。

    • CCIE_TOZAI より:

      確かにそれは不可解ですね。バージョンアップしたことで解決したとの事、安心しました。
      でも、studentさんが「バージョンアップしてみようかな」と思ったのは、きっとtraceの結果が明らかに自分の想定と違ったからですよね。
      つまり、「本来こうなっているべき」状況がわかっているからだと思うんです。それってCCIEラボのTroubleshootingにも
      とても役立ちますよ!頑張ってください!

  5. TK より:

    はじめまして、R/Sの取得を目指している者です。
    私もSoOがどのようなケースで用いられるのかさっぱり・・・だったので
    このような一歩踏み込んだ記事は非常に勉強になりました。
    文章も丁寧に書かれておりとてもわかりやすかったです。
    ありがとうございます!

    • CCIE_TOZAI より:

      コメントありがとうございます!
      そういって頂けると、本当に嬉しいです。自分もはじめは「何故SoOが必要なのか?」が分からなかったので記事をかいたので。
      L3VPNとかは、言葉でIPとかLabelとか言っても、それが上のIP/Labelか下のIP/Labelかとか考えながら勉強しないとごっちゃになっちゃいますね。

  6. saka より:

    マルチホームでなくてもSoOは必要かなと思ってます。私のウェブサイトで、私の理解を図解していますので、間違ってたら教えてほしいです。
    もっとCCOがわかり易く説明してくれれば、こんなに苦労しないんですがね。。。

    • CCIE_TOZAI より:

      情報ありがとうございます。訪問させて頂きます。
      そうなんですよね。。CCOって欲しい情報を検索する用途では、かなり不便ですよね。
      今後ともよろしくお願いします。

  7. kajinya より:

    とてもわかりやすい記事をありがとうございます!
    いつもこのブログを非常に参考にさせていただいております。

    >>詳しい人、教えて欲しいのですが、これってつまり、例えばR7-R3間の経路が切れたとして、するとR9->R2の通信はできなくなると思うのですが、それは仕方ない(コア間を経由出来ない)ということですよね?

    EIGRPのSoOと同じと考えることができるのではないでしょうか?
    EIGRPのSoOにはPEにしか設定しない場合と、CEにも設定する場合の2つが紹介されていると思います。
    今回このブログ内で紹介していただいている設定は前者のパターンで、後者のように
    R6のG1/0.67とR7のG1/0.37に65000:67
    R1のG1/0.13とR3のG1/0.37に65000:13
    といったようにSoOを付加してあげればBGP経由のルートを破棄しないと思われます。
    一応検証してみたら、R9>R2への経路情報をeBGPで学習しました!

    • CCIE_TOZAI より:

      記事を読んでくれてありがとうございます!

      確かに、EIGRPでも基本的なコンセプトは同じですね。
      最近BGP全然やっていないので復習しないと・・・

タイトルとURLをコピーしました