Skip to content

Commit 07d30c6

Browse files
committed
[TCPIP] Read the interface metric from the registry or use the automatic metric feature
- Read the interface metric from the registry. - Assign an automatic metric to an interface if a registry value is not available. - Determine the automatic metric from the link speed. The metric for the loopback interface is always 1.
1 parent 606d22d commit 07d30c6

File tree

5 files changed

+57
-11
lines changed

5 files changed

+57
-11
lines changed

drivers/network/tcpip/datalink/lan.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
576576
UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask");
577577
UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway");
578578
UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP");
579+
UNICODE_STRING InterfaceMetric = RTL_CONSTANT_STRING(L"InterfaceMetric");
579580
UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
580581
UNICODE_STRING TcpipRegistryPath;
581582
UNICODE_STRING RegistryDataU;
@@ -619,6 +620,21 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
619620
return FALSE;
620621
}
621622

623+
/* Read the InterfaceMetric value */
624+
Interface->Metric = 0;
625+
Status = ZwQueryValueKey(ParameterHandle,
626+
&InterfaceMetric,
627+
KeyValuePartialInformation,
628+
KeyValueInfo,
629+
KeyValueInfoLength,
630+
&Unused);
631+
if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG))
632+
{
633+
Interface->Metric = (UINT)*(PULONG)KeyValueInfo->Data;
634+
if (Interface->Metric > 9999)
635+
Interface->Metric = 9999;
636+
}
637+
622638
/* Read the EnableDHCP entry */
623639
Status = ZwQueryValueKey(ParameterHandle,
624640
&EnableDhcp,
@@ -700,7 +716,7 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
700716
AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer));
701717

702718
if (!AddrIsUnspecified(&Router))
703-
RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface, 1);
719+
RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface);
704720

705721
RtlFreeAnsiString(&RegistryDataA);
706722
}

drivers/network/tcpip/include/ip.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ typedef struct _IP_INTERFACE {
156156
UINT MinFrameSize; /* Minimum frame size in bytes */
157157
UINT MTU; /* Maximum transmission unit */
158158
UINT Speed; /* Link speed */
159+
UINT Metric; /* Interface metric */
159160
IP_ADDRESS Unicast; /* Unicast address */
160161
IP_ADDRESS PointToPoint; /* Point to point address */
161162
IP_ADDRESS Netmask; /* Netmask */

drivers/network/tcpip/include/router.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ PFIB_ENTRY RouterCreateRoute(
3434
PIP_ADDRESS NetworkAddress,
3535
PIP_ADDRESS Netmask,
3636
PIP_ADDRESS RouterAddress,
37-
PIP_INTERFACE Interface,
38-
UINT Metric);
37+
PIP_INTERFACE Interface);
3938

4039
NTSTATUS RouterStartup(
4140
VOID);
@@ -49,4 +48,6 @@ UINT CountFIBs(PIP_INTERFACE IF);
4948

5049
UINT CopyFIBs( PIP_INTERFACE IF, PFIB_ENTRY Target );
5150

51+
UINT ProcessAutoMetric(PIP_INTERFACE Interface);
52+
5253
/* EOF */

drivers/network/tcpip/ip/network/router.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,37 @@
1717
LIST_ENTRY FIBListHead;
1818
KSPIN_LOCK FIBLock;
1919

20-
void RouterDumpRoutes() {
20+
UINT
21+
ProcessAutoMetric(
22+
_In_ PIP_INTERFACE Interface)
23+
{
24+
if (Interface == Loopback)
25+
return 1;
26+
27+
if (Interface->Metric != 0)
28+
return Interface->Metric;
29+
30+
/* Auto metric */
31+
if (Interface->Speed > 2000000000)
32+
return 5;
33+
else if (Interface->Speed > 200000000)
34+
return 10;
35+
else if (Interface->Speed > 80000000)
36+
return 20;
37+
else if (Interface->Speed > 20000000)
38+
return 25;
39+
else if (Interface->Speed > 4000000)
40+
return 30;
41+
else if (Interface->Speed > 500000)
42+
return 40;
43+
else
44+
return 50;
45+
}
46+
47+
48+
VOID
49+
RouterDumpRoutes(VOID)
50+
{
2151
PLIST_ENTRY CurrentEntry;
2252
PLIST_ENTRY NextEntry;
2353
PFIB_ENTRY Current;
@@ -422,16 +452,14 @@ PFIB_ENTRY RouterCreateRoute(
422452
PIP_ADDRESS NetworkAddress,
423453
PIP_ADDRESS Netmask,
424454
PIP_ADDRESS RouterAddress,
425-
PIP_INTERFACE Interface,
426-
UINT Metric)
455+
PIP_INTERFACE Interface)
427456
/*
428457
* FUNCTION: Creates a route with IPv4 addresses as parameters
429458
* ARGUMENTS:
430459
* NetworkAddress = Address of network
431460
* Netmask = Netmask of network
432461
* RouterAddress = Address of router to use
433-
* NTE = Pointer to NTE to use
434-
* Metric = Cost of this route
462+
* Interface = Network interface
435463
* RETURNS:
436464
* Pointer to FIB entry if the route was created, NULL if not.
437465
* The FIB entry references the NTE. The caller is responsible
@@ -475,7 +503,7 @@ PFIB_ENTRY RouterCreateRoute(
475503
return NULL;
476504
}
477505

478-
return RouterAddRoute(NetworkAddress, Netmask, NCE, Metric);
506+
return RouterAddRoute(NetworkAddress, Netmask, NCE, ProcessAutoMetric(Interface));
479507
}
480508

481509

drivers/network/tcpip/tcpip/ninfo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize)
327327

328328
if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
329329
TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
330-
if (!RouterCreateRoute( &Address, &Netmask, &Router,
331-
IF, Route->Metric1))
330+
IF->Metric = Route->Metric1;
331+
if (!RouterCreateRoute(&Address, &Netmask, &Router, IF))
332332
return TDI_NO_RESOURCES;
333333

334334
return TDI_SUCCESS;

0 commit comments

Comments
 (0)