diff --git a/.github/workflows/smoke/smoke-windows.ps1 b/.github/workflows/smoke/smoke-windows.ps1 index e94768a9..fbc4dede 100644 --- a/.github/workflows/smoke/smoke-windows.ps1 +++ b/.github/workflows/smoke/smoke-windows.ps1 @@ -228,6 +228,14 @@ try { Write-Host "OK: $DevName $family NlMtu=$Mtu" } + # Both are set on the same handle as the v6 NlMtu, so by now they are either applied or never will be. + Wait-Until -TimeoutSec 30 -What "$DevName IPv6 DadTransmits=0 RouterDiscovery=Disabled" -Predicate { + if ($lhProc.HasExited) { throw "lighthouse exited (code $($lhProc.ExitCode)) before the v6 interface was configured" } + $rows = @(Get-NetIPInterface -InterfaceAlias $DevName -AddressFamily IPv6 -ErrorAction SilentlyContinue) + $rows.Count -gt 0 -and -not ($rows | Where-Object { $_.DadTransmits -ne 0 -or "$($_.RouterDiscovery)" -ne 'Disabled' }) + } + Write-Host "OK: $DevName IPv6 DadTransmits=0 RouterDiscovery=Disabled" + Wait-Until -TimeoutSec 30 -What "WSL nebula1 with $Ip2" -Predicate { if ($peerProc.HasExited) { throw "peer exited (code $($peerProc.ExitCode)) before tun was ready" } $r = wsl -d $Distro -u root -- bash -c "ip -o addr show nebula1 2>/dev/null | grep -q 'inet $Ip2' && echo yes" diff --git a/overlay/tun_windows.go b/overlay/tun_windows.go index 56c18131..d869b353 100644 --- a/overlay/tun_windows.go +++ b/overlay/tun_windows.go @@ -218,7 +218,8 @@ func (t *winTun) addRoutes(logErrors bool) error { return t.setMTU(luid, foundDefault4, carriesV6) } -// setMTU applies tun.mtu per address family. The default route metric rides along on the v4 handle. +// setMTU applies tun.mtu per address family. The default route metric rides along on the v4 handle, DAD and +// router discovery come off with the v6 one. func (t *winTun) setMTU(luid winipcfg.LUID, foundDefault4, carriesV6 bool) error { ipif, err := luid.IPInterface(windows.AF_INET) if err != nil { @@ -249,6 +250,11 @@ func (t *winTun) setMTU(luid winipcfg.LUID, foundDefault4, carriesV6 bool) error } ipif6.NLMTU = uint32(t.MTU) + // Nothing answers on the far side of this adapter but nebula, which drops the probes. DAD only holds the + // address tentative for a round it can never lose, and solicitations only invite RAs we would drop anyway. + // wireguard-windows turns both off on the same handle. + ipif6.DadTransmits = 0 + ipif6.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled if err := ipif6.Set(); err != nil { return fmt.Errorf("failed to set ipv6 interface: %w", err) }