mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 23:33:24 +08:00
[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.
This commit is contained in:
@@ -576,6 +576,7 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
|
||||
UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask");
|
||||
UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway");
|
||||
UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP");
|
||||
UNICODE_STRING InterfaceMetric = RTL_CONSTANT_STRING(L"InterfaceMetric");
|
||||
UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
|
||||
UNICODE_STRING TcpipRegistryPath;
|
||||
UNICODE_STRING RegistryDataU;
|
||||
@@ -619,6 +620,21 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read the InterfaceMetric value */
|
||||
Interface->Metric = 0;
|
||||
Status = ZwQueryValueKey(ParameterHandle,
|
||||
&InterfaceMetric,
|
||||
KeyValuePartialInformation,
|
||||
KeyValueInfo,
|
||||
KeyValueInfoLength,
|
||||
&Unused);
|
||||
if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG))
|
||||
{
|
||||
Interface->Metric = (UINT)*(PULONG)KeyValueInfo->Data;
|
||||
if (Interface->Metric > 9999)
|
||||
Interface->Metric = 9999;
|
||||
}
|
||||
|
||||
/* Read the EnableDHCP entry */
|
||||
Status = ZwQueryValueKey(ParameterHandle,
|
||||
&EnableDhcp,
|
||||
@@ -700,7 +716,7 @@ BOOLEAN ReadIpConfiguration(PIP_INTERFACE Interface)
|
||||
AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer));
|
||||
|
||||
if (!AddrIsUnspecified(&Router))
|
||||
RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface, 1);
|
||||
RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface);
|
||||
|
||||
RtlFreeAnsiString(&RegistryDataA);
|
||||
}
|
||||
|
||||
@@ -156,6 +156,7 @@ typedef struct _IP_INTERFACE {
|
||||
UINT MinFrameSize; /* Minimum frame size in bytes */
|
||||
UINT MTU; /* Maximum transmission unit */
|
||||
UINT Speed; /* Link speed */
|
||||
UINT Metric; /* Interface metric */
|
||||
IP_ADDRESS Unicast; /* Unicast address */
|
||||
IP_ADDRESS PointToPoint; /* Point to point address */
|
||||
IP_ADDRESS Netmask; /* Netmask */
|
||||
|
||||
@@ -34,8 +34,7 @@ PFIB_ENTRY RouterCreateRoute(
|
||||
PIP_ADDRESS NetworkAddress,
|
||||
PIP_ADDRESS Netmask,
|
||||
PIP_ADDRESS RouterAddress,
|
||||
PIP_INTERFACE Interface,
|
||||
UINT Metric);
|
||||
PIP_INTERFACE Interface);
|
||||
|
||||
NTSTATUS RouterStartup(
|
||||
VOID);
|
||||
@@ -49,4 +48,6 @@ UINT CountFIBs(PIP_INTERFACE IF);
|
||||
|
||||
UINT CopyFIBs( PIP_INTERFACE IF, PFIB_ENTRY Target );
|
||||
|
||||
UINT ProcessAutoMetric(PIP_INTERFACE Interface);
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -17,7 +17,37 @@
|
||||
LIST_ENTRY FIBListHead;
|
||||
KSPIN_LOCK FIBLock;
|
||||
|
||||
void RouterDumpRoutes() {
|
||||
UINT
|
||||
ProcessAutoMetric(
|
||||
_In_ PIP_INTERFACE Interface)
|
||||
{
|
||||
if (Interface == Loopback)
|
||||
return 1;
|
||||
|
||||
if (Interface->Metric != 0)
|
||||
return Interface->Metric;
|
||||
|
||||
/* Auto metric */
|
||||
if (Interface->Speed > 2000000000)
|
||||
return 5;
|
||||
else if (Interface->Speed > 200000000)
|
||||
return 10;
|
||||
else if (Interface->Speed > 80000000)
|
||||
return 20;
|
||||
else if (Interface->Speed > 20000000)
|
||||
return 25;
|
||||
else if (Interface->Speed > 4000000)
|
||||
return 30;
|
||||
else if (Interface->Speed > 500000)
|
||||
return 40;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
RouterDumpRoutes(VOID)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PFIB_ENTRY Current;
|
||||
@@ -422,16 +452,14 @@ PFIB_ENTRY RouterCreateRoute(
|
||||
PIP_ADDRESS NetworkAddress,
|
||||
PIP_ADDRESS Netmask,
|
||||
PIP_ADDRESS RouterAddress,
|
||||
PIP_INTERFACE Interface,
|
||||
UINT Metric)
|
||||
PIP_INTERFACE Interface)
|
||||
/*
|
||||
* FUNCTION: Creates a route with IPv4 addresses as parameters
|
||||
* ARGUMENTS:
|
||||
* NetworkAddress = Address of network
|
||||
* Netmask = Netmask of network
|
||||
* RouterAddress = Address of router to use
|
||||
* NTE = Pointer to NTE to use
|
||||
* Metric = Cost of this route
|
||||
* Interface = Network interface
|
||||
* RETURNS:
|
||||
* Pointer to FIB entry if the route was created, NULL if not.
|
||||
* The FIB entry references the NTE. The caller is responsible
|
||||
@@ -475,7 +503,7 @@ PFIB_ENTRY RouterCreateRoute(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return RouterAddRoute(NetworkAddress, Netmask, NCE, Metric);
|
||||
return RouterAddRoute(NetworkAddress, Netmask, NCE, ProcessAutoMetric(Interface));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -327,8 +327,8 @@ TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize)
|
||||
|
||||
if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
|
||||
TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
|
||||
if (!RouterCreateRoute( &Address, &Netmask, &Router,
|
||||
IF, Route->Metric1))
|
||||
IF->Metric = Route->Metric1;
|
||||
if (!RouterCreateRoute(&Address, &Netmask, &Router, IF))
|
||||
return TDI_NO_RESOURCES;
|
||||
|
||||
return TDI_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user