Pull request efi-next-2024-12-04

With this pull request support for the EFI_HTTP_PROTOCOL and
 EFI_IP4_CONFIG2 protocols are added. This allows EFI applications
 to load files via HTTP.
 
 UEFI:
       add efi_dp_from_ipv4 function
       add efi_net_set_addr, efi_net_get_addr functions
       add support for HTTP device path
       set EFI bootdevice device path to HTTP when loaded from wget
       add support to send http requests and parse http headers
       provide EFI_IP4_CONFIG2_PROTOCOL
       provide EFI_HTTP_PROTOCOL
       support IPv4() in device path to text protocol
       provide unit tests for the HTTP and IPv4 Config2 protocols
 
 Network:
       zero terminate string with headers in wget_fill_info()
       zero terminate string with headers in wget_lwip_fill_info()
       pass port and server_name via wget_ctx in lwIP network stack
       let wget_with_dns work with dns disabled
 
 Others:
       Add HTTP and IPV4 Config II protocols to UUID library functions.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEK7wKXt3/btL6/yA+hO4vgnE3U0sFAmdQPCsACgkQhO4vgnE3
 U0vqSA//Qhe8pM2na+9xuF1woFhLwAvxRyFc4XFkCNfuMk8qLbL+pqNoXpRKzqSE
 bm8qAfanO3twDKIyrFPYtUtI3ntm0/KpcB2eYsSaROoT7nDrh2EpUZ/5wjsGhkJn
 DbL8fYcRTxSDhf7gWimVBiF3Frdctfu5OOrkqT/CFx6l7GJtugF7cCU44Kg1Ec+P
 h2X+itvZ2B44YAgGwuOmbjf6FZeWj6HckNxr6w/XAw6LchDwTei2QCDRE/mJNSzy
 Ugm72VBD7bEa0B0zv33FARVmDzC94eITCRyPj+OhuQhqGopPq4v/vczsR69s6Gpn
 aucJukq+s4jdvivfKPEstvGBHC1kzPfuNOMRhdCLfdHDDS0L0Vr17BuZLDWrhflp
 i5HU8RPbUWeeLfP5uogbbgGKpTY/SzHHt7k9nsr4SceSlqXlzAqUvMFBBdfSxRS/
 YI5ThsLpnHfALnWv4cnlq+OW4Lo5wAmsrf4REGqH0JP/9sR1m2IszktgSIwYcSoC
 xPfGxqEQbSeJdjYWaB6LpMhEqIpNYZH44dEOOy2FS3Dwop3FBzb05BtDqeun90mS
 Bzzu/B4tbFOI88Gn/7P+5bD6KgGJzd8SmOWgu4imTCKLUKJV63V3mVz/6Kd3NoPm
 72vwMcKbrJZxRnaKKNisEQTzGygdz6eKRo7Ule1stYJ0R2KBJF8=
 =Wa3j
 -----END PGP SIGNATURE-----

Merge tag 'efi-next-2024-12-04' of https://source.denx.de/u-boot/custodians/u-boot-efi into next

CI: https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/23707

With this pull request support for the EFI_HTTP_PROTOCOL and
EFI_IP4_CONFIG2 protocols are added. This allows EFI applications
to load files via HTTP.

UEFI:
      add efi_dp_from_ipv4 function
      add efi_net_set_addr, efi_net_get_addr functions
      add support for HTTP device path
      set EFI bootdevice device path to HTTP when loaded from wget
      add support to send http requests and parse http headers
      provide EFI_IP4_CONFIG2_PROTOCOL
      provide EFI_HTTP_PROTOCOL
      support IPv4() in device path to text protocol
      provide unit tests for the HTTP and IPv4 Config2 protocols

Network:
      zero terminate string with headers in wget_fill_info()
      zero terminate string with headers in wget_lwip_fill_info()
      pass port and server_name via wget_ctx in lwIP network stack
      let wget_with_dns work with dns disabled

Others:
      Add HTTP and IPV4 Config II protocols to UUID library functions.
This commit is contained in:
Tom Rini 2024-12-04 09:32:28 -06:00
commit c498b6cace
19 changed files with 2131 additions and 57 deletions

View file

@ -974,6 +974,116 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
return start;
}
/**
* efi_dp_from_ipv4() - set device path from IPv4 address
*
* Set the device path to an ethernet device path as provided by
* efi_dp_from_eth() concatenated with a device path of subtype
* DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an END node.
*
* @ip: IPv4 local address
* @mask: network mask
* @srv: IPv4 remote/server address
* Return: pointer to device path, NULL on error
*/
static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
struct efi_ipv4_address *mask,
struct efi_ipv4_address *srv)
{
struct efi_device_path *dp1, *dp2, *pos;
struct {
struct efi_device_path_ipv4 ipv4dp;
struct efi_device_path end;
} dp;
memset(&dp.ipv4dp, 0, sizeof(dp.ipv4dp));
dp.ipv4dp.dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
dp.ipv4dp.dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_IPV4;
dp.ipv4dp.dp.length = sizeof(dp.ipv4dp);
dp.ipv4dp.protocol = 6;
if (ip)
memcpy(&dp.ipv4dp.local_ip_address, ip, sizeof(*ip));
if (mask)
memcpy(&dp.ipv4dp.subnet_mask, mask, sizeof(*mask));
if (srv)
memcpy(&dp.ipv4dp.remote_ip_address, srv, sizeof(*srv));
pos = &dp.end;
memcpy(pos, &END, sizeof(END));
dp1 = efi_dp_from_eth();
if (!dp1)
return NULL;
dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)&dp, 0);
efi_free_pool(dp1);
return dp2;
}
/**
* efi_dp_from_http() - set device path from http
*
* Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
* concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
* and an END node.
*
* @server: URI of remote server
* Return: pointer to HTTP device path, NULL on error
*/
struct efi_device_path *efi_dp_from_http(const char *server)
{
struct efi_device_path *dp1, *dp2;
struct efi_device_path_uri *uridp;
efi_uintn_t uridp_len;
char *pos;
char tmp[128];
struct efi_ipv4_address ip;
struct efi_ipv4_address mask;
if ((server && strlen("http://") + strlen(server) + 1 > sizeof(tmp)) ||
(!server && IS_ENABLED(CONFIG_NET_LWIP)))
return NULL;
efi_net_get_addr(&ip, &mask, NULL);
dp1 = efi_dp_from_ipv4(&ip, &mask, NULL);
if (!dp1)
return NULL;
strcpy(tmp, "http://");
if (server) {
strlcat(tmp, server, sizeof(tmp));
#if !IS_ENABLED(CONFIG_NET_LWIP)
} else {
ip_to_string(net_server_ip, tmp + strlen("http://"));
#endif
}
uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1;
uridp = efi_alloc(uridp_len + sizeof(END));
if (!uridp) {
log_err("Out of memory\n");
return NULL;
}
uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
uridp->dp.length = uridp_len;
debug("device path: setting uri device path to %s\n", tmp);
memcpy(uridp->uri, tmp, strlen(tmp) + 1);
pos = (char *)uridp + uridp_len;
memcpy(pos, &END, sizeof(END));
dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0);
efi_free_pool(uridp);
efi_free_pool(dp1);
return dp2;
}
/* Construct a device-path for memory-mapped image */
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
uint64_t start_address,
@ -1074,8 +1184,9 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
(uintptr_t)image_addr, image_size);
} else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) {
dp = efi_dp_from_eth();
} else if (IS_ENABLED(CONFIG_NETDEVICES) &&
(!strcmp(dev, "Net") || !strcmp(dev, "Http"))) {
efi_net_get_dp(&dp);
} else if (!strcmp(dev, "Uart")) {
dp = efi_dp_from_uart();
} else {