A verdade salto a salto
Sua ferramenta de caminhos desenha um corredor. Roteadores encaminham salto a salto. Aqui está a medição dessa diferença em 4.032 pares.
Michel Wijnberg
Quase toda ferramenta de caminho de rede que eu já usei (inclusive a minha, até pouco tempo atrás) funciona assim:
- Pega o roteador de origem.
- Roda Dijkstra sobre a topologia.
- Desenha o caminho mais curto que sair dali.
Isso é um corredor enraizado na origem, e é um modelo sutilmente errado do encaminhamento IP. O encaminhamento real não tem corredor. Cada roteador compara de forma independente o endereço de destino com a própria tabela de roteamento e escolhe um próximo salto. As duas respostas só coincidem enquanto a regra de decisão e o conjunto de entrada de cada roteador intermediário coincidirem com os da origem.
Em OSPF, rotineiramente não coincidem.
Um pacote que nunca chega
Este é um caso do meu laboratório, medido em cada roteador envolvido com
show ip route, lido dos equipamentos e não modelado:
| Roteador | O que diz sobre o destino | Encaminha para |
|---|---|---|
dfw1-gw2 | metric 20031, type inter area | dfw1-cr1 |
dfw1-cr1 | metric 30001, type intra area | ord1-cr1 ← não dfw2-cr1 |
ord1-cr1 | metric 20001, type intra area | jfk1-cr1 |
jfk1-cr1 | metric 10001, type intra area | lhr1-cr1 |
lhr1-cr1 | metric 1, connected | entregue |
O corredor enraizado na origem desenhou isto:
dfw1-gw2 → dfw1-cr1 → dfw2-cr1 → iad2-cr1 → ams1-cr1 → lhr1-cr1
O pacote nunca chega a dfw2-cr1. O corredor é um caminho mais barato. Ele só não é
um caminho que roteador nenhum vai construir. Duas regras independentes da RFC 2328
fazem dfw1-cr1 recusá-lo:
§16 passo (3) / §16.2 ¶1: o portão do backbone. Um roteador ligado a várias áreas
examina apenas os summary-LSAs do backbone. O summary mais barato de dfw2-cr1, de
custo 20011, está genuinamente no banco de dados da área 4.6.23.0 de dfw1-cr1
(confirmei com show ip ospf database summary), mas não é um candidato, porque
dfw1-cr1 é um ABR e aquele summary não chegou pela área 0. A RFC 3509 §2.1/§2.2 (o
comportamento de ABR da Cisco que de fato roda nesses equipamentos) condiciona isso a
haver uma conexão ativa com o backbone, que dfw1-cr1 tem.
§16.2 passo (6): intra ganha de inter, ponto final. “If the paths present in the
table are intra-area paths, do nothing with the LSA (intra-area paths are always
preferred).” dfw1-cr1 já tem um caminho intra-área com métrica 30001. O summary de
20011 perde para ele. A métrica é irrelevante: esta é uma regra sobre o tipo de
caminho, e a comparação de custo nunca acontece.
Qualquer uma das duas regras, sozinha, mata o corredor. Uma ferramenta que roda um
único SPF a partir da origem não enxerga nenhuma das duas, porque nunca pergunta a
dfw1-cr1 o que dfw1-cr1 pensa.
Com que frequência isso importa de verdade?
Esta é a parte com que eu me importo, porque “seu modelo é teoricamente impreciso” é uma afirmação muito mais fraca do que um número.
Então li a tabela de roteamento OSPF completa dos 64 roteadores do AS 200 e comparei cada um dos 4.032 pares ordenados origem/destino:
| Medição | Resultado |
|---|---|
| Pares interárea em que o corredor desenhou ≥1 salto que roteador nenhum tomaria | 360 de 2.839 (12,68%) |
| Pares intra-área com o mesmo defeito | 0 de 1.193 |
| Geral | 360 de 4.032 (8,93%) |
O zero de intra-área é o teste de sanidade. Dentro de uma única área, todo roteador roda SPF sobre um LSDB idêntico, e um caminho mais curto continua sendo o mais curto a partir de qualquer ponto ao longo dele, então os dois modelos têm todos os motivos para coincidir. O ponto é que a coincidência foi medida, e não presumida: 1.193 pares, nenhuma discordância. No instante em que um ABR e um summary-LSA entram em cena, um caminho em cada oito é ficção.
Não “levemente subótimo”. Ficção, contendo um roteador que o pacote comprovadamente nunca visita. Se você está usando esse caminho para planejar uma janela de manutenção ou para explicar um incidente, está raciocinando sobre uma rota que não existe.
A correção: perguntar a cada roteador
O Osprey agora percorre a cadeia. A cada salto ele avalia a rota que aquele roteador instalou em direção ao endereço de destino, usando o LSDB daquele roteador, as próprias associações de área dele, o próprio status de ABR dele e a própria mistura de distâncias administrativas dele; depois segue o próximo salto que ele de fato seleciona, e repete.
Validado contra os mesmos 4.032 pares:
| Verificação | Resultado |
|---|---|
| Métrica do próprio roteador reproduzida exatamente | 4.032 / 4.032 |
| Tipo de caminho (intra / inter / externo) exato | 4.032 / 4.032 |
| Conjunto completo de próximos saltos ECMP instalados idêntico | 4.032 / 4.032 |
A cadeia termina em delivered no destino solicitado | 4.032 / 4.032 |
Não “perto”. Idêntico, em cada par, incluindo o conjunto completo de próximos saltos de custo igual em vez de um membro escolhido arbitrariamente.
É assim que isso aparece na tela: caminho de ida em laranja, de volta em azul, e tudo que não está no caminho esmaecido até virar um corredor:
Repare no seletor 4 equal-cost paths e no rótulo per-flow hash. O Osprey enumera o
conjunto ECMP completo em vez de escolher um membro e apresentá-lo como o caminho,
porque seu tráfego é distribuído por hash entre os quatro, e uma sessão de diagnóstico que
examine apenas um deles não vai achar nada de errado em três de cada quatro vezes.
E aqui está o mesmo caminho aberto:
Cada salto carrega o roteador que tomou a decisão, a área em que a tomou, as interfaces
físicas de entrada e saída com seus endereços, e o custo. Os selos ABR são derivados dos
LSDBs, e não de nomes de host. A faixa de áreas embaixo mostra o caminho cruzando
12.1.24.0 → 0.0.0.0 → 6.18.1.0, que é o trânsito pelo backbone exigido pela RFC 2328
para tráfego interárea.
E o custo total exibido, 30061, é a métrica que a própria origem tem instalada. É
literalmente o número que o show ip route imprime em lax1-gw1, custo de stub incluído,
e não uma soma que o Osprey calculou juntando os enlaces de que gostou.
A explicação é gerada, não decorativa:
- Route type: O IA (inter-area): Source 172.16.2.33 and destination 172.16.5.23 have no shared area, routing via backbone (area 0.0.0.0)
- Path traverses: area 12.1.24.0 (cost 10) → area 0.0.0.0 (cost 30040) → area 6.18.1.0 (cost 10)
- Total cost: 30061 via 10 hops
- ECMP: 4 equal-cost paths available
Atravessando a fronteira do AS
Dentro de um IGP a cadeia é computável porque o LSDB é completo. Atravessando uma fronteira de AS, nada é. Não há banco de dados compartilhado, não há espaço métrico compartilhado e não há política de distância administrativa compartilhada.
A resposta honesta não é desistir, e definitivamente não é fingir que as métricas se compõem. É emendar evidências.
Quinze saltos de lax1-gw1 no AS 200 (locatário Harrier-Broadband, OSPF) até i-sin1-gw1
no AS 300 (locatário Merlin-Carrier, IS-IS). Leia o que ele faz:
- O salto 8,
jfk1-gw1, traz um seloBGP: é aqui que o IGP para e a decisão do BGP assume. - O salto 9,
i-jfk1-gw1, traz um seloIS-IS: um protocolo completamente diferente, outro plano de endereçamento, outro locatário. - O rodapé diz “Per-segment costs (never summed) | 15 hops”. Um custo OSPF de 20051 e um
custo IS-IS de 1320 são números em espaços métricos sem relação entre si. Somá-los daria
21371, que não é uma quantidade existente. O Osprey se recusa a imprimir isso.
A explicação gerada nomeia suas evidências a cada passo:
- BGP border selection:
jfk1-gw1holds 10.66.0.0/15 for 10.66.15.3 (AS path: 300)- AS 200: IGP segment:
lax1-gw1→jfk1-gw1, cost 20051- eBGP transition 200 → 300:
jfk1-gw1 Et1/1 → i-jfk1-gw1 Et1/2(bmp-peer+l2; ip-bound)- AS 300: IGP segment:
i-jfk1-gw1→i-sin1-gw1, cost 1320
O passo 3 é a minha linha favorita do produto. Ele não diz “esses dois roteadores provavelmente estão conectados de algum jeito”. Ele nomeia portas físicas nas duas pontas, e depois mostra o raciocínio dentro daquele parêntese:
bmp-peer: uma sessão eBGP estabelecida entre eles, vista via BMP+l2: o lado remoto foi casado através da adjacência LLDP/CDP dos roteadores de fronteiraip-bound: os dois endereços da sessão resolveram para aquelas portas específicas pelos vínculos da IP-MIB dos dispositivos
Três evidências independentes concordando. Quando elas não concordam, o produto diz isso, e esse é justamente o assunto do próximo texto.
Por que eu me importo mais com isso do que com recursos
Um desenho de caminho é uma afirmação sobre o que sua rede vai fazer com um pacote. Se a afirmação está errada uma vez em cada oito e nada na tela distingue as erradas das certas, o desenho é pior do que inútil. Ele é confiantemente inútil, e será acreditado exatamente no momento em que estar errado sai caro.
Sair de “plausível” para “reproduz exatamente as 64 tabelas de roteamento, 4.032 de 4.032” exigiu um arcabouço de validação, um laboratório do qual eu consigo ler a verdade de referência, e disposição para descobrir que a minha própria ferramenta vinha desenhando ficção 360 vezes.
É para isso que serve o laboratório.
A seguir, o outro lado da mesma moeda: os lugares onde o Osprey não consegue calcular a resposta, e diz isso: O que o Osprey se recusa a adivinhar.