Come promesso nel Post precedente sul BFD, in questo vedremo come implementarlo in pratica. Come al solito darò solo le idee fondamentali, tralasciando molti dettagli per i quali potete consultare la documentazione ufficiale dei costruttori. Illustrerò le configurazioni più importanti nelle piattaforme Cisco e Juniper, ed esporrò i risultati di prove reali di laboratorio, con i router che abbiamo a disposizione. Le prove riguarderanno la sola versione single-hop, che è quella utilizzata nella quasi totalità delle applicazioni pratiche.
NOTA: mentre stavo terminando di scrivere questo Post, è comparso sul blog del mio amico Ivan Pepelnjak un Post dal titolo "MICRO-BFD: BFD OVER LAG (PORT CHANNEL)", che tratta dell'applicazione del BFD su collegamenti "bundle", meglio noti tra i cultori delle reti Switched Ethernet (tra i quali non c'è il sottoscritto !) come "Port Channel", o Etherchannel, o LAG (Link Aggregation Group). L'argomento è interessante ed è stato oggetto della RFC 7130 "Bidirectional Forwarding Detection (BFD) on Link Aggregation Group (LAG) Interfaces", del Febbraio 2014. Il (semplice) meccanismo utilizzato, noto come Micro-BFD è già implementato nel JUNOS a partire dalla versione 13.3, e nelle versioni più recenti dei sistemi operativi Cisco NX-OS e IOS-XR. Mi riprometto in seguito di affrontare l'argomento in un Post dedicato.
IMPLEMENTAZIONE CISCO (IOS E IOS XR)
L'implementazione Cisco differisce abbastanza sia nello stile di configurazione che nei default utilizzati, tra IOS e IOS XR. Non ho l'opportunità di fare delle prove con il NX-OS dei Nexus, ma da quel poco che ho visto le configurazioni sono simili a quelle dell'IOS. Stesso discorso vale per l'IOS XE.
Prima di illustrare le prove effettuate, alcune considerazioni generali. L'implementazione Cisco supporta il BFD per tutti i principali protocolli di routing IPv4/IPv6 (EIGRP, OSPF, IS-IS, BGP, PIM), per le route statiche IPv4/IPv6, per i tunnel MPLS-TE e per protocolli di High Availability come HSRP e VRRP (per eventuali restrizioni è sempre comunque opportuno verificare la documentazione relativa alla versione IOS/IOS XR che si sta utilizzando).
I messaggi BFD HELLO vengono inviati utilizzando come indirizzi IP sorgente e destinazione:
- Nel caso di sessioni BFD IPv4, rispettivamente l'indirizzo dell'interfaccia da dove vengono trasmessi i messaggi, e indirizzo IP destinazione l'estremo remoto comunicato da un protocollo Client.
- Nel caso di sessioni BFD IPv6, gli indirizzi link-local associati alle interfacce locale e remota (NOTA: per chi non fosse familiare con IPv6, gli indirizzi link-local hanno come ambito di propagazione un segmento di rete, come ad esempio un link punto-punto, e sono parte del prefisso IPv6 fe80::/10. Tipicamente assumono la forma fe80::/64).
I messaggi BFD ECO, nell'IOS vengono inviati con indirizzo IP sorgente l'indirizzo dell'interfaccia da dove vengono trasmessi i messaggi; nell'IOS XR viene utilizzato il router-id globale, se configurato, altrimenti lo stesso indirizzo utilizzato nell'IOS. Nell'IOS XR è anche possibile sceglierlo con il comando "echo ipv4 source <indirizzo-IP>", eseguito a livello di protocollo BFD o a livello di interfaccia all'interno della configurazione del protocollo BFD. Ad esempio, se si volesse utilizzare l'indirizzo IP sorgente 1.1.1.1 per tutte le sessioni BFD, la configurazione da eseguire è la seguente:
RP/0/RP0/CPU0:router(config)# bfd
RP/0/RP0/CPU0:router(config-bfd)# echo ipv4 source 1.1.1.1
Qualore si volesse utilizzare l'indirizzo 2.2.2.2, ad esempio per l'interfaccia "Gigabitethernet 0/2/0/0", la configurazione da eseguire è la seguente:
RP/0/RP0/CPU0:router(config)# bfd
RP/0/RP0/CPU0:router(config-bfd)# interface gigabitethernet 0/2/0/0
RP/0/RP0/CPU0:router(config-bfd-if)# echo ipv4 source 2.2.2.2
Conformemente alla RFC 5881, i messaggi BFD vengono inviati con TTL IP pari a 255. Questo consente di evitare lo spoofing dei messaggi BFD, utilizzando la funzionalità Generalized TTL Security Mechanism (GTSM), standardizzata nella RFC 5082 (NOTA: la funzionalità GTSM non è peculiare del BFD, ma è molto generale e utilizzata anche da altri protocolli, come ad esempio il BGP).
Infine, le porte UDP utilizzate:
- Nei messaggi BFD HELLO: porta sorgente 49152, porta destinazione 3784.
- Nei messaggi BFD ECO: porta sorgente e porta destinazione 3785.
Passiamo ora alle prove di laboratorio. Nelle prove che ho effettuato mi sono avvalso di un router Cisco 3825 con IOS 15.1(3)T e del nostro vecchio glorioso GSR 12k, con IOS XR 4.2.4. Lo schema della rete di prova è riportato nella figura seguente:
Poiché la configurazione del BFD associato al protocollo BGP è già stata vista nel precedente Post sulla convergenza del BGP (Parte I), ho attivato sul collegamento un'adiacenza OSPFv2, una OSPFv3 e ho configurato due route statiche (IPv4) per mettere in comunicazione le due interfacce Loopback 0 tra i due router. Per cercare di rendere la prova più interessante ho utilizzato valori dei timer BFD e del Detect Mult diversi. Così, facendo queste prove ho scoperto molte cose interessanti. Innanzitutto le configurazioni rilevanti:
hostname PE1-1
!
interface GigabitEthernet0/1
ip address 172.16.1.111 255.255.255.0
ip ospf 1 area 0
ip ospf bfd
ipv6 enable
ipv6 ospf bfd
ipv6 ospf 1 area 0
bfd interval 150 min_rx 100 multiplier 3
!
ip route static bfd GigabitEthernet0/1 172.16.1.113
ip route 192.168.0.13 255.255.255.255 GigabitEthernet0/1 172.16.1.113
hostname PE1-3
!
router static
address-family ipv4 unicast
192.168.0.11/32 172.16.1.111 bfd fast-detect minimum-interval 150 multiplier 3
!
!
router ospf 1
area 0
interface GigabitEthernet0/2/0/0
bfd minimum-interval 100
bfd fast-detect
bfd multiplier 5
!
!
!
router ospfv3 1
area 0
interface GigabitEthernet0/2/0/0
bfd multiplier 4
bfd fast-detect
bfd minimum-interval 150
!
!
!
Prima di vedere i risultati della prova, una considerazione sulle configurazioni. Nell'IOS, l'abilitazione del BFD richiede due passi:
- La definizione all'interno della configurazione dell'interfaccia locale del collegamento da monitorare, dei due timer Desired Min TX Interval e Required Min RX Interval e del Detect Mult. I valori utilizzati nella configurazione di PE1-1 sono rispettivamente 150 ms, 100 ms e 3.
- Associare il BFD al protocollo. Nel caso dell'OSPFv2 questo può essere fatto in due modi: o con il comando "ip ospf bfd" a livello interfaccia. In alternativa, se tutte le interfacce abilitate OSPF utilizzano anche il BFD, si può eseguire il comando "bfd all-interfaces" a livello di processo OSPF:
PE1-1(config)#int GigabitEthernet0/1
PE1-1(config-if)#no ip ospf bfd
PE1-1(config)#router ospf 1
PE1-1(config-router)#bfd all-interfaces
Qualora si volesse disattivare il BFD su una particolare interfaccia (es. la GigabitEthernet0/2), è possibile farlo attraverso il seguentre comando:
PE1-1(config)#int GigabitEthernet0/2
PE1-1(config-if)#ip ospf bfd disable
Gli stessi identici comandi valgono per OSPFv3. E' sufficiente sostituire nei comandi "ip" con "ipv6".
Per contro nell'IOS XR, tutte le configurazioni del BFD vanno eseguite all'interno dei processi OSPFv2/v3. Inoltre, una cosa che salta subito all'occhio è che l'IOS XR non prevede la possibilità di differenziare i due timer Desired Min TX Interval e Required Min RX Interval, ma è possibile solo configurarli uguali, con il comando "bfd minimum-interval <valore-in-ms>". Il valore di Detect Mult potrebbe anche non essere configurato, nel qual caso l'IOS XR assegna il valore di default 3.
Un discorso a parte merita l'abilitazione del BFD sulle route statiche, sia IPv4 che IPv6, poiché non vi è come in OSPF, BGP, ecc. un modo automatico per comunicare al BFD l'indirizzo IP estremo remoto della sessione, non essendoci nessuna adiacenza o sessione stabilite in modo automatico. E' necessario quindi comunicare manualmente al BFD quale è l'indirizzo IP del BFD peer. Nell'IOS questo avviene con il comando a livello globale "ip route static bfd <interfaccia> <next-hop>". Si noti che nel comando è obbligatorio specificare l'interfaccia all'estremo locale del collegamento da monitorare. Inoltre è obbligatorio specificare l'interfaccia anche nella route statica, altrimenti l'associazione BFD route statica non avviene (NOTA: nella route statica l'indirizzo IP del Next-Hop non è necessario, ma io lo metto sempre comunque).
Questo comando crea un'associazione tra BFD e la route statica che ha come interfaccia Next-Hop e indirizzo IP Next-Hop quelli specificati nel comando. Ma cosa accade se nel router non è configurata alcuna route statica, magari perché un percorso verso la destinazione è stato appreso attraverso un altro protocollo ? Nessun problema, è sufficente aggiungere in coda al comando la parola chiave "unassociate" e il gioco è fatto. Questa parola chiave indica al router di completare comunque le procedure per l'apertura della sessione BFD anche in assenza di una route statica configurata.
Nell'IOS XR è sufficiente specificare timer e Detect Mult dopo il Next-Hop, come mostrato nella configurazione sopra. Non ho trovato tra la documentazione un concetto simile alla parola chiave "unassociate".
Vediamo ora il risultato della configurazione. Per questo l'IOS ha il comando "show bfd neighbors [detail]" e l'IOS XR l'analogo comando "show bfd all session [detail]". (NOTA: per tutte le altre opzioni disponibili rimandiamo alla documentazione Cisco).
Vediamo l'esecuzione di entrambi i comandi con la parola chiave "detail" su entrambi i router.
PE1-1# show bfd neighbors detail
NeighAddr LD/RD RH/RS State Int
172.16.1.113 2/-2146959355 Up Up Gi0/1
Session state is UP and using echo function with 150 ms interval.
OurAddr: 172.16.1.111
Local Diag: 0, Demand mode: 0, Poll bit: 0
MinTxInt: 1000000, MinRxInt: 1000000, Multiplier: 3
Received MinRxInt: 2000000, Received Multiplier: 3
Holddown (hits): 0(0), Hello (hits): 2000(102)
Rx Count: 98, Rx Interval (ms) min/max/avg: 460/1984/1817 last: 180 ms ago
Tx Count: 104, Tx Interval (ms) min/max/avg: 1/2000/1711 last: 220 ms ago
Elapsed time watermarks: 0 0 (last: 0)
Registered protocols: IPv4 Static OSPF
Uptime: 00:02:54
Last packet: Version: 1 - Diagnostic: 0
State bit: Up - Demand bit: 0
Poll bit: 0 - Final bit: 0
Multiplier: 3 - Length: 24
My Discr.: -2146959355 - Your Discr.: 2
Min tx interval: 2000000 - Min rx interval: 2000000
Min Echo interval: 1000
NeighAddr LD/RD RH/RS State Int
FE80::204:DEFF:FE51:CC70 1/-2146959358 Up Up Gi0/1
Session state is UP and not using echo function.
OurAddr: FE80::FEFB:FBFF:FE35:DE71
Local Diag: 0, Demand mode: 0, Poll bit: 0
MinTxInt: 150000, MinRxInt: 100000, Multiplier: 3
Received MinRxInt: 250000, Received Multiplier: 4
Holddown (hits): 788(0), Hello (hits): 250(847)
Rx Count: 814, Rx Interval (ms) min/max/avg: 36/272/230 last: 212 ms ago
Tx Count: 846, Tx Interval (ms) min/max/avg: 192/252/221 last: 204 ms ago
Elapsed time watermarks: 0 0 (last: 0)
Registered protocols: OSPFv3
Uptime: 00:03:07
Last packet: Version: 1 - Diagnostic: 0
State bit: Up - Demand bit: 0
Poll bit: 0 - Final bit: 0
Multiplier: 4 - Length: 24
My Discr.: -2146959358 - Your Discr.: 1
Min tx interval: 250000 - Min rx interval: 250000
Min Echo interval: 0
RP/0/0/CPU0:PE1-3#show bfd all session detail
Mon Oct 20 18:15:21.316 UTC
IPv4:
-----
I/f: GigabitEthernet0/2/0/0, Location: 0/2/CPU0
Dest: 172.16.1.111
Src: 172.16.1.113
State: UP for 0d:0h:4m:3s, number of times UP: 1
Session type: PR/V4/SH
Received parameters:
Version: 1, desired tx interval: 1 s, required rx interval: 1 s
Required echo rx interval: 100 ms, multiplier: 3, diag: None
My discr: 2, your discr: 2148007941, state UP, D/F/P/C/A: 0/0/0/0/0
Transmitted parameters:
Version: 1, desired tx interval: 2 s, required rx interval: 2 s
Required echo rx interval: 1 ms, multiplier: 3, diag: None
My discr: 2148007941, your discr: 2, state UP, D/F/P/C/A: 0/0/0/1/0
Timer Values:
Local negotiated async tx interval: 2 s
Remote negotiated async tx interval: 2 s
Desired echo tx interval: 150 ms, local negotiated echo tx interval: 150 ms
Echo detection time: 450 ms(150 ms*3), async detection time: 6 s(2 s*3)
Local Stats:
Intervals between async packets:
Tx: Number of intervals=100, min=1665 ms, max=1991 ms, avg=1832 ms
Last packet transmitted 1573 ms ago
Rx: Number of intervals=100, min=1510 ms, max=1992 ms, avg=1748 ms
Last packet received 691 ms ago
Intervals between echo packets:
Tx: Number of intervals=50, min=7701 ms, max=7701 ms, avg=7701 ms
Last packet transmitted 69 ms ago
Rx: Number of intervals=50, min=7700 ms, max=7702 ms, avg=7700 ms
Last packet received 68 ms ago
Latency of echo packets (time between tx and rx):
Number of packets: 100, min=0 us, max=2 ms, avg=530 us
Session owner information:
Desired Adjusted
Client Interval Multiplier Interval Multiplier
-------------------- --------------------- ---------------------
ipv4_static 150 ms 3 2 s 3
ospf-1 100 ms 5 2 s 5
IPv6:
-----
I/f: GigabitEthernet0/2/0/0, Location: 0/2/CPU0
Dest: fe80::fefb:fbff:fe35:de71
Src: fe80::204:deff:fe51:cc70
State: UP for 0d:0h:4m:16s, number of times UP: 1
Session type: PR/V6/SH
Received parameters:
Version: 1, desired tx interval: 150 ms, required rx interval: 100 ms
Required echo rx interval: 0 us, multiplier: 3, diag: None
My discr: 1, your discr: 2148007938, state UP, D/F/P/C/A: 0/0/0/0/0
Transmitted parameters:
Version: 1, desired tx interval: 250 ms, required rx interval: 250 ms
Required echo rx interval: 0 us, multiplier: 4, diag: None
My discr: 2148007938, your discr: 1, state UP, D/F/P/C/A: 0/0/0/1/0
Timer Values:
Local negotiated async tx interval: 250 ms
Remote negotiated async tx interval: 250 ms
Desired echo tx interval: 0 s, local negotiated echo tx interval: 0 s
Echo detection time: 0 s(0 s*4), async detection time: 750 ms(250 ms*3)
Local Stats:
Intervals between async packets:
Tx: Number of intervals=100, min=211 ms, max=251 ms, avg=228 ms
Last packet transmitted 7 ms ago
Rx: Number of intervals=100, min=191 ms, max=252 ms, avg=221 ms
Last packet received 135 ms ago
Intervals between echo packets:
Tx: Number of intervals=0, min=0 s, max=0 s, avg=0 s
Last packet transmitted 0 s ago
Rx: Number of intervals=0, min=0 s, max=0 s, avg=0 s
Last packet received 0 s ago
Latency of echo packets (time between tx and rx):
Number of packets: 0, min=0 us, max=0 us, avg=0 us
Session owner information:
Desired Adjusted
Client Interval Multiplier Interval Multiplier
-------------------- --------------------- ---------------------
ospfv3-1 150 ms 4 250 ms 4
Label:
------
------
Sulla base della configurazione effettuata, i due router stabiliscono due sessioni BFD, una per IPv4 (protocolli Client OSPFv2 e Route Statica) e una per IPv6 (protocollo Client OSPFv3).
Vediamo dapprima le caratteristiche della sessione BFD per IPv4. Prima considerazione: l'IOS e IOS XR, per la sessione BFD IPv4, utilizzano di default la funzione eco. Ciò si evince ad esempio dal comando "show bfd neighbors detail" sul router PE1-1, dove alla terza riga si legge: "Session state is UP and using echo function with 150 ms interval.". Il periodo dei messaggi BFD ECO (= 150 ms) coincide con il valore di configurazione "bfd interval <valore-in-ms> ...", definito a livello interfaccia. L'Holdtime (non riportato nella visualizzazione IOS) è pari 150*3 = 450 ms, dove 3 è il valore di Detect Mult configurato nel comando "bfd ... multiplier <valore-Detect-Mult>".
La funzione eco può essere disabilitata sia per l'IOS, con il comando a livello interfaccia "no bfd echo", che per l'IOS XR con il comando "echo disable" all'interno della configurazione del protocollo BFD:
RP/0/0/CPU0:PE1-3#(config)# bfd
RP/0/0/CPU0:PE1-3#(config-bfd)# echo disable
Seconda considerazione: l'IOS e IOS XR utilizzano valori di default diversi per il periodo di trasmissione dei messaggi BFD HELLO (che, ricordiamo, vengono scambiati comunque, ma molto più lentamente). L'IOS utilizza il valore di default 1 sec, l'IOS XR il valore 2 sec. Questo si evince dalla sesta e settima riga del comando "show bfd neighbors detail" sul router PE1-1:
MinTxInt: 1000000, MinRxInt: 1000000, Multiplier: 3
Received MinRxInt: 2000000, Received Multiplier: 3
dove MinTxInt è il valore del Desired Min TX Interval (= 1000000 microsec = 1 sec), MinRxInt è il valore del Required Min RX Interval (= 1000000 microsec = 1 sec). Il valore di Detec Mult è pari a 3 (valore impostato su base configurazione). Il valore negoziato di periodo dei messaggi BFD HELLO è 2 sec (il valore massimo tra i due). Nell'IOS il valore del periodo dei messaggi BFD HELLO può essere variato con il comando globale "bfd slow timers <valore>". Non ho trovato un comando analogo nell'IOS XR.
Il comando IOS XR "show bfd all session detail" mette in evidenza sia i timer ricevuti che quelli inviati e i valori del periodo dei messaggi BFD HELLO negoziati sia locale che remoto.
Il comando IOS XR "show bfd all session detail" mette in evidenza sia i timer ricevuti che quelli inviati e i valori del periodo dei messaggi BFD HELLO negoziati sia locale che remoto.
Received parameters:
Version: 1, desired tx interval: 1 s, required rx interval: 1 s
Required echo rx interval: 100 ms, multiplier: 3, diag: None
My discr: 3, your discr: 2148007941, state UP, D/F/P/C/A: 0/0/0/0/0
Transmitted parameters:
Version: 1, desired tx interval: 2 s, required rx interval: 2 s
Required echo rx interval: 1 ms, multiplier: 3, diag: None
My discr: 2148007941, your discr: 3, state UP, D/F/P/C/A: 0/0/0/1/0
Timer Values:
Local negotiated async tx interval: 2 s
Remote negotiated async tx interval: 2 s
Si noti che nei parametri ricevuti e inviati sono specificati tutti i campi dei messaggi BFD HELLO, incluso lo stato della sessione BFD (= UP) e le varie flag presenti (D/F/P/C/A). E' interessante il valore della flag C, posto a 1 dal GSR12k e a 0 dal 3825. Questo indica che il GSR 12k elabora i messaggi BFD a livello di linecard, mentre il 3825 li elabora a livello di CPU.
Vediamo infine come viene determinato il valore del periodo dei messaggi BFD ECO. Abbiamo già visto quello su PE1-1, pari a 150 ms.
Prima di vedere come viene determinato su PE1-3, dobbiamo innanzitutto porci una domanda. Poiché la sessione BFD IPv4 è unica e ha due protocolli Client (OSPFv2 e route statica), che utilizzano timer e Detect Mult diversi, quali valori vengono utilizzati per determinare il periodo dei messaggi BFD ECO ? Si noti che questo problema per l'IOS non si pone poiché tutti i protocolli Client che utilizzano la stessa interfaccia utilizzano gli stessi timer e Detect Mult. Bene, l'IOS XR adotta un approccio secondo il quale vengono utilizzati i timer più aggressivi. La frase è un po' sibillina, ma questo è quanto riporta la documentazione Cisco dell'IOS XR versione 4.3: "When multiple applications share the same BFD session, the application with the most aggressive timer wins locally".
Ho fatto molte prove per capire il senso di questa affermazione, e quello che ho dedotto è l'IOS XR fa un conticino molto semplice: per ciascun protocollo Client determina il valore (Local min TX interval)*(Local Detect Mult). L'IOS XR prende quindi il valore minore e utilizza per la determinazione del valore del periodo dei messaggi BFD ECO e il calcolo dell'Holdtime i timer e Detect Mult relativi. Ad esempio, applicando su PE1-3 questo metodo si ha:
- Client Route Statica : (Local min TX interval)*(Local Detect Mult) = 150*3 = 450 ms
- Client OSPFv2 : (Local min TX interval)*(Local Detect Mult) = 100*5 = 500 ms
Poiché 450 < 500, PE1-3 utilizza un periodo di 150 ms per il periodo dei messaggi BFD ECO e di 450 ms per l'Holdtime. Ciò può essere verificato dalla visualizzazione riportata sopra (NOTA: l'Holdtime dei messaggi BFD HELLO è invece 2*3 = 6 sec):
Desired echo tx interval: 150 ms, local negotiated echo tx interval: 150 ms
Echo detection time: 450 ms(150 ms*3), async detection time: 6 s(2 s*3)
Al di la di questa disquisizione, ritengo opportuno utilizzare per tutti i protocolli Client gli stessi timer e Detect Mult, lasciando l'utilizzo di valori diversi solo a casi molto particolari.
Infine, l'ultima parte della visualizzazione del comando "show bfd all session detail" su PE1-3 mostra i protocolli Client della sessione BFD per IPv4: OSPFv2 e la route statica IPv4.
Session owner information:
Desired Adjusted
Client Interval Multiplier Interval Multiplier
-------------------- --------------------- ---------------------
ipv4_static 150 ms 3 2 s 3
ospf-1 100 ms 5 2 s 5
La stessa informazione sul router PE1-1 si ha nella riga "Registered protocols: IPv4 Static OSPF".
Mi sono divertito ad un certo punto ad abilitare la funzionalità di sicurezza unicast RPF sull'interfaccia Gi0/1 del router PE1-1, con il comando:
PE1-1(config)#interface GigabitEthernet0/1
PE1-1(config-if)#ip verify unicast source reachable-via rx
Ecco quello che è successo:
PE1-1(config-if)#
*Oct 16 10:22:35.407: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from FULL to DOWN, Neighbor Down: BFD node down
*Oct 16 10:22:39.459: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from LOADING to FULL, Loading Done
PE1-1(config-if)#
*Oct 16 10:22:42.499: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from FULL to DOWN, Neighbor Down: BFD node down
*Oct 16 10:22:48.987: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from LOADING to FULL, Loading Done
*Oct 16 10:22:55.835: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from FULL to DOWN, Neighbor Down: BFD node down
*Oct 16 10:22:58.159: %OSPF-5-ADJCHG: Process 1, Nbr 192.168.0.13 on GigabitEthernet0/1 from LOADING to FULL, Loading Done
ossia un continuo up/down dell'adiacenza OSPF e della sessione BFD. Questo accade perché, come detto nel Post precedente sul BFD, la funzione eco è incompatibile con la funzionalità uRPF.
Vediamo ora le caratteristiche della sessione BFD per IPv6. La prima cosa da notare è che IOS e IOS XR per le sessioni BFD IPv6 non utilizzano la funzione eco, ma la semplice modalità asincrona. Si noti che i messaggi BFD HELLO utilizzano come indirizzi IPv6 sorgente e destinazione degli indirizzi link-local:
IPv6:
-----
I/f: GigabitEthernet0/2/0/0, Location: 0/2/CPU0
Dest: fe80::fefb:fbff:fe35:de71
Src: fe80::204:deff:fe51:cc70
Vediamo ora, dal punto di vista di PE1-3, la negoziazione dei timer e la determinazione dell'Holdtime (= detection time). I risultati si evincono dalla visualizzazione del comando "show bfd all session detail":
Timer Values:
Local negotiated async tx interval: 250 ms
Remote negotiated async tx interval: 250 ms
Desired echo tx interval: 0 s, local negotiated echo tx interval: 0 s
Echo detection time: 0 s(0 s*4), async detection time: 750 ms(250 ms*3)
Anche qui, ho scoperto una curiosità. Mi aspettavo infatti, su PE1-3, un valore del periodo negoziato dei messaggi BFD HELLO di 150 ms, ossia il valore massimo tra il Desired Min TX Interval (= 150 ms) locale e Required Min RX Interval ricevuto da PE1-1 (= 100 ms). Invece mi sono ritrovato come valore negoziato 250 ms. Dopo un po' di prove ho scoperto che l'IOS XR, per valori di "minimum interval" configurati, inferiori a 250 ms, aggiusta comunque il valore a 250 ms. Questo si evince dalla parte finale della visualizzazione del comando "show bfd all session detail":
Session owner information:
Desired Adjusted
Client Interval Multiplier Interval Multiplier
-------------------- --------------------- ---------------------
ospfv3-1 150 ms 4 250 ms 4
Il valore di Holdtime è quindi 250*3 = 750 ms (ricordiamo che nel calcolo viene utilizzato il valore di Detect Mult ricevuto, pari a 3, vedi Post precedente). Per contro, lasciamo al lettore verificare che il valore del periodo dei messaggi BFD HELLO e di Holdtime determinati da PE1-1 sono rispettivamente 250 ms e 250*4 = 1000 ms.
Questo completa le mie considerazioni sull'implementazione Cisco del BFD. Vi sarebbero molte altre cose da dire, ma il Post diventerebbe chilometrico. Quanto riportato sopra si concentra sugli aspetti più importanti e più utili per le applicazioni pratiche. Argomenti come l'autenticazione dei messaggi, il BFD damping (molto simile al BGP Route Flap damping), il BFD nei collegamenti bundle, ecc. sono stati volutamente tralasciati. Eventualmente ci tornerò in futuro con qualche altro Post. Chi invece vorrà cimentarsi con l'esame di certificazione CCIE dovrà necessariamente approfondire tutti gli aspetti di configurazione (nell'IOS o IOS XR, in funzione del tipo di certificazione).
IMPLEMENTAZIONE JUNIPER
Fortunatamente tutte le piattaforme Juniper sono basate sullo stesso sistema operativo, il JUNOS, e quindi questo renderà la trattazione più breve (NOTA: non considererò piattaforme basate sul JUNOSe, che comunque ha una CLI simile a quella Cisco).
La prima considerazione da fare circa l'implementazione BFD del JUNOS, è che non supporta la funzione eco (almeno fino alla release 14.1), ma solo la modalità asincrona. Il BFD è supportato per tutti i principali protocolli di routing IPv4/IPv6 (RIP, OSPF, IS-IS, BGP, PIM), per le route statiche IPv4/IPv6, per i tunnel MPLS-TE, ecc.(anche qui, per eventuali restrizioni è sempre comunque opportuno verificare la documentazione relativa alla versione JUNOS che si sta utilizzando).
Un aspetto interessante del JUNOS riguarda la gestione dei timer. Dopo la negoziazione iniziale, che segue le regole esposte nel Post precedente, i timer vengono gestiti in modo adattativo, ossia il JUNOS varia i timer in funzione delle condizioni del collegamento. Il meccanismo è assolutamente automatico e non ha bisogno di alcuna configurazione, e può essere solo disabilitato (ma è sconsigliato !). Ad esempio, quando vi sono più di tre passaggi up/down in 15 secondi della sessione BFD, i timer associati ai messaggi BFD HELLO aumentano automaticamente.
Le considerazioni fatte sugli indirizzi IP sorgente/destinazione dei messaggi BFD HELLO e le porte utilizzate nei router Cisco valgono anche per i router Juniper.
La configurazione del BFD avviene all'interno del protocollo Client con il comando seguente (di cui riportiamo le sole opzioni più importanti):
bfd-liveness-detection {
minimum-interval <valore-in-msec>;
minimum-receive-interval <valore-in-msec>;
multiplier <numero-intero>;
no-adaptation;
version (1 | automatic);
}
Il valore di Required Min RX Interval definito con il comando "minimum-receive-interval <valore-in-msec>", se non specificato esplicitamente viene preso identico al valore configurato nel comando "minimum-interval <valore-in-msec>". Il comando "no-adaptation" disabilita la gestione adattativa dei timer (ma, come detto sopra, è bene lasciarla attiva). Infine, il comando "version (1 | automatic)" consente di specificare la versione del BFD (tipicamente la 1), o lasciarne la determinazione automatica.
Passiamo ora alle prove di laboratorio. Nelle prove che ho effettuato mi sono avvalso di due router J2350 con il JUNOS 10.4R9.2.
Lo schema della rete di prova è analogo a quello utilizzato sopra per l'ambiente Cisco ed è riportato nella figura seguente:
Anche qui, poiché la configurazione del BFD associato al protocollo BGP è già stata vista nel precedente Post sulla convergenza del BGP (Parte I), ho attivato sul collegamento un'adiacenza OSPFv2, una OSPFv3 e ho configurato due route statiche (IPv4) per mettere in comunicazione le due interfacce Loopback 0 tra i due router. Per cercare di rendere la prova più interessante ho utilizzato valori dei timer BFD e del Detect Mult diversi. Queste sono le configurazioni rilevanti utilizzate:
[edit]
tt@P1# show routing-options
static {
route 192.168.1.2/32 {
next-hop 172.30.1.2;
bfd-liveness-detection {
minimum-interval 250;
multiplier 5;
local-address 172.30.1.1;
}
}
}
[edit]
tt@P1# show protocols
ospf {
area 0.0.0.0 {
interface ge-0/0/0.0 {
bfd-liveness-detection {
minimum-interval 150;
minimum-receive-interval 100;
multiplier 3;
}
}
}
}
ospf3 {
area 0.0.0.0 {
interface ge-0/0/0.0 {
bfd-liveness-detection {
minimum-interval 100;
minimum-receive-interval 200;
multiplier 5;
}
}
}
}
[edit]
tt@P2# show routing-options
static {
route 192.168.1.1/32 {
next-hop 172.30.1.1;
bfd-liveness-detection {
minimum-interval 250;
multiplier 3;
local-address 172.30.1.2;
}
}
}
tt@P2# show protocols
ospf {
area 0.0.0.0 {
interface ge-0/0/0.0 {
bfd-liveness-detection {
minimum-interval 100;
minimum-receive-interval 200;
multiplier 5;
}
}
}
}
ospf3 {
area 0.0.0.0 {
interface ge-0/0/0.0 {
bfd-liveness-detection {
minimum-interval 150;
minimum-receive-interval 100;
multiplier 3;
}
}
}
}
Vediamo ora il risultato della configurazione. Per questo il JUNOS ha il comando "show bfd session [detail | extensive]". (NOTA: per tutte le altre opzioni disponibili rimandiamo alla documentazione JUNOS).
Vediamo l'esecuzione del comando con l'opzione "extensive" dapprima sul router P1.
tt@P1> show bfd session extensive
Detect Transmit
Address State Interface Time Interval Multiplier
172.30.1.2 Up ge-0/0/0.0 0.500 0.200 3
Client Static, TX interval 0.250, RX interval 0.250
Client OSPF realm ospf-v2 Area 0.0.0.0, TX interval 0.150, RX interval 0.100
Session up time 00:00:05, previous down time 00:00:01
Local diagnostic CtlExpire, remote diagnostic CtlExpire
Remote state Up, version 1
Min async interval 0.150, min slow interval 1.000
Adaptive async TX interval 0.150, RX interval 0.100
Local min TX interval 0.150, minimum RX interval 0.100, multiplier 3
Remote min TX interval 0.100, min RX interval 0.200, multiplier 5
Local discriminator 1, remote discriminator 1
Echo mode disabled/inactive
Detect Transmit
Address State Interface Time Interval Multiplier
fe80::226:88ff:fefa:8a80 Up ge-0/0/0.0 0.600 0.100 5
Client OSPF realm ipv6-unicast Area 0.0.0.0, TX interval 0.100, RX interval 0.200
Session up time 00:00:05, previous down time 00:00:01
Local diagnostic CtlExpire, remote diagnostic CtlExpire
Remote state Up, version 1
Min async interval 0.100, min slow interval 1.000
Adaptive async TX interval 0.100, RX interval 0.200
Local min TX interval 0.100, minimum RX interval 0.200, multiplier 5
Remote min TX interval 0.150, min RX interval 0.100, multiplier 3
Local discriminator 3, remote discriminator 3
Echo mode disabled/inactive
2 sessions, 3 clients
Cumulative transmit rate 15.0 pps, cumulative receive rate 15.0 pps
Dalla visualizzazione si vede che la sessione BFD IPv4 è regolarmente nello stato "up", che l'indirizzo del BFD peer è 172.30.1.2 (che P1 rileva dall'indirizzo IP sorgente dei messaggi BFD HELLO ricevuti), l'interfacia locale che riceve i messaggi BFD HELLO è la ge-0/0/0 e infine vi sono i timer negoziati (di cui darò conto a breve). Lo stesso dicasi per la sessione BFD IPv6, dove però l'indirizzo del BFD peer è l'indirizzo IPv6 link-local fe80::2a8a:1cff:fe46:5940.
Altre informazioni che è possibile dedurre dalla visualizzazione sono che la sessione BFD IPv4 ha due protocolli Client, la route statica e OSPFv2:
Client Static, TX interval 0.250, RX interval 0.250
Client OSPF realm ospf-v2 Area 0.0.0.0, TX interval 0.150, RX interval 0.100
e che la versione di protocollo utilizzata è la 1.
Remote state Up, version 1
La sessione BFD IPv6 ha invece un solo protocollo Client, OSPFv3:
Client OSPF realm ipv6-unicast Area 0.0.0.0, TX interval 0.100, RX interval 0.200
Lo stesso comando eseguito sul router P2 da i seguenti risultati:
tt@P2> show bfd session extensive
Detect Transmit
Address State Interface Time Interval Multiplier
172.30.1.1 Up ge-0/0/0.0 0.600 0.100 5
Client Static, TX interval 0.250, RX interval 0.250
Client OSPF realm ospf-v2 Area 0.0.0.0, TX interval 0.100, RX interval 0.200
Session up time 00:04:28, previous down time 00:00:00
Local diagnostic CtlExpire, remote diagnostic CtlExpire
Remote state Up, version 1
Min async interval 0.100, min slow interval 1.000
Adaptive async TX interval 0.100, RX interval 0.200
Local min TX interval 0.100, minimum RX interval 0.200, multiplier 5
Remote min TX interval 0.150, min RX interval 0.100, multiplier 3
Local discriminator 1, remote discriminator 1
Echo mode disabled/inactive
Detect Transmit
Address State Interface Time Interval Multiplier
fe80::2a8a:1cff:fe46:5940 Up ge-0/0/0.0 0.500 0.200 3
Client OSPF realm ipv6-unicast Area 0.0.0.0, TX interval 0.150, RX interval 0.100
Session up time 00:04:27, previous down time 00:00:01
Local diagnostic CtlExpire, remote diagnostic CtlExpire
Remote state Up, version 1
Min async interval 0.150, min slow interval 1.000
Adaptive async TX interval 0.150, RX interval 0.100
Local min TX interval 0.150, minimum RX interval 0.100, multiplier 3
Remote min TX interval 0.100, min RX interval 0.200, multiplier 5
Local discriminator 3, remote discriminator 3
Echo mode disabled/inactive
2 sessions, 3 clients
Cumulative transmit rate 15.0 pps, cumulative receive rate 15.0 pps
Vediamo ora come sono stati negoziati su P1 i timer per la sessione BFD IPv4 (le analoghe considerazioni su P2 sono lasciate come esercizio !).
Analogamente a quanto fatto per l'IOS XR, innanzitutto dobbiamo porci una domanda. Poiché la sessione BFD IPv4 è unica e ha due protocolli Client, che utilizzano timer e Detect Mult diversi, quali valori vengono comunicati al BFD peer con i messaggi BFD HELLO ? Bene, il JUNOS adotta un approccio secondo il quale vengono comunicati i timer più aggressivi. Ma come si determinano i timer più aggressivi ? Il JUNOS fa lo stesso conticino già visto per l'IOS XR: per ciascun protocollo Client determina il valore (Local min TX interval)*(Local Detect Mult). Il JUNOS prende quindi il valore minore e comunica al BFD peer i timer e Detect Mult relativi. Ad esempio, applicando su P1 questo metodo si ha:
Client OSPFv2 : (Local min TX interval)*(Local Detect Mult) = 150*3 = 450 ms
Client Route Statica : (Local min TX interval)*(Local Detect Mult) = 250*5 = 1250 ms
Poiché 450 < 1250, P1 comunica al BFD peer P2 i seguenti timer e Detect Mult:
Desired min TX interval = 150 ms
Required min RX interval = 100 ms
Detect Mult = 3
Ciò può essere verificato dal risultato del comando "show bfd session extensive" su P1 e P2:
Su P1 : Local min TX interval 0.150, minimum RX interval 0.100, multiplier 3
Su P2 : Remote min TX interval 0.150, min RX interval 0.100, multiplier 3
Lo stesso identico ragionamento eseguito su P2 porta a concludere che i timer e Detect Mult comunicati da P2 a P1 attraverso i messaggi BFD HELLO sono (i dettagli sono lasciati al lettore):
Desired min TX interval = 100 ms
Required min RX interval = 200 ms
Detect Mult = 5
Ciò può essere verificato dal risultato del comando "show bfd session extensive" su P1 e P2:
Su P1 : Remote min TX interval 0.100, min RX interval 0.200, multiplier 5
Su P2 : Local min TX interval 0.100, minimum RX interval 0.200, multiplier 5
Ora, la determinazione del periodo di trasmissione dei messaggi BFD HELLO (indicato nelle visualizzazioni sopra come "Transmit Interval") segue le regole già ampiamente esposte:
Su P1: Transmit Interval = max[Desired min TX interval locale, Required min RX interval remoto] = max[150,200] = 200 ms
Su P2: Transmit Interval = max[Desired min TX interval locale, Required min RX interval remoto] = max[100,100] = 100 ms
Anche la determinazione dell'Holdtime (indicato nelle visualizzazioni sopra come "Detect Time"), segue le regole già ampiamente esposte:
Su P1: Detect Time = Transmit Interval di P2 * Detect Mult di P2 = 100*5 = 500 ms = 0.500 sec
Su P2: Detect Time = Transmit Interval di P1 * Detect Mult di P1 = 200*3 = 600 ms = 0.600 sec
Per la sessione BFD IPv6 i timer sono di più facile determinazione poiché il protocollo Client è unico (OSPFv3). Il periodo negoziato dei messaggi BFD HELLO su P1 è 100 ms (= max[100, 100]) mentre su P2 è 200 ms (= max[150, 200]).
I valori di Holdtime sono quindi rispettivamente:
Su P1: 200*3 = 600 ms (= Trasmit Interval di P2 * Detec Mult di P2).
Su P2: 100*5 = 500 ms (= Trasmit Interval di P1 * Detec Mult di P1).
E qui concludo questo Post. Le cose da dire sarebbero ancora molte ma non vorrei essere troppo noioso. Magari in seguito tornerò su qualche altra applicazione del BFD, se ne varrà la pena.
CONCLUSIONI
Le implementazioni Cisco e Juniper del BFD, benché conformi alle RFC, utilizzano default diversi e di questo è necessario tener conto in caso di interlavoro tra piattaforme eterogenee.
L'implementazione Cisco è fortemente dipendente dal sistema operativo utilizzato, sia nello stile di configurazione che nei valori di default. Tra l'altro vi sono default diversi per il BFD IPv4 e quello IPv6.
L'implementazione Juniper, grazie al fatto che tutte le piattaforme Juniper sono basate sul JUNOS (a parte quelle che utilizzano il JUNOSe, ma sono una minoranza), è molto più omogenea.