ip4route.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 779 行 · 第 1/2 页

C
779
字号
/*++

Copyright (c) 2005 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 


Module Name:

  Ip4Route.c

Abstract:

--*/

#include "Ip4Impl.h"

STATIC
IP4_ROUTE_ENTRY *
Ip4CreateRouteEntry (
  IN IP4_ADDR               Dest,
  IN IP4_ADDR               Netmask,
  IN IP4_ADDR               GateWay
  )
/*++

Routine Description:

  Allocate a route entry then initialize it with the Dest/Netmaks 
  and Gateway.

Arguments:

  Dest     - The destination network
  Netmask  - The destination network mask
  GateWay  - The nexthop address

Returns:

  NULL if failed to allocate memeory, otherwise the newly created
  route entry. 

--*/
{
  IP4_ROUTE_ENTRY           *RtEntry;

  RtEntry = NetAllocatePool (sizeof (IP4_ROUTE_ENTRY));

  if (RtEntry == NULL) {
    return NULL;
  }

  NetListInit (&RtEntry->Link);

  RtEntry->RefCnt  = 1;
  RtEntry->Dest    = Dest;
  RtEntry->Netmask = Netmask;
  RtEntry->NextHop = GateWay;
  RtEntry->Flag    = 0;

  return RtEntry;
}

STATIC
VOID
Ip4FreeRouteEntry (
  IN IP4_ROUTE_ENTRY    *RtEntry
  )
/*++

Routine Description:

  Free the route table entry. It is reference counted.

Arguments:

  RtEntry - The route entry to free.

Returns:

  NONE

--*/
{
  ASSERT (RtEntry->RefCnt > 0);

  if (--RtEntry->RefCnt == 0) {
    NetFreePool (RtEntry);
  }
}

STATIC
IP4_ROUTE_CACHE_ENTRY *
Ip4CreateRouteCacheEntry (
  IN IP4_ADDR               Dst,
  IN IP4_ADDR               Src,
  IN IP4_ADDR               GateWay,
  IN UINTN                  Tag
  )
/*++

Routine Description:

  Allocate and initialize a IP4 route cache entry.

Arguments:

  Dst     - The destination address
  Src     - The source address
  GateWay - The next hop address
  Tag     - The tag from the caller. This marks all the cache entries
            spawned from one route table entry.

Returns:

  NULL if failed to allocate memory for the cache, other point
  to the created route cache entry.

--*/
{
  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;

  RtCacheEntry = NetAllocatePool (sizeof (IP4_ROUTE_CACHE_ENTRY));

  if (RtCacheEntry == NULL) {
    return NULL;
  }

  NetListInit (&RtCacheEntry->Link);

  RtCacheEntry->RefCnt  = 1;
  RtCacheEntry->Dest    = Dst;
  RtCacheEntry->Src     = Src;
  RtCacheEntry->NextHop = GateWay;
  RtCacheEntry->Tag     = Tag;

  return RtCacheEntry;
}

VOID
Ip4FreeRouteCacheEntry (
  IN IP4_ROUTE_CACHE_ENTRY  *RtCacheEntry
  )
/*++

Routine Description:

  Free the route cache entry. It is reference counted.

Arguments:

  RtCacheEntry  - The route cache entry to free.

Returns:

  None

--*/
{
  ASSERT (RtCacheEntry->RefCnt > 0);

  if (--RtCacheEntry->RefCnt == 0) {
    NetFreePool (RtCacheEntry);
  }
}

VOID
Ip4InitRouteCache (
  IN IP4_ROUTE_CACHE        *RtCache
  )
/*++

Routine Description:

  Initialize an empty route cache table.

Arguments:

  RtCache - The rotue cache table to initialize.

Returns:

  NONE

--*/
{
  UINT32                    Index;

  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {
    NetListInit (&(RtCache->CacheBucket[Index]));
  }
}

VOID
Ip4CleanRouteCache (
  IN IP4_ROUTE_CACHE        *RtCache
  )
/*++

Routine Description:

  Clean up a route cache, that is free all the route cache 
  entries enqueued in the cache.

Arguments:

  RtCache - The route cache table to clean up

Returns:

  None

--*/
{
  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;
  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;
  UINT32                    Index;

  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtCache->CacheBucket[Index])) {
      RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);

      NetListRemoveEntry (Entry);
      Ip4FreeRouteCacheEntry (RtCacheEntry);
    }
  }
}


IP4_ROUTE_TABLE *
Ip4CreateRouteTable (
  VOID
  )
/*++

Routine Description:

  Create an empty route table, includes its internal route cache

Arguments:

  None

Returns:

  NULL if failed to allocate memory for the route table, otherwise
  the point to newly created route table.

--*/
{
  IP4_ROUTE_TABLE           *RtTable;
  UINT32                    Index;

  RtTable = NetAllocatePool (sizeof (IP4_ROUTE_TABLE));

  if (RtTable == NULL) {
    return NULL;
  }

  RtTable->RefCnt   = 1;
  RtTable->TotalNum = 0;

  for (Index = 0; Index < IP4_MASK_NUM; Index++) {
    NetListInit (&(RtTable->RouteArea[Index]));
  }

  RtTable->Next = NULL;

  Ip4InitRouteCache (&RtTable->Cache);
  return RtTable;
}

VOID
Ip4FreeRouteTable (
  IN IP4_ROUTE_TABLE        *RtTable
  )
/*++

Routine Description:

  Free the route table and its associated route cache. Route 
  table is reference counted.

Arguments:

  RtTable - The route table to free.

Returns:

  None
  
--*/
{
  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;
  IP4_ROUTE_ENTRY           *RtEntry;
  UINT32                    Index;

  ASSERT (RtTable->RefCnt > 0);

  if (--RtTable->RefCnt > 0) {
    return ;
  }

  //
  // Free all the route table entry and its route cache.
  //
  for (Index = 0; Index < IP4_MASK_NUM; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtTable->RouteArea[Index])) {
      RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);

      NetListRemoveEntry (Entry);
      Ip4FreeRouteEntry (RtEntry);
    }
  }

  Ip4CleanRouteCache (&RtTable->Cache);
  
  NetFreePool (RtTable);
}


STATIC
VOID
Ip4PurgeRouteCache (
  IN IP4_ROUTE_CACHE        *RtCache,
  IN UINTN                  Tag
  )
/*++

Routine Description:

  Remove all the cache entries bearing the Tag. When a route cache
  entry is created, it is tagged with the address of route entry 
  from which it is spawned. When a route entry is deleted, the cache
  entries spawned from it are also deleted.

Arguments:

  RtCache - Route cache to remove the entries from
  Tag     - The Tag of the entries to remove

Returns:

  None

--*/
{
  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;
  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;
  UINT32                    Index;

  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtCache->CacheBucket[Index]) {

      RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);

      if (RtCacheEntry->Tag == Tag) {
        NetListRemoveEntry (Entry);
        Ip4FreeRouteCacheEntry (RtCacheEntry);
      }
    }
  }
}

EFI_STATUS
Ip4AddRoute (
  IN IP4_ROUTE_TABLE        *RtTable,
  IN IP4_ADDR               Dest,
  IN IP4_ADDR               Netmask,
  IN IP4_ADDR               Gateway
  )
/*++

Routine Description:

  Add a route entry to the route table. All the IP4_ADDRs are in 
  host byte order.

Arguments:

  RtTable - Route table to add route to
  Dest    - The destination of the network

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?