Rutare pe politici IPv6 când două uplink-uri împart fe80::1
Două uplink-uri pot prezenta același next hop fe80::1 pe legături diferite. Alege un tabel pe politică, stăpânește duratele de viață și verifică printr-o căutare de rută.
Ai două uplink-uri, iar ip -6 route show afișează același next hop pe amândouă: default via fe80::1 dev uplink0 și default via fe80::1 dev uplink1. Nu este un conflict de adrese duplicate, iar copierea next hop-ului gol fe80::1 într-un tabel de politici nu îi spune nucleului la ce legătură te-ai referit. Întrebarea reală este mai îngustă decât sugerează simptomul: are nevoie al doilea tabel de o legătură sau de amândouă, și ce ține acele rute în viață după o repornire. Trei condiții, verificate în ordine, rezolvă cea mai mare parte.
Același fe80::1 sunt doi vecini diferiți
Adresele link-local sunt limitate la o singură legătură, așa că fe80::1 nu este o adresă afișată de două ori; sunt doi vecini care împart din întâmplare un sufix. Indexul de zonă este modul în care un host spune pe care îl înțelege, așa că fe80::1%uplink0 și fe80::1%uplink1 sunt destinații diferite pentru nucleu, iar acel sufix nu călătorește niciodată la un router îndepărtat. RFC 4007 descrie modelul de zone din spate, și de aceea un tabel de politici trebuie să poarte un dispozitiv cu fiecare next hop link-local.
Un generator de configurații VPN care copiază un ID de zonă numeric de pe un host într-un șablon tratează contextul local ca și cum ar face parte din adresă, iar fișierul pe care îl scrie este greșit pe fiecare mașină ale cărei nume sau indici de interfață diferă. Nici un tabel de politici nu fuzionează două legături într-una: o VPN rutată transmite pachete între rețele, dar nu duce identitatea link-local a unui vecin Ethernet îndepărtat prin tunel, așa că traficul link-local rămâne pe legătura lui.
Scoate dispozitivul și ruta devine nescriibilă. ip -6 route add default via fe80::1 table 200 nu poate rezolva gateway-ul, iar iproute2 îl respinge cu Error: Nexthop has invalid gateway. Adaugă dev uplink0 și comanda reușește, pentru că dispozitivul este cel care fixează next hop-ul la unul dintre cei doi vecini. Ce nu îți poate spune dispozitivul este dacă uplink0 este legătura potrivită pentru acest tabel, iar o rută copiată de pe alt host aduce cu ea numele de interfață ale acelui host, și de acolo vin greșelile reale.
Condiția unu: o legătură sau două în tabel
Începe cu scopul celui de-al doilea uplink. Dacă ambele legături poartă același trafic și una este de rezervă, tabelul alternativ ar trebui să conțină ambele gateway-uri cu metrici distincte: aceleași destinații, o cale preferată, o a doua alegere evidentă. Dacă uplink-urile există pentru că trafic diferit trebuie să iasă prin furnizori diferiți, sau pentru că acesta este un split tunnel în care o parte din trafic ocolește VPN-ul în timp ce restul rămâne înăuntru, cele două legături nu aparțin deloc unui singur tabel. Aparțin a două tabele, alese de o regulă, iar regula alege tabelul, nu tunelul: traficul care ocolește este marcat înainte de a fi rutat, iar marcajul este cel care îl trimite în al doilea tabel.
În acel al doilea caz regula decide când este consultat un tabel, iar ruta decide unde merge pachetul odată ce se întâmplă:
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 201Niciunul dintre obiecte nu îl înlocuiește pe celălalt, iar un tabel care conține doar un default poate totuși să nu reușească să își rezolve gateway-ul. Dacă un add este respins, sau ruta există dar este inutilizabilă, pune prefixul conectat al acelei interfețe în același tabel, sau marchează hop-ul onlink când acel prefix este rutat în altă parte. În blocul de mai sus, 2001:db8:100::/48 înlocuiește acel prefix conectat pe uplink1, nu o destinație arbitrară. Regula fwmark consumă doar un marcaj pe care altceva trebuie să îl seteze, dintr-o regulă nftables sau iptables pe calea de forwarding sau din SO_MARK pe socket, așa că un bloc copiat fără o sursă de marcaj nu se potrivește cu nimic.
Condiția doi: metricile nu detectează un furnizor mort
O metrică este o preferință între rute care există, nu o verificare de sănătate. Când cade operatorul, nucleul elimină rutele de pe acel dispozitiv și al doilea default preia controlul. Când cablul rămâne sus și furnizorul din spate moare, în tabel nu se schimbă nimic: ruta preferată este instalată, vecinul este accesibil la nivelul 2, iar pachetele pleacă într-o gaură neagră. Dacă distincția aceasta contează pentru configurația ta, failover-ul trebuie să vină de la ceva care sondaază calea și elimină ruta, fie că este un daemon de rutare sau un mic script care șterge și reinstalează intrarea.
Verifică alegerea după ce tabelul este construit, și verifică-l așa cum îl va vedea nucleul. ip -6 route get 2001:db8:100::1 afișează ruta care ar fi folosită, inclusiv dispozitivul și adresa sursă selectată, și respectă regulile de politică. O adresă sursă care aparține uplink-ului greșit este semnul obișnuit că o regulă s-a potrivit mai devreme decât te așteptai.
Condiția trei: decide cine deține persistența
O rută adăugată cu ip -6 route add supraviețuiește până la repornire sau până când ceva o șterge. Un default învățat din anunțurile routerului are o durată de viață și poate fi retras de router, în timp ce un default adăugat manual nu expiră niciodată de la sine. Amestecarea celor două într-un tabel este modul în care o rută permanentă veche ajunge să le depășească pe una proaspăt anunțată, mult după ce uplink-ul pe care îl descria a încetat să existe.
Alege un singur proprietar pe tabel. Dacă un network manager sau un daemon de rutare gestionează deja interfața, descrie ruta de politică acolo și lasă nucleul în pace. Dacă o scriptezi, fă scriptul idempotent și scrie teardown-ul în același timp, pentru că îl vei avea nevoie la prima schimbare proastă:
ip -6 route flush table 201
ip -6 rule del fwmark 0x2 table 201Pe un router care face forwarding pentru alte hosturi, verifică net.ipv6.conf.all.forwarding înainte de a da vina pe tabel. Cu forwarding-ul oprit, pachetele adresate altei rețele sunt aruncate, oricât de corect ar fi tabelul 201.
Documentează proiectul ca următoarea persoană să îl poată audita
Un inventar care stochează doar fe80::1 aruncă câmpurile care contează. Înregistrează împreună destinația, next hop-ul, dispozitivul, tabelul și metrica, plus de unde a venit fiecare rută, dacă este anunțată, generată de manager sau statică. Când cineva întreabă mai târziu dacă al doilea uplink chiar duce trafic, acea evidență răspunde fără presupuneri.
Înainte să declari tabelul terminat, confirmă vecinul cu ip -6 neigh show dev uplink0, recitește ip -6 rule show pentru accidente de ordonare, și testează cu trafic care se potrivește cu regula în loc de un ping care ia ruta implicită. Apoi coboară intenționat un uplink și urmărește pe ce rută revine nucleul; răspunsul ar trebui să corespundă cu cel pe care l-ai notat.