弈心:從事計算機網絡工作十一年(新加坡7年,沙特4年),2013年考取CCIE,在新加坡先後任職於AT&T,新加坡交通部,蘋果,Equinix,蘇格蘭皇家銀行等大型企業、銀行和政府部門。目前供職於“世界第一土豪大學“沙特阿卜杜拉國王科技大學(KAUST),擔任Senior Network Engineer,為KAUST校史上第一位也是唯一一位華人IT部門高級職員。2019年6月在知乎發佈了華語圈第一本專門為編程零基礎的網絡工程師量身打造的Python教程《網絡工程師的Python之路》。
這是筆者從業11年來碰到過最難的一道CCIE挑戰題,能把EIGRP和BGP兩個路由協議研究到如此的深度,不得不佩服出題者的鑽研精神。好東西不敢獨享,特意拿出來分享給大家,相信讀完本文你肯定能收穫一些不為大多數人所知的乾貨。
背景信息:
1. 某公司有兩個site, Site A(192.168.1.55)直連CE-1,Site B (192.168.2.55)直連CE-2。
2. 兩個site跑MPLS VPN, CE-1直連PE-1,CE-2直連PE-2,PE和CE之間的IGP用的是EIGRP。
3. CE-1和CE-2之間有一條直連的後門(Backdoor)鏈路192.168.12.0/30.
4. 在PE-2上做traceroute,PE-2去往Site-A(192.168.1.55)的流量走的是PE-2----P----PE-1----CE-1。這是因為PE-2去往192.168.1.55的路由是從MPLS的BGP學到的。"show ip orute vrp CUST_A 192.168.1.55"和"show bgp vpnv4 uni all 192.168.1.55"的結果證明了這點
5.現在公司要求使用CE-1和CE-2之間的後門鏈路,使得PE-2去往Site-A(192.168.1.55)的流量走PE-2----CE-2----CE-1。為了達到目的,針對PE-2去往192.168.1.55的這條路由,出題者嘗試在PE-2上修改在BGP裡重分發的EIGRP路由的local pref到500來影響BGP的選路,從而達到目的,配置如下:
問題:
配置過後,如下圖再show bgp vpnv4 uni all 192.168.1.55看一遍,發現PE-2去往Site A的下一跳依然是10.255.255.1,也就是MPLS! 這還不止,更扯的是這裡注意看localpref 100這個參數,這說明了前面將192.168.1.55的路由的local pref改到500根本沒起作用,要求給出解釋和解法。
解題思路:
如下圖,這道題的關鍵還是在“show bgp vpnv4 uni all 192.168.1.55"裡(改了local pref過後),注意看帶下劃線的部分:“Cost :pre-bestpath:128:156160”。
Cost:pre-bestpath:128:156160是什麼?其實它就是Pre-bestpath Cost Community。Cost Community是BGP的一個擴展的Community屬性,它只能傳遞給iBGP鄰居或聯邦peer(含聯邦iBGP及聯邦eBGP鄰居),不能傳遞給eBGP鄰居。眾所周知,BGP有14條選路原則,一般的網絡工程師最多記住前六條選路原則就足夠應付工作中絕大多數的BGP選路問題了,比如weight,local pref, as-path, med之類的,而這個cost community絕大多數人覺得很陌生,為什麼?因為它排在14條選路原則的最後!
和weight這個BGP屬性一樣,cost community最初也是由思科提出的,並且針對該BGP屬性的RFC尚未正式公佈,目前只知道該RFC尚處在“草稿階段”,該RFC草稿又被稱為"BGP Custom Decisions"。
重點:
"BGP Custom Decisions"引用了“插入點”( point of insertion,又稱POI)這一概念來決定一臺BGP路由器什麼時候開始使用“14條選路原則“來進行BGP選路,"BGP Custom Decisions"制定了4個POI值,分別為128,129,130,131,它們的含義如下圖所示:
以這道題的Cost:pre-bestpath:128:156160為例,128為POI值,緊接在它後面的156160為community cost的具體值,這裡提一下,community cost值又叫做Value/Cost,越小越優先,理論上的最大值為4294967294.
現在按照上圖各個POI值來看,一目瞭然,當POI值為128的時候,BGP路由器直接使用"Cost Community"來做為選路屬性,也就是說它直接忽略了排在選路原則第一位的weight,(當然也更不用說,在這道題裡面,作者修改的排在第二位的Local Preference值了),正因為當Cost Community的POI值為128時”如此強大“,所以思科又將POI等於128的cost community的值稱為 ABSOLUTE_VALUE,並且給它賦名"Pre-bestpath Community Cost"。
理解了cost community這個BGP擴展屬性後,再來看看它和EIGRP有什麼關係。
1. 默認情況下,所有在MP-BGP裡被重分發的EIGRP路由的POI值(也叫做Community-ID)都為128。
2. 既然POI值為128,那就意味著在選路的時候,我們只需要看該重分發路由的cost community值(也叫做Value/Cost)了,這個cost community值是怎麼來的?很簡單,其實它就是EIGRP路由被重分發之前的度量值。EIGRP的度量值計算很複雜,Delay, Bandwidth, Reliability, Load, MTU等等都要看,如果K值被修改過,那麼計算起來更復雜,關於EIGRP度量值的計算這裡不做討論,任何一個能堅持把這篇文章讀到這裡的人,不可能不瞭解EIGRP的度量值怎麼計算。
3.當EIGRP被用作MPLS的CE和PE之間的IGP時,PE路由器使用另外一組community(如下圖)來將EIGRP度量值傳遞給下一個PE,這裡需要注意的是MPLScloud的度量值為0,也就是說不管兩個PE之間隔了多少個P,它們之間所傳遞的這個EIGRP度量值不會因此而增加。
4. 這道題裡的這些0x8800, 0x8801, 0x8802等等community在哪裡看?答案還是在”show bgp vpnv4 uni all 192.168.1.55“裡,如下圖:
5. 上圖裡已經針對各個community給出了詳細的解注了,不再贅述。這裡只要知道這道題裡的Cost :pre-bestpath:128:156160,這個156160(cost community值)代表的是EIGRP的度量值。
理解了在MP-BGP裡重分發的EIGRP路由的community cost是怎麼回事後,下面就係統地分析一下這道題的問題出在哪。
假設我們現在從PE-2上的某個loopback口做為源地址來ping Site A(192.168.1.55)。不管這個ping包它怎麼走,icmp echo request包最終必然會經過CE-1才能到達192.168.1.55,因為Site A和CE-1直連。當192.168.1.55收到icmp echo request包後,它當然會把icmp echo reply包回丟給做為自己默認網關的CE-1。CE-1跑的是EIGRP,它現在有兩個EIGRP鄰居,一個是PE-1,另外一個是CE-2,這意味著這時CE-1將有兩條路來選擇將該包丟回給PE-2:一條是走PE-1,經過MPLS丟回給PE-2;另外一條是走CE-2,也就是後門鏈路,再丟回給PE-2。
1. 先來看當CE-1走PE-1,也就是MPLS這條路時發生了什麼。之前已經分析過了,走這條路的EIGRP度量值是156160,所以當PE-1在其MP-BGP裡重分發CE-1的EIGRP路由時,該條路由的pre-bestpath community cost值為Cost: pre-bestpath:128:156160。而且前面也提到過,MPLS cloud本身不會對該pre-bestpath community cost值做任何修改,最後PE-2從MPLS收到的icmp echo reply包仍然是Cost:pre-bestpath:128:156160。
2. 當CE-1走後門鏈路,也就是CE-2時,通過計算,該條路由的EIGRP度量值為158720, 當PE-2在其MP-BGP裡重分發CE-2的EIGRP路由時,該條路由的pre-bestpath community cost值為Cost :pre-bestpath:128:158720。
如下圖所示:
3. 兩相比較,156160<158720,所以PE-2會選擇走MPLS這條路。
4. 如果你還在問我為什麼修改了PE-2從CE-2重分發來的EIGRP路由的local pref為500後,PE-2依然走的是MPLS,那說明前面重點部分你還沒讀懂。
解法:
這道題解法有4種。
解法1.
在PE-2上修改Pre-bestpath community cost值,讓EIGRP度量值大於158720。注意:這裡不僅要修改EIGRP度量值,同時也要修改POI值,因為現在PE-2上有兩個Pre-bestpath community cost值,一個走MPLS(156160),一個走EIGRP(158720),他們兩個的POI值都為128,在這種情況下PE-2肯定選前者(這也就是為什麼show bgp vpnv4 uni all 192.168.1.55的時候只看到156160, 而看不到158720)。同樣的道理,如果我們繼續使用128做為POI值的話,當EIGRP被MP-BGP重分發時,POI後面的community cost值會被重置回156160,因為156160依然小於我們配置的值(比如這裡的999999),兩個POI都為128,一個156160,一個999999,PE-2當然還是選156160,這樣的話等於白做了。 所以這裡我們必須把POI值修改為任意一個小於128的數值,因為根據RFC草稿,POI值越小越優先。
這裡我們把POI修改為1,把度量值修改為999999,這樣的話show bgp vpnv4 uni all 192.168.1.55後,你就能看到兩個Pre-bestpath community cost值了,MPLS那條變成999999,大於EIGRP那條的158720,這樣我們的目的也就達到了。
相關配置命令和驗證如下:
PE-2#sh run | s access-list|route-map|router bgp
ip access-list standard CE1_LOOPBACK
permit 192.168.1.55
!
route-map SET_EXT_COST_COMMUNITY permit 10
match ip address CE1_LOOPBACK
set extcommunity cost pre-bestpath 1 9999999
route-map SET_EXT_COST_COMMUNITY permit 99
!
router bgp 100
address-family ipv4 vrf CUST_A
redistribute eigrp 100 route-map SET_EXT_COST_COMMUNITY
PE-2#sh bgp vpnv4 uni all 192.168.1.55
BGP routing table entry for 100:1:192.168.1.55/32,version 8
Paths: (1 available,best #1,table CUST_A)
Advertised to update-groups:
1
Local
192.168.2.2 from 0.0.0.0 (10.255.255.2)
Origin incomplete,metric 158720,localpref 100,weight 32768,valid,sourced,best
Extended Community: RT:100:1
Cost:pre-bestpath:1:9999999
Cost:pre-bestpath:128:158720 0x8800:32768:0 0x8801:100:133120
0x8802:65282:25600 0x8803:65281:1500
mpls labels in/out 33/nolabel
PE-2#
PE-2#traceroute vrf CUST_A 192.168.1.55
Type escape sequence to abort.
Tracing the route to 192.168.1.55
1 192.168.2.2 64 msec 28 msec 12 msec
2 192.168.12.1 44 msec * 24 msec
PE-2#
解法2.
在PE-1上修改Pre-bestpath community cost值,這個和解法1類似,不過注意的是PE-1上只需要修改走MPLS的Pre-bestpath community cost值,所以可以繼續將POI值保留為128,只需修改EIGRP度量值,這裡我們把EIGRP度量值改為777777. 相關配置命令和驗證如下:
PE-1#sh run | s access-list|route-map|router b
ip access-list standard CE1_LOOPBACK
permit 192.168.1.55
!
route-map SET_EXT_COMM permit 10
match ip address CE1_LOOPBACK
set extcommunity cost pre-bestpath 128 7777777
route-map SET_EXT_COMM permit 999
!
!
router bgp 100
address-family vpnv4
neighbor 10.255.255.2 route-map SET_EXT_COMM out
PE-2#sh bgp vpnv4 uni all 192.168.1.55
BGP routing table entry for 100:1:192.168.1.55/32,version 36
Paths: (2 available,best #2,table CUST_A)
Flag: 0x820
Advertised to update-groups:
1
Local
10.255.255.1 (metric 3)from 10.255.255.1 (10.255.255.1)
Origin incomplete,metric 156160,localpref 100,valid,internal
Extended Community: RT:100:1
Cost:pre-bestpath:128:7777777 0x8800:32768:0
0x8801:100:130560 0x8802:65281:25600 0x8803:65281:1500
mpls labels in/out 24/20
Local
192.168.2.2 from 0.0.0.0 (10.255.255.2)
Origin incomplete,metric 158720,localpref 100,weight 32768,valid,sourced,best
Extended Community: RT:100:1 Cost:pre-bestpath:128:158720
0x8800:32768:0 0x8801:100:133120 0x8802:65282:25600 0x8803:65281:1500
mpls labels in/out 24/nolabel
PE-2#
解法3.
在PE-1將EIGRP重分發進MP-BGP並傳給PE-2之前,在PE-1將EIGRP度量值用Offset-lists改大。
PE-1#sh run | s access-list|router eigrp
ip access-list standard CE1_LOOPBACK
permit 192.168.1.55
!
!
router eigrp 1
address-family ipv4 vrf CUST_A
offset-list CE1_LOOPBACK in 1000000 FastEthernet0/0
解法4.
關閉Pre-bestpath community cost,
這個是萬不得已才用的方法,因為你必須在所有BGP路由器上都關閉pre-bestpath,如果遺漏哪怕一個路由器,都會因為不連續的community cost選路過程而造成造成環路!注意在關閉pre-bestpath後,show bgp vpnv4 uni all 192.168.1.55依然能看到128:156160和128:158720,但是這時它們已不會對選路造成影響了。
PE-1(config)#router bgp 100
PE-1(config-router)#bgp bestpath cost-community ignore
PE-1(config-router)#^Z
PE-2(config)#router bgp 100
PE-2(config-router)#bgp bestpath cost-community ignore
PE-2(config-router)#^Z
PE-2#sh bgp vpnv4 uni all 192.168.1.55
BGP routing table entry for 100:1:192.168.1.55/32,version 3
Paths: (2 available,best #2,table CUST_A)
Flag: 0x820
Advertised to update-groups:
1
Local
10.255.255.1 (metric 3)from 10.255.255.1 (10.255.255.1)
Origin incomplete,metric 156160,localpref 100,valid,internal
Extended Community: RT:100:1 Cost:pre-bestpath:128:156160
0x8800:32768:0 0x8801:100:130560 0x8802:65281:25600 0x8803:65281:1500
mpls labels in/out 19/18
Local
192.168.2.2 from 0.0.0.0 (10.255.255.2)
Origin incomplete,metric 158720,localpref 100,weight 32768,valid,sourced,best
Extended Community: RT:100:1 Cost:pre-bestpath:128:158720
0x8800:32768:0 0x8801:100:133120 0x8802:65282:25600 0x8803:65281:1500
mpls labels in/out 19/nolabel
PE-2#traceroute vrf CUST_A 192.168.1.55
Type escape sequence to abort.
Tracing the route to 192.168.1.55
1 192.168.2.2 24 msec 16 msec 20 msec
2 192.168.12.1 44 msec * 52 msec
PE-2#