IPv6-policyrouting när två upplänkar delar fe80::1
Två upplänkar kan visa samma nästa hopp fe80::1 på olika länkar. Välj en tabell per policy, äg livstiderna och verifiera med en route-uppslagning.
Du har två upplänkar, och ip -6 route show skriver ut samma nästa hopp på båda: default via fe80::1 dev uplink0 och default via fe80::1 dev uplink1. Det är ingen konflikt med dubblerade adresser, och att kopiera det nakna nästa hoppet fe80::1 in i en policytabell talar inte om för kärnan vilken länk du menade. Den verkliga frågan är snävare än symptomet antyder: behöver den andra tabellen en länk eller båda, och vad håller dessa rutter vid liv efter en omstart. Tre villkor, kontrollerade i ordning, avgör det mesta.
Samma fe80::1 är två olika grannar
Link-local-adresser är begränsade till en enda länk, så fe80::1 är inte en adress utskriven två gånger; det är två grannar som råkar dela ett suffix. Zonindexet är hur en värd säger vilken av dem den menar, så fe80::1%uplink0 och fe80::1%uplink1 är olika destinationer för kärnan, och det suffixet färdas aldrig till en fjärrrouter. RFC 4007 beskriver zonmodellen bakom detta, och det är därför en policytabell måste bära en enhet med varje link-local nästa hopp.
En VPN-konfigurationsgenerator som kopierar ett numeriskt zon-ID från en värd in i en mall behandlar lokal kontext som om den vore en del av adressen, och filen den skriver är fel på varje maskin vars gränssnittsnamn eller index skiljer sig. En policytabell slår heller inte samman två länkar till en: en routad VPN skickar paket mellan nätverk, men den bär inte en fjärr-Ethernetgrannes link-local-identitet genom tunneln, så link-local-trafik stannar på sin egen länk.
Ta bort enheten och rutten blir oskrivbar. ip -6 route add default via fe80::1 table 200 kan inte slå upp gatewayen, och iproute2 avvisar den med Error: Nexthop has invalid gateway. Lägg till dev uplink0 och kommandot lyckas, eftersom det är enheten som fäster nästa hopp vid en av de två grannarna. Vad enheten inte kan berätta är om uplink0 är rätt länk för den här tabellen, och en rutt kopierad från en annan värd tar med sig den värdens gränssnittsnamn, och det är där de verkliga misstagen kommer från.
Villkor ett: en länk eller två i tabellen
Börja med vad den andra upplänken är till för. Om båda länkarna bär samma trafik och en är standby, bör den alternativa tabellen hålla båda gatewayerna med olika metrik: samma destinationer, en föredragen väg, ett uppenbart andraval. Om upplänkarna finns för att olika trafik måste lämna via olika leverantörer, eller för att detta är en split tunnel där en del trafik går förbi VPN:en medan resten stannar inne, hör de två länkarna inte i en tabell alls. De hör i två tabeller, valda av en regel, och regeln väljer tabellen, inte tunneln: trafik som ska förbi markeras innan den routas, och markeringen är det som skickar den till den andra tabellen.
I det andra fallet avgör regeln när en tabell konsulteras, och rutten avgör vart paketet tar vägen när den är det:
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 201Inget av objekten ersätter det andra, och en tabell som bara håller en standardrutt kan fortfarande misslyckas med att slå upp sin gateway. Om en add avvisas, eller rutten finns men är oanvändbar, lägg det anslutna prefixet för det gränssnittet i samma tabell, eller markera hoppet onlink när det prefixet routas någon annanstans. I blocket ovan står 2001:db8:100::/48 för det anslutna prefixet på uplink1, inte för en godtycklig destination. fwmark-regeln förbrukar bara en markering som något annat måste sätta, från en nftables- eller iptables-regel på vidarebefordringsvägen eller från SO_MARK på socketen, så ett block kopierat utan en markeringskälla matchar ingenting.
Villkor två: metrik upptäcker inte en död leverantör
En metrik är en preferens bland rutter som finns, inte en hälsokontroll. När operatören faller tar kärnan bort ruttarna på den enheten och standardrutten nummer två tar över. När kabeln ligger kvar och leverantören bakom den dör ändras ingenting i tabellen: den föredragna rutten är installerad, grannen är nåbar på lager 2, och paketen försvinner in i ett svart hål. Om den skillnaden spelar roll för din uppsättning måste failover komma från något som sondrar vägen och tar bort rutten, vare sig det är en routingdaemon eller ett litet skript som raderar och installerar posten igen.
Verifiera valet efter att tabellen är byggd, och verifiera det så som kärnan kommer att se det. ip -6 route get 2001:db8:100::1 skriver ut rutten som skulle användas, inklusive enheten och den valda källadressen, och den respekterar policyregler. En källadress som hör till fel upplänk är det vanliga tecknet på att en regel matchade tidigare än du förväntade dig.
Villkor tre: bestäm vem som äger persistensen
En rutt tillagd med ip -6 route add överlever till omstart eller till något spolar den. En standardrutt inlärd från routerannonser har en livstid och kan dras tillbaka av routern, medan en manuellt tillagd standardrutt aldrig löper ut av sig själv. Att blanda de två i en tabell är hur en gammal permanent rutt hamnar över en färsk annonserad sådan, långt efter att upplänken den beskrev slutade existera.
Välj en ägare per tabell. Om en nätverkshanterare eller routingdaemon redan hanterar gränssnittet, beskriv policyrutten där och lämna kärnan i fred. Om du skriptar det, gör skriptet idempotent och skriv nedmonteringen samtidigt, för du behöver den vid den första dåliga ändringen:
ip -6 route flush table 201
ip -6 rule del fwmark 0x2 table 201På en router som vidarebefordrar för andra värdar, kontrollera net.ipv6.conf.all.forwarding innan du skyller på tabellen. Med vidarebefordran avstängd släpps paket adresserade till ett annat nätverk, hur korrekt tabell 201 än är.
Dokumentera designen så nästa person kan granska den
En inventering som bara lagrar fe80::1 kastar bort fälten som betyder något. Registrera destinationen, nästa hopp, enheten, tabellen och metriken tillsammans, plus var varje rutt kom ifrån, om den är annonserad, hanterargenererad eller statisk. När någon senare frågar om den andra upplänken faktiskt bär trafik svarar den posten utan gissningar.
Innan du kallar tabellen färdig, bekräfta grannen med ip -6 neigh show dev uplink0, läs om ip -6 rule show för ordningsolyckor, och testa med trafik som matchar regeln i stället för en ping som tar standardrutten. Ta sedan ner en upplänk med avsikt och se vilken rutt kärnan faller tillbaka till; svaret bör stämma med det du skrev ner.