[syslinux:master] efi/pxe: Reuse handle

syslinux-bot for Gene Cumm gene.cumm at gmail.com
Thu Jun 25 19:09:03 PDT 2015


Commit-ID:  23b2707bd835d8a7158f9751134f427c6e743c40
Gitweb:     http://www.syslinux.org/commit/23b2707bd835d8a7158f9751134f427c6e743c40
Author:     Gene Cumm <gene.cumm at gmail.com>
AuthorDate: Thu, 25 Jun 2015 22:04:08 -0400
Committer:  Gene Cumm <gene.cumm at gmail.com>
CommitDate: Thu, 25 Jun 2015 22:04:08 -0400

efi/pxe: Reuse handle

Store and reuse handle found with EFI_LOADED_IMAGE_PROTOCOL for
EFI_PXE_BASE_CODE_PROTOCOL and EFI_UDP4_SERVICE_BINDING_PROTOCOL

This caused machines with multiple NICs to not reliably attach to the
correct NIC handle.

gnu-efi LoadedImageProtocol PxeBaseCodeProtocol Udp4ServiceBindingProtocol

Reported-By: Holger Baust <holger.baust at freenet.ag>
Reported-By: Michael Glasgow <glasgow at beer.net>
Reported-By: Da Shi Cao <dscao999 at gmail.com>
Signed-off-by: Gene Cumm <gene.cumm at gmail.com>

---
 efi/efi.h  |  2 +-
 efi/main.c | 40 ++++++++++++++++------------------------
 efi/pxe.c  | 16 ++++++----------
 3 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/efi/efi.h b/efi/efi.h
index ef5bacb..1416488 100644
--- a/efi/efi.h
+++ b/efi/efi.h
@@ -42,7 +42,7 @@ struct efi_binding {
     EFI_HANDLE this;
 };
 
-extern EFI_HANDLE image_handle;
+extern EFI_HANDLE image_handle, pxe_handle;
 
 struct screen_info;
 extern void setup_screen(struct screen_info *);
diff --git a/efi/main.c b/efi/main.c
index 208fee4..6e43f79 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -40,36 +40,27 @@ efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
 			     guid, agent, controller);
 }
 
+/* As of UEFI-2.4.0, all EFI_SERVICE_BINDINGs are for networking */
 struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
 {
     EFI_SERVICE_BINDING *sbp;
     struct efi_binding *b;
     EFI_STATUS status;
-    EFI_HANDLE protocol, child, *handles = NULL;
-    UINTN i, nr_handles = 0;
+    EFI_HANDLE protocol, child;
 
     b = malloc(sizeof(*b));
     if (!b)
 	return NULL;
 
-    status = LibLocateHandle(ByProtocol, bguid, NULL, &nr_handles, &handles);
+    status = uefi_call_wrapper(BS->OpenProtocol, 6, pxe_handle,
+			       bguid, (void **)&sbp,
+			       image_handle, pxe_handle,
+			       EFI_OPEN_PROTOCOL_GET_PROTOCOL);
     if (status != EFI_SUCCESS)
 	goto free_binding;
 
-    for (i = 0; i < nr_handles; i++) {
-	status = uefi_call_wrapper(BS->OpenProtocol, 6, handles[i],
-				   bguid, (void **)&sbp,
-				   image_handle, handles[i],
-				   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-	if (status == EFI_SUCCESS)
-	    break;
-
-	uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
-			  image_handle, handles[i]);
-    }
-
-    if (i == nr_handles)
-	goto free_binding;
+    uefi_call_wrapper(BS->CloseProtocol, 4, pxe_handle, bguid,
+		      image_handle, pxe_handle);
 
     child = NULL;
 
@@ -78,13 +69,13 @@ struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
 	goto close_protocol;
 
     status = uefi_call_wrapper(BS->OpenProtocol, 6, child,
-			      pguid, (void **)&protocol,
-			      image_handle, sbp,
-			      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+			       pguid, (void **)&protocol,
+			       image_handle, sbp,
+			       EFI_OPEN_PROTOCOL_GET_PROTOCOL);
     if (status != EFI_SUCCESS)
 	goto destroy_child;
 
-    b->parent = handles[i];
+    b->parent = pxe_handle;
     b->binding = sbp;
     b->child = child;
     b->this = protocol;
@@ -95,8 +86,8 @@ destroy_child:
     uefi_call_wrapper(sbp->DestroyChild, 2, sbp, child);
 
 close_protocol:
-    uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
-		      image_handle, handles[i]);
+    uefi_call_wrapper(BS->CloseProtocol, 4, pxe_handle, bguid,
+		      image_handle, pxe_handle);
 
 free_binding:
     free(b);
@@ -454,7 +445,7 @@ get_mem_desc(unsigned long memmap, UINTN desc_sz, int i)
 	return (EFI_MEMORY_DESCRIPTOR *)(memmap + (i * desc_sz));
 }
 
-EFI_HANDLE image_handle;
+EFI_HANDLE image_handle, pxe_handle;
 
 static inline UINT64 round_up(UINT64 x, UINT64 y)
 {
@@ -1295,6 +1286,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 	} else {
 		efi_derivative(SYSLINUX_FS_PXELINUX);
 		ops[0] = &pxe_fs_ops;
+		pxe_handle = info->DeviceHandle;
 	}
 
 	/* setup timer for boot menu system support */
diff --git a/efi/pxe.c b/efi/pxe.c
index 443ab47..82cdee4 100644
--- a/efi/pxe.c
+++ b/efi/pxe.c
@@ -93,20 +93,13 @@ void net_parse_dhcp(void)
     EFI_PXE_BASE_CODE *bc;
     unsigned int pkt_len = sizeof(EFI_PXE_BASE_CODE_PACKET);
     EFI_STATUS status;
-    EFI_HANDLE *handles = NULL;
-    UINTN nr_handles = 0;
     uint8_t hardlen;
     uint32_t ip;
     char dst[256];
+    UINTN i = 0;
 
-    status = LibLocateHandle(ByProtocol, &PxeBaseCodeProtocol,
-			 NULL, &nr_handles, &handles);
-    if (status != EFI_SUCCESS)
-	return;
-
-    /* Probably want to use IPv4 protocol to decide which handle to use */
-    status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[0],
-			   &PxeBaseCodeProtocol, (void **)&bc);
+    status = uefi_call_wrapper(BS->HandleProtocol, 3, pxe_handle,
+			       &PxeBaseCodeProtocol, (void **)&bc);
     if (status != EFI_SUCCESS) {
 	Print(L"Failed to lookup PxeBaseCodeProtocol\n");
     }
@@ -182,4 +175,7 @@ void net_parse_dhcp(void)
         ((const uint8_t *)&ip)[3]);
 
     Print(L"My IP is %a\n", dst);
+    if (!(ip_ok(ip))) {
+	Print(L"  NO valid IP found.\n");
+    }
 }


More information about the Syslinux-commits mailing list