public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration
@ 2017-07-26  6:28 Jiaxin Wu
  2017-07-26  6:28 ` [Patch 1/3] MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol Jiaxin Wu
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jiaxin Wu @ 2017-07-26  6:28 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ye Ting, Fu Siyuan, Wu Jiaxin

UEFI Spec 2.7 adds the clarification on SetData interface usage to clear specific
individual data types. The series patches are used to support this feature.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>

Jiaxin Wu (3):
  MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol
  MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific
    configuration
  NetworkPkg/Ip6Dxe: Support SetData interface to clear specific
    configuration

 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c      | 285 ++++++---
 MdePkg/Include/Protocol/Ip4Config2.h               |  17 +-
 MdePkg/Include/Protocol/Ip6Config.h                |  15 +-
 NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c                  | 692 ++++++++++++---------
 4 files changed, 610 insertions(+), 399 deletions(-)

-- 
1.9.5.msysgit.1



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Patch 1/3] MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol
  2017-07-26  6:28 [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration Jiaxin Wu
@ 2017-07-26  6:28 ` Jiaxin Wu
  2017-07-26  6:28 ` [Patch 2/3] MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration Jiaxin Wu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jiaxin Wu @ 2017-07-26  6:28 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ye Ting, Fu Siyuan, Wu Jiaxin

Update the comments of Ip4Config2/Ip6Config Protocol to consistent
with UEFI Spec 2.7, which provides the capability to clear specific
individual data types.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
 MdePkg/Include/Protocol/Ip4Config2.h | 17 +++++++++++------
 MdePkg/Include/Protocol/Ip6Config.h  | 15 ++++++++++-----
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/MdePkg/Include/Protocol/Ip4Config2.h b/MdePkg/Include/Protocol/Ip4Config2.h
index fca2bb5..ced63cb 100644
--- a/MdePkg/Include/Protocol/Ip4Config2.h
+++ b/MdePkg/Include/Protocol/Ip4Config2.h
@@ -1,10 +1,10 @@
 /** @file
   This file provides a definition of the EFI IPv4 Configuration II
   Protocol.
 
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
 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<BR>
 http://opensource.org/licenses/bsd-license.php
 
@@ -49,29 +49,35 @@ typedef enum {
   Ip4Config2DataTypePolicy,
   ///
   /// The station addresses set manually for the EFI IPv4 network 
   /// stack. It is only configurable when the policy is 
   /// Ip4Config2PolicyStatic. The corresponding Data is of 
-  /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS.
+  /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS. When DataSize 
+  /// is 0 and Data is NULL, the existing configuration is cleared 
+  /// from the EFI IPv4 Configuration II Protocol instance.
   ///
   Ip4Config2DataTypeManualAddress,
   ///
   /// The gateway addresses set manually for the EFI IPv4 network 
   /// stack running on the communication device this EFI IPv4 
   /// Configuration II Protocol manages. It is not configurable when 
   /// the policy is Ip4Config2PolicyDhcp. The gateway 
   /// addresses must be unicast IPv4 addresses. The corresponding 
   /// Data is a pointer to an array of EFI_IPv4_ADDRESS instances.
+  /// When DataSize is 0 and Data is NULL, the existing configuration 
+  /// is cleared from the EFI IPv4 Configuration II Protocol instance.
   ///
   Ip4Config2DataTypeGateway,
   ///
   /// The DNS server list for the EFI IPv4 network stack running on 
   /// the communication device this EFI IPv4 Configuration II 
   /// Protocol manages. It is not configurable when the policy is 
   /// Ip4Config2PolicyDhcp. The DNS server addresses must be 
   /// unicast IPv4 addresses. The corresponding Data is a pointer to 
-  /// an array of EFI_IPv4_ADDRESS instances.
+  /// an array of EFI_IPv4_ADDRESS instances. When DataSize 
+  /// is 0 and Data is NULL, the existing configuration is cleared 
+  /// from the EFI IPv4 Configuration II Protocol instance.
   ///
   Ip4Config2DataTypeDnsServer,
   Ip4Config2DataTypeMaximum
 } EFI_IP4_CONFIG2_DATA_TYPE;
 
@@ -184,13 +190,12 @@ typedef struct {
 
   @retval EFI_SUCCESS             The specified configuration data for the EFI IPv4 network stack is set 
                                   successfully.
   @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
                                   This is NULL.
-                                  Data is NULL.
-                                  One or more fields in Data do not match the requirement of the data type 
-                                  indicated by DataType.
+                                  One or more fields in Data and DataSize do not match the 
+                                  requirement of the data type indicated by DataType.
   @retval EFI_WRITE_PROTECTED     The specified configuration data is read-only or the specified configuration 
                                   data can not be set under the current policy.
   @retval EFI_ACCESS_DENIED       Another set operation on the specified configuration data is already in process.
   @retval EFI_NOT_READY           An asynchronous process is invoked to set the specified configuration data and 
                                   the process is not finished yet.
diff --git a/MdePkg/Include/Protocol/Ip6Config.h b/MdePkg/Include/Protocol/Ip6Config.h
index b2c3be9..bcb8ba2 100644
--- a/MdePkg/Include/Protocol/Ip6Config.h
+++ b/MdePkg/Include/Protocol/Ip6Config.h
@@ -1,10 +1,10 @@
 /** @file
   This file provides a definition of the EFI IPv6 Configuration
   Protocol.
 
-Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
 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<BR>
 http://opensource.org/licenses/bsd-license.php
 
@@ -64,29 +64,35 @@ typedef enum {
   Ip6ConfigDataTypeDupAddrDetectTransmits,
   /// 
   /// The station addresses set manually for the EFI 
   /// IPv6 network stack. It is only configurable when the policy is 
   /// Ip6ConfigPolicyManual. The corresponding Data is a 
-  /// pointer to an array of EFI_IPv6_ADDRESS instances.
+  /// pointer to an array of EFI_IPv6_ADDRESS instances. When 
+  /// DataSize is 0 and Data is NULL, the existing configuration 
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
   /// 
   Ip6ConfigDataTypeManualAddress,
   /// 
   /// The gateway addresses set manually for the EFI IPv6 
   /// network stack running on the communication device this EFI 
   /// IPv6 Configuration Protocol manages. It is not configurable when 
   /// the policy is Ip6ConfigPolicyAutomatic. The gateway 
   /// addresses must be unicast IPv6 addresses. The corresponding 
   /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  /// When DataSize is 0 and Data is NULL, the existing configuration 
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
   /// 
   Ip6ConfigDataTypeGateway,
   /// 
   /// The DNS server list for the EFI IPv6 network stack 
   /// running on the communication device this EFI IPv6 
   /// Configuration Protocol manages. It is not configurable when the 
   /// policy is Ip6ConfigPolicyAutomatic.The DNS server 
   /// addresses must be unicast IPv6 addresses. The corresponding 
   /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  /// When DataSize is 0 and Data is NULL, the existing configuration 
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
   /// 
   Ip6ConfigDataTypeDnsServer,
   ///
   /// The number of this enumeration memebers.
   ///
@@ -226,13 +232,12 @@ typedef struct {
   
   @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6 
                                 network stack is set successfully.
   @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                 - This is NULL.
-                                - Data is NULL.
-                                - One or more fields in Data do not match the requirement of the 
-                                  data type indicated by DataType. 
+                                - One or more fields in Data and DataSize do not match the 
+                                  requirement of the data type indicated by DataType. 
   @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified 
                                 configuration data can not be set under the current policy
   @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration 
                                 data is already in process.
   @retval EFI_NOT_READY         An asynchronous process is invoked to set the specified
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Patch 2/3] MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration
  2017-07-26  6:28 [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration Jiaxin Wu
  2017-07-26  6:28 ` [Patch 1/3] MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol Jiaxin Wu
@ 2017-07-26  6:28 ` Jiaxin Wu
  2017-07-26  6:28 ` [Patch 3/3] NetworkPkg/Ip6Dxe: " Jiaxin Wu
  2017-08-10  5:54 ` [Patch 0/3] Support Ip4Config2/Ip6Config.SetData " Ye, Ting
  3 siblings, 0 replies; 5+ messages in thread
From: Jiaxin Wu @ 2017-07-26  6:28 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ye Ting, Fu Siyuan, Wu Jiaxin

UEFI Spec 2.7 adds the clarification on SetData interface usage to clear specific
individual data types. This patch is to support this feature.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c      | 285 ++++++++++++++-------
 1 file changed, 190 insertions(+), 95 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
index 3e38085..26530e3 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
@@ -1239,63 +1239,127 @@ Ip4Config2SetManualAddress (
   EFI_STATUS                     Status;
   IP4_ADDR                       StationAddress;
   IP4_ADDR                       SubnetMask;
   VOID                           *Ptr;
   IP4_SERVICE                    *IpSb;
+  IP4_INTERFACE                  *IpIf;
+  IP4_ROUTE_TABLE                *RouteTable;
+
+  DataItem   = NULL;
+  Status     = EFI_SUCCESS;
+  Ptr        = NULL;
+  IpIf       = NULL;
+  RouteTable = NULL;
 
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
 
   ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);
 
-  if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {
+  if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0)) {
     return EFI_BAD_BUFFER_SIZE;
   }
 
   if (Instance->Policy != Ip4Config2PolicyStatic) {
     return EFI_WRITE_PROTECTED;
   }
 
-  NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);
+  DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
 
-  StationAddress = EFI_NTOHL (NewAddress.Address);
-  SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
+  if (Data != NULL && DataSize != 0) {
+    NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);
 
-  //
-  // Check whether the StationAddress/SubnetMask pair is valid.
-  //
-  if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {
-    return EFI_INVALID_PARAMETER;
-  }
+    StationAddress = EFI_NTOHL (NewAddress.Address);
+    SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
 
-  //
-  // Store the new data, and init the DataItem status to EFI_NOT_READY because
-  // we may have an asynchronous configuration process.
-  //
-  Ptr = AllocateCopyPool (DataSize, Data);
-  if (Ptr == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
+    //
+    // Check whether the StationAddress/SubnetMask pair is valid.
+    //
+    if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {
+      return EFI_INVALID_PARAMETER;
+    }
 
-  DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
-  if (DataItem->Data.Ptr != NULL) {
-    FreePool (DataItem->Data.Ptr);
-  }
-  
-  DataItem->Data.Ptr = Ptr;
-  DataItem->DataSize = DataSize;
-  DataItem->Status   = EFI_NOT_READY;
+    //
+    // Store the new data, and init the DataItem status to EFI_NOT_READY because
+    // we may have an asynchronous configuration process.
+    //
+    Ptr = AllocateCopyPool (DataSize, Data);
+    if (Ptr == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
 
-  IpSb->Reconfig = TRUE;
-  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
+    if (DataItem->Data.Ptr != NULL) {
+      FreePool (DataItem->Data.Ptr);
+    }
+    
+    DataItem->Data.Ptr = Ptr;
+    DataItem->DataSize = DataSize;
+    DataItem->Status   = EFI_NOT_READY;
+
+    IpSb->Reconfig = TRUE;
+    Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
 
-  DataItem->Status = Status; 
+    DataItem->Status = Status;
 
-  if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {
-    if (Ptr != NULL) {
-      FreePool (Ptr);
+    if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {
+      if (Ptr != NULL) {
+        FreePool (Ptr);
+      }
+      DataItem->Data.Ptr = NULL; 
+    }
+  } else {
+    //
+    // DataSize is 0 and Data is NULL, clean up the manual address.
+    //
+    if (DataItem->Data.Ptr != NULL) {
+      FreePool (DataItem->Data.Ptr);
+    }
+    DataItem->Data.Ptr = NULL;
+    DataItem->DataSize = 0;
+    DataItem->Status   = EFI_NOT_FOUND;
+
+    //
+    // Free the default router table and Interface, clean up the assemble table.
+    //
+    if (IpSb->DefaultInterface != NULL) {
+      if (IpSb->DefaultRouteTable != NULL) {
+        Ip4FreeRouteTable (IpSb->DefaultRouteTable);
+        IpSb->DefaultRouteTable = NULL;    
+      }
+
+      Ip4CancelReceive (IpSb->DefaultInterface);
+
+      Ip4FreeInterface (IpSb->DefaultInterface, NULL);
+      IpSb->DefaultInterface = NULL;
+    }
+
+    Ip4CleanAssembleTable (&IpSb->Assemble);
+
+    //
+    // Create new default interface and route table.
+    //    
+    IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
+    if (IpIf == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    RouteTable = Ip4CreateRouteTable ();
+    if (RouteTable == NULL) {
+      Ip4FreeInterface (IpIf, NULL);
+      return EFI_OUT_OF_RESOURCES;
+    }
+    
+    IpSb->DefaultInterface  = IpIf;
+    InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
+    IpSb->DefaultRouteTable = RouteTable;
+    Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
+
+    //
+    // Reset the State to unstarted. 
+    //
+    if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) {
+      IpSb->State = IP4_SERVICE_UNSTARTED;
     }
-    DataItem->Data.Ptr = NULL; 
   }
 
   return Status;
 }
 
@@ -1340,98 +1404,114 @@ Ip4Config2SetGateway (
   UINTN                 NewGatewayCount;
   BOOLEAN               OneRemoved;
   BOOLEAN               OneAdded;
   VOID                  *Tmp;
 
-  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
+  OldGateway      = NULL;
+  NewGateway      = NULL;
+  OneRemoved      = FALSE;
+  OneAdded        = FALSE;
+  Tmp             = NULL;
+
+  if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv4_ADDRESS) != 0)) {
     return EFI_BAD_BUFFER_SIZE;
   }
 
   if (Instance->Policy != Ip4Config2PolicyStatic) {
     return EFI_WRITE_PROTECTED;
   }
 
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
 
-  NewGateway      = (EFI_IPv4_ADDRESS *) Data;
-  NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
-    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
-
-    if ((IpSb->DefaultInterface->SubnetMask != 0) && 
-        !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
-      if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
-        return EFI_INVALID_PARAMETER;
-      }
-    }
-  }
- 
-  DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
+  DataItem        = &Instance->DataItem[Ip4Config2DataTypeGateway];
   OldGateway      = DataItem->Data.Gateway;
   OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);
-  OneRemoved      = FALSE;
-  OneAdded        = FALSE;
-
-  if (NewGatewayCount != OldGatewayCount) {
-    Tmp = AllocatePool (DataSize);
-    if (Tmp == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-  } else {
-    Tmp = NULL;
-  }
 
   for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
     //
-    // Remove this route entry.
+    // Remove the old route entry.
     //
     CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));
     Ip4DelRoute (
       IpSb->DefaultRouteTable,
       IP4_ALLZERO_ADDRESS,
       IP4_ALLZERO_ADDRESS,
       NTOHL (Gateway)
       );
     OneRemoved = TRUE;
-
   }
 
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
-    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
-    Ip4AddRoute (
-      IpSb->DefaultRouteTable,
-      IP4_ALLZERO_ADDRESS,
-      IP4_ALLZERO_ADDRESS,
-      NTOHL (Gateway)
-      );    
-
-    OneAdded = TRUE;
-  }
+  if (Data != NULL && DataSize != 0) {
+    NewGateway      = (EFI_IPv4_ADDRESS *) Data;
+    NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+      CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
 
+      if ((IpSb->DefaultInterface->SubnetMask != 0) && 
+          !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {
+        return EFI_INVALID_PARAMETER;
+      }
 
-  if (!OneRemoved && !OneAdded) {
-    DataItem->Status = EFI_SUCCESS;
-    return EFI_ABORTED;
-  } else {
+      for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
+        if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
+          return EFI_INVALID_PARAMETER;
+        }
+      }
+    }
 
-    if (Tmp != NULL) {
-      if (DataItem->Data.Ptr != NULL) {
-        FreePool (DataItem->Data.Ptr);
+    if (NewGatewayCount != OldGatewayCount) {
+      Tmp = AllocatePool (DataSize);
+      if (Tmp == NULL) {
+        return EFI_OUT_OF_RESOURCES;
       }
-      DataItem->Data.Ptr = Tmp;
+    } else {
+      Tmp = NULL;
     }
 
-    CopyMem (DataItem->Data.Ptr, Data, DataSize);
-    DataItem->DataSize = DataSize;
-    DataItem->Status   = EFI_SUCCESS;
-    return EFI_SUCCESS;
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+      //
+      // Add the new route entry.
+      //
+      CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
+      Ip4AddRoute (
+        IpSb->DefaultRouteTable,
+        IP4_ALLZERO_ADDRESS,
+        IP4_ALLZERO_ADDRESS,
+        NTOHL (Gateway)
+        );    
+
+      OneAdded = TRUE;
+    }
+
+    if (!OneRemoved && !OneAdded) {
+      DataItem->Status = EFI_SUCCESS;
+      return EFI_ABORTED;
+    } else {
+      if (Tmp != NULL) {
+        if (DataItem->Data.Ptr != NULL) {
+          FreePool (DataItem->Data.Ptr);
+        }
+        DataItem->Data.Ptr = Tmp;
+      }
+
+      CopyMem (DataItem->Data.Ptr, Data, DataSize);
+      DataItem->DataSize = DataSize;
+      DataItem->Status   = EFI_SUCCESS;
+    }
+  } else {
+    //
+    // DataSize is 0 and Data is NULL, clean up the Gateway address.
+    //
+    if (DataItem->Data.Ptr != NULL) {
+      FreePool (DataItem->Data.Ptr);
+    }
+    DataItem->Data.Ptr = NULL;
+    DataItem->DataSize = 0;
+    DataItem->Status   = EFI_NOT_FOUND;
   }
 
+  return EFI_SUCCESS;
 }
 
 /**
   The work function is to set the DNS server list for the EFI IPv4 network 
   stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL 
@@ -1459,13 +1539,15 @@ Ip4Config2SetDnsServer (
   IN IP4_CONFIG2_INSTANCE *Instance,
   IN UINTN                DataSize,
   IN VOID                 *Data
   )
 {
-  IP4_CONFIG2_DATA_ITEM *Item;
+  EFI_STATUS                     Status;
+  IP4_CONFIG2_DATA_ITEM          *Item;
 
-  Item = NULL;
+  Status = EFI_SUCCESS;
+  Item   = NULL;
 
   if (Instance->Policy != Ip4Config2PolicyStatic) {
     return EFI_WRITE_PROTECTED;
   }
 
@@ -1473,11 +1555,25 @@ Ip4Config2SetDnsServer (
 
   if (DATA_ATTRIB_SET (Item->Attribute, DATA_ATTRIB_VOLATILE)) {
     REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);
   }
 
-  return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);
+  if (Data != NULL && DataSize != 0) {
+    Status = Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);
+  } else {
+    //
+    // DataSize is 0 and Data is NULL, clean up the DnsServer address. 
+    //
+    if (Item->Data.Ptr != NULL) {
+      FreePool (Item->Data.Ptr);
+    }
+    Item->Data.Ptr = NULL;
+    Item->DataSize = 0;
+    Item->Status   = EFI_NOT_FOUND;
+  }
+  
+  return Status;
 }
 
 /**
   Generate the operational state of the interface this IP4 config2 instance manages
   and output in EFI_IP4_CONFIG2_INTERFACE_INFO.
@@ -1552,13 +1648,12 @@ Ip4Config2OnDhcp4Event (
 
   @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                 network stack was set successfully.
   @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                 - This is NULL.
-                                - Data is NULL.
-                                - One or more fields in Data do not match the requirement of the
-                                  data type indicated by DataType.
+                                - One or more fields in Data and DataSize do not match the 
+                                  requirement of the data type indicated by DataType.
   @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified
                                 configuration data cannot be set under the current policy.
   @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration
                                 data is already in process.
   @retval EFI_NOT_READY         An asynchronous process was invoked to set the specified
@@ -1582,11 +1677,11 @@ EfiIp4Config2SetData (
   EFI_TPL              OldTpl;
   EFI_STATUS           Status;
   IP4_CONFIG2_INSTANCE *Instance;
   IP4_SERVICE          *IpSb;
 
-  if ((This == NULL) || (Data == NULL)) {
+  if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) {
     return EFI_INVALID_PARAMETER;
   }
 
   if (DataType >= Ip4Config2DataTypeMaximum) {
     return EFI_UNSUPPORTED;
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Patch 3/3] NetworkPkg/Ip6Dxe: Support SetData interface to clear specific configuration
  2017-07-26  6:28 [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration Jiaxin Wu
  2017-07-26  6:28 ` [Patch 1/3] MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol Jiaxin Wu
  2017-07-26  6:28 ` [Patch 2/3] MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration Jiaxin Wu
@ 2017-07-26  6:28 ` Jiaxin Wu
  2017-08-10  5:54 ` [Patch 0/3] Support Ip4Config2/Ip6Config.SetData " Ye, Ting
  3 siblings, 0 replies; 5+ messages in thread
From: Jiaxin Wu @ 2017-07-26  6:28 UTC (permalink / raw)
  To: edk2-devel; +Cc: Ye Ting, Fu Siyuan, Wu Jiaxin

UEFI Spec 2.7 adds the clarification on SetData interface usage to clear specific
individual data types. This patch is to support this feature.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
 NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 692 ++++++++++++++++++++++----------------
 1 file changed, 399 insertions(+), 293 deletions(-)

diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
index 7c7acc7..9e9dc89 100644
--- a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
+++ b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
@@ -917,254 +917,333 @@ Ip6ConfigSetManualAddress (
   LIST_ENTRY                     *Entry2;
   IP6_INTERFACE                  *IpIf;
   IP6_PREFIX_LIST_ENTRY          *PrefixEntry;
   EFI_STATUS                     Status;
   BOOLEAN                        IsUpdated;
+  LIST_ENTRY                     *Next;
+  IP6_DAD_ENTRY                  *DadEntry;
+  IP6_DELAY_JOIN_LIST            *DelayNode;
+
+  NewAddress      = NULL;
+  TmpAddress      = NULL;
+  CurrentAddrInfo = NULL;
+  Copy            = NULL;
+  Entry           = NULL;
+  Entry2          = NULL;
+  IpIf            = NULL;
+  PrefixEntry     = NULL;
+  Next            = NULL;
+  DadEntry        = NULL;
+  DelayNode       = NULL;
+  Status          = EFI_SUCCESS;
 
   ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status != EFI_NOT_READY);
 
-  if (((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {
+  if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0)) {
     return EFI_BAD_BUFFER_SIZE;
   }
 
   if (Instance->Policy != Ip6ConfigPolicyManual) {
     return EFI_WRITE_PROTECTED;
   }
 
-  NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
-  NewAddress      = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data;
+  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
 
-  for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
+  DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
 
-    if (NetIp6IsLinkLocalAddr (&NewAddress->Address)    ||
-        !NetIp6IsValidUnicast (&NewAddress->Address)    ||
-        (NewAddress->PrefixLength > 128)
-        ) {
-      //
-      // make sure the IPv6 address is unicast and not link-local address &&
-      // the prefix length is valid.
-      //
-      return EFI_INVALID_PARAMETER;
-    }
+  if (Data != NULL && DataSize != 0) {
+    NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
+    NewAddress      = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data;
 
-    TmpAddress = NewAddress + 1;
-    for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) {
-      //
-      // Any two addresses in the array can't be equal.
-      //
-      if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) {
+    for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
 
+      if (NetIp6IsLinkLocalAddr (&NewAddress->Address)    ||
+          !NetIp6IsValidUnicast (&NewAddress->Address)    ||
+          (NewAddress->PrefixLength > 128)
+          ) {
+        //
+        // make sure the IPv6 address is unicast and not link-local address &&
+        // the prefix length is valid.
+        //
         return EFI_INVALID_PARAMETER;
       }
+
+      TmpAddress = NewAddress + 1;
+      for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) {
+        //
+        // Any two addresses in the array can't be equal.
+        //
+        if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) {
+
+          return EFI_INVALID_PARAMETER;
+        }
+      }
     }
-  }
 
-  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
+    //
+    // Build the current source address list.
+    //
+    InitializeListHead (&CurrentSourceList);
+    CurrentSourceCount = 0;
 
-  //
-  // Build the current source address list.
-  //
-  InitializeListHead (&CurrentSourceList);
-  CurrentSourceCount = 0;
+    NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
+      IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
 
-  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
-    IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
+      NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
+        CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
 
-    NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
-      CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
+        Copy            = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo);
+        if (Copy == NULL) {
+          break;
+        }
 
-      Copy            = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo);
-      if (Copy == NULL) {
-        break;
+        InsertTailList (&CurrentSourceList, &Copy->Link);
+        CurrentSourceCount++;
       }
+    }
+
+    //
+    // Update the value... a long journey starts
+    //
+    NewAddress = AllocateCopyPool (DataSize, Data);
+    if (NewAddress == NULL) {
+      Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0);
 
-      InsertTailList (&CurrentSourceList, &Copy->Link);
-      CurrentSourceCount++;
+      return EFI_OUT_OF_RESOURCES;
     }
-  }
 
-  //
-  // Update the value... a long journey starts
-  //
-  NewAddress = AllocateCopyPool (DataSize, Data);
-  if (NewAddress == NULL) {
-    Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0);
+    //
+    // Store the new data, and init the DataItem status to EFI_NOT_READY because
+    // we may have an asynchronous configuration process.
+    //
+    if (DataItem->Data.Ptr != NULL) {
+      FreePool (DataItem->Data.Ptr);
+    }
+    DataItem->Data.Ptr = NewAddress;
+    DataItem->DataSize = DataSize;
+    DataItem->Status   = EFI_NOT_READY;
 
-    return EFI_OUT_OF_RESOURCES;
-  }
+    //
+    // Trigger DAD, it's an asynchronous process.
+    //
+    IsUpdated  = FALSE;
 
-  //
-  // Store the new data, and init the DataItem status to EFI_NOT_READY because
-  // we may have an asynchronous configuration process.
-  //
-  DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
-  if (DataItem->Data.Ptr != NULL) {
-    FreePool (DataItem->Data.Ptr);
-  }
-  DataItem->Data.Ptr = NewAddress;
-  DataItem->DataSize = DataSize;
-  DataItem->Status   = EFI_NOT_READY;
+    for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
+      if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) {
+        ASSERT (CurrentAddrInfo != NULL);
+        //
+        // Remove this already existing source address from the CurrentSourceList
+        // built before.
+        //
+        Ip6RemoveAddr (
+          NULL,
+          &CurrentSourceList,
+          &CurrentSourceCount,
+          &CurrentAddrInfo->Address,
+          128
+          );
 
-  //
-  // Trigger DAD, it's an asynchronous process.
-  //
-  IsUpdated  = FALSE;
+        //
+        // If the new address's prefix length is not specified, just use the previous configured
+        // prefix length for this address.
+        //
+        if (NewAddress->PrefixLength == 0) {
+          NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength;
+        }
 
-  for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
-    if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) {
-      ASSERT (CurrentAddrInfo != NULL);
-      //
-      // Remove this already existing source address from the CurrentSourceList
-      // built before.
-      //
-      Ip6RemoveAddr (
-        NULL,
-        &CurrentSourceList,
-        &CurrentSourceCount,
-        &CurrentAddrInfo->Address,
-        128
-        );
+        //
+        // This manual address is already in use, see whether prefix length is changed.
+        //
+        if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) {
+          //
+          // Remove the on-link prefix table, the route entry will be removed
+          // implicitly.
+          //
+          PrefixEntry = Ip6FindPrefixListEntry (
+                          IpSb,
+                          TRUE,
+                          CurrentAddrInfo->PrefixLength,
+                          &CurrentAddrInfo->Address
+                          );
+          if (PrefixEntry != NULL) {
+            Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
+          }
 
-      //
-      // If the new address's prefix length is not specified, just use the previous configured
-      // prefix length for this address.
-      //
-      if (NewAddress->PrefixLength == 0) {
-        NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength;
-      }
+          //
+          // Save the prefix length.
+          //
+          CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength;
+          IsUpdated = TRUE;
+        }
 
-      //
-      // This manual address is already in use, see whether prefix length is changed.
-      //
-      if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) {
         //
-        // Remove the on-link prefix table, the route entry will be removed
-        // implicitly.
+        // create a new on-link prefix entry.
         //
         PrefixEntry = Ip6FindPrefixListEntry (
                         IpSb,
                         TRUE,
-                        CurrentAddrInfo->PrefixLength,
-                        &CurrentAddrInfo->Address
+                        NewAddress->PrefixLength,
+                        &NewAddress->Address
                         );
-        if (PrefixEntry != NULL) {
-          Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
+        if (PrefixEntry == NULL) {
+          Ip6CreatePrefixListEntry (
+            IpSb,
+            TRUE,
+            (UINT32) IP6_INFINIT_LIFETIME,
+            (UINT32) IP6_INFINIT_LIFETIME,
+            NewAddress->PrefixLength,
+            &NewAddress->Address
+            );
         }
 
+        CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast;
         //
-        // Save the prefix length.
+        // Artificially mark this address passed DAD be'coz it is already in use.
+        //
+        Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance);
+      } else {
+        //
+        // A new address.
         //
-        CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength;
         IsUpdated = TRUE;
+
+        //
+        // Set the new address, this will trigger DAD and activate the address if
+        // DAD succeeds.
+        //
+        Ip6SetAddress (
+          IpSb->DefaultInterface,
+          &NewAddress->Address,
+          NewAddress->IsAnycast,
+          NewAddress->PrefixLength,
+          (UINT32) IP6_INFINIT_LIFETIME,
+          (UINT32) IP6_INFINIT_LIFETIME,
+          Ip6ManualAddrDadCallback,
+          Instance
+          );
       }
+    }
+
+    //
+    // Check the CurrentSourceList, it now contains those addresses currently in
+    // use and will be removed.
+    //
+    IpIf = IpSb->DefaultInterface;
+
+    while (!IsListEmpty (&CurrentSourceList)) {
+      IsUpdated = TRUE;
+
+      CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link);
 
       //
-      // create a new on-link prefix entry.
+      // This local address is going to be removed, the IP instances that are
+      // currently using it will be destroyed.
+      //
+      Ip6RemoveAddr (
+        IpSb,
+        &IpIf->AddressList,
+        &IpIf->AddressCount,
+        &CurrentAddrInfo->Address,
+        128
+        );
+
+      //
+      // Remove the on-link prefix table, the route entry will be removed
+      // implicitly.
       //
       PrefixEntry = Ip6FindPrefixListEntry (
                       IpSb,
                       TRUE,
-                      NewAddress->PrefixLength,
-                      &NewAddress->Address
+                      CurrentAddrInfo->PrefixLength,
+                      &CurrentAddrInfo->Address
                       );
-      if (PrefixEntry == NULL) {
-        Ip6CreatePrefixListEntry (
-          IpSb,
-          TRUE,
-          (UINT32) IP6_INFINIT_LIFETIME,
-          (UINT32) IP6_INFINIT_LIFETIME,
-          NewAddress->PrefixLength,
-          &NewAddress->Address
-          );
+      if (PrefixEntry != NULL) {
+        Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
       }
 
-      CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast;
-      //
-      // Artificially mark this address passed DAD be'coz it is already in use.
-      //
-      Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance);
+      RemoveEntryList (&CurrentAddrInfo->Link);
+      FreePool (CurrentAddrInfo);
+    }
+
+    if (IsUpdated) {
+      if (DataItem->Status == EFI_NOT_READY) {
+        //
+        // If DAD is disabled on this interface, the configuration process is
+        // actually synchronous, and the data item's status will be changed to
+        // the final status before we reach here, just check it.
+        //
+        Status = EFI_NOT_READY;
+      } else {
+        Status = EFI_SUCCESS;
+      }
     } else {
       //
-      // A new address.
+      // No update is taken, reset the status to success and return EFI_ABORTED.
       //
-      IsUpdated = TRUE;
+      DataItem->Status = EFI_SUCCESS;
+      Status           = EFI_ABORTED;
+    }
+  } else {
+    //
+    // DataSize is 0 and Data is NULL, clean up the manual address.
+    //
+    if (DataItem->Data.Ptr != NULL) {
+      FreePool (DataItem->Data.Ptr);
+    }
+    DataItem->Data.Ptr = NULL;
+    DataItem->DataSize = 0;
+    DataItem->Status   = EFI_NOT_FOUND;
 
-      //
-      // Set the new address, this will trigger DAD and activate the address if
-      // DAD succeeds.
-      //
-      Ip6SetAddress (
-        IpSb->DefaultInterface,
-        &NewAddress->Address,
-        NewAddress->IsAnycast,
-        NewAddress->PrefixLength,
+    Ip6CleanDefaultRouterList (IpSb);
+    Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix);
+    Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix);
+    Ip6CleanAssembleTable (&IpSb->Assemble);
+
+    if (IpSb->LinkLocalOk) {
+      Ip6CreatePrefixListEntry (
+        IpSb,
+        TRUE,
         (UINT32) IP6_INFINIT_LIFETIME,
         (UINT32) IP6_INFINIT_LIFETIME,
-        Ip6ManualAddrDadCallback,
-        Instance
+        IP6_LINK_LOCAL_PREFIX_LENGTH,
+        &IpSb->LinkLocalAddr
         );
     }
-  }
 
-  //
-  // Check the CurrentSourceList, it now contains those addresses currently in
-  // use and will be removed.
-  //
-  IpIf = IpSb->DefaultInterface;
-
-  while (!IsListEmpty (&CurrentSourceList)) {
-    IsUpdated = TRUE;
-
-    CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link);
-
-    //
-    // This local address is going to be removed, the IP instances that are
-    // currently using it will be destroyed.
-    //
     Ip6RemoveAddr (
       IpSb,
-      &IpIf->AddressList,
-      &IpIf->AddressCount,
-      &CurrentAddrInfo->Address,
-      128
+      &IpSb->DefaultInterface->AddressList,
+      &IpSb->DefaultInterface->AddressCount,
+      NULL,
+      0
       );
 
-    //
-    // Remove the on-link prefix table, the route entry will be removed
-    // implicitly.
-    //
-    PrefixEntry = Ip6FindPrefixListEntry (
-                    IpSb,
-                    TRUE,
-                    CurrentAddrInfo->PrefixLength,
-                    &CurrentAddrInfo->Address
-                    );
-    if (PrefixEntry != NULL) {
-      Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
-    }
-
-    RemoveEntryList (&CurrentAddrInfo->Link);
-    FreePool (CurrentAddrInfo);
-  }
-
-  if (IsUpdated) {
-    if (DataItem->Status == EFI_NOT_READY) {
+    NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
       //
-      // If DAD is disabled on this interface, the configuration process is
-      // actually synchronous, and the data item's status will be changed to
-      // the final status before we reach here, just check it.
+      // Remove all pending delay node and DAD entries for the global addresses.
       //
-      Status = EFI_NOT_READY;
-    } else {
-      Status = EFI_SUCCESS;
+      IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
+
+      NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) {
+        DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link);
+        if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) {
+          RemoveEntryList (&DelayNode->Link);
+          FreePool (DelayNode);
+        }
+      }
+
+      NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) {
+        DadEntry = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE);
+
+        if (!NetIp6IsLinkLocalAddr (&DadEntry->AddressInfo->Address)) {
+          //
+          // Fail this DAD entry if the address is not link-local.
+          //
+          Ip6OnDADFinished (FALSE, IpIf, DadEntry);
+        }
+      }
     }
-  } else {
-    //
-    // No update is taken, reset the status to success and return EFI_ABORTED.
-    //
-    DataItem->Status = EFI_SUCCESS;
-    Status           = EFI_ABORTED;
   }
 
   return Status;
 }
 
@@ -1208,98 +1287,107 @@ Ip6ConfigSetGateway (
   BOOLEAN               OneAdded;
   IP6_SERVICE           *IpSb;
   IP6_DEFAULT_ROUTER    *DefaultRouter;
   VOID                  *Tmp;
 
-  if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
+  OldGateway      = NULL;
+  NewGateway      = NULL;
+  Item            = NULL;
+  DefaultRouter   = NULL;
+  Tmp             = NULL;
+  OneRemoved      = FALSE;
+  OneAdded        = FALSE;
+
+  if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
     return EFI_BAD_BUFFER_SIZE;
   }
 
   if (Instance->Policy != Ip6ConfigPolicyManual) {
     return EFI_WRITE_PROTECTED;
   }
 
-  NewGateway      = (EFI_IPv6_ADDRESS *) Data;
-  NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
-
-    if (!NetIp6IsValidUnicast (NewGateway + Index1)) {
-
-      return EFI_INVALID_PARAMETER;
-    }
-
-    for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
-      if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
-        return EFI_INVALID_PARAMETER;
-      }
-    }
-  }
-
   IpSb            = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
   Item            = &Instance->DataItem[Ip6ConfigDataTypeGateway];
   OldGateway      = Item->Data.Gateway;
   OldGatewayCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
-  OneRemoved      = FALSE;
-  OneAdded        = FALSE;
-
-  if (NewGatewayCount != OldGatewayCount) {
-    Tmp = AllocatePool (DataSize);
-    if (Tmp == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-  } else {
-    Tmp = NULL;
-  }
 
   for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
     //
-    // Find the gateways that are no long in the new setting and remove them.
+    // Remove this default router.
     //
-    for (Index2 = 0; Index2 < NewGatewayCount; Index2++) {
-      if (EFI_IP6_EQUAL (OldGateway + Index1, NewGateway + Index2)) {
-        OneRemoved = TRUE;
-        break;
+    DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
+    if (DefaultRouter != NULL) {
+      Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
+      OneRemoved = TRUE;
+    }
+  }
+
+  if (Data != NULL && DataSize != 0) {
+    NewGateway      = (EFI_IPv6_ADDRESS *) Data;
+    NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+
+      if (!NetIp6IsValidUnicast (NewGateway + Index1)) {
+
+        return EFI_INVALID_PARAMETER;
+      }
+
+      for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
+        if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
+          return EFI_INVALID_PARAMETER;
+        }
       }
     }
 
-    if (Index2 == NewGatewayCount) {
-      //
-      // Remove this default router.
-      //
-      DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
-      if (DefaultRouter != NULL) {
-        Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
+    if (NewGatewayCount != OldGatewayCount) {
+      Tmp = AllocatePool (DataSize);
+      if (Tmp == NULL) {
+        return EFI_OUT_OF_RESOURCES;
       }
+    } else {
+      Tmp = NULL;
     }
-  }
 
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
 
-    DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1);
-    if (DefaultRouter == NULL) {
-      Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME);
-      OneAdded = TRUE;
+      DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1);
+      if (DefaultRouter == NULL) {
+        Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME);
+        OneAdded = TRUE;
+      }
     }
-  }
 
-  if (!OneRemoved && !OneAdded) {
-    Item->Status = EFI_SUCCESS;
-    return EFI_ABORTED;
-  } else {
+    if (!OneRemoved && !OneAdded) {
+      Item->Status = EFI_SUCCESS;
+      return EFI_ABORTED;
+    } else {
 
-    if (Tmp != NULL) {
-      if (Item->Data.Ptr != NULL) {
-        FreePool (Item->Data.Ptr);
+      if (Tmp != NULL) {
+        if (Item->Data.Ptr != NULL) {
+          FreePool (Item->Data.Ptr);
+        }
+        Item->Data.Ptr = Tmp;
       }
-      Item->Data.Ptr = Tmp;
-    }
 
-    CopyMem (Item->Data.Ptr, Data, DataSize);
-    Item->DataSize = DataSize;
-    Item->Status   = EFI_SUCCESS;
-    return EFI_SUCCESS;
+      CopyMem (Item->Data.Ptr, Data, DataSize);
+      Item->DataSize = DataSize;
+      Item->Status   = EFI_SUCCESS;
+      return EFI_SUCCESS;
+    }
+  } else {
+    //
+    // DataSize is 0 and Data is NULL, clean up the Gateway address.
+    //
+    if (Item->Data.Ptr != NULL) {
+      FreePool (Item->Data.Ptr);
+    }
+    Item->Data.Ptr = NULL;
+    Item->DataSize = 0;
+    Item->Status   = EFI_NOT_FOUND;
   }
+
+  return EFI_SUCCESS;
 }
 
 /**
   The work function for EfiIp6ConfigSetData() to set the DNS server list for the
   EFI IPv6 network stack running on the communication device that this EFI IPv6
@@ -1337,87 +1425,106 @@ Ip6ConfigSetDnsServer (
   UINTN                 NewDnsCount;
   IP6_CONFIG_DATA_ITEM  *Item;
   BOOLEAN               OneAdded;
   VOID                  *Tmp;
 
-  if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
+  OldDns = NULL;
+  NewDns = NULL;
+  Item   = NULL;
+  Tmp    = NULL;
+
+  if ((DataSize == 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
     return EFI_BAD_BUFFER_SIZE;
   }
 
   if (Instance->Policy != Ip6ConfigPolicyManual) {
     return EFI_WRITE_PROTECTED;
   }
 
-  Item        = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
-  NewDns      = (EFI_IPv6_ADDRESS *) Data;
-  OldDns      = Item->Data.DnsServers;
-  NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
-  OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
-  OneAdded    = FALSE;
+  Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
 
-  if (NewDnsCount != OldDnsCount) {
-    Tmp = AllocatePool (DataSize);
-    if (Tmp == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-  } else {
-    Tmp = NULL;
-  }
+  if (Data != NULL && DataSize != 0) {
+    NewDns      = (EFI_IPv6_ADDRESS *) Data;
+    OldDns      = Item->Data.DnsServers;
+    NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
+    OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
+    OneAdded    = FALSE;
 
-  for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
-
-    if (!NetIp6IsValidUnicast (NewDns + NewIndex)) {
-      //
-      // The dns server address must be unicast.
-      //
-      if (Tmp != NULL) {
-        FreePool (Tmp);
+    if (NewDnsCount != OldDnsCount) {
+      Tmp = AllocatePool (DataSize);
+      if (Tmp == NULL) {
+        return EFI_OUT_OF_RESOURCES;
       }
-      return EFI_INVALID_PARAMETER;
+    } else {
+      Tmp = NULL;
     }
 
-    if (OneAdded) {
-      //
-      // If any address in the new setting is not in the old settings, skip the
-      // comparision below.
-      //
-      continue;
-    }
+    for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
 
-    for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
-      if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+      if (!NetIp6IsValidUnicast (NewDns + NewIndex)) {
         //
-        // If found break out.
+        // The dns server address must be unicast.
         //
-        break;
+        if (Tmp != NULL) {
+          FreePool (Tmp);
+        }
+        return EFI_INVALID_PARAMETER;
       }
-    }
 
-    if (OldIndex == OldDnsCount) {
-      OneAdded = TRUE;
+      if (OneAdded) {
+        //
+        // If any address in the new setting is not in the old settings, skip the
+        // comparision below.
+        //
+        continue;
+      }
+
+      for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
+        if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+          //
+          // If found break out.
+          //
+          break;
+        }
+      }
+
+      if (OldIndex == OldDnsCount) {
+        OneAdded = TRUE;
+      }
     }
-  }
 
-  if (!OneAdded && (DataSize == Item->DataSize)) {
+    if (!OneAdded && (DataSize == Item->DataSize)) {
+      //
+      // No new item is added and the size is the same.
+      //
+      Item->Status = EFI_SUCCESS;
+      return EFI_ABORTED;
+    } else {
+      if (Tmp != NULL) {
+        if (Item->Data.Ptr != NULL) {
+          FreePool (Item->Data.Ptr);
+        }
+        Item->Data.Ptr = Tmp;
+      }
+
+      CopyMem (Item->Data.Ptr, Data, DataSize);
+      Item->DataSize = DataSize;
+      Item->Status   = EFI_SUCCESS;
+    }
+  } else  {
     //
-    // No new item is added and the size is the same.
+    // DataSize is 0 and Data is NULL, clean up the DnsServer address. 
     //
-    Item->Status = EFI_SUCCESS;
-    return EFI_ABORTED;
-  } else {
-    if (Tmp != NULL) {
-      if (Item->Data.Ptr != NULL) {
-        FreePool (Item->Data.Ptr);
-      }
-      Item->Data.Ptr = Tmp;
+    if (Item->Data.Ptr != NULL) {
+      FreePool (Item->Data.Ptr);
     }
-
-    CopyMem (Item->Data.Ptr, Data, DataSize);
-    Item->DataSize = DataSize;
-    Item->Status   = EFI_SUCCESS;
-    return EFI_SUCCESS;
+    Item->Data.Ptr = NULL;
+    Item->DataSize = 0;
+    Item->Status   = EFI_NOT_FOUND;
   }
+
+  return EFI_SUCCESS;
 }
 
 /**
   Generate the operational state of the interface this IP6 config instance manages
   and output in EFI_IP6_CONFIG_INTERFACE_INFO.
@@ -1822,13 +1929,12 @@ Ip6ConfigOnDhcp6SbInstalled (
 
   @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                 network stack was set successfully.
   @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                 - This is NULL.
-                                - Data is NULL.
-                                - One or more fields in Data do not match the requirement of the
-                                  data type indicated by DataType.
+                                - One or more fields in Data and DataSizedo not match the 
+                                  requirement of the data type indicated by DataType.
   @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified
                                 configuration data cannot be set under the current policy.
   @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration
                                 data is already in process.
   @retval EFI_NOT_READY         An asynchronous process was invoked to set the specified
@@ -1852,11 +1958,11 @@ EfiIp6ConfigSetData (
   EFI_TPL              OldTpl;
   EFI_STATUS           Status;
   IP6_CONFIG_INSTANCE  *Instance;
   IP6_SERVICE          *IpSb;
 
-  if ((This == NULL) || (Data == NULL)) {
+  if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) {
     return EFI_INVALID_PARAMETER;
   }
 
   if (DataType >= Ip6ConfigDataTypeMaximum) {
     return EFI_UNSUPPORTED;
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration
  2017-07-26  6:28 [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration Jiaxin Wu
                   ` (2 preceding siblings ...)
  2017-07-26  6:28 ` [Patch 3/3] NetworkPkg/Ip6Dxe: " Jiaxin Wu
@ 2017-08-10  5:54 ` Ye, Ting
  3 siblings, 0 replies; 5+ messages in thread
From: Ye, Ting @ 2017-08-10  5:54 UTC (permalink / raw)
  To: Wu, Jiaxin, edk2-devel@lists.01.org; +Cc: Fu, Siyuan

Series Reviewed-by: Ye Ting <ting.ye@intel.com>


-----Original Message-----
From: Wu, Jiaxin 
Sent: Wednesday, July 26, 2017 2:28 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration

UEFI Spec 2.7 adds the clarification on SetData interface usage to clear specific individual data types. The series patches are used to support this feature.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>

Jiaxin Wu (3):
  MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol
  MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific
    configuration
  NetworkPkg/Ip6Dxe: Support SetData interface to clear specific
    configuration

 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c      | 285 ++++++---
 MdePkg/Include/Protocol/Ip4Config2.h               |  17 +-
 MdePkg/Include/Protocol/Ip6Config.h                |  15 +-
 NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c                  | 692 ++++++++++++---------
 4 files changed, 610 insertions(+), 399 deletions(-)

--
1.9.5.msysgit.1



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-08-10  8:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-26  6:28 [Patch 0/3] Support Ip4Config2/Ip6Config.SetData interface to clear specific configuration Jiaxin Wu
2017-07-26  6:28 ` [Patch 1/3] MdePkg: Update the comments of Ip4Config2/Ip6Config Protocol Jiaxin Wu
2017-07-26  6:28 ` [Patch 2/3] MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration Jiaxin Wu
2017-07-26  6:28 ` [Patch 3/3] NetworkPkg/Ip6Dxe: " Jiaxin Wu
2017-08-10  5:54 ` [Patch 0/3] Support Ip4Config2/Ip6Config.SetData " Ye, Ting

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox