一些學習和翻譯,搬運自國外博客,翻譯水平有限,99%依靠谷歌翻譯,1%靠自己理解。僅用於記錄和學習,歡迎討論和指出錯誤
原文鏈接:https://www.networkfuntimes.com/junos-routers-what-does-the-inet-3-table-actually-do/
原文鏈接二:https://www.networkfuntimes.com/moving-lsps-between-inet-3-and-inet-0-on-a-juniper-router/
圖例

幾個基礎概念
一、inet.0
1、這是我們常規理解的,“正常”的路由表,靜態和直連路由都包含在里面,當我們通過IGP學習路由時,通過這些路由器的下一跳來學習路由
2、BGP學到的路由也會進入到inet.0表里,但是BGP的下一跳工作方式不太一樣
- 比如說IBGP回環口建立鄰居,雖然兩台設備之間有很多其他的路由器,但是IBGP路由器還是把自己作為他們通告的任意路由的下一跳
- 總的來說,接受路由的路由器需要進行第二次查找路由表,來計算出實際下一跳是誰

以上是一般情況下的IGP和BGP一起運行,查找inet.0表的情況,但是當mpls介入之后,就不太一樣了
二、標簽交換路徑(LSP)
LSP是網絡中兩個路由器之間預先商定的路徑,數據包將通過該路徑到達目的地。路由器進行通信以指示他們希望為該路徑的流量,接收什么標簽。並且鏈接的路由器在發送數據包之前,將該標簽添加到數據包中。接收數據的路由器剝離標簽,並可能在它這條路徑上進一步轉發數據包時,打上一個新的標簽。
比如說,通過RSVP去創建LSP,指向的是回環地址,無論我們選擇使用LDP還是RSVP,有關LSP的信息都存儲在以下兩個位置之一,mpls.0或者inet.3。在Juniper設備里,跟常見廠商的設備不同,他有多個不同的路由表,每個路由表存儲的信息都不相同,在尋路時根據不同情況會查找不同的路由表。

1、如果說路由器是LSP的入口,或者說是隧道的起點,那么就要到inet.3表中找LSP的另一端(隧道的出口),比如說,在路由器的所有接口上都打開了LDP,這就意味着有了一個LSP到我網絡中每個路由器的回環口。然后手動創建了一個RSVP LSP指向Router3(3.3.3.3)

2、從路由表里可以看出,RSVP的路由優先級是7,LDP的路由優先級是9,默認情況下選擇RSVP的路徑。但是去往3.3.3.3的路徑,是通過LDP學到的標簽(push 299952)
3、路由表中,我們可以看到在數據包離開接口時,會給數據包打上標簽。
- 由於空間位置不夠,RSVP路由沒有顯示標簽,但是如果添加了 extensive關鍵字,就可以看到這個標簽,但是2.2.2.2和4.4.4.4的標簽沒有看到
- 由於Router2和Router4都是直連Router1的,默認情況下MPLS不會為目的地是直連的路由器的數據包添加標簽,這個行為被成為 Penultimate-Hop Popping(PHP)
- 如果你是LSP中的倒數第二跳路由,那么在發送數據包之前,通過“彈出”標簽來幫助充當LSP出口的路由器
- 如果有標簽,出口路由器必須做兩倍的工作,業務他必須查找標簽,如果查看數據包的目的地是自己,就彈出標簽,然后對IP地址進行第二次查找
三、inet.3
在Junos中,inet.3表用來解析BGP下一跳。每當路由器通過BGP學到路由時,Junos需要決定如何到達協議的下一跳。為了得到答案,**會同時查看inet.0和inet.3**,它同時考慮兩個表,但默認情況下RSVP和LDP的路由優先級比OSPF或者ISIS低很多,所以始終會選擇標簽路徑
注意,這個尋路原則僅適用於查找通過BGP學習到的路由條目,如果是訪問3.3.3.3(對端的回環口地址),不會采用標簽交換路徑,它只會作為常規數據包從路由器發出。但是,當同時滿足以下所有情況的時候,流量還是會選擇采用標簽交換路徑:
- 常規inet.0表中有一個路由前綴
- 這個路由前綴是通過BGP學習到的
- 協議的下一跳為3.3.3.3
- 如果BGP的下一跳(3.3.3.3)在inet.3表中存在
簡單來說,因為路由器會同時查看inet.3和inet.0,其實就是如果inet.3里有下一跳的路由,就走標簽轉發,如果沒有,就走普通的路由轉發。
-
先查看一個路由,在全局表里看到路由是通過BGP從3.3.3.3學到的,3.3.3.3通過RSVP寫了一條LSP,然后通過LDP被上一級分發了標簽299904。說明,要去往這個目的地的數據包里,要push進去一個標簽,然后發給10.10.12.2,走的是TO_ROUTER_3這條路徑。

-
然后到Router2上面查看標簽表,看到下一跳要發給10.10.23.3,而且還能看到配置的LSP的名稱。另外,Router2在發送數據包時,業務下一跳是R3,也就是目的地。所以在R2上會把標簽彈出,因為倒數第二跳彈出,數據包發送時不帶標簽。
-
另外,(S=0)指的是MPLS頭中是否設備了“bottom-of-stack”位,如果S=1,則標簽為棧底。如果S=0,則這個“下面”還有一個或者多個標簽。目前測試下來,在倒數第二跳的時候查看標簽表,會出現S=0的這個。中間的轉發路由器都不顯示。


inet.3和inet.0的區別和聯系
一、為什么只有通過BGP學習的路由才查詢inet.3表?
- 首先,OSPF和ISIS都是通過直連來獲取他們的下一跳,所以不需要使用LSP
- 因為默認情況下路由器不給物理接口通告標簽,指給回環接口通告標簽。BGP一般通告回環接口作為下一跳,所以一般情況下目的地址是通過BGP獲取的,我們往往也只想沿着標簽交換路徑去發現路由
- 另外,在大型ISP中,實際運行具有無BGP核心的網絡是很常見的。換句話說,並非每個路由器都會實際運行BGP。MPLS允許流量通過核心網絡,而核心網絡實際上完全不知道如何到達數據包中的IP地址。但是OSPF和ISIS不會出現指給情況,這兩種協議看到是在網絡中全網運行的。
- 最后一個例子是MPLS VPN,本身就是由BGP發布的。這些標簽用於區分兩個不同的客戶,甚至可能使用相同私網IP的客戶。此外,標簽的使用意味着我們的核心路由器不需要了解我們的VRF的任何信息。我們可以在網絡邊緣運行三層VPN,二層VPN,VPLS等,而我們的核心路由器可以完全不知道。
- 所以,大多數情況下,inet.3表只被BGP需要,但是指給也是可以調整的,比如 導表。
二、在inet.3和inet.0之間,移動LSP
前面說了,基本上因為只有BGP的情況才查詢inet.3表,為了讓其他情況下也能夠查詢標簽交換路徑,所以可以把inet.3的數據復制到inet.0中。**其實也就方式五靠譜,現網也是用的方式五,前面其他方法都是過渡學習用的。**
方式一:在inet.3中設置路由前綴,並將其與RSVP LSP關聯
還是使用上文的拓撲,所有設備都開啟了LDP,此外還有一個從R1直接到R3的RSVP LSP,R3到R1的LSP。R3與R6之間運行了EBGP,並通過BGP學到了一條路由前綴69.69.69.0/24。

流量走向:R3通過IP地址為10.10.36.0/24的直連到R6,意味着當R3接收到69.69.69.0/24的通告后,通過IBGP把他擴散給AS12345里的其他路由器時,R3不會更改下一跳,下一跳仍然時10.10.36.6(R6的互聯地址)。如果左邊這些路由器都有這個地址的路由,那就沒問題。但是如果一些ISP沒有學過這條路由,流量就過不去。為此,可以使用next-hop-self,在R3將路由通告給其他路由器之前,他會把下一跳變更為自己,也就是3.3.3.3。這就可以使用RSVP LSP,R1看到3.3.3.3的下一跳,看到inet.3中有這個BGP下一跳的條目,於是將數據包封入標簽,進行標簽交換。
但是,如果以上流程,我們不執行next-hop-self,但是通過OSPF或者ISIS把互聯地址10.10.36.6重分布進IBGP里,讓左邊這些路由器學到這個路由條目,流量也可以到達。但是因為R3與R6之間沒有運行LDP或者RSVP,這就意味着inet.3表中沒有10.10.36.6的條目(inet.0里有)。這個情況下,流量只會進行正常的IP轉發。
所以,對於通過LSP的流量,默認情況下,BGP協議的下一跳必須位於inet.3中,並且R1的IBGP鄰居的EBGP鄰居的接口IP地址10.10.36.6肯定不會在inet.3中。
但是,這個我們也可以手動配置,讓他出現在inet.3中,只需要通過install進行關聯即可。現在10.10.36.6/32會出現在inet.3表中,所有我們通過BGP學習的任何路由前綴,下一跳為10.10.36.6的,都會通過LSP。

但是,這個方式基本上等同於一個靜態路由,擴展性並不好。只是把10.10.36.66強制指向了3.3.3.3而已。
方式二:將RSVP LSP宣告到IGP中
如果我們願意,可以讓OSPF或者ISIS相信我們的LSP是一條實際的鏈路,直連兩端的兩台路由器。你所要作的就是在兩個方向上創建LSP,然后將LSP添加到IGP中。
set protocols isis label-switched-path TO_ROUTER_3 level 2 metric 1
或者
set protocols ospf area 0.0.0.0 label-switched-path TO_ROUTER_3 metric 1
現在查看ISIS的鄰接關系里,能看到位於LSP另一端的路由器了

查看ISIS在SPF計算中使用的LSP,紅色的是引入ISIS中的LSP,藍色的是原來計算的路由器。主要看 VIA,下一跳。正常情況下,下一跳就是鄰接的路由器。我們引入的LSP被是為一條可用鏈路,我們設置的metric為1,所以總的metric為11(10+1)。正常從R1到R3的總metric為20,所以會選擇使用LSP的路徑。

但是,這個方式的缺點在於,低效路徑可能會優於最短路徑,具體取決於LSP的形成方式
方式三:將所有內容遷移至inet.0
R1有到R3的LSP,這意味着BGP下一跳為3.3.3.3的流量將沿LSP下行。但是,如果你還希望所有發往3.3.3.3這個地址的網絡流量也通過LSP怎么辦?
這個命令,是移動不是復制。吧inet.3的內容移動到inet.0中。LSP仍將用於解析BGP下一跳。要記住,BGP可以同時使用inet.3和inet.0這兩個表,它只是更喜歡用inet.3。但是現在,所有其他流量也都可以使用LSP了(包括ospf,isis等)
set protocols mpls traffic-engineering bgp-igp
所以,現在查看inet.3的時候,會發現這個表是空的

這就相當於把兩個表給合並了,所有內容都在inet.0中,因為RSVP和LDP的路由有優先級比ISIS高,所以我們的路由器選擇這些路由,而非IGP。

雖然只通過一個命令就可以讓每個非VRF前綴都訪問使用LSP,但是,如果把所有內容都移出inet.3,會破壞運行MPLS VPN的能力。
方式四:將所有內容從inet.3復制到inet.0
把inet.3的內容復制一份到inet.0中,這意味着你的普通前綴可以使用LSP,並且你可以繼續使用MPLS VPN。
set protocols mpls traffic-engineering bgp-igp-both-ribs
如果我們在R1的路由表中查找R2的回環口,我們會在inet.0和inet.3中看到一個LDP條目

當使用這個命令后並將LSP設置為inet.0表中的首選路由時,這可能會嚴重破壞正常的IGP。因為優先級的問題,此時的IGP路由不再是active路由,這可能會阻止條目被正確分配。相當於,IGP的選路基本上是廢了
方式五:僅將LSP用於轉發,將你的IGP僅用於宣告路由(現網是使用這個方案,在PE上做的,P節點上沒做)
將LSP復制到inet.0中進行轉發,這個命令允許路由器選擇LSP來轉發流量,但在涉及路由器將前綴通告到IGP的方式時忽略他們。
set protocols mpls traffic-engineering mpls-forwarding
主要注意下圖里出現的新符號,如 @ 和 # 符號。這向我們表明,流量將沿着 LSP 轉發,但 IS-IS 仍然使用自己的“最佳”路徑來實現一致的 IS-IS 拓撲。
@ : 僅路由使用
# : 僅轉發使用
+ : 活動路由
- : 最后一個活動
* : 最優路由

比如現網環境下,查看另一個設備的回環口地址,在inet.0里流量轉發時使用RSVP的LSP路徑,路由學習宣告時使用ISIS的直連接口。inet.3里,就只有通過RSVP寫的LSP路徑
但是,這個命令是把inet3.0里的所有數據都復制到inet.0中,沒法做太多的認為控制。
方式六:解決路由反射器(RR)的問題
假設你有一個不在流量轉發路徑中的路由反射器,並且你正在向該路由反射器通告MPLS VPN前綴。但是,假設你沒有在此路由器上允許MPLS,那么他的inet.3表將是空的。如果我們的路由反射器無法解析inet.3表中的MPLS VPN前綴的下一跳,它也不會反射我們的前綴(畢竟,當路由器實際上不轉發任何流量時,它為什么還要讓路由反射器分配標簽呢?)
一個很容易被忘記的前提,路由反射器不會自動反射他們學到的所有東西。如果路由反射器收到一個它認為無效的前綴,例如它無法解析的下一跳,他就不會反射該前綴。
對此,有很多種解決方案,其中許多涉及到告訴路由器使用哪個路由表來解析這些前綴。例如,使用rib-group或者resolution rib,就可以操作路由器使用不同的表來解析前綴,或者告訴它從inet復制少量的下一跳IP.0到inet.3。
現在梳理一下,一般來說當我們在inet.3中查找下一跳時,該下一跳會帶有某種標簽。因此,如果我們將下一跳從inet.0復制到inet.3時,時沒有任何標簽的,如果RR實際上在轉發流量,那么這個方案就行不通。
但是,我們的RR並不會轉發流量,實際上,這是一種欺騙路由器的方式。我們讓它認為,它可以“解析”下一跳,而實際上它並不能。但沒關系,下一跳在inet.3中,這足以讓我們的RR將路由反射到實際上可以轉發此流量的路由器上。
