domenica 27 novembre 2016

Scalabilità dei servizi VPN BGP/MPLS: BGP RT Constraint

Il servizio L3VPN su reti BGP/MPLS è sicuramente quello che ha decretato il successo di MPLS. Dalle sue prime implementazioni intorno al 2000-2001, con la crescita del numero di Clienti, sono state introdotte nuove funzionalità in grado di aumentarne la scalabilità. Una di queste, a dire il vero poco conosciuta e poco implementata, riguarda la riduzione dei messaggi UPDATE MP-iBGP (AFI/SAFI = 1/128), utilizzati come noto per annunciare i prefissi dei Clienti VPN. Di altre tecniche di scalabilità, come ad esempio le VPN gerarchiche, parlerò in post futuri. 

In realtà la funzionalità introdotta in questo post non è applicabile solo a servizi L3VPN, ma ha validità più generale ed è applicabile a tutti i servizi VPN basati sull'architettura BGP/MPLS (es. L3VPN IPv4 e IPv6, BGP-based VPLS, EVPN, NG-MVPN, ecc.). Questo spiega perché nel titolo si parla genericamente di scalabilità dei servizi VPN BGP/MPLS, ossia, servizi VPN che hanno il piano di controllo basato sul BGP (in realtà il piano dati MPLS è indipendente da questo discorso; tutto ciò che verrà illustrato in questo post riguarda il solo piano di controllo basato sul BGP). Comunque in questo post farò riferimento al servizio L3VPN, poiché il più familiare ai più.

IL PROBLEMA
Nella versione originale del servizio L3VPN e ancora ampiamente utilizzata, quando un router PE invia un messaggio MP-iBGP UPDATE per annunciare un prefisso di un Cliente VPN, il messaggio viene inviato a tutti gli altri PE della rete, anche quelli che non hanno alcun sito del Cliente L3VPN. Di norma, anche in reti di modeste dimensioni, l'invio dei messaggi avviene attraverso l'utilizzo di Route Reflector.


Questo modo di procedere crea un notevole spreco di risorse, sia in termini di utilizzo della CPU dei router, a causa dell'elaborazione inutile di una gran quantità di messaggi MP-iBGP, sia in termini di banda occupata inutilmente (anche se questo è un problema minore).

Pensate ad esempio ad un ISP che ha 10.000 Clienti VPN, e ciascuno abbia mediamente 100 prefissi, per un totale di 1.000.000 di prefissi. Poiché spesso un PE ha due sessioni MP-iBGP verso due Route Reflector, questo riceve un totale di poco meno di 2.000.000 di UPDATE MP-iBGP, quando in realtà il PE è interessato a un numero di gran lunga inferiore. Se un PE ad esempio ha attestati siti di solo 100 Clienti VPN, il numero di prefissi a cui è interessato è poco meno di 10.000 (il poco meno deriva dal fatto che alcuni prefissi sono locali, e quindi non appresi attraverso annunci MP-iBGP).

LA SOLUZIONE: BGP CONSTRAINED ROUTE DISTRIBUTION (RFC 4684)
La soluzione di questo problema di scalabilità è semplice ed è stata standardizzata nella RFC 4684 - Constrained Route Distribution for Border Gateway Protocol/MultiProtocol Label Switching (BGP/MPLS) Internet Protocol (IP) Virtual Private Networks (VPNs), del Novembre 2006.

L'idea di fondo come dicevo è semplice: ogniqualvolta si crea su un PE una nuova VRF, il PE annuncia ai Route Reflector, via BGP, tutti i Route Target (RT) configurati nella VRF come import. Ovviamente questo sono annunci un po' particolari, che richiedono la definizione di una nuova address family BGP, che chiamerò "address family RT", e quindi l'utilizzo dell'estensione Multi Protocol del BGP. 

La nuova address family RT, come specificato nella RFC 4684, è caratterizzata dai valori AFI/SAFI = 1/132, e il campo NLRI degli attributi MP_REACH_NLRI e MP_UNREACH_NLRI è codificato come nella figura seguente (tratta dalla RFC 4684).











dove nel campo origin as viene inserito il numero di AS del router che genera l'annuncio, e nel campo route target il valore di RT annunciato. Si noti che il campo origin as è già predisposto per il supporto degli AS a 4 byte. 

La codifica dei RT segue le regole specificate nella RFC 4360 BGP Extended Communities Attribute, poiché come noto i RT sono attributi BGP di tipo Extended Community. In generale, un attributo BGP Extended Community ha il formato diviso in due parti, il tipo (Type), che può essere di 1 o 2 byte, e il valore (Value) che è di 6 o 7 byte. La lunghezza totale è in ogni caso di 8 byte. Gli attributi BGP Extended Community di tipo RT hanno il campo Type di due byte (vedi RFC 4360), di cui il secondo sempre pari a 0x02. Sono previsti tre formati del campo Value
  • Type = 0x00-02 : Value Numero-AS-2byte:nn (esempio 54512:12345).
  • Type = 0x01-02 : Value Indirizzo-IP:nn (esempio 192.168.0.1:12345).
  • Type = 0x02-02 o 0x42-02 : Value Numero-AS-4byte:nn (esempio 1.1:12345).
dove nn è un numero arbitrario a disposizione dell’ISP. L’ultimo formato è specificato nella RFC 5668 - 4-Octet AS Specific BGP Extended Community.

Con questa informazione, i Route Reflector si creano una mappa PE<->RT-import, dove per ciascun PE sono noti i RT import configurati sulle varie VRF del PE. 

A questo punto siamo arrivati alla soluzione del nostro problema: quando un Route Reflector riceve un annuncio L3VPN, confronta i RT contenuti nell'annuncio con la mappa PE<->RT-import, e quindi propaga l'annuncio ai soli PE interessati, ossia quelli che hanno su una qualsiasi VRF, almeno un RT import coincidente con almeno un RT contenuto nell'annuncio.

Questa soluzione può tranquillamente essere applicata anche in assenza di Route Reflector, è sufficiente abilitare l'address family RT su ciascuna sessione MP-iBGP tra ogni coppia di PE. 

Nel caso più comune di utilizzo di Route Reflector, per ottimizzare ulteriormente la distribuzione degli annunci dell'address family RT, è possibile evitare la riflessione degli annunci. Infatti, con una simile topologia sono solo i Route Reflector che hanno necessità di conoscere la mappa PE<->RT-import. Per raggiungere questo obiettivo è sufficiente che i Route Reflector annuncino l'equivalente di una default-route, che si ottiene ponendo a zero tutti i campi del NLRI (nel seguito farò riferimento a questa particolare default-route con la notazione "default-route RT"). In un certo senso è come se i Route Reflector dicessero a tutti i PE, inviatemi tutte le vostre route L3VPN che penso io a come ottimizzare la distribuzione (NOTA: chi si è letto questo post su "DMVPN fase 1", troverà forti analogie con la metodologia di routing lì utilizzata, anche se il contesto è ovviamente diverso !).

La figura seguente riporta lo scambio di annunci della nuova address family RT, in presenza di Route Reflector.



Questa funzionalità deve essere ovviamente supportata sia dai PE che dai Route Reflector, e viene negoziata all'apertura della sessione MP-iBGP tramite le BGP Capability. In ogni caso, qualora si abbia a che fare con un Route Reflector che non supporta questa funzionalità e magari altri si, è possibile far coesistere entrambe le modalità di propagazione degli annunci L3VPN, quella classica (non efficiente) e quella ottimizzata trattata in questo post.

I vantaggi di questa ottimizzazione del piano di controllo BGP-based delle VPN, sono evidenti:
  • Minore utilizzo della CPU dei PE e risparmio di banda a causa del minor numero di annunci L3VPN propagati.
  • Minor numero di annunci L3VPN propagati da parte dei Route Reflector.
  • Riduzione del tempo di convergenza BGP.
Ciò detto, i router Cisco e Juniper (e anche degli vendor tradizionali) supportano da tempo questa funzionalità. E quindi, per completezza, illustrerò con delle prove di laboratorio le procedure di configurazione da utilizzare per la sua implementazione. In entrambi i casi farò riferimento a una topologia di rete molto semplice, descritta nella figura seguente, ma sufficiente per rendere l'idea. 



Nel caso di ambiente Cisco farò riferimento all'IOS XR, anche se la funzionalità è comunque supportata nell'IOS e IOS XE.

IMPLEMENTAZIONE JUNOS
Nel JUNOS l'abilitazione dell'address family RT avviene con il comando "set family route-target" all'interno della configurazione del BGP. A questo comando può essere aggiunta l'opzione "advertise-default", per far si che venga annunciata la default-route RT. Si noti che l'annuncio della default-route RT, implica automaticamente che gli annunci dell'address family RT non vengano riflessi dai Route Reflector.

Di seguito le configurazioni BGP rilevanti su PE1-1 e su RR-1 (la configurazione di PE2-1 è analoga a quella di PE1-1, mentre quella di RR-2 è analoga a quella di RR-1).

RR-1

tt@RR-1> show configuration protocols bgp
local-address 192.168.1.1;
group RR-CLIENT {
    type internal;
    family inet-vpn {
        unicast;
    }
    family route-target {
        advertise-default;
    }
    cluster 192.168.1.1;
    neighbor 192.168.0.11;
    neighbor 192.168.0.21;
}
group RR-TOP {
    type internal;
    family inet-vpn {
        unicast;
    }
    neighbor 192.168.1.2;
}


PE1-1

tt@PE1-1> show configuration protocols bgp
group RR-CLIENT {
    type internal;
    local-address 192.168.0.11;
    family inet-vpn {
        unicast;
    }
    family route-target;
    neighbor 192.168.1.1;
    neighbor 192.168.1.2;
}

Il JUNOS memorizza gli annunci dell'address family RT nella tabella "bgp.rtarget.0", che può essere visualizzata con il classico comando "show route table bgp.rtarget.0". Eseguito su RR-1, il comando da la seguente visualizzazione:

tt@RR-1> show route table bgp.rtarget.0
bgp.rtarget.0: 3 destinations, 4 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

0:0:0/0
                   *[RTarget/5] 00:01:11
                      Type Default
                      Local
1234:1234:1/96
                   *[BGP/170] 00:14:54, localpref 100, from 192.168.0.11
                      AS path: I, validation-state: unverified
                    > to 172.16.13.11 via ge-0/0/0.0
                    [BGP/170] 00:11:26, localpref 100, from 192.168.0.21
                      AS path: I, validation-state: unverified
                    > to 172.16.35.21 via ge-0/0/1.0
1234:1234:2/96
                   *[BGP/170] 00:14:54, localpref 100, from 192.168.0.11
                      AS path: I, validation-state: unverified
                    > to 172.16.13.11 via ge-0/0/0.0

I NLRI (prima colonna) sono riportati nel formato <AS>:<RT import>/96 (NOTA: il /96 indica la lunghezza massima in bit del NLRI; non è importante e può essere ignorato). Il primo annuncio è quello della default-route RT, generata localmente da RR-1 e propagata a PE1-1 e PE2-1. Poi ci sono i due annunci del RT import 1234:1, configurato sia su PE1-1 (VRF B) che su PE2-1 (sempre VRF B). Uno dei due annunci viene eletto best path, ma questo ai fini del funzionamento è ininfluente. Infine, l'ultimo annuncio riguarda il RT import 1234:2, configurato nella VRF C di PE1-1.

RR-1 propaga ai PE la sola default-route RT, e non gli annunci dei RT (che sarebbero inutili). Ad esempio, il seguente comando prova che PE1-1 riceve da RR-1 la sola default-route RT:

tt@PE1-1> show route receive-protocol bgp 192.168.1.1 table bgp.rtarget.0
bgp.rtarget.0: 3 destinations, 5 routes (3 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
  0:0:0/0
*                         192.168.1.1                      100          I

Per contro, PE1-1 annuncia a RR-1 entrambi i RT import configurati nelle sue due VRF:

tt@PE1-1> show route advertising-protocol bgp 192.168.1.1 table bgp.rtarget.0
bgp.rtarget.0: 2 destinations, 6 routes (2 active, 0 holddown, 0 hidden)
  Prefix                    Nexthop              MED     Lclpref    AS path
  1234:1234:1/96
*                             Self                                100          I
  1234:1234:2/96
*                             Self                                100          I

Per chiudere questo breve esempio, vi illustro l'effetto dell'introduzione dell'address family RT. Prima dell'introduzione dell'address family RT, RR-1 annuncia a PE2-1 sia le route L3VPN della VPN B che quelle della VPN C:

tt@RR-1> show route advertising-protocol bgp 192.168.0.21
bgp.l3vpn.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
  Prefix                       Nexthop              MED     Lclpref    AS path
  1234:1:1.1.1.1/32
*                              192.168.0.11                    100          I
  1234:2:2.2.2.2/32
*                              192.168.0.11                    100          I

Ma la route della VPN C verrà scartata da PE2-1 poiché questo non ha attestato alcun sito della VPN C. Ecco invece ciò che accade dopo l'attivazione dell'address family RT su tutti i router:

tt@RR-1> show route advertising-protocol bgp 192.168.0.21

bgp.l3vpn.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)

  Prefix                       Nexthop              MED     Lclpref    AS path
  1234:1:1.1.1.1/32
*                              192.168.0.11                    100          I

Come si può notare, RR-1 (e anche RR-2) non invia a PE2-1 l'annuncio L3VPN della VPN C, poiché sa che RR-1 non ha configurato alcun RT import pari 1234:2.

IMPLEMENTAZIONE CISCO (IOS XR)
Nell'IOS XR Cisco l'abilitazione dell'address family RT avviene con il comando "address-family ipv4 rt-filter", all'interno della configurazione del BGP. Non è necessario alcun comando specifico per la generazione della default-route RT, che viene annunciata automaticamente dai Route Reflector. Si noti che nell'IOS XR Cisco, di default i Route Reflector non riflettono gli annunci dell'address family RT.

NOTA: il comando Cisco per l'abilitazione dell'address family RT utilizza la parola chiave "ipv4" poichè l'AFI dell'address family RT è pari a 1, che identifica la famiglia di indirizzi IPv4. Però questo trae in inganno poiché la funzionalità BGP Constrained Route Distribution, come detto all'inizio del post, vale per qualsiasi tipologia di servizi VPN, purché basati su un piano di controllo BGPPer cui l'utilizzo della parola "ipv4" è un po' ambiguo (almeno a mio parere !).

Di seguito le configurazioni rilevanti su RR-1 e PE1-1.

RR-1

RP/0/0/CPU0:RR-1# show running-config router bgp
Tuesday Nov 22 08:24:12.135 UTC
router bgp 1234
  address-family vpnv4 unicast
  address-family ipv4 rt-filter
!
  neighbor-group RR-CLIENT
    remote-as 1234
    update-source loopback0
    address-family vpnv4 unicast
       route-reflector-client
    address-family ipv4 rt-filter
!
  neighbor 192.168.1.2
    remote-as 1234
    description SESSIONE MP-iBGP CON RR-2
    update-source Loopback0
    address-family vpnv4 unicast
!
 neighbor 192.168.0.11
  use neighbor-group RR-CLIENT
  description SESSIONE MP-iBGP CON PE1-1
!
 neighbor 192.168.0.21
  use neighbor-group RR-CLIENT
  description SESSIONE MP-iBGP CON PE2-1
  
PE1-1

RP/0/0/CPU0:PE1-1# show running-config router bgp
Tuesday Nov 22 08:28:35.574 UTC
router bgp 1234
  address-family vpnv4 unicast
  address-family ipv4 rt-filter
!
  neighbor-group RR-TOP
    remote-as 1234
    update-source loopback0
    address-family vpnv4 unicast
    address-family ipv4 rt-filter

 neighbor 192.168.1.1
    use neighbor-group RR-TOP
    description SESSIONE MP-iBGP CON RR-1
 !
 neighbor 192.168.1.2
  use neighbor-group RR-TOP
  description SESSIONE MP-iBGP CON RR-2
 !
 vrf VPN-B
  rd 1234:1
  address-family ipv4 unicast
   redistribute connected
 !
 vrf VPN-C
  rd 1234:2
  address-family ipv4 unicast
   redistribute connected
  
Per verificare gli annunci dell'address family RT inviati/ricevuti da RR-1, si utilizza il comando "show bgp ipv4 rt-filter":

RP/0/0/CPU0:RR-1# show bgp ipv4 rt-filter
Tue Nov 22 08:50:30.210 UTC
BGP router identifier 192.168.1.1, local AS number 1234

... < output omesso > ...

Status codes: s suppressed, d damped, h history, * valid, > best
              i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
   Network                  Next Hop             Metric  LocPrf  Weight  Path
*> 0:0x0000:0:0/0       0.0.0.0                                              0   i
*>i1234:2:1234:1/96   192.168.0.11                       100          0   i
*  i                             192.168.0.21                       100          0   i
*>i1234:2:1234:2/96   192.168.0.11                       100          0   i

I NLRI (prima colonna), ad eccezione della default-route RT, sono riportati nel seguente formato, leggermente diverso da quello del JUNOS <AS>:2:<RT import>/96. Rispetto al JUNOS compare un 2 dopo il numero di AS, che sta a indicare che la BGP Extended Community annunciata è di tipo Route Target. Per il resto valgono le stesse considerazioni fatte sopra per l'analogo output nel JUNOS. 

Lo stesso comando eseguito su PE1-1 mostra che i Route Reflector non riflettono gli annunci dell'address family RT:

RP/0/0/CPU0:PE1-1# show bgp ipv4 rt-filter
Tue Nov 22 08:53:43.857 UTC
BGP router identifier 192.168.0.11, local AS number 1234

... < output omesso > ...

Status codes: s suppressed, d damped, h history, * valid, > best
              i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
   Network                   Next Hop            Metric   LocPrf   Weight   Path
*>i0:0x0000:0:0/0       192.168.1.1                         100            0   i
*  i                              192.168.1.2                        100            0   i
*> 1234:2:1234:1/96    0.0.0.0                                                0   i
*> 1234:2:1234:2/96    0.0.0.0                                                0   i

Infine, anche qui per chiudere questo breve esempio, vi illustro l'effetto dell'introduzione dell'address family RT, lasciandovi i commenti.

Prima dell'introduzione dell'address family RT:

RP/0/0/CPU0:RR-1# show bgp vpnv4 unicast neighbor 192.168.0.21 advertised-routes
Tue Nov 22 09:03:17.086 UTC
Network             Next Hop          From                AS Path
Route Distinguisher: 1234:2
1.1.1.1/32          192.168.0.11    192.168.0.11     ?
Route Distinguisher: 1234:3
2.2.2.2/32          192.168.0.11    192.168.0.11     ?

Dopo l'introduzione dell'address family RT:

RP/0/0/CPU0:RR-1# show bgp vpnv4 unicast neighbor 192.168.0.21 advertised-routes
Tue Nov 22 09:05:04.590 UTC
Network            Next Hop          From               AS Path
Route Distinguisher: 1234:2
1.1.1.1/32         192.168.0.11    192.168.0.11    ?

E con questo "mi taccio" !

CONCLUSIONI
La funzionalità introdotta in questo post non è nuova, ma poco nota e poco utilizzata. Per questo ho voluto illustrarla, magari a qualcuno viene voglia di implementarla. D'altra parte è molto semplice e da innegabili vantaggi in termini di scalabilità.
Arrivederci al prossimo post. L'argomento ancora non lo so.

Nessun commento:

Posta un commento