diff options
author | Gene Cumm <gene.cumm@gmail.com> | 2015-06-25 22:04:08 -0400 |
---|---|---|
committer | Gene Cumm <gene.cumm@gmail.com> | 2015-06-25 22:04:08 -0400 |
commit | 23b2707bd835d8a7158f9751134f427c6e743c40 (patch) | |
tree | 35030f03f49a138541800d95b7193a8258f5712a | |
parent | 6e958ddff25c1df2a11e8c72b8b1e20bd671e3fe (diff) | |
download | syslinux-23b2707bd835d8a7158f9751134f427c6e743c40.tar.gz syslinux-23b2707bd835d8a7158f9751134f427c6e743c40.tar.xz syslinux-23b2707bd835d8a7158f9751134f427c6e743c40.zip |
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@freenet.ag>
Reported-By: Michael Glasgow <glasgow@beer.net>
Reported-By: Da Shi Cao <dscao999@gmail.com>
Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r-- | efi/efi.h | 2 | ||||
-rw-r--r-- | efi/main.c | 40 | ||||
-rw-r--r-- | efi/pxe.c | 16 |
3 files changed, 23 insertions, 35 deletions
@@ -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 *); @@ -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 */ @@ -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"); + } } |