College Online
0%

Roteamento

Modulo 4 · Aula 2 ~25 min de leitura Nivel: Intermediario

Video da aula estara disponivel em breve

O que e roteamento?

Roteamento é o processo de determinar o caminho que um pacote deve seguir da origem ao destino, atravessando múltiplos roteadores. Cada roteador mantém uma tabela de roteamento que indica, para cada destino, qual é o próximo salto (next hop). É importante distinguir: forwarding (plano de dados) é a ação de mover um pacote de uma interface de entrada para uma de saída; routing (plano de controle) é o processo de construir a tabela que determina para onde o forwarding envia.

Tabelas de roteamento

Diagrama
Exemplo de tabela de roteamento:

Destino          Mascara          Next Hop        Interface
──────────────   ──────────────   ────────────    ─────────
192.168.1.0      255.255.255.0    diretamente     eth0
10.0.0.0         255.0.0.0        192.168.1.1     eth0
0.0.0.0          0.0.0.0          192.168.1.254   eth0  (default)

Algoritmo de forwarding:
  1. Recebe pacote com IP destino
  2. Procura o "longest prefix match" na tabela
  3. Encaminha para o next hop correspondente
  4. Se nenhuma entrada corresponde: usa default route (0.0.0.0/0)

Algoritmos de roteamento

Link-state (estado de enlace)

Cada roteador conhece a topologia completa da rede. Usa o algoritmo de Dijkstra para calcular o caminho mais curto para todos os destinos.

Python
import heapq

def dijkstra(graph, start):
    """Algoritmo de Dijkstra para shortest path."""
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    previous = {node: None for node in graph}
    pq = [(0, start)]

    while pq:
        current_dist, current = heapq.heappop(pq)
        if current_dist > distances[current]:
            continue
        for neighbor, weight in graph[current].items():
            distance = current_dist + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                previous[neighbor] = current
                heapq.heappush(pq, (distance, neighbor))

    return distances, previous

# Topologia de rede (grafo ponderado)
network = {
    "R1": {"R2": 1, "R3": 4},
    "R2": {"R1": 1, "R3": 2, "R4": 6},
    "R3": {"R1": 4, "R2": 2, "R4": 3},
    "R4": {"R2": 6, "R3": 3},
}

dist, prev = dijkstra(network, "R1")
print("Distancias de R1:", dist)
# {'R1': 0, 'R2': 1, 'R3': 3, 'R4': 6}

Distance-vector (vetor de distâncias)

Cada roteador conhece apenas seus vizinhos diretos e as distâncias que eles anunciam. Usa o algoritmo de Bellman-Ford distribuído. Cada roteador envia sua tabela de distâncias aos vizinhos periodicamente.

Python
import copy

def bellman_ford_distributed(topology, max_iterations=10):
    """Simulação do algoritmo distance-vector distribuído.
    Cada router troca tabelas com vizinhos até convergir."""

    nodes = list(topology.keys())
    # Inicializa: cada node conhece distância 0 para si
    tables = {n: {n: 0} for n in nodes}

    for iteration in range(max_iterations):
        old_tables = copy.deepcopy(tables)

        for node in nodes:
            for neighbor, cost in topology[node].items():
                # Recebe tabela do vizinho
                for dest, dist in old_tables[neighbor].items():
                    new_dist = cost + dist
                    if dest not in tables[node] or new_dist < tables[node][dest]:
                        tables[node][dest] = new_dist

        if tables == old_tables:
            print(f"Convergiu na iteração {iteration + 1}")
            break

    return tables

network = {
    "R1": {"R2": 1, "R3": 4},
    "R2": {"R1": 1, "R3": 2, "R4": 6},
    "R3": {"R1": 4, "R2": 2, "R4": 3},
    "R4": {"R2": 6, "R3": 3},
}
tables = bellman_ford_distributed(network)
for node, table in tables.items():
    print(f"{node}: {table}")

Count-to-infinity e split horizon

O distance-vector sofre do problema count-to-infinity: quando um link falha, routers podem trocar informações desatualizadas indefinidamente, incrementando custos até infinito. Soluções:

Diagrama
Problema count-to-infinity:
  A ---[1]--- B ---[1]--- C
  Se link B-C cai, B acha que pode chegar a C via A (custo 3)
  A atualiza: custo para C = 4 (via B que diz 3 + 1)
  B atualiza: custo para C = 5 (via A que diz 4 + 1)
  ... loop infinito até atingir "infinito" (16 no RIP)

Soluções:
  Split horizon:    Não anunciar rota de volta para quem a ensinou
  Poison reverse:   Anunciar custo infinito de volta para o vizinho
  Triggered update: Enviar atualização imediata quando rota muda
  Hold-down timer:  Ignorar atualizações por T segundos após falha
Referencia
Link-state vs Distance-vector:

                    Link-state          Distance-vector
──────────────     ──────────────      ──────────────
Conhecimento        Topologia completa  Apenas vizinhos
Algoritmo           Dijkstra            Bellman-Ford
Convergencia        Rapida              Lenta (count-to-infinity)
Mensagens           Floods LSAs         Envia tabela aos vizinhos
Protocolo real      OSPF, IS-IS         RIP, EIGRP
Escalabilidade      Melhor              Pior em redes grandes

Protocolos de roteamento reais

OSPF (Open Shortest Path First)

Protocolo link-state usado dentro de sistemas autonomos (intra-AS). Cada roteador envia LSAs (Link State Advertisements) para construir um mapa completo da rede.

BGP (Border Gateway Protocol)

Protocolo path-vector usado entre sistemas autônomos (inter-AS). É o protocolo que "cola" a Internet — cada AS anuncia quais prefixos IP pode alcançar. BGP é o protocolo mais crítico da Internet e utiliza políticas de roteamento (não apenas menor custo) para decidir rotas.

Diagrama
        AS 1 (Google)          AS 2 (Amazon)
       ┌──────────────┐      ┌──────────────┐
       │  OSPF interno │      │  OSPF interno │
       │  R1──R2──R3   │      │  R4──R5──R6   │
       └──────┬───────┘      └──────┬───────┘
              │                      │
              └────── BGP ──────────┘
              (troca de rotas inter-AS)

BGP: "Eu (AS1) posso alcançar 172.217.0.0/16"
     "Eu (AS2) posso alcançar 54.239.0.0/16"

BGP path attributes (o que determina a melhor rota):
  1. LOCAL_PREF     Preferência local (maior = melhor)
  2. AS_PATH        Lista de ASes no caminho (menor = melhor)
  3. NEXT_HOP       Próximo roteador BGP
  4. MED            Multi-Exit Discriminator (sugestão do vizinho)

Diferença crucial: OSPF minimiza custo (shortest path)
                    BGP aplica POLÍTICAS (business relationships)
  - Customer → Provider (paga, recebe trânsito)
  - Peer → Peer (troca gratuita de tráfego)
  - Provider → Customer (oferece trânsito)

Longest prefix match em detalhes

O algoritmo longest prefix match é fundamental para o forwarding IP. Quando um roteador tem múltiplas entradas que correspondem ao destino, ele escolhe a mais específica (maior prefixo):

Python
import ipaddress

def longest_prefix_match(dest_ip, routing_table):
    """Implementa longest prefix match para forwarding IP."""
    dest = ipaddress.ip_address(dest_ip)
    best_match = None
    best_prefix_len = -1

    for network_str, next_hop in routing_table:
        network = ipaddress.ip_network(network_str)
        if dest in network and network.prefixlen > best_prefix_len:
            best_match = next_hop
            best_prefix_len = network.prefixlen

    return best_match, best_prefix_len

# Tabela de roteamento
table = [
    ("10.0.0.0/8",       "R1"),     # Rota genérica
    ("10.1.0.0/16",     "R2"),     # Mais específica
    ("10.1.1.0/24",     "R3"),     # Mais específica ainda
    ("0.0.0.0/0",       "default"), # Default route
]

# Teste: 10.1.1.50 corresponde a /8, /16 e /24 — qual ganha?
hop, prefix = longest_prefix_match("10.1.1.50", table)
print(f"10.1.1.50 → {hop} (prefix /{prefix})")  # R3 (/24 — mais longo)

hop, prefix = longest_prefix_match("10.2.0.1", table)
print(f"10.2.0.1  → {hop} (prefix /{prefix})")  # R1 (/8)

hop, prefix = longest_prefix_match("8.8.8.8", table)
print(f"8.8.8.8   → {hop} (prefix /{prefix})")  # default (/0)

No harness.os

Python
# Tabela de roteamento harness.os: concern -> agent
# Funciona como uma routing table onde "destino" e o concern

routing_table = {
    "governance":    {"agent": "governance-agent",  "priority": 1},
    "security":      {"agent": "security-agent",    "priority": 1},
    "causal":        {"agent": "build-agent",       "priority": 2},
    "relational":    {"agent": "knowledge-agent",   "priority": 2},
    "metacognitive": {"agent": "meta-agent",        "priority": 3},
    "*":             {"agent": "general-agent",     "priority": 99},  # default route
}

def route_request(concern: str) -> str:
    """Roteia um request para o agente correto baseado no concern."""
    if concern in routing_table:
        return routing_table[concern]["agent"]
    return routing_table["*"]["agent"]  # default route

print(route_request("governance"))    # governance-agent
print(route_request("unknown"))       # general-agent (default)

Resumo

Homework

Exercício 1: Construa uma routing table para harness.os que mapeia concerns para agentes especializados.

  1. Liste todos os 5 concerns e o agente responsável por cada um
  2. Adicione uma default route para concerns desconhecidos
  3. Implemente longest-prefix match: se concern é "security.mcp", match "security"
  4. Adicione métricas (latência, custo) e escolha a melhor rota

Exercício 2: Implemente o algoritmo de Dijkstra para uma rede com 6 roteadores. Desenhe a topologia, atribua pesos aos links, e calcule a árvore de caminhos mínimos a partir de cada roteador.

Exercício 3: Simule o problema count-to-infinity com 3 roteadores em linha (A-B-C). Remova o link B-C e mostre quantas iterações o distance-vector precisa para convergir. Implemente split horizon e compare.

Exercício 4: Pesquise um incidente real de BGP hijacking (ex: Pakistan YouTube 2008, ou Cloudflare 2019). Explique: o que aconteceu, por que BGP permitiu, e como poderia ser prevenido (RPKI).

Verifique seu entendimento

Qual algoritmo e usado pelo protocolo OSPF para calcular o caminho mais curto?

  • Dijkstra (shortest path first)
  • Bellman-Ford
  • Floyd-Warshall
  • Round-robin

Verifique seu entendimento

Um roteador tem estas entradas na tabela: 10.0.0.0/8 → R1, 10.1.0.0/16 → R2, 10.1.1.0/24 → R3. Para qual next hop vai um pacote destinado a 10.1.1.50?

  • R1 (porque 10.0.0.0/8 é a primeira entrada na tabela)
  • R2 (porque 10.1.0.0/16 é mais genérica)
  • R3 (porque 10.1.1.0/24 é o longest prefix match — prefixo mais longo)
  • Descartado (nenhuma rota corresponde)

Verifique seu entendimento

Qual é a principal diferença entre OSPF e BGP?

  • OSPF é mais rápido que BGP
  • OSPF é intra-AS (dentro de uma rede, otimiza custo); BGP é inter-AS (entre redes, usa políticas de negócio)
  • BGP usa Dijkstra e OSPF usa Bellman-Ford
  • OSPF é para redes sem fio e BGP é para redes cabeadas