Allow efi loader to get network params from uboot

Summary:
efi loader does not work with static network parameters. It always uses
BOOTP/DHCP and also uses RARP as a fallback.  Problems with DHCP servers can
cause the loader to fail to populate network parameters.

Submitted by:	Siddharth Tuli <siddharthtuli_gmail.com>
Reviewed by:	imp
Sponsored by:	Juniper Networks, Inc.
Differential Revision:	https://reviews.freebsd.org/D20811
This commit is contained in:
Justin Hibbits 2019-07-12 00:54:20 +00:00
parent fe1329e446
commit 1ea717577f
2 changed files with 74 additions and 0 deletions

View File

@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
#include <efi.h> #include <efi.h>
#include <efilib.h> #include <efilib.h>
#include "dev_net.h"
static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL; static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL;
static void efinet_end(struct netif *); static void efinet_end(struct netif *);
@ -198,6 +200,74 @@ efinet_get(struct iodesc *desc, void **pkt, time_t timeout)
return (ret); return (ret);
} }
/*
* Loader uses BOOTP/DHCP and also uses RARP as a fallback to populate
* network parameters and problems with DHCP servers can cause the loader
* to fail to populate them. Allow the device to ask about the basic
* network parameters and if present use them.
*/
static void
efi_env_net_params(struct iodesc *desc)
{
char *envstr;
in_addr_t ipaddr, mask, gwaddr, serveraddr;
n_long rootaddr;
if ((envstr = getenv("rootpath")) != NULL)
strlcpy(rootpath, envstr, sizeof(rootpath));
/*
* Get network parameters.
*/
envstr = getenv("ipaddr");
ipaddr = (envstr != NULL) ? inet_addr(envstr) : 0;
envstr = getenv("netmask");
mask = (envstr != NULL) ? inet_addr(envstr) : 0;
envstr = getenv("gatewayip");
gwaddr = (envstr != NULL) ? inet_addr(envstr) : 0;
envstr = getenv("serverip");
serveraddr = (envstr != NULL) ? inet_addr(envstr) : 0;
/* No network params. */
if (ipaddr == 0 && mask == 0 && gwaddr == 0 && serveraddr == 0)
return;
/* Partial network params. */
if (ipaddr == 0 || mask == 0 || gwaddr == 0 || serveraddr == 0) {
printf("Incomplete network settings from U-Boot\n");
return;
}
/*
* Set network parameters.
*/
myip.s_addr = ipaddr;
netmask = mask;
gateip.s_addr = gwaddr;
servip.s_addr = serveraddr;
/*
* There must be a rootpath. It may be ip:/path or it may be just the
* path in which case the ip needs to be serverip.
*/
rootaddr = net_parse_rootpath();
if (rootaddr == INADDR_NONE)
rootaddr = serveraddr;
rootip.s_addr = rootaddr;
#ifdef EFINET_DEBUG
printf("%s: ip=%s\n", __func__, inet_ntoa(myip));
printf("%s: mask=%s\n", __func__, intoa(netmask));
printf("%s: gateway=%s\n", __func__, inet_ntoa(gateip));
printf("%s: server=%s\n", __func__, inet_ntoa(servip));
#endif
desc->myip = myip;
}
static void static void
efinet_init(struct iodesc *desc, void *machdep_hint) efinet_init(struct iodesc *desc, void *machdep_hint)
{ {
@ -207,6 +277,9 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
EFI_STATUS status; EFI_STATUS status;
UINT32 mask; UINT32 mask;
/* Attempt to get netboot params from env */
efi_env_net_params(desc);
if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) { if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) {
printf("Invalid network interface %d\n", nif->nif_unit); printf("Invalid network interface %d\n", nif->nif_unit);
return; return;

View File

@ -91,6 +91,7 @@ extern struct in_addr rootip;
extern struct in_addr swapip; extern struct in_addr swapip;
extern struct in_addr gateip; extern struct in_addr gateip;
extern struct in_addr nameip; extern struct in_addr nameip;
extern struct in_addr servip;
extern n_long netmask; extern n_long netmask;
extern u_int intf_mtu; extern u_int intf_mtu;