aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini2021-10-22 08:56:45 -0400
committerTom Rini2021-10-22 12:43:30 -0400
commitf055f2e5a2038002519e5b9affbf259345f4ade9 (patch)
tree2388e5ea59e1e246d8f51b680d04861178f9608f /lib
parent06685f9de2c1ae37cd015848d245f8a59cbc93dc (diff)
parentaf484011f12e2aa37bcf4f9cbb4258dea4ef14ac (diff)
Merge tag 'efi-2022-01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2022-01-rc1 Documentation: Use Sphinx 3.43. Move system reset documentation to HTML UEFI: Fix linking EFI apps with LLVM Fix alignment of loaded image Correct simple network protocol test Code cleanup
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_driver/Makefile2
-rw-r--r--lib/efi_loader/Kconfig1
-rw-r--r--lib/efi_loader/efi_device_path.c103
-rw-r--r--lib/efi_loader/efi_disk.c48
-rw-r--r--lib/efi_loader/efi_helper.c24
-rw-r--r--lib/efi_loader/efi_image_loader.c12
-rw-r--r--lib/efi_loader/efi_load_initrd.c3
-rw-r--r--lib/efi_loader/efi_memory.c52
-rw-r--r--lib/efi_loader/efi_var_file.c8
-rw-r--r--lib/efi_selftest/efi_selftest_snp.c90
10 files changed, 152 insertions, 191 deletions
diff --git a/lib/efi_driver/Makefile b/lib/efi_driver/Makefile
index 83baa1c9a49..f2b6c05cc24 100644
--- a/lib/efi_driver/Makefile
+++ b/lib/efi_driver/Makefile
@@ -6,6 +6,6 @@
# object inclusion implicitly depends on it
obj-y += efi_uclass.o
-ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
+ifeq ($(CONFIG_PARTITIONS),y)
obj-y += efi_block_device.o
endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 83d584a60e5..06633e90a10 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -11,6 +11,7 @@ config EFI_LOADER
# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT
depends on BLK
+ depends on DM_ETH || !NET
default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
select LIB_UUID
select PARTITION_UUIDS
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index cbdb466da41..c04439d16d8 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -46,7 +46,7 @@ static const struct efi_device_path_vendor ROOT = {
.guid = U_BOOT_GUID,
};
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+#if defined(CONFIG_MMC)
/*
* Determine if an MMC device is an SD card.
*
@@ -486,7 +486,6 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
}
-#ifdef CONFIG_DM
/* size of device-path not including END node for device and all parents
* up to the root device.
*/
@@ -503,7 +502,6 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
case UCLASS_ETH:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_mac_addr);
-#ifdef CONFIG_BLK
case UCLASS_BLK:
switch (dev->parent->uclass->uc_drv->id) {
#ifdef CONFIG_IDE
@@ -511,12 +509,12 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
return dp_size(dev->parent) +
sizeof(struct efi_device_path_atapi);
#endif
-#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
+#if defined(CONFIG_SCSI)
case UCLASS_SCSI:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_scsi);
#endif
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+#if defined(CONFIG_MMC)
case UCLASS_MMC:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_sd_mmc_path);
@@ -554,8 +552,7 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
default:
return dp_size(dev->parent);
}
-#endif
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+#if defined(CONFIG_MMC)
case UCLASS_MMC:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_sd_mmc_path);
@@ -590,7 +587,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
*vdp = ROOT;
return &vdp[1];
}
-#ifdef CONFIG_DM_ETH
+#ifdef CONFIG_NET
case UCLASS_ETH: {
struct efi_device_path_mac_addr *dp =
dp_fill(buf, dev->parent);
@@ -607,7 +604,6 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return &dp[1];
}
#endif
-#ifdef CONFIG_BLK
case UCLASS_BLK:
switch (dev->parent->uclass->uc_drv->id) {
#ifdef CONFIG_SANDBOX
@@ -662,7 +658,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return &dp[1];
}
#endif
-#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
+#if defined(CONFIG_SCSI)
case UCLASS_SCSI: {
struct efi_device_path_scsi *dp =
dp_fill(buf, dev->parent);
@@ -676,7 +672,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return &dp[1];
}
#endif
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+#if defined(CONFIG_MMC)
case UCLASS_MMC: {
struct efi_device_path_sd_mmc_path *sddp =
dp_fill(buf, dev->parent);
@@ -727,8 +723,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
dev->name, dev->parent->uclass->uc_drv->id);
return dp_fill(buf, dev->parent);
}
-#endif
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+#if defined(CONFIG_MMC)
case UCLASS_MMC: {
struct efi_device_path_sd_mmc_path *sddp =
dp_fill(buf, dev->parent);
@@ -770,24 +765,18 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return dp_fill(buf, dev->parent);
}
}
-#endif
static unsigned dp_part_size(struct blk_desc *desc, int part)
{
unsigned dpsize;
+ struct udevice *dev;
+ int ret;
-#ifdef CONFIG_BLK
- {
- struct udevice *dev;
- int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+ ret = blk_find_device(desc->if_type, desc->devnum, &dev);
- if (ret)
- dev = desc->bdev->parent;
- dpsize = dp_size(dev);
- }
-#else
- dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb);
-#endif
+ if (ret)
+ dev = desc->bdev->parent;
+ dpsize = dp_size(dev);
if (part == 0) /* the actual disk, not a partition */
return dpsize;
@@ -877,36 +866,14 @@ static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
*/
static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
{
-#ifdef CONFIG_BLK
- {
- struct udevice *dev;
- int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+ struct udevice *dev;
+ int ret;
- if (ret)
- dev = desc->bdev->parent;
- buf = dp_fill(buf, dev);
- }
-#else
- /*
- * We *could* make a more accurate path, by looking at if_type
- * and handling all the different cases like we do for non-
- * legacy (i.e. CONFIG_BLK=y) case. But most important thing
- * is just to have a unique device-path for if_type+devnum.
- * So map things to a fictitious USB device.
- */
- struct efi_device_path_usb *udp;
-
- memcpy(buf, &ROOT, sizeof(ROOT));
- buf += sizeof(ROOT);
-
- udp = buf;
- udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
- udp->dp.length = sizeof(*udp);
- udp->parent_port_number = desc->if_type;
- udp->usb_interface = desc->devnum;
- buf = &udp[1];
-#endif
+ ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+
+ if (ret)
+ dev = desc->bdev->parent;
+ buf = dp_fill(buf, dev);
if (part == 0) /* the actual disk, not a partition */
return buf;
@@ -1051,39 +1018,18 @@ struct efi_device_path *efi_dp_from_uart(void)
#ifdef CONFIG_NET
struct efi_device_path *efi_dp_from_eth(void)
{
-#ifndef CONFIG_DM_ETH
- struct efi_device_path_mac_addr *ndp;
-#endif
void *buf, *start;
unsigned dpsize = 0;
assert(eth_get_dev());
-#ifdef CONFIG_DM_ETH
dpsize += dp_size(eth_get_dev());
-#else
- dpsize += sizeof(ROOT);
- dpsize += sizeof(*ndp);
-#endif
start = buf = dp_alloc(dpsize + sizeof(END));
if (!buf)
return NULL;
-#ifdef CONFIG_DM_ETH
buf = dp_fill(buf, eth_get_dev());
-#else
- memcpy(buf, &ROOT, sizeof(ROOT));
- buf += sizeof(ROOT);
-
- ndp = buf;
- ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
- ndp->dp.length = sizeof(*ndp);
- ndp->if_type = 1; /* Ethernet */
- memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN);
- buf = &ndp[1];
-#endif
*((struct efi_device_path *)buf) = END;
@@ -1263,7 +1209,6 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp,
* initrd location
*
* @lo: EFI_LOAD_OPTION containing a valid device path
- * @size: size of the discovered device path
* @guid: guid to search for
*
* Return:
@@ -1272,7 +1217,7 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp,
*/
struct
efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
- efi_uintn_t *size, efi_guid_t guid)
+ const efi_guid_t *guid)
{
struct efi_device_path *fp = lo->file_path;
struct efi_device_path_vendor *vendor;
@@ -1287,8 +1232,8 @@ efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
continue;
vendor = (struct efi_device_path_vendor *)fp;
- if (!guidcmp(&vendor->guid, &guid))
- return efi_dp_dup(fp);
+ if (!guidcmp(&vendor->guid, guid))
+ return efi_dp_dup(efi_dp_next(fp));
}
log_debug("VenMedia(%pUl) not found in %ls\n", &guid, lo->label);
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 988907ecb91..ef8b5c88ff9 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -555,7 +555,6 @@ efi_status_t efi_disk_register(void)
struct efi_disk_obj *disk;
int disks = 0;
efi_status_t ret;
-#ifdef CONFIG_BLK
struct udevice *dev;
for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
@@ -583,54 +582,7 @@ efi_status_t efi_disk_register(void)
&disk->header, desc, if_typename,
desc->devnum, dev->name);
}
-#else
- int i, if_type;
- /* Search for all available disk devices */
- for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
- const struct blk_driver *cur_drvr;
- const char *if_typename;
-
- cur_drvr = blk_driver_lookup_type(if_type);
- if (!cur_drvr)
- continue;
-
- if_typename = cur_drvr->if_typename;
- log_info("Scanning disks on %s...\n", if_typename);
- for (i = 0; i < 4; i++) {
- struct blk_desc *desc;
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
-
- desc = blk_get_devnum_by_type(if_type, i);
- if (!desc)
- continue;
- if (desc->type == DEV_TYPE_UNKNOWN)
- continue;
-
- snprintf(devname, sizeof(devname), "%s%d",
- if_typename, i);
-
- /* Add block device for the full device */
- ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
- i, NULL, 0, &disk);
- if (ret == EFI_NOT_READY) {
- log_notice("Disk %s not ready\n", devname);
- continue;
- }
- if (ret) {
- log_err("ERROR: failure to add disk device %s, r = %lu\n",
- devname, ret & ~EFI_ERROR_MASK);
- return ret;
- }
- disks++;
-
- /* Partitions show up as block devices in EFI */
- disks += efi_disk_create_partitions
- (&disk->header, desc,
- if_typename, i, devname);
- }
- }
-#endif
log_info("Found %d disks\n", disks);
return EFI_SUCCESS;
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index d03a7364615..b80a6e07dff 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -13,6 +13,11 @@
#include <efi_loader.h>
#include <efi_variable.h>
+#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI_LOAD_FILE2_INITRD)
+/* GUID used by Linux to identify the LoadFile2 protocol with the initrd */
+const efi_guid_t efi_lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
+#endif
+
/**
* efi_create_current_boot_var() - Return Boot#### name were #### is replaced by
* the value of BootCurrent
@@ -63,10 +68,8 @@ out:
*/
struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
{
- struct efi_device_path *file_path = NULL;
- struct efi_device_path *tmp = NULL;
struct efi_load_option lo;
- void *var_value = NULL;
+ void *var_value;
efi_uintn_t size;
efi_status_t ret;
u16 var_name[16];
@@ -81,18 +84,11 @@ struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
ret = efi_deserialize_load_option(&lo, var_value, &size);
if (ret != EFI_SUCCESS)
- goto out;
-
- tmp = efi_dp_from_lo(&lo, &size, guid);
- if (!tmp)
- goto out;
+ goto err;
- /* efi_dp_dup will just return NULL if efi_dp_next is NULL */
- file_path = efi_dp_dup(efi_dp_next(tmp));
+ return efi_dp_from_lo(&lo, &guid);
-out:
- efi_free_pool(tmp);
+err:
free(var_value);
-
- return file_path;
+ return NULL;
}
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index e9572d4d5db..eb95580538c 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -898,9 +898,9 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
image_base = opt->ImageBase;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
handle->image_type = opt->Subsystem;
- virt_size = ALIGN(virt_size, opt->SectionAlignment);
- efi_reloc = efi_alloc(virt_size,
- loaded_image_info->image_code_type);
+ efi_reloc = efi_alloc_aligned_pages(virt_size,
+ loaded_image_info->image_code_type,
+ opt->SectionAlignment);
if (!efi_reloc) {
log_err("Out of memory\n");
ret = EFI_OUT_OF_RESOURCES;
@@ -914,9 +914,9 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
image_base = opt->ImageBase;
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
handle->image_type = opt->Subsystem;
- virt_size = ALIGN(virt_size, opt->SectionAlignment);
- efi_reloc = efi_alloc(virt_size,
- loaded_image_info->image_code_type);
+ efi_reloc = efi_alloc_aligned_pages(virt_size,
+ loaded_image_info->image_code_type,
+ opt->SectionAlignment);
if (!efi_reloc) {
log_err("Out of memory\n");
ret = EFI_OUT_OF_RESOURCES;
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
index e2a80630230..c5e6652e664 100644
--- a/lib/efi_loader/efi_load_initrd.c
+++ b/lib/efi_loader/efi_load_initrd.c
@@ -52,7 +52,6 @@ static efi_handle_t efi_initrd_handle;
*/
static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
{
- const efi_guid_t lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
struct efi_device_path *dp = NULL;
/*
@@ -65,7 +64,7 @@ static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
* We can then use this specific return value and not install the
* protocol, while allowing the boot to continue
*/
- dp = efi_get_dp_from_boot(lf2_initrd_guid);
+ dp = efi_get_dp_from_boot(efi_lf2_initrd_guid);
if (!dp)
return EFI_INVALID_PARAMETER;
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index f4acbee4f9b..7f0b5072819 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -550,6 +550,58 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
}
/**
+ * efi_alloc_aligned_pages - allocate
+ *
+ * @len: len in bytes
+ * @memory_type: usage type of the allocated memory
+ * @align: alignment in bytes
+ * Return: aligned memory or NULL
+ */
+void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align)
+{
+ u64 req_pages = efi_size_in_pages(len);
+ u64 true_pages = req_pages + efi_size_in_pages(align) - 1;
+ u64 free_pages;
+ u64 aligned_mem;
+ efi_status_t r;
+ u64 mem;
+
+ /* align must be zero or a power of two */
+ if (align & (align - 1))
+ return NULL;
+
+ /* Check for overflow */
+ if (true_pages < req_pages)
+ return NULL;
+
+ if (align < EFI_PAGE_SIZE) {
+ r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
+ req_pages, &mem);
+ return (r == EFI_SUCCESS) ? (void *)(uintptr_t)mem : NULL;
+ }
+
+ r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
+ true_pages, &mem);
+ if (r != EFI_SUCCESS)
+ return NULL;
+
+ aligned_mem = ALIGN(mem, align);
+ /* Free pages before alignment */
+ free_pages = efi_size_in_pages(aligned_mem - mem);
+ if (free_pages)
+ efi_free_pages(mem, free_pages);
+
+ /* Free trailing pages */
+ free_pages = true_pages - (req_pages + free_pages);
+ if (free_pages) {
+ mem = aligned_mem + req_pages * EFI_PAGE_SIZE;
+ efi_free_pages(mem, free_pages);
+ }
+
+ return (void *)(uintptr_t)aligned_mem;
+}
+
+/**
* efi_allocate_pool - allocate memory from pool
*
* @pool_type: type of the pool from which memory is to be allocated
diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
index c7c6805ed05..76a2ff9e412 100644
--- a/lib/efi_loader/efi_var_file.c
+++ b/lib/efi_loader/efi_var_file.c
@@ -19,6 +19,13 @@
#define PART_STR_LEN 10
+/* GUID used by Shim to store the MOK database */
+#define SHIM_LOCK_GUID \
+ EFI_GUID(0x605dab50, 0xe046, 0x4300, \
+ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
+static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
+
/**
* efi_set_blk_dev_to_system_partition() - select EFI system partition
*
@@ -175,6 +182,7 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
if (!safe &&
(efi_auth_var_get_type(var->name, &var->guid) !=
EFI_AUTH_VAR_NONE ||
+ !guidcmp(&var->guid, &shim_lock_guid) ||
!(var->attr & EFI_VARIABLE_NON_VOLATILE)))
continue;
if (!var->length)
diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c
index 79f04678039..818cbfcacd4 100644
--- a/lib/efi_selftest/efi_selftest_snp.c
+++ b/lib/efi_selftest/efi_selftest_snp.c
@@ -309,6 +309,18 @@ static int execute(void)
return EFI_ST_FAILURE;
}
+ /* Check media connected */
+ ret = net->get_status(net, NULL, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to get status");
+ return EFI_ST_FAILURE;
+ }
+ if (net->mode && net->mode->media_present_supported &&
+ !net->mode->media_present) {
+ efi_st_error("Network media is not connected");
+ return EFI_ST_FAILURE;
+ }
+
/*
* Send DHCP discover message
*/
@@ -328,8 +340,6 @@ static int execute(void)
events[0] = timer;
events[1] = net->wait_for_packet;
for (;;) {
- u32 int_status;
-
/*
* Wait for packet to be received or timer event.
*/
@@ -352,48 +362,46 @@ static int execute(void)
continue;
}
/*
- * Receive packet
+ * Receive packets until buffer is empty
*/
- buffer_size = sizeof(buffer);
- ret = net->get_status(net, &int_status, NULL);
- if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to get status");
- return EFI_ST_FAILURE;
- }
- if (!(int_status & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT)) {
- efi_st_error("RX interrupt not set");
- return EFI_ST_FAILURE;
- }
- ret = net->receive(net, NULL, &buffer_size, &buffer,
- &srcaddr, &destaddr, NULL);
- if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to receive packet");
- return EFI_ST_FAILURE;
+ for (;;) {
+ buffer_size = sizeof(buffer);
+ ret = net->receive(net, NULL, &buffer_size, &buffer,
+ &srcaddr, &destaddr, NULL);
+ if (ret == EFI_NOT_READY) {
+ /* The received buffer is empty. */
+ break;
+ }
+
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to receive packet");
+ return EFI_ST_FAILURE;
+ }
+ /*
+ * Check the packet is meant for this system.
+ * Unfortunately QEMU ignores the broadcast flag.
+ * So we have to check for broadcasts too.
+ */
+ if (memcmp(&destaddr, &net->mode->current_address, ARP_HLEN) &&
+ memcmp(&destaddr, BROADCAST_MAC, ARP_HLEN))
+ continue;
+ /*
+ * Check this is a DHCP reply
+ */
+ if (buffer.p.eth_hdr.et_protlen != ntohs(PROT_IP) ||
+ buffer.p.ip_udp.ip_hl_v != 0x45 ||
+ buffer.p.ip_udp.ip_p != IPPROTO_UDP ||
+ buffer.p.ip_udp.udp_src != ntohs(67) ||
+ buffer.p.ip_udp.udp_dst != ntohs(68) ||
+ buffer.p.dhcp_hdr.op != BOOTREPLY)
+ continue;
+ /*
+ * We successfully received a DHCP reply.
+ */
+ goto received;
}
- /*
- * Check the packet is meant for this system.
- * Unfortunately QEMU ignores the broadcast flag.
- * So we have to check for broadcasts too.
- */
- if (memcmp(&destaddr, &net->mode->current_address, ARP_HLEN) &&
- memcmp(&destaddr, BROADCAST_MAC, ARP_HLEN))
- continue;
- /*
- * Check this is a DHCP reply
- */
- if (buffer.p.eth_hdr.et_protlen != ntohs(PROT_IP) ||
- buffer.p.ip_udp.ip_hl_v != 0x45 ||
- buffer.p.ip_udp.ip_p != IPPROTO_UDP ||
- buffer.p.ip_udp.udp_src != ntohs(67) ||
- buffer.p.ip_udp.udp_dst != ntohs(68) ||
- buffer.p.dhcp_hdr.op != BOOTREPLY)
- continue;
- /*
- * We successfully received a DHCP reply.
- */
- break;
}
-
+received:
/*
* Write a log message.
*/