Come ho mostrato nel Post precedente, il trucchetto utilizza Route Distinguisher (RD) diversi sulle VRF dei due PE dove sono terminati i collegamenti primario e backup del router CE. (NOTA: il trucchetto non cambia se ad annunciare il prefisso IP sono due CE attestati a due PE diversi).
Questo trucchetto però funziona solo in uno scenario L3VPN, e ha un serio problema di scalabilità (gestionale) su reti di ISP che hanno decine/centinaia di migliaia di siti ridondati di Clienti VPN.
In ambito IETF è stata proposta una soluzione più semplice e più generale al problema. Questa soluzione, nota come funzionalità BGP Add-Path, ancora non ha raggiunto lo stato di RFC ma è già implementata da Cisco e Juniper.
ROUTING SUB-OTTIMO IN PRESENZA DI ROUTE REFLECTOR
Prima di vedere come opera la funzionalità BGP Add-Path, voglio mettere in luce alcune problematiche di routing inerenti l'utilizzo dei Route Reflector (RR). Come è noto, un RR funziona per certi aspetti come un normale BGP speaker, ad esempio, in presenza di più annunci dello stesso prefisso IP, esegue il processo di selezione, sceglie il best-path e quindi annuncia il best-path seguendo le regole di propagazione dei RR (che, ricordo, in certi casi violano il dogma sacro del BGP Split-Horizon).
Vediamo con un esempio cosa accade in pratica. Lo scenario di riferimento è riportato nella figura seguente. In tutti gli scenari seguenti supporrò che sui router PE sia attivo il BGP Next-Hop-Self.
Il router CE-12 annuncia ai router PE-1 e PE-2, via eBGP, il prefisso "NET X". I router PE-1 e PE-2 propagano l'annuncio al RR, il quale esegue il processo di selezione sui due annunci. A parità di tutti gli attributi BGP classici, il processo di selezione sceglie come best-path l'annuncio ricevuto da PE-1, perché il costo IGP verso il BGP Next-Hop PE-1, pari a 5, è inferiore al costo IGP verso il BGP Next-Hop PE-2, pari a 10. Il RR propaga a PE-3 il best-path, e nella tabella BGP di PE-3 si troverà quindi un solo annuncio del prefisso "NET X", con BGP Next-Hop PE-1. Ma come si vede dalla figura, il BGP Next-Hop più vicino a PE-3 non è PE-1, che è "distante" 20 (ossia con costo IGP da PE-3 a PE-1 pari a 20), bensì PE-2, distante 10.
L'introduzione di un RR può quindi creare problemi di routing sub-ottimo. Nella pratica però non vi è mai un singolo RR, quindi l'esempio appena descritto si può considerare accademico, ma utile per mettere in luce un problema indotto dall'utilizzo dei RR.
Vediamo cosa accade aggiungendo un secondo RR. Lo scenario di riferimento è riportato nella figura seguente.
Supponiamo che RR-1 sia più vicino (secondo il costo IGP) a PE-1 e che RR-2 sia più vicino a PE-2. Il risultato, ripercorrendo quanto visto nel caso di singolo RR, è che RR-1 elegge come best-path l'annuncio ricevuto da PE-1 e RR-2 elegge come best-path l'annuncio ricevuto da PE-2.
PE-3 riceverà quindi due annunci del prefisso "NET X", uno da RR-1 con BGP Next-Hop PE-1 e uno da RR-2 con BGP Next-Hop PE-2.
Stupendo, abbiamo quindi raggiunto il nostro scopo di avere nella Tabella BGP di PE-3 due annunci, e quindi rendere possibile l'applicazione della funzionalità PIC senza colpo ferire.
Purtroppo la realtà è ben diversa. Nelle reti di grandi dimensioni, pensare di agire sulle metriche IGP per fare in modo che i due RR vedano i PE con distanze diverse è assolutamente improponibile. Inoltre si potrebbe incorrere in problemi di routing sub-ottimo come quello descritto nel primo esempio. Poi, se i due RR fossero colocati, la distanza IGP da ciascun RR verso lo stesso PE sarebbe identica, e quindi verrebbe sempre riflesso lo stesso annuncio. Ad esempio, nel caso in cui RR-1 e RR-2 fossero colocati, la distanza IGP di RR-1 e RR-2 da PE-1 sarebbe identica, supponiamo pari a 10. Allo stesso modo, anche la distanza IGP di RR-1 e RR-2 da PE-2 sarebbe identica, supponiamo pari a 20. Come risultato si ha che RR-1 sceglierà come best-path l'annuncio proveniente da PE-1 (distanza IGP più bassa), e lo stesso farà RR-2. Per cui è vero che su PE-3 arriveranno due annunci BGP del prefisso "NET X", ma entrambi avranno BGP Next-Hop PE-1, per cui la funzionalità PIC non si può applicare (NOTA: ricordo che la funzionalità PIC richiede la presenza di due annunci BGP dello steso prefisso, ma con BGP Next-Hop diversi !).
LA FUNZIONALITA' BGP ADD-PATH
La soluzione del problema posto nel secondo esempio, potrebbe essere ottenuta facendo in modo che i due RR, oltre al best-path, annuncino anche il best-path alternativo. Una sorta di "Uovo di Colombo". Così facendo, su PE-3 si avrebbero, oltre agli annunci con BGP Next-Hop PE-1, anche quelli con BGP Next-Hop PE-2, rendendo applicabile la funzionalità PIC. Ma il comportamento di default dei RR non è questo.
Vi sono due soluzioni possibili, una, la funzionalità BGP Add-Path, che sarà trattata in questo Post, mentre la seconda soluzione, detta BGP Diverse Path sarà trattata in un Post successivo.
La possibilità che i RR annuncino sia best-path che best-path alternativo può essere raggiunta con un trucchetto simile a quello che ho mostrato nello scenario L3VPN, e che ho ripreso all'inizio di questo Post, ossia l'utilizzo di RD diversi. In uno scenario generale non si può però fare affidamento ai RD.
La funzionalità BGP Add-Path utilizza un'idea simile, estendendo la definizione classica di NLRI (Network Layer Reachability Information). L'idea del BGP Add-Path è riportata nella figura seguente.
Il RR annuncia sia best-path che best-path alternativo (NOTA: in realtà potrebbe annunciare anche altri percorsi disponibili, e non solo 2). Inoltre, associa a ciascun annuncio, un identificativo (Path ID) generato automaticamente dal processo BGP. L'identificativo viene aggiunto al NLRI e rende la coppia <Path ID ; prefisso> univoca. Il BGP speaker che riceve i due annunci, li installa entrambi nella Tabella BGP considerandoli diversi. Faccio notare che la presenza del Path ID è l'elemento chiave. Senza il Path ID, a causa del meccanismo di implict withdraw del BGP, il secondo annuncio rimpiazzerebbe il primo, e quindi nella Tabella BGP si troverebbe un solo annuncio.
La funzionalità BGP Add-Path fornisce un trucchetto semplice per annunciare più percorsi verso lo stesso prefisso, evitando che gli annunci successivi al primo implicitamente rimpiazzino l'annuncio precedente. Si raggiunge così la Path diversity invece che il Path Hiding.
Come il lettore attento avrà notato, la funzionalità BGP Add-Path richiede però una modifica al codice di base del BGP. Infatti, i due BGP speaker agli estremi della sessione BGP devono, uno essere in grado di generare annunci con NLRI modificati (ossia, con l'aggiunta del Path ID) e l'altro essere in grado di interpretarli. E' quindi ora di passare a un po' di poesia (poi ritornerò alla prosa ...).
UN PO' DI TEORIA
La funzionalità BGP Add-Path non ha ancora ad oggi raggiunto lo status di RFC, ma è comunque implementata da tempo sia da Cisco che da Juniper. Il documento ufficiale al momento è il draft IETF "draft-ietf-idr-add-paths-10", che scade il 27 Aprile 2015.
La proposta del draft IETF è di cambiare il campo NLRI presente nei messaggi BGP UPDATE descritto nella RFC 4271, aggiungendo un Path ID, come mostrato nella figura seguente.
Allo stesso modo, il draft IETF propone di cambiare la codifica del campo NLRI della RFC 3107 Carrying Label Information in BGP-4, come mostrato nella figura seguente.
In entrambi i casi, la differenza chiave è l'aggiunta del Path ID, che in questo contesto gioca il ruolo del RD nello scenario L3VPN, ma con una diffrenza fondamentale: il Path ID non è oggetto di configurazione ma viene scelto automaticamente dal BGP speaker che invia annunci multipli dello stesso prefisso, eliminando quindi qualsiasi problema gestionale di assegnazione dei RD.
La funzionalità BGP Add-Path, come ho detto sopra, va supportata dai BGP peer agli estremi di una sessione iBGP (NOTA IMPORTANTE: al momento la funzionalità BGP Add-path è supportata solo sulle sessioni iBGP). Quindi i due BGP peer devono negoziarne il supporto. Come noto a chi mastica un po' di BGP, le funzionalità aggiuntive vengono negoziate attraverso le BGP Capability, presenti nel messaggio OPEN. Il draft IETF propone l'utilizzo della ADD-PATH BGP Capability, alla quale lo IANA ha assegnato il Capability Code 69, che ha il formato seguente.
I campi AFI/SAFI sono ben noti e identificano la famiglia di indirizzi. Il campo Send/Receive invece stabilisce il ruolo del BGP Speaker. I valori possibili sono (in decimale) 1, 2 e 3:
1 : il BGP speaker è in grado di ricevere annunci
2 : il BGP speaker è in grado di inviare annunci
3 : il BGP speaker è in grado di inviare e ricevere annunci
con NLRI estesi con il Path ID, per la famiglia di indirizzi specificati dai codici AFI/SAFI.
Questo è sufficiente per i nostri scopi. Per il lettore che volesse approfondire anche gli aspetti operativi, consiglio la lettura dei due seguenti draft IETF:
draft-ietf-idr-add-paths-guidelines-07.txt : Best Practices for Advertisement of Multiple Paths in IBGP
draft-retana-idr-add-paths-implementation-01 : Advertisement of Multiple Paths in BGP: Implementation Report
Il primo draft è in particolare interessante poiché definisce la modalità di selezione degli annunci multipli.
IMPLEMENTAZIONE CISCO
Nelle piattaforme Cisco, il supporto della funzionalità BGP Add-Path è stata introdotta a partire dalle versioni IOS 15.3T, IOS XE 3.10S e IOS XR 4.0.0.
I passi generali da intraprendere sono 3:
- Specificare se il BGP speaker deve negoziare o meno la ADD-PATH Capability e la modalità (send, receive, send/receive).
- Selezionare con un qualche criterio l'insieme dei percorsi da annunciare, oltre al best-path. Le piattaforme Cisco non supportano tutti i criteri specificati nel documento menzionato sopra draft-ietf-idr-add-paths-guidelines-07.txt.
- Specificare, per ciascun BGP peer, l'insieme dei percorsi da annunciare (che possono anche essere un sottoinsieme di quelli specificati nel passo precedente).
Come al solito le configurazioni differiscono tra le varie versioni IOS. Nell'IOS e IOS XE, il comando da eseguire per la negoziazione della ADD-PATH Capability è il seguente:
router bgp numero-AS
address-family ipv4 [unicast | multicast]
bgp additional-paths {send [receive] | receive}
Nell'IOS XR la negoziazione della ADD-PATH Capability avviene invece attraverso i seguenti comandi:
router bgp numero-AS
address-family ...
additional-paths send | receive
! in aggiunta o in alternativa
additional-paths receive | send
dove a differenza dell'IOS/IOS XE, il comando è supportato per tutte le più importanti address-family (IPv4, IPv6, VPNv4, VPNv6, VRF IPv4, VRF IPv6).
Il criterio per la definizione dell'insieme dei percorsi da annunciare, nell'IOS e IOS XE si configura nel modo seguente:
router bgp numero-AS
address-family ipv4 [unicast | multicast]
bgp additional-paths select best numero
bgp additional-paths select all
bgp additional-paths select group-best
dove gli ultimi tre comandi sono alternativi. Il comando bgp additional-paths select best numero, dove numero nell'IOS/IOS XE può essere o 2 o 3, consente di annunciare, oltre al best-path anche un best-path alternativo (ottenuto da un nuovo processo di selezione BGP dove viene eliminato il best-path primario), se numero = 2, oppure due ulteriori best-path alternativi se numero = 3. Il comando bgp additional-paths select all consente invece di selezionare tutti gli annunci che hanno un diverso BGP Next-Hop. Infine, il comando bgp additional-paths select group-best è un po' più complesso. Preferisco illustrarne il funzionamento tramite un esempio. Supponiamo che il BGP speaker abbia tre peering con tre diversi AS, AS 1, AS 2 e AS 3. Ciascuno di questi invia tre annunci dello stesso prefisso X. Per brevità li chiamerò Xnm, dove n è il numero di AS e m il numero di sequenza degli annunci. Ad esempio i tre annunci dell'AS 1 saranno X11, X12 e X13.
Per scegliere quali inviare, il router esegue il processo di selezione su tutti gli annunci provenienti dallo stesso AS. Supporrò che i best-path siano rispettivamente X11, X21 e X31. Allora l'opzione group-best selezionerà per l'invio proprio i tre annunci X11, X21 e X31.
Nell'IOS XR il criterio di scelta è definito attraverso una routing policy:
router bgp numero-AS
address-family ...
additional-paths selection route-policy nome-RP
dove, come sopra, il comando è supportato per tutte le più importanti address-family. All'interno della routing-policy, il comando che consente di scegliere il criterio è il seguente: set path-selection {backup numero | group-best | all | best-path} advertise, dove le opzioni group-best e all hanno lo stesso significato visto per l'IOS/IOS XE. L'opzione backup numero, dove numero al momento può assumere il solo valore 1, consente di annunciare, oltre al best-path, un solo best-path alternativo. L'opzione best-path consente invece il solo annuncio del best-path.
Infine, per completare la configurazione, l'IOS e IOS XE (ma non l'IOS XR) richiedono il terzo passo descritto sopra, che utilizza il comando neighbor IP-peer advertise additional-paths [best numero] [group-best] [all].
Nella sezione "TEST DI LABORATORIO" sotto, mostrerò una prova di laboratorio realizzata con router che utilizzano l'IOS XR.
IMPLEMENTAZIONE JUNIPER
Il JUNOS supporta la funzionalità BGP Add-Path dalla versione 11.3, inizialmente per la sola family inet e successivamente per altre famiglie di indirizzi, ma non al momento la family inet-vpn. I comandi da utilizzare sono i seguenti:
[edit protocols bgp group nome-gruppo family ...]
add-path {
receive;
send {
path-count numero;
prefix-policy nome-RP;
}
}
dove, come nel caso delle piattaforme Cisco, le opzioni send e receive possono essere utilizzate separatamente. Quando si sceglie l'opzione send è obbligatorio specificare il "path-count ..." che è il numero di annunci che si selezionano, incluso il best-path (per questa ragione il valore minimo di numero è pari a 2. L'opzione "prefix-policy nome-RP" consente di definire per quali prefissi applicare la funzionalità BGP Add-Path. Senza questa opzione, la funzionalità viene applicata a tutti i prefissi.
TEST DI LABORATORIO
Ho fatto un test di laboratorio per verificare la funzionalità BGP Add-Path, utilizzando il nostro glorioso GSR 12k, con IOS XR 4.2.4, e altri router con IOS. Lo scenario utilizzato è quello della prima figura (con le metriche IGP al loro valore di default), con la "NET X" coincidente con il prefisso 10.1.99.11/32. I router PE-X (X=1,2,3) hanno indirizzo IP dell'interfaccia Loopback 0, 192.168.0.X. Il RR ha invece indirizzo IP dell'interfaccia Loopback 0 pari a 192.168.0.100. Tutte le sessioni iBGP sono state stabilite utilizzando gli indirizzi IP delle interfacce Loopback 0. La funzionalità BGP Add-Path è stata configurata tra il RR (modalità send) e il router PE-3 (modalità receive).
Ho lasciato tutti gli attributi BGP al loro valore di default. Senza applicare il BGP Add-Path, RR riceve due annunci del prefisso 10.1.99.11/32, rispettivamente dai router PE-1 e PE-2. RR esegue quindi il processo di selezione e annuncia il solo best-path risultante. Su PE-3 si avrà quindi un solo annuncio del prefisso 10.1.99.11/32:
RP/0/4/CPU0:PE-3#show bgp ipv4 unicast
Mon Feb 2 14:05:23.719 UTC
. . . < output omesso > . . .
Network Next Hop Metric LocPrf Weight Path
*>i 10.1.99.11/32 192.168.0.1 0 100 0 65201 i
Processed 1 prefixes, 1 paths
Queste sono le configurazioni del processo BGP sui router RR e PE-3, inclusi i comandi per l'abilitazione del BGP Add-Path:
RP/0/0/CPU0:RR#sh run router bgp
Mon Feb 2 14:00:57.119 UTC
router bgp 3269
address-family ipv4 unicast
additional-paths send
additional-paths selection route-policy ALLROUTES
!
neighbor-group RR-CLIENT
remote-as 3269
update-source Loopback0
address-family ipv4 unicast
route-reflector-client
!
!
neighbor 192.168.0.1
use neighbor-group RR-CLIENT
!
neighbor 192.168.0.2
use neighbor-group RR-CLIENT
!
neighbor 192.168.0.3
use neighbor-group RR-CLIENT
!
!
route-policy ALLROUTES
set path-selection all advertise
end-policy
RP/0/4/CPU0:PE-3#sh run router bgp
Mon Feb 2 14:01:29.705 UTC
router bgp 3269
address-family ipv4 unicast
additional-paths receive
!
neighbor 192.168.0.100
remote-as 3269
update-source Loopback0
address-family ipv4 unicast
!
!
!
Per verificare il risultato, ho controllato la presenza dei due annunci su PE-3 (invece che uno come nel caso senza BGP Add-Path):
RP/0/4/CPU0:PE-3# show bgp ipv4 unicast 10.1.99.11/32
Mon Feb 2 13:58:18.530 UTC
BGP routing table entry for 10.1.99.11/32
Versions:
Process bRIB/RIB SendTblVer
Speaker 9 9
Last Modified: Feb 2 13:57:45.982 for 00:00:32
Paths: (2 available, best #1)
Not advertised to any peer
Path #1: Received by speaker 0
Not advertised to any peer
65201
192.168.0.1 (metric 4) from 192.168.0.100 (192.168.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best, group-best
Received Path ID 1, Local Path ID 1, version 9
Originator: 192.168.0.1, Cluster list: 192.168.0.100
Path #2: Received by speaker 0
Not advertised to any peer
65201
192.168.0.2 (metric 4) from 192.168.0.100 (192.168.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
Received Path ID 2, Local Path ID 0, version 0
Originator: 192.168.0.2, Cluster list: 192.168.0.100
E' interessante in questa visualizzazione il valore del Path ID ricevuto, pari a 1 per il primo annuncio e pari a 2 per il secondo. Questi valori sono stati scelti dinamicamente dal RR e aggiunti al NLRI. Ciò si può vedere bene dalla visualizzazione seguente, che mostra il dettaglio degli annunci che il RR invia e PE-3:
RP/0/0/CPU0:RR# show bgp ipv4 unicast advertised neighbor 192.168.0.3
Mon Feb 2 14:00:04.768 UTC
10.1.99.11/32 is advertised to 192.168.0.3
Path info:
neighbor: 192.168.0.1 neighbor router id: 192.168.0.1
(Received from a RR-client) valid internal best
Received Path ID 0, Local Path ID 1, version 3
Attributes after inbound policy was applied:
next hop: 192.168.0.1
MET ORG AS LOCAL
origin: IGP neighbor as: 65201 metric: 0 local pref: 100
aspath: 65201
Attributes after outbound policy was applied:
next hop: 192.168.0.1
MET ORG AS LOCAL
origin: IGP neighbor as: 65201 metric: 0 local pref: 100
aspath: 65201
originator: 192.168.0.1 cluster list: 192.168.0.100
10.1.99.11/32 is advertised to 192.168.0.3
Path info:
neighbor: 192.168.0.2 neighbor router id: 192.168.0.2
(Received from a RR-client) valid internal
Received Path ID 0, Local Path ID 2, version 3
Attributes after inbound policy was applied:
next hop: 192.168.0.2
MET ORG AS LOCAL
origin: IGP neighbor as: 65201 metric: 0 local pref: 100
aspath: 65201
Attributes after outbound policy was applied:
next hop: 192.168.0.2
MET ORG AS LOCAL
origin: IGP neighbor as: 65201 metric: 0 local pref: 100
aspath: 65201
originator: 192.168.0.2 cluster list: 192.168.0.100
La funzionalità BGP Add-Path può essere utilizzata congiuntamente o in alternativa alla funzionalità BGP Best External descritta in un Post precedente. Ad esempio, in uno scenario in cui il collegamento CE-12<-->PE-1 venga scelto come primario (ad esempio imponendo su PE-1 agli annunci ricevuti da CE-1 un valore di Local Preference maggiore di 100), come abbiamo visto nel Post precedente, applicando la funzionalità BGP Best External su PE-2 è possibile far arrivare al RR due annunci, e con la funzionalità BGP Add-Path configurata come sopra tra RR e PE-3, PE-3 riceverà entrambi gli annunci, uno con BGP Next-Hop PE-1 e l'altro con BGP Next-Hop PE-2.
In alternativa, si potrebbe utilizzare la sola funzionalità BGP Add-Path su PE-2, RR e PE-3. Su PE-2 in modalità send, su RR in modalità send/receive e su PE-3 in modalità receive. Provare per credere... (io l'ho fatto !).
Per i più curiosi, riporto di seguito le configurazioni equivalenti JUNOS su RR e PE-3.
[edit protocols bgp group PE-3]
tt@RR# show
type internal;
local-address 192.168.0.100;
cluster 192.168.0.100;
neighbor 192.168.0.3 {
family inet {
unicast {
add-path {
send {
path-count 2;
}
}
}
}
}