IPv6: dertig jaar onderweg en nog steeds niet overal
De eerste IPv6-specificatie, RFC 1883, verscheen in december 1995. Ruim dertig jaar later gaat nog lang niet al het verkeer over IPv6. Volgens de metingen van Google kwam op 28 maart 2026 voor het eerst meer dan de helft van de gebruikers via IPv6 binnen. Een protocol dat al zo lang klaarligt en toch maar half wordt gebruikt: dat wilde ik beter begrijpen.
Ik bouwde op één Linux-machine een testnetwerk met een router en een laptop en las elk pakketje mee. Hieronder zie je hoe een IPv6-adres in elkaar zit, hoe een apparaat zichzelf een adres geeft zonder DHCP, waarom je MAC-adres er niet meer in staat, en waarom de overstap zo traag gaat.
Van 32 naar 128 bits
Een IPv4-adres is 32 bits: ruim 4,29 miljard adressen. Dat is te weinig, en in het artikel over NAT zag je welke noodgreep daarvoor nodig is. IPv6 maakt het adres 128 bits lang. Dat geeft 2¹²⁸ adressen, ongeveer 3,4 × 10³⁸.
De huidige specificatie is RFC 8200 uit juli 2017. Die noemt naast de grotere adressen een eenvoudigere header. De vaste IPv6-header is 40 bytes, waarvan 32 voor de twee adressen. Routers knippen onderweg ook geen pakketjes meer in stukken: volgens RFC 8200 doet alleen de afzender dat nog.
Hoe een adres eruitziet
Een IPv6-adres schrijf je als acht groepjes van vier hexadecimale cijfers, en een reeks nullen mag je één keer vervangen door ::. In de voorbeelden gebruik ik 2001:db8::/32, de reeks die RFC 3849 voor documentatie reserveert.
Het adres bestaat bijna altijd uit twee helften van 64 bits. De eerste helft is het prefix: het netwerk. De tweede helft is de interface identifier: het apparaat binnen dat netwerk. RFC 4291 schrijft voor dat die tweede helft voor gewone adressen 64 bits is.
Je thuisrouter krijgt van de provider een groter blok, meestal via DHCPv6 prefix delegation (RFC 8415). Het RIPE-document RIPE-690 adviseert een /56 voor thuisaansluitingen of een /48 voor iedereen. Een /56 bevat 2⁸ = 256 netwerken van /64. Daarnaast heeft elk apparaat een link-local adres dat begint met fe80::, dat alleen op het eigen netwerk geldig is.
Het testnetwerk
Net als bij het artikel over ARP maakte ik met network namespaces losse "computers" die via een virtuele switch verbonden zijn. Router R heeft MAC-adres 02:00:00:00:00:01, laptop H heeft 02:00:00:00:00:02. Een Python-scriptje op R beantwoordt verzoeken van routerzoekers en een tweede scriptje leest op H elk frame mee.
Eerst een adres voor het eigen netwerk
Zodra H's netwerkkaart aangaat, maakt H zelf een link-local adres. Gebruiken mag nog niet: eerst moet H controleren of niemand anders het al heeft. Dat heet duplicate address detection:
1.040s uit 86B :: -> ff02::1:ff00:2 NS doel=fe80::ff:fe00:2
2.060s uit 70B fe80::ff:fe00:2 -> ff02::2 RS
Het controlebericht is een neighbor solicitation, met als afzender :: omdat H nog geen adres heeft. Het gaat naar een multicastadres dat is afgeleid van de laatste 24 bits van het gezochte adres. Alleen apparaten met een adres dat zo eindigt, hebben zich voor die groep aangemeld; de rest kan het bericht al op de netwerkkaart negeren. Een ARP-vraag bij IPv4 gaat naar iedereen.
Zolang de controle loopt, is het adres tentative. RFC 4862 schrijft voor dat pakketjes aan zo'n adres stil worden weggegooid. Komt er geen antwoord, dan is het adres van H. In drie runs duurde dat 1,2 tot 1,9 seconden na het aanzetten van de interface.
De router vertelt het prefix
Met een werkend link-local adres vraagt H aan alle routers (ff02::2) of er iemand is: een router solicitation. R antwoordde binnen dezelfde milliseconde met een router advertisement aan alle apparaten (ff02::1):
2.060s in 118B fe80::ff:fe00:1 -> ff02::1 RA hoplimit=64 lifetime=1800
mtu=1500 prefix=2001:db8:1::/64 flags=0xc0 valid=86400 pref=14400
Het prefix is 2001:db8:1::/64. De vlaggen 0xc0 betekenen: dit prefix is lokaal bereikbaar, en je mag er zelf een adres in maken. Dat laatste is SLAAC, stateless address autoconfiguration. De router houdt niet bij wie welk adres heeft. Elk ND-bericht had hop limit 255. RFC 4861 eist dat, omdat een pakketje met 255 nooit door een router kan zijn doorgestuurd en dus echt van het eigen netwerk komt.
H plakte zijn interface identifier achter het prefix, deed opnieuw een duplicaatcontrole en had na 2,9 tot 3,5 seconden 2001:db8:1::ff:fe00:2, plus de router als standaardroute.
Je MAC-adres in je IP-adres
Kijk naar die laatste helft: ::ff:fe00:2. Dat is het MAC-adres 02:00:00:00:00:02, met ff:fe in het midden en één bit omgedraaid, de methode uit bijlage A van RFC 4291. Je laptop heeft zo in elk netwerk dezelfde tweede helft. Een website kan je daaraan herkennen, ook als je van thuis naar kantoor gaat.
Daarom zette ik H opnieuw aan met twee instellingen die moderne systemen gebruiken. RFC 7217 beschrijft een stable privacy adres: wel vast binnen één netwerk, maar per netwerk anders en zonder MAC-adres. RFC 8981 voegt daar tijdelijke adressen met willekeurige tweede helft aan toe. H kreeg er nu twee:
inet6 2001:db8:1:0:ee83:8df5:c617:7593/64 scope global temporary dynamic
inet6 2001:db8:1:0:84f:e405:a3e4:5188/64 scope global dynamic mngtmpaddr stable-privacy
Voor een uitgaande verbinding koos H het tijdelijke adres. RFC 8981 stelt als standaard voor dat zo'n adres één dag de voorkeur heeft en twee dagen geldig blijft. Linux gebruikt standaard een dag en zeven dagen.
Geen vertaling, wel een slot op de deur
Achter R hing ik een derde namespace als stukje "internet": I, op 2001:db8:ff::99. H pingde I, en I zag dit binnenkomen:
in 118B 2001:db8:1:0:ee83:8df5:c617:7593 -> 2001:db8:ff::99 hl=63 echo-request
Het afzenderadres is precies het tijdelijke adres van H. De router heeft niets herschreven, alleen de hop limit met één verlaagd, van 64 naar 63.
Dat betekent niet dat je laptop open en bloot op internet staat. RFC 6092 uit januari 2011 bevat aanbevelingen voor thuisrouters met IPv6. Het document stelt zelf dat het filtergedrag van NAT bij gebruikers verwachtingen heeft gewekt die bij IPv6 blijven bestaan. Het advies, overgenomen uit RFC 4864, is een stateful filter: inkomend verkeer mag alleen als er van binnenuit eerst een verbinding is opgezet.
Waarom het zo lang duurt
IPv6 is niet compatibel met IPv4. Een apparaat met alleen IPv6 kan niet zomaar met een server met alleen IPv4 praten. Daarom draait vrijwel alles dual stack: beide protocollen tegelijk. Zolang elke site ook via IPv4 bereikbaar is, merkt een klant zonder IPv6 niets, en heeft niemand haast.
Bij dual stack moet je apparaat kiezen. RFC 8305, Happy Eyeballs, beschrijft dat het IPv6 voorrang geeft, maar na een korte wachttijd parallel ook IPv4 probeert. Aanbevolen is 250 milliseconden; curl gebruikt 200. Een kapotte IPv6-route kost dus een fractie van een seconde, en de gebruiker ziet niets.
Hoe ver het nu is, laat de data achter Google's statistiekenpagina zien:
| Datum | Gebruikers via IPv6 |
|---|---|
| 6 juni 2012 | 0,65% |
| 6 juni 2016 | 9,9% |
| 6 juni 2020 | 32,5% |
| 6 juni 2024 | 43,0% |
| 3 oktober 2026 (zaterdag) | 51,7% |
Wat me opviel: het cijfer schommelt per dag van de week. In september 2026 lag het op werkdagen gemiddeld op 46,6 procent en in het weekend op 50,0. Per land verschilt het flink. Op 9 oktober 2026 meet Google voor Nederland 53,2 procent, voor België 73,9, voor Duitsland 75,7 en voor Frankrijk 87,3.
Zelf proberen
Kijk welke adressen je eigen apparaat heeft. Op Linux:
ip -6 addr show
Zie je scope global temporary, dan gebruikt je systeem privacy-adressen. Welk adres het kiest voor een bepaalde bestemming, zie je met:
ip -6 route get 2001:4860:4860::8888
Of een site via IPv6 bereikbaar is, zie je aan het AAAA-record:
$ dig +short AAAA ripe.net
2001:67c:2e8:25::c100:b33
$ dig +short AAAA github.com
$ dig +short AAAA wallieweb.nl
Geen uitvoer betekent: geen IPv6-adres.
Tot slot
Twee dingen verrasten me. De eerste is hoe weinig er nodig is: één bericht van de router, en na zo'n drie seconden heeft een apparaat een wereldwijd uniek adres, een standaardroute en een MTU, zonder dat er ergens een server bijhoudt wie wat heeft. De tweede is dat je aan de IPv6-cijfers kunt zien of het weekend is. En toen ik voor dit artikel de AAAA-records naliep, bleek wallieweb.nl er zelf ook geen te hebben. Dit artikel over IPv6 komt dus via IPv4 bij je binnen.