Ip4Route.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
abd8dd44106c507dd2cb64359b63d7d56fa0a9c8Christian Maeder/** @file
abd8dd44106c507dd2cb64359b63d7d56fa0a9c8Christian Maeder
09249711700a6acbc40a2e337688b434d7aafa28Christian MaederCopyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
76647324ed70f33b95a881b536d883daccf9568dChristian MaederThis program and the accompanying materials
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian Maederare licensed and made available under the terms and conditions of the BSD License
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maederwhich accompanies this distribution. The full text of the license may be found at
3f69b6948966979163bdfe8331c38833d5d90ecdChristian Maederhttp://opensource.org/licenses/bsd-license.php
abd8dd44106c507dd2cb64359b63d7d56fa0a9c8Christian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian MaederTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
f3a94a197960e548ecd6520bb768cb0d547457bbChristian MaederWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder**/
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder#include "Ip4Impl.h"
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder/**
950e053ba55ac9c7d9c26a1ab48bd00202b29511Christian Maeder Allocate a route entry then initialize it with the Dest/Netmaks
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder and Gateway.
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder @param[in] Dest The destination network
d48085f765fca838c1d972d2123601997174583dChristian Maeder @param[in] Netmask The destination network mask
5d7e4bf173534e7eb3fc84dce7bb0151079d3f8aChristian Maeder @param[in] GateWay The nexthop address
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder @return NULL if failed to allocate memeory, otherwise the newly created
abd8dd44106c507dd2cb64359b63d7d56fa0a9c8Christian Maeder route entry.
d48085f765fca838c1d972d2123601997174583dChristian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder**/
d48085f765fca838c1d972d2123601997174583dChristian MaederIP4_ROUTE_ENTRY *
d48085f765fca838c1d972d2123601997174583dChristian MaederIp4CreateRouteEntry (
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder IN IP4_ADDR Dest,
d48085f765fca838c1d972d2123601997174583dChristian Maeder IN IP4_ADDR Netmask,
d48085f765fca838c1d972d2123601997174583dChristian Maeder IN IP4_ADDR GateWay
d48085f765fca838c1d972d2123601997174583dChristian Maeder )
d48085f765fca838c1d972d2123601997174583dChristian Maeder{
d48085f765fca838c1d972d2123601997174583dChristian Maeder IP4_ROUTE_ENTRY *RtEntry;
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry = AllocatePool (sizeof (IP4_ROUTE_ENTRY));
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder if (RtEntry == NULL) {
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder return NULL;
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder }
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder InitializeListHead (&RtEntry->Link);
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry->RefCnt = 1;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry->Dest = Dest;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry->Netmask = Netmask;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry->NextHop = GateWay;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtEntry->Flag = 0;
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder
a716971174535184da7713ed308423e355a4aa66Christian Maeder return RtEntry;
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder}
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder
a716971174535184da7713ed308423e355a4aa66Christian Maeder
feab655b0275874012c3cf9859064c177860cc70Christian Maeder/**
f2c2b420e386a90d940c758c631d16f12952d2b7Christian Maeder Free the route table entry. It is reference counted.
f2c2b420e386a90d940c758c631d16f12952d2b7Christian Maeder
f2c2b420e386a90d940c758c631d16f12952d2b7Christian Maeder @param RtEntry The route entry to free.
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder**/
a716971174535184da7713ed308423e355a4aa66Christian MaederVOID
a716971174535184da7713ed308423e355a4aa66Christian MaederIp4FreeRouteEntry (
a716971174535184da7713ed308423e355a4aa66Christian Maeder IN IP4_ROUTE_ENTRY *RtEntry
a716971174535184da7713ed308423e355a4aa66Christian Maeder )
a716971174535184da7713ed308423e355a4aa66Christian Maeder{
a716971174535184da7713ed308423e355a4aa66Christian Maeder ASSERT (RtEntry->RefCnt > 0);
a716971174535184da7713ed308423e355a4aa66Christian Maeder
a716971174535184da7713ed308423e355a4aa66Christian Maeder if (--RtEntry->RefCnt == 0) {
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder FreePool (RtEntry);
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder }
d48085f765fca838c1d972d2123601997174583dChristian Maeder}
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder/**
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder Allocate and initialize an IP4 route cache entry.
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder @param[in] Dst The destination address
793945d4ac7c0f22760589c87af8e71427c76118Christian Maeder @param[in] Src The source address
a716971174535184da7713ed308423e355a4aa66Christian Maeder @param[in] GateWay The next hop address
a716971174535184da7713ed308423e355a4aa66Christian Maeder @param[in] Tag The tag from the caller. This marks all the cache
a716971174535184da7713ed308423e355a4aa66Christian Maeder entries spawned from one route table entry.
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder @return NULL if failed to allocate memory for the cache, other point
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder to the created route cache entry.
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder**/
d48085f765fca838c1d972d2123601997174583dChristian MaederIP4_ROUTE_CACHE_ENTRY *
d48085f765fca838c1d972d2123601997174583dChristian MaederIp4CreateRouteCacheEntry (
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder IN IP4_ADDR Dst,
d48085f765fca838c1d972d2123601997174583dChristian Maeder IN IP4_ADDR Src,
d48085f765fca838c1d972d2123601997174583dChristian Maeder IN IP4_ADDR GateWay,
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder IN UINTN Tag
d48085f765fca838c1d972d2123601997174583dChristian Maeder )
d48085f765fca838c1d972d2123601997174583dChristian Maeder{
d48085f765fca838c1d972d2123601997174583dChristian Maeder IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry = AllocatePool (sizeof (IP4_ROUTE_CACHE_ENTRY));
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder if (RtCacheEntry == NULL) {
d48085f765fca838c1d972d2123601997174583dChristian Maeder return NULL;
d48085f765fca838c1d972d2123601997174583dChristian Maeder }
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder InitializeListHead (&RtCacheEntry->Link);
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry->RefCnt = 1;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder RtCacheEntry->Dest = Dst;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry->Src = Src;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry->NextHop = GateWay;
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry->Tag = Tag;
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder return RtCacheEntry;
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder}
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder/**
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder Free the route cache entry. It is reference counted.
d48085f765fca838c1d972d2123601997174583dChristian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder @param RtCacheEntry The route cache entry to free.
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder**/
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian MaederVOID
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian MaederIp4FreeRouteCacheEntry (
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder IN IP4_ROUTE_CACHE_ENTRY *RtCacheEntry
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder )
d48085f765fca838c1d972d2123601997174583dChristian Maeder{
d48085f765fca838c1d972d2123601997174583dChristian Maeder ASSERT (RtCacheEntry->RefCnt > 0);
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder if (--RtCacheEntry->RefCnt == 0) {
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder FreePool (RtCacheEntry);
d48085f765fca838c1d972d2123601997174583dChristian Maeder }
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder}
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder/**
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder Initialize an empty route cache table.
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder @param[in, out] RtCache The rotue cache table to initialize.
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder**/
81946e2b3f6dde6167f48769bd02c7a634736856Christian MaederVOID
81946e2b3f6dde6167f48769bd02c7a634736856Christian MaederIp4InitRouteCache (
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder IN OUT IP4_ROUTE_CACHE *RtCache
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder )
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder{
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder UINT32 Index;
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
9a44a07ffc79da9852b6319bd6d9df81efe99809Christian Maeder for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder InitializeListHead (&(RtCache->CacheBucket[Index]));
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder }
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder}
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder/**
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder Clean up a route cache, that is free all the route cache
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder entries enqueued in the cache.
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder @param[in] RtCache The route cache table to clean up
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder**/
d48085f765fca838c1d972d2123601997174583dChristian MaederVOID
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian MaederIp4CleanRouteCache (
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder IN IP4_ROUTE_CACHE *RtCache
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder )
d48085f765fca838c1d972d2123601997174583dChristian Maeder{
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder LIST_ENTRY *Entry;
d48085f765fca838c1d972d2123601997174583dChristian Maeder LIST_ENTRY *Next;
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;
d48085f765fca838c1d972d2123601997174583dChristian Maeder UINT32 Index;
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {
d48085f765fca838c1d972d2123601997174583dChristian Maeder NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtCache->CacheBucket[Index])) {
d48085f765fca838c1d972d2123601997174583dChristian Maeder RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);
d48085f765fca838c1d972d2123601997174583dChristian Maeder
d48085f765fca838c1d972d2123601997174583dChristian Maeder RemoveEntryList (Entry);
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder Ip4FreeRouteCacheEntry (RtCacheEntry);
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder }
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder }
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder}
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder/**
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder Create an empty route table, includes its internal route cache
d48085f765fca838c1d972d2123601997174583dChristian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder @return NULL if failed to allocate memory for the route table, otherwise
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder the point to newly created route table.
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder**/
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian MaederIP4_ROUTE_TABLE *
81946e2b3f6dde6167f48769bd02c7a634736856Christian MaederIp4CreateRouteTable (
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder VOID
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder )
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder{
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder IP4_ROUTE_TABLE *RtTable;
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder UINT32 Index;
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder RtTable = AllocatePool (sizeof (IP4_ROUTE_TABLE));
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder if (RtTable == NULL) {
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder return NULL;
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder }
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder RtTable->RefCnt = 1;
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder RtTable->TotalNum = 0;
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder for (Index = 0; Index < IP4_MASK_NUM; Index++) {
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder InitializeListHead (&(RtTable->RouteArea[Index]));
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder }
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder RtTable->Next = NULL;
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder Ip4InitRouteCache (&RtTable->Cache);
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder return RtTable;
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder}
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
3eb7ebab2dd79ac5277f087b18e8f05b9e9f0f9bChristian Maeder
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder/**
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder Free the route table and its associated route cache. Route
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder table is reference counted.
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder @param[in] RtTable The route table to free.
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder**/
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian MaederVOID
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian MaederIp4FreeRouteTable (
98c47b3c137bdb20c53b6c1d346c0fb48b48d673Christian Maeder IN IP4_ROUTE_TABLE *RtTable
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder )
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder{
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder LIST_ENTRY *Entry;
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder LIST_ENTRY *Next;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder IP4_ROUTE_ENTRY *RtEntry;
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder UINT32 Index;
a39a820684c1974350f46593025e0bb279f41bc6Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder ASSERT (RtTable->RefCnt > 0);
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder if (--RtTable->RefCnt > 0) {
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder return ;
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder }
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder //
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder // Free all the route table entry and its route cache.
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder //
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder for (Index = 0; Index < IP4_MASK_NUM; Index++) {
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtTable->RouteArea[Index])) {
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder RemoveEntryList (Entry);
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder Ip4FreeRouteEntry (RtEntry);
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder }
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder }
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder Ip4CleanRouteCache (&RtTable->Cache);
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder FreePool (RtTable);
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder}
e47d29b522739fbf08aac80c6faa447dde113fbcChristian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder/**
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder Remove all the cache entries bearing the Tag. When a route cache
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder entry is created, it is tagged with the address of route entry
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder from which it is spawned. When a route entry is deleted, the cache
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder entries spawned from it are also deleted.
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder @param RtCache Route cache to remove the entries from
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder @param Tag The Tag of the entries to remove
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder**/
76647324ed70f33b95a881b536d883daccf9568dChristian MaederVOID
19f104861f1832b452c9f98e59880d05e865d9bdChristian MaederIp4PurgeRouteCache (
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder IN OUT IP4_ROUTE_CACHE *RtCache,
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder IN UINTN Tag
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder )
19f104861f1832b452c9f98e59880d05e865d9bdChristian Maeder{
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder LIST_ENTRY *Entry;
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder LIST_ENTRY *Next;
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder UINT32 Index;
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {
62ecb1e7f8fd9573eea8369657de12c7bf9f4f25Christian Maeder NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtCache->CacheBucket[Index]) {
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder if (RtCacheEntry->Tag == Tag) {
adfdcfa67b7f12df6df7292e238c3f9a4b637980Christian Maeder RemoveEntryList (Entry);
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder Ip4FreeRouteCacheEntry (RtCacheEntry);
62ecb1e7f8fd9573eea8369657de12c7bf9f4f25Christian Maeder }
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder }
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder }
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder}
d1012ae182d765c4e6986029d210b9e7b48de205Christian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder/**
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder Add a route entry to the route table. All the IP4_ADDRs are in
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder host byte order.
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder @param[in, out] RtTable Route table to add route to
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder @param[in] Dest The destination of the network
09249711700a6acbc40a2e337688b434d7aafa28Christian Maeder @param[in] Netmask The netmask of the destination
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder @param[in] Gateway The next hop address
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder @retval EFI_ACCESS_DENIED The same route already exists
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the entry
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder @retval EFI_SUCCESS The route is added successfully.
adfdcfa67b7f12df6df7292e238c3f9a4b637980Christian Maeder
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder**/
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederEFI_STATUS
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederIp4AddRoute (
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski IN OUT IP4_ROUTE_TABLE *RtTable,
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder IN IP4_ADDR Dest,
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder IN IP4_ADDR Netmask,
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder IN IP4_ADDR Gateway
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder )
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder{
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder LIST_ENTRY *Head;
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder LIST_ENTRY *Entry;
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder IP4_ROUTE_ENTRY *RtEntry;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder //
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder // All the route entries with the same netmask length are
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder // linke to the same route area
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder //
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder Head = &(RtTable->RouteArea[NetGetMaskLength (Netmask)]);
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder //
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder // First check whether the route exists
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder //
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder NET_LIST_FOR_EACH (Entry, Head) {
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder if (IP4_NET_EQUAL (RtEntry->Dest, Dest, Netmask) && (RtEntry->NextHop == Gateway)) {
94b34b35075c9115a22b512fd4ec3fb290f13d59Christian Maeder return EFI_ACCESS_DENIED;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder }
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder }
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder //
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder // Create a route entry and insert it to the route area.
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder //
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder RtEntry = Ip4CreateRouteEntry (Dest, Netmask, Gateway);
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder if (RtEntry == NULL) {
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder return EFI_OUT_OF_RESOURCES;
35cd0c10843c2cdbbe29f00a2a5d7e5e4f2d0064Christian Maeder }
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder if (Gateway == IP4_ALLZERO_ADDRESS) {
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder RtEntry->Flag = IP4_DIRECT_ROUTE;
d5c415f6373274fed04d83b9322891f3b82e9c26Christian Maeder }
d5c415f6373274fed04d83b9322891f3b82e9c26Christian Maeder
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder InsertHeadList (Head, &RtEntry->Link);
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder RtTable->TotalNum++;
5b1f1d57c75562a7af79e8256f4afa07febe921bChristian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder return EFI_SUCCESS;
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder}
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder/**
d48085f765fca838c1d972d2123601997174583dChristian Maeder Remove a route entry and all the route caches spawn from it.
9cb4aa4ea6685489a38f9b609f5dbe5d37f25bc7Christian Maeder
13f6b64b022fac1179149bfacf9a2ad908f7038dChristian Maeder @param RtTable The route table to remove the route from
13f6b64b022fac1179149bfacf9a2ad908f7038dChristian Maeder @param Dest The destination network
94b34b35075c9115a22b512fd4ec3fb290f13d59Christian Maeder @param Netmask The netmask of the Dest
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder @param Gateway The next hop address
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder @retval EFI_SUCCESS The route entry is successfully removed
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maeder @retval EFI_NOT_FOUND There is no route entry in the table with that
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder properity.
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder**/
717686b54b9650402e2ebfbaadf433eab8ba5171Christian MaederEFI_STATUS
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaederIp4DelRoute (
9348e8460498ddfcd9da11cd8b5794c06023e004Christian Maeder IN OUT IP4_ROUTE_TABLE *RtTable,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder IN IP4_ADDR Dest,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder IN IP4_ADDR Netmask,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder IN IP4_ADDR Gateway
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder )
72909c6c1cfe9702f5910d0a135c8b55729c7917Christian Maeder{
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder LIST_ENTRY *Head;
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder LIST_ENTRY *Entry;
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder LIST_ENTRY *Next;
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder IP4_ROUTE_ENTRY *RtEntry;
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder Head = &(RtTable->RouteArea[NetGetMaskLength (Netmask)]);
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder
5a13581acc5a76d392c1dec01657bb3efd4dcf2dChristian Maeder if (IP4_NET_EQUAL (RtEntry->Dest, Dest, Netmask) && (RtEntry->NextHop == Gateway)) {
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder Ip4PurgeRouteCache (&RtTable->Cache, (UINTN) RtEntry);
4ef2a978e66e2246ff0b7f00c77deb7aabb28b8eChristian Maeder RemoveEntryList (Entry);
4ef2a978e66e2246ff0b7f00c77deb7aabb28b8eChristian Maeder Ip4FreeRouteEntry (RtEntry);
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder
64b9ab8e743c8e284caab0ca522aa69b2e10ad15Christian Maeder RtTable->TotalNum--;
76647324ed70f33b95a881b536d883daccf9568dChristian Maeder return EFI_SUCCESS;
64b9ab8e743c8e284caab0ca522aa69b2e10ad15Christian Maeder }
64b9ab8e743c8e284caab0ca522aa69b2e10ad15Christian Maeder }
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski
64b9ab8e743c8e284caab0ca522aa69b2e10ad15Christian Maeder return EFI_NOT_FOUND;
8c27ccd6d90c4dcdfbe52b95c1f0bef655918f26Christian Maeder}
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski
/**
Find a route cache with the dst and src. This is used by ICMP
redirect messasge process. All kinds of redirect is treated as
host redirect according to RFC1122. So, only route cache entries
are modified according to the ICMP redirect message.
@param[in] RtTable The route table to search the cache for
@param[in] Dest The destination address
@param[in] Src The source address
@return NULL if no route entry to the (Dest, Src). Otherwise the point
to the correct route cache entry.
**/
IP4_ROUTE_CACHE_ENTRY *
Ip4FindRouteCache (
IN IP4_ROUTE_TABLE *RtTable,
IN IP4_ADDR Dest,
IN IP4_ADDR Src
)
{
LIST_ENTRY *Entry;
IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;
UINT32 Index;
Index = IP4_ROUTE_CACHE_HASH (Dest, Src);
NET_LIST_FOR_EACH (Entry, &RtTable->Cache.CacheBucket[Index]) {
RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);
if ((RtCacheEntry->Dest == Dest) && (RtCacheEntry->Src == Src)) {
NET_GET_REF (RtCacheEntry);
return RtCacheEntry;
}
}
return NULL;
}
/**
Search the route table for a most specific match to the Dst. It searches
from the longest route area (mask length == 32) to the shortest route area
(default routes). In each route area, it will first search the instance's
route table, then the default route table. This is required by the following
requirements:
1. IP search the route table for a most specific match
2. The local route entries have precedence over the default route entry.
@param[in] RtTable The route table to search from
@param[in] Dst The destionation address to search
@return NULL if no route matches the Dst, otherwise the point to the
most specific route to the Dst.
**/
IP4_ROUTE_ENTRY *
Ip4FindRouteEntry (
IN IP4_ROUTE_TABLE *RtTable,
IN IP4_ADDR Dst
)
{
LIST_ENTRY *Entry;
IP4_ROUTE_ENTRY *RtEntry;
IP4_ROUTE_TABLE *Table;
INTN Index;
RtEntry = NULL;
for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {
for (Table = RtTable; Table != NULL; Table = Table->Next) {
NET_LIST_FOR_EACH (Entry, &Table->RouteArea[Index]) {
RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
if (IP4_NET_EQUAL (RtEntry->Dest, Dst, RtEntry->Netmask)) {
NET_GET_REF (RtEntry);
return RtEntry;
}
}
}
}
return NULL;
}
/**
Search the route table to route the packet. Return/create a route
cache if there is a route to the destination.
@param[in] RtTable The route table to search from
@param[in] Dest The destination address to search for
@param[in] Src The source address to search for
@return NULL if failed to route packet, otherwise a route cache
entry that can be used to route packet.
**/
IP4_ROUTE_CACHE_ENTRY *
Ip4Route (
IN IP4_ROUTE_TABLE *RtTable,
IN IP4_ADDR Dest,
IN IP4_ADDR Src
)
{
LIST_ENTRY *Head;
LIST_ENTRY *Entry;
LIST_ENTRY *Next;
IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;
IP4_ROUTE_CACHE_ENTRY *Cache;
IP4_ROUTE_ENTRY *RtEntry;
IP4_ADDR NextHop;
UINT32 Count;
ASSERT (RtTable != NULL);
Head = &RtTable->Cache.CacheBucket[IP4_ROUTE_CACHE_HASH (Dest, Src)];
RtCacheEntry = Ip4FindRouteCache (RtTable, Dest, Src);
//
// If found, promote the cache entry to the head of the hash bucket. LRU
//
if (RtCacheEntry != NULL) {
RemoveEntryList (&RtCacheEntry->Link);
InsertHeadList (Head, &RtCacheEntry->Link);
return RtCacheEntry;
}
//
// Search the route table for the most specific route
//
RtEntry = Ip4FindRouteEntry (RtTable, Dest);
if (RtEntry == NULL) {
return NULL;
}
//
// Found a route to the Dest, if it is a direct route, the packet
// will be sent directly to the destination, such as for connected
// network. Otherwise, it is an indirect route, the packet will be
// sent to the next hop router.
//
if ((RtEntry->Flag & IP4_DIRECT_ROUTE) != 0) {
NextHop = Dest;
} else {
NextHop = RtEntry->NextHop;
}
Ip4FreeRouteEntry (RtEntry);
//
// Create a route cache entry, and tag it as spawned from this route entry
//
RtCacheEntry = Ip4CreateRouteCacheEntry (Dest, Src, NextHop, (UINTN) RtEntry);
if (RtCacheEntry == NULL) {
return NULL;
}
InsertHeadList (Head, &RtCacheEntry->Link);
NET_GET_REF (RtCacheEntry);
//
// Each bucket of route cache can contain at most 64 entries.
// Remove the entries at the tail of the bucket. These entries
// are likely to be used least.
//
Count = 0;
NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
if (++Count < IP4_ROUTE_CACHE_MAX) {
continue;
}
Cache = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);
RemoveEntryList (Entry);
Ip4FreeRouteCacheEntry (Cache);
}
return RtCacheEntry;
}
/**
Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of
GetModeData. The EFI_IP4_ROUTE_TABLE is clumsy to use in the
internal operation of the IP4 driver.
@param[in] IpInstance The IP4 child that requests the route table.
@retval EFI_SUCCESS The route table is successfully build
@retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the rotue table.
**/
EFI_STATUS
Ip4BuildEfiRouteTable (
IN IP4_PROTOCOL *IpInstance
)
{
LIST_ENTRY *Entry;
IP4_ROUTE_TABLE *RtTable;
IP4_ROUTE_ENTRY *RtEntry;
EFI_IP4_ROUTE_TABLE *Table;
UINT32 Count;
INT32 Index;
RtTable = IpInstance->RouteTable;
if (IpInstance->EfiRouteTable != NULL) {
FreePool (IpInstance->EfiRouteTable);
IpInstance->EfiRouteTable = NULL;
IpInstance->EfiRouteCount = 0;
}
Count = RtTable->TotalNum;
if (RtTable->Next != NULL) {
Count += RtTable->Next->TotalNum;
}
if (Count == 0) {
return EFI_SUCCESS;
}
Table = AllocatePool (sizeof (EFI_IP4_ROUTE_TABLE) * Count);
if (Table == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Copy the route entry to EFI route table. Keep the order of
// route entry copied from most specific to default route. That
// is, interlevel the route entry from the instance's route area
// and those from the default route table's route area.
//
Count = 0;
for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {
for (RtTable = IpInstance->RouteTable; RtTable != NULL; RtTable = RtTable->Next) {
NET_LIST_FOR_EACH (Entry, &(RtTable->RouteArea[Index])) {
RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
EFI_IP4 (Table[Count].SubnetAddress) = HTONL (RtEntry->Dest & RtEntry->Netmask);
EFI_IP4 (Table[Count].SubnetMask) = HTONL (RtEntry->Netmask);
EFI_IP4 (Table[Count].GatewayAddress) = HTONL (RtEntry->NextHop);
Count++;
}
}
}
IpInstance->EfiRouteTable = Table;
IpInstance->EfiRouteCount = Count;
return EFI_SUCCESS;
}