Enrutamiento de políticas IPv6 cuando dos enlaces ascendentes comparten fe80::1
Dos enlaces ascendentes pueden presentar el mismo siguiente salto fe80::1 en enlaces distintos. Elija una tabla por política, asuma las duraciones y verifique con una consulta de ruta.
Tiene dos enlaces ascendentes, y ip -6 route show muestra el mismo siguiente salto en ambos: default via fe80::1 dev uplink0 y default via fe80::1 dev uplink1. No es un conflicto de direcciones duplicadas, y copiar el siguiente salto desnudo fe80::1 en una tabla de políticas no le dice al núcleo qué enlace quería decir. La pregunta real es más estrecha de lo que sugiere el síntoma: ¿la segunda tabla necesita un enlace o ambos, y qué mantiene vivas esas rutas tras un reinicio. Tres condiciones, comprobadas en orden, resuelven la mayor parte.
El mismo fe80::1 son dos vecinos distintos
Las direcciones link-local están limitadas a un solo enlace, así que fe80::1 no es una dirección impresa dos veces; son dos vecinos que casualmente comparten un sufijo. El índice de zona es cómo un host dice cuál quiere decir, así que fe80::1%uplink0 y fe80::1%uplink1 son destinos distintos para el núcleo, y ese sufijo nunca viaja hasta un enrutador remoto. RFC 4007 describe el modelo de zonas que hay detrás, y por eso una tabla de políticas debe llevar un dispositivo con cada siguiente salto link-local.
Un generador de configuración de VPN que copia un ID de zona numérico de un host a una plantilla trata el contexto local como si fuera parte de la dirección, y el archivo que escribe es incorrecto en cada máquina cuyos nombres o índices de interfaz difieren. Una tabla de políticas tampoco fusiona dos enlaces en uno: una VPN enrutada pasa paquetes entre redes, pero no transporta la identidad link-local de un vecino Ethernet remoto a través del túnel, así que el tráfico link-local se queda en su propio enlace.
Quite el dispositivo y la ruta deja de ser escribible. ip -6 route add default via fe80::1 table 200 no puede resolver la puerta de enlace, e iproute2 la rechaza con Error: Nexthop has invalid gateway. Añada dev uplink0 y el comando se ejecuta, porque el dispositivo es lo que fija el siguiente salto a uno de esos dos vecinos. Lo que el dispositivo no puede decirle es si uplink0 es el enlace correcto para esta tabla, y una ruta copiada de otro host trae los nombres de interfaz de ese host, y de ahí vienen los errores reales.
Condición uno: un enlace o dos en la tabla
Empiece por para qué sirve el segundo enlace ascendente. Si ambos enlaces llevan el mismo tráfico y uno es de reserva, la tabla alternativa debería contener ambas puertas de enlace con métricas distintas: mismos destinos, un camino preferido, una segunda opción obvia. Si los enlaces existen porque tráfico distinto debe salir por proveedores distintos, o porque es un túnel dividido donde parte del tráfico evita la VPN mientras el resto se queda dentro, los dos enlaces no pertenecen en absoluto a una sola tabla. Pertenecen a dos tablas, elegidas por una regla, y la regla elige la tabla, no el túnel: el tráfico que evita se marca antes de enrutarse, y la marca es lo que lo envía a la segunda tabla.
En ese segundo caso la regla decide cuándo se consulta una tabla, y la ruta decide adónde va el paquete una vez hecho esto:
ip -6 rule add fwmark 0x2 table 201
ip -6 route add default via fe80::1 dev uplink1 metric 100 table 201
ip -6 route add 2001:db8:100::/48 dev uplink1 metric 100 table 201
ip -6 route show table 201Ninguno de los dos objetos sustituye al otro, y una tabla que solo contiene una ruta por defecto todavía puede fallar al resolver su puerta de enlace. Si se rechaza una adición, o la ruta está presente pero es inutilizable, ponga el prefijo conectado de esa interfaz en la misma tabla, o marque el salto onlink cuando ese prefijo se enruta en otro sitio. En el bloque de arriba 2001:db8:100::/48 representa justo ese prefijo conectado en uplink1, no un destino arbitrario. La regla fwmark solo consume una marca que otra cosa debe poner, desde una regla nftables o iptables en la ruta de reenvío o desde SO_MARK en el socket, así que un bloque copiado sin origen de marca no coincide con nada.
Condición dos: las métricas no detectan un proveedor muerto
Una métrica es una preferencia entre rutas que existen, no una comprobación de salud. Cuando el portador cae, el núcleo elimina las rutas de ese dispositivo y la segunda ruta por defecto toma el relevo. Cuando el cable sigue conectado y el proveedor de detrás muere, nada cambia en la tabla: la ruta preferida está instalada, el vecino es alcanzable en la capa 2, y los paquetes salen hacia un agujero negro. Si esa distinción importa para su instalación, el failover tiene que venir de algo que sondee el camino y elimine la ruta, ya sea un demonio de enrutamiento o un pequeño script que borre y reinstale la entrada.
Verifique la elección una vez construida la tabla, y verifíquela tal como la verá el núcleo. ip -6 route get 2001:db8:100::1 imprime la ruta que se usaría, incluido el dispositivo y la dirección de origen seleccionada, y respeta las reglas de política. Una dirección de origen que pertenece al enlace ascendente equivocado es la señal habitual de que una regla coincidió antes de lo que esperaba.
Condición tres: decida quién posee la persistencia
Una ruta añadida con ip -6 route add sobrevive hasta un reinicio o hasta que algo la purgue. Una ruta por defecto aprendida de anuncios de enrutador lleva una duración y el enrutador puede retirarla, mientras que una ruta por defecto añadida a mano nunca caduca sola. Mezclar las dos en una tabla es como una ruta permanente obsoleta acaba superando a una recién anunciada, mucho después de que el enlace ascendente que describía dejara de existir.
Elija un propietario por tabla. Si un gestor de red o un demonio de enrutamiento ya gestiona la interfaz, describa allí la ruta de política y deje el núcleo en paz. Si lo hace con un script, haga el script idempotente y escriba el desmontaje al mismo tiempo, porque lo necesitará durante el primer cambio malo:
ip -6 route flush table 201
ip -6 rule del fwmark 0x2 table 201En un enrutador que reenvía para otros hosts, compruebe net.ipv6.conf.all.forwarding antes de culpar a la tabla. Con el reenvío desactivado, los paquetes dirigidos a otra red se descartan, por correcta que sea la tabla 201.
Registre el diseño para que la siguiente persona pueda auditarlo
Un inventario que solo guarda fe80::1 tira los campos que importan. Registre el destino, el siguiente salto, el dispositivo, la tabla y la métrica juntos, además de de dónde vino cada ruta: anunciada, generada por el gestor o estática. Cuando alguien pregunte más adelante si el segundo enlace ascendente lleva tráfico de verdad, ese registro responde a la pregunta sin conjeturas.
Antes de dar la tabla por terminada, confirme el vecino con ip -6 neigh show dev uplink0, relea ip -6 rule show por accidentes de orden, y pruebe con tráfico que coincida con la regla en lugar de un ping que toma la ruta por defecto. Luego baje un enlace ascendente a propósito y observe a qué ruta recurre el núcleo; la respuesta debería coincidir con la que anotó.