v2:
*
If the VLAN has duplicate items, try to delete it instead using VLAN
Id 4095 which is a "reserved" tag number.

Duplicate items in VLAN variable will cause MNP driver binding
start function fall into infinite loop,so we should check it's
content before using it.

Cc: Fu Siyuan <[email protected]>
Cc: Ye Ting <[email protected]>
Cc: Wu Jiaxin <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang Lubo <[email protected]>
---
 MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c | 46 +++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c 
b/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
index 6e14c1f..7000e2e 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
@@ -228,10 +228,51 @@ MnpInsertVlanTag (
   VlanTci->Bits.Cfi      = VLAN_TCI_CFI_CANONICAL_MAC;
   VlanTci->Bits.Priority = MnpServiceData->Priority;
   VlanTci->Uint16        = HTONS (VlanTci->Uint16);
 }
 
+/**
+  Check VLAN configuration variable and delete the duplicative content if has 
identical Vlan ID.
+
+  @param[in]      Buffer             Pointer to the buffer contains the array 
of VLAN_TCI.
+  @param[in]      NumberOfVlan       Pointer to number of VLAN.
+  @param[out]     NewNumberOfVlan    Pointer to number of unique VLAN.
+
+**/
+VOID
+MnpCheckVlanVariable (
+  IN     VLAN_TCI          *Buffer,
+  IN     UINTN             NumberOfVlan,
+     OUT UINTN             *NewNumberOfVlan
+  )
+{
+  UINTN             Index;
+  UINTN             Index2;
+  UINTN             Count;
+  BOOLEAN           FoundDuplicateItem;
+
+  Count = 0;
+  FoundDuplicateItem  = FALSE;
+
+  for (Index = 0; Index < NumberOfVlan; Index++) {
+   for (Index2 = Index + 1; Index2 < NumberOfVlan; Index2++) {
+     if (Buffer[Index].Bits.Vid == Buffer[Index2].Bits.Vid) {
+       FoundDuplicateItem = TRUE;
+       Count++;
+       continue;
+     }
+   }
+   if (FoundDuplicateItem) {
+    for (Index2 = Index +1; Index2 < NumberOfVlan; Index++, Index2++) {
+      CopyMem (Buffer + Index, Buffer + Index2, sizeof (VLAN_TCI));
+    }
+   }
+   FoundDuplicateItem = FALSE;
+  }
+
+  *NewNumberOfVlan = NumberOfVlan - Count;
+}
 
 /**
   Get VLAN configuration variable.
 
   @param[in]       MnpDeviceData      Pointer to the MNP device context data.
@@ -253,10 +294,11 @@ MnpGetVlanVariable (
   )
 {
   UINTN       BufferSize;
   EFI_STATUS  Status;
   VLAN_TCI    *Buffer;
+  UINTN       NewNumberOfVlan;
 
   //
   // Get VLAN configuration from EFI Variable
   //
   Buffer = NULL;
@@ -290,17 +332,17 @@ MnpGetVlanVariable (
   if (EFI_ERROR (Status)) {
     FreePool (Buffer);
     return Status;
   }
 
-  *NumberOfVlan = BufferSize / sizeof (VLAN_TCI);
+  MnpCheckVlanVariable (Buffer, BufferSize / sizeof (VLAN_TCI), 
&NewNumberOfVlan);
+  *NumberOfVlan = NewNumberOfVlan;
   *VlanVariable = Buffer;
 
   return Status;
 }
 
-
 /**
   Set VLAN configuration variable.
 
   @param[in] MnpDeviceData       Pointer to the MNP device context data.
   @param[in] NumberOfVlan        Number of VLAN in array VlanVariable.
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to