Windows XP used a straightforward approach for automatic route metric assignment based solely on interface speed, as documented in KB299540. However, Windows 7 introduced a more complex algorithm that considers multiple factors beyond just link speed.
The automatic metric in Windows 7 is calculated using this formula:
Metric = InterfaceMetric + DestinationPrefixMetric + GatewayMetric
Where:
- InterfaceMetric: Based on the interface speed (similar to XP but with different values)
- DestinationPrefixMetric: Length of the destination prefix
- GatewayMetric: Additional cost if the route uses a gateway
Let's analyze your specific routing table entries:
0.0.0.0/0 via 192.168.0.1 (Gigabit) - Metric 10
0.0.0.0/0 via 10.202.254.254 (VPN) - Metric 286
192.168.0.0/24 - Metric 266
10.202.0.0/16 - Metric 286
127.0.0.0/8 - Metric 306
You can manually set metrics using the route
command:
route change 0.0.0.0 mask 0.0.0.0 10.202.254.254 metric 20
Or disable automatic metrics entirely via PowerShell:
Get-NetAdapter | ForEach-Object {
Set-NetIPInterface -InterfaceIndex $_.ifIndex -AutomaticMetric Disabled
}
For granular control, modify these registry keys:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DisableDHCPMediaSense
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableDeadGWDetect
When debugging routing problems:
- Verify interface speeds with
Get-NetAdapter
- Check current metrics with
route print
- Test connectivity with
Test-NetConnection
While Windows XP used a straightforward speed-based metric calculation as documented in KB299540, Windows 7 introduced a more complex algorithm that considers multiple factors:
// Windows XP metric calculation (simplified)
int CalculateMetricXP(int interfaceSpeed) {
if (interfaceSpeed > 200000) return 10;
if (interfaceSpeed > 20000) return 20;
if (interfaceSpeed > 4000) return 30;
if (interfaceSpeed > 500) return 40;
return 50;
}
Windows 7 considers these additional parameters:
- Interface speed (still primary factor)
- Interface type (wired vs wireless)
- Historical reliability data
- Connection state (VPN tunneling overhead)
- Network location type (Public/Private/Domain)
Examining your routing table reveals several interesting patterns:
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.0.1 192.168.0.3 10
0.0.0.0 0.0.0.0 10.202.254.254 10.202.1.2 286
10.202.0.0 255.255.0.0 On-link 10.202.1.2 286
192.168.0.0 255.255.255.0 On-link 192.168.0.3 266
===========================================================================
Key observations:
- The direct Gigabit connection gets base metric 10
- Other routes through same interface get 256 + base metric (10 + 256 = 266)
- VPN connections get higher penalty (base 10 + 256 + 20 for VPN overhead = 286)
- Loopback gets highest metric (306)
To override automatic metrics, use the netsh
command:
netsh interface ipv4 set interface "Local Area Connection" metric=10
netsh interface ipv4 add route 0.0.0.0/0 "Local Area Connection" 192.168.0.1 metric=10 store=active
Use WMI to retrieve detailed interface information:
using System.Management;
var query = new SelectQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
var searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject mo in searcher.Get())
{
Console.WriteLine($"Interface: {mo["Description"]}");
Console.WriteLine($"Metric: {mo["IPConnectionMetric"]}");
Console.WriteLine($"Speed: {mo["Speed"]} bps");
}
While not officially documented, analysis suggests this formula:
base_metric = speed_based_value (from XP table)
if (is_vpn) base_metric += 20
if (is_wireless) base_metric += 20
route_metric = base_metric + (interface_index * 256)
This explains why you see metrics like 266 (256 + 10) and 286 (256 + 30).
Use these commands to gather more information:
route print -4
netsh interface ipv4 show interfaces
netsh interface ipv4 show addresses