summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_net.c
diff options
context:
space:
mode:
authorAdriano Cordova <adrianox@gmail.com>2024-12-04 00:05:23 -0300
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2024-12-04 12:24:37 +0100
commite55a4acb54e807c6411c4f6ab914fa2b3f55784e (patch)
treeef9154333c7481e99569aefebd71b4dcfab51ffa /lib/efi_loader/efi_net.c
parent4b0723004b65bfaab528ce3aa669eb552e06130a (diff)
efi_loader: net: set EFI bootdevice device path to HTTP when loaded from wget
Set the device path of the efi boot device to an HTTP device path (as formed by efi_dp_from_http) when the next boot stage is loaded using wget (i.e., when wget is used with wget_info.set_bootdev=1). When loaded from HTTP, the device path should account for it so that the next boot stage is aware (e.g. grub only loads its http stack if it itself was loaded from http, and it checks this from its device path). Signed-off-by: Adriano Cordova <adrianox@gmail.com> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib/efi_loader/efi_net.c')
-rw-r--r--lib/efi_loader/efi_net.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 3491d4c4818..e8af2e3d95e 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -16,6 +16,7 @@
*/
#include <efi_loader.h>
+#include <dm.h>
#include <malloc.h>
#include <vsprintf.h>
#include <net.h>
@@ -33,6 +34,13 @@ static int rx_packet_num;
static struct efi_net_obj *netobj;
/*
+ * The current network device path. This device path is updated when a new
+ * bootfile is downloaded from the network. If then the bootfile is loaded
+ * as an efi image, net_dp is passed as the device path of the loaded image.
+ */
+static struct efi_device_path *net_dp;
+
+/*
* The notification function of this event is called in every timer cycle
* to check if a new network packet has been received.
*/
@@ -902,8 +910,10 @@ efi_status_t efi_net_register(void)
&netobj->net);
if (r != EFI_SUCCESS)
goto failure_to_add_protocol;
+ if (!net_dp)
+ efi_net_set_dp("Net", NULL);
r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
- efi_dp_from_eth());
+ net_dp);
if (r != EFI_SUCCESS)
goto failure_to_add_protocol;
r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid,
@@ -1000,6 +1010,49 @@ out_of_resources:
}
/**
+ * efi_net_set_dp() - set device path of efi net device
+ *
+ * This gets called to update the device path when a new boot
+ * file is downloaded
+ *
+ * @dev: dev to set the device path from
+ * @server: remote server address
+ * Return: status code
+ */
+efi_status_t efi_net_set_dp(const char *dev, const char *server)
+{
+ efi_free_pool(net_dp);
+
+ net_dp = NULL;
+ if (!strcmp(dev, "Net"))
+ net_dp = efi_dp_from_eth();
+ else if (!strcmp(dev, "Http"))
+ net_dp = efi_dp_from_http(server);
+
+ if (!net_dp)
+ return EFI_OUT_OF_RESOURCES;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_net_get_dp() - get device path of efi net device
+ *
+ * Produce a copy of the current device path
+ *
+ * @dp: copy of the current device path, or NULL on error
+ */
+void efi_net_get_dp(struct efi_device_path **dp)
+{
+ if (!dp)
+ return;
+ if (!net_dp)
+ efi_net_set_dp("Net", NULL);
+ if (net_dp)
+ *dp = efi_dp_dup(net_dp);
+}
+
+/**
* efi_net_get_addr() - get IP address information
*
* Copy the current IP address, mask, and gateway into the