1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-16 15:11:52 +00:00

Netboot: allow both tftpfs and nfs in both pxeboot and loader.efi

Add a new 'netproto' variable which can be set for now to
NET_TFTP or NET_NFS (default to NET_NONE)

From the dhcp options if one sets the root-path option to:
"ip:path", the loader will consider it is booting over NFS
(meaning same behaviour as the default current behaviour)

if the dhcp option "tftp server address" is set (option 150)
the loader will consider it is booting over tftpfs, it will then
consider the root-path options with 2 possible case
1. "path" then the IP of the tftp server will be the one passed by
the option 150, and the files will be retrieved under "path" on the tftp
server
2. "ip:path" then the IP of the tftp server will be the one passed in
the option "overwritting the IP from the option 150.

We could not "abuse" the rootpath option in the form or tftp://ip:path because
this is already used for other purpose by iPXE preventing any chainload from
iPXE to the FreeBSD loader.

Given at each open(), the loader loops over all available filesystems and keep
the "best" error, we needed to prevent tftpfs to fallback on nfs and vice versa.
the tftpfs and nfs implementation in libstand now return EINVAL early if
'netproto' for that purpose.

Reviewed by:	tsoome
Relnotes:	yes
Sponsored by:	Gandi.net
Differential Revision:	https://reviews.freebsd.org/D7628
This commit is contained in:
Baptiste Daroussin 2016-08-31 13:16:40 +00:00
parent 44feca2360
commit 6a695123b0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305125
13 changed files with 64 additions and 44 deletions

View File

@ -411,6 +411,10 @@ vend_rfc1048(cp, len)
bcopy(cp, &dhcp_serverip.s_addr,
sizeof(dhcp_serverip.s_addr));
}
if (tag == TAG_TFTP_SERVER) {
bcopy(cp, &tftpip.s_addr,
sizeof(tftpip.s_addr));
}
#endif
cp += size;
}

View File

@ -106,6 +106,7 @@ struct bootp {
#define TAG_T2 ((unsigned char) 59)
#define TAG_CLASSID ((unsigned char) 60)
#define TAG_CLIENTID ((unsigned char) 61)
#define TAG_TFTP_SERVER ((unsigned char) 150)
#endif
#define TAG_END ((unsigned char) 255)

View File

@ -25,12 +25,14 @@ char hostname[FNAME_SIZE]; /* our hostname */
int hostnamelen;
char domainname[FNAME_SIZE]; /* our DNS domain */
int domainnamelen;
int netproto = NET_NONE; /* Network prototol */
char ifname[IFNAME_SIZE]; /* name of interface (e.g. "le0") */
struct in_addr myip; /* my ip address */
struct in_addr nameip; /* DNS server ip address */
struct in_addr rootip; /* root ip address */
struct in_addr swapip; /* swap ip address */
struct in_addr gateip; /* gateway ip address */
struct in_addr tftpip; /* TFTP ip address */
n_long netmask = 0xffffff00; /* subnet or net mask */
u_int intf_mtu; /* interface mtu from bootp/dhcp */
int errno; /* our old friend */

View File

@ -36,6 +36,8 @@
* $FreeBSD$
*/
#ifndef _STAND_NET_H
#define _STAND_NET_H
#ifndef _KERNEL /* XXX - see <netinet/in.h> */
#undef __IPADDR
#define __IPADDR(x) htonl((u_int32_t)(x))
@ -45,6 +47,12 @@
#define BA { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
enum net_proto {
NET_NONE,
NET_NFS,
NET_TFTP
};
/* Returns true if n_long's on the same net */
#define SAMENET(a1, a2, m) ((a1.s_addr & m) == (a2.s_addr & m))
@ -74,6 +82,7 @@ extern char hostname[FNAME_SIZE];
extern int hostnamelen;
extern char domainname[FNAME_SIZE];
extern int domainnamelen;
extern int netproto;
extern char ifname[IFNAME_SIZE];
/* All of these are in network order. */
@ -82,6 +91,7 @@ extern struct in_addr rootip;
extern struct in_addr swapip;
extern struct in_addr gateip;
extern struct in_addr nameip;
extern struct in_addr tftpip;
extern n_long netmask;
extern u_int intf_mtu;
@ -120,3 +130,4 @@ n_long inet_addr(char *);
/* Machine-dependent functions: */
time_t getsecs(void);
#endif

View File

@ -458,6 +458,9 @@ nfs_open(const char *upath, struct open_file *f)
int error;
char *path;
if (netproto != NET_NFS)
return (EINVAL);
#ifdef NFS_DEBUG
if (debug)
printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);
@ -1100,6 +1103,9 @@ nfs_open(const char *upath, struct open_file *f)
int error;
char *path;
if (netproto != NET_NFS)
return (EINVAL);
#ifdef NFS_DEBUG
if (debug)
printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);

View File

@ -402,6 +402,9 @@ tftp_open(const char *path, struct open_file *f)
size_t pathsize;
const char *extraslash;
if (netproto != NET_TFTP)
return (EINVAL);
if (strcmp(f->f_dev->dv_name, "net") != 0) {
#ifdef __i386__
if (strcmp(f->f_dev->dv_name, "pxe") != 0)

View File

@ -167,13 +167,14 @@ net_open(struct open_file *f, ...)
setenv("boot.netif.ip", inet_ntoa(myip), 1);
setenv("boot.netif.netmask", intoa(netmask), 1);
setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
#ifdef LOADER_TFTP_SUPPORT
setenv("boot.tftproot.server", inet_ntoa(rootip), 1);
setenv("boot.tftproot.path", rootpath, 1);
#else
setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
setenv("boot.nfsroot.path", rootpath, 1);
#endif
setenv("boot.netif.server", inet_ntoa(rootip), 1);
if (netproto == NET_TFTP) {
setenv("boot.tftproot.server", inet_ntoa(rootip), 1);
setenv("boot.tftproot.path", rootpath, 1);
} else if (netproto == NET_NFS) {
setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
setenv("boot.nfsroot.path", rootpath, 1);
}
if (intf_mtu != 0) {
char mtu[16];
sprintf(mtu, "%u", intf_mtu);
@ -367,16 +368,24 @@ net_print(int verbose)
uint32_t
net_parse_rootpath()
{
int i;
int i, ipstart;
n_long addr = INADDR_NONE;
netproto = NET_NFS;
if (tftpip.s_addr != 0) {
netproto = NET_TFTP;
addr = tftpip.s_addr;
}
for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
if (rootpath[i] == ':')
break;
if (i && i != FNAME_SIZE && rootpath[i] == ':') {
rootpath[i++] = '\0';
addr = inet_addr(&rootpath[0]);
addr = inet_addr(&rootpath[ipstart]);
bcopy(&rootpath[i], rootpath, strlen(&rootpath[i])+1);
}
return (addr);
}

View File

@ -13,10 +13,6 @@ SRCS+= time.c
SRCS+= time_event.c
.endif
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT -DNETIF_OPEN_CLOSE_ONCE
.endif
# We implement a slightly non-standard %S in that it always takes a
# CHAR16 that's common in UEFI-land instead of a wchar_t. This only
# seems to matter on arm64 where wchar_t defaults to an int instead

View File

@ -21,10 +21,6 @@ SRCS= autoload.c \
smbios.c \
vers.c
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT -DNETIF_OPEN_CLOSE_ONCE
.endif
.if ${MK_ZFS} != "no"
SRCS+= zfs.c
.PATH: ${.CURDIR}/../../zfs

View File

@ -51,11 +51,8 @@ struct fs_ops *file_system[] = {
&dosfs_fsops,
&ufs_fsops,
&cd9660_fsops,
#ifdef LOADER_TFTP_SUPPORT
&tftp_fsops,
#else
&nfs_fsops,
#endif
&gzipfs_fsops,
&bzipfs_fsops,
NULL

View File

@ -288,10 +288,15 @@ pxe_open(struct open_file *f, ...)
bootp(pxe_sock, BOOTP_PXE);
if (rootip.s_addr == 0)
rootip.s_addr = bootplayer.sip;
#ifdef LOADER_NFS_SUPPORT
if (!rootpath[0])
netproto = NET_NFS;
if (tftpip.s_addr != 0) {
netproto = NET_TFTP;
rootip.s_addr = tftpip.s_addr;
}
if (netproto == NET_NFS && !rootpath[0])
strcpy(rootpath, PXENFSROOTPATH);
#endif
for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
if (rootpath[i] == ':')
@ -315,17 +320,17 @@ pxe_open(struct open_file *f, ...)
sprintf(mtu, "%u", intf_mtu);
setenv("boot.netif.mtu", mtu, 1);
}
#ifdef LOADER_NFS_SUPPORT
printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
printf("pxe_open: server path: %s\n", rootpath);
printf("pxe_open: gateway ip: %s\n", inet_ntoa(gateip));
setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
setenv("boot.nfsroot.path", rootpath, 1);
#else
setenv("boot.netif.server", inet_ntoa(rootip), 1);
setenv("boot.tftproot.path", rootpath, 1);
#endif
if (netproto == NET_NFS) {
setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
setenv("boot.nfsroot.path", rootpath, 1);
} else if (netproto == NET_TFTP) {
setenv("boot.netif.server", inet_ntoa(rootip), 1);
setenv("boot.tftproot.path", rootpath, 1);
}
setenv("dhcp.host-name", hostname, 1);
setenv("pxeboot.ip", inet_ntoa(myip), 1);
@ -359,10 +364,10 @@ pxe_close(struct open_file *f)
if (pxe_opens > 0)
return(0);
#ifdef LOADER_NFS_SUPPORT
/* get an NFS filehandle for our root filesystem */
pxe_setnfshandle(rootpath);
#endif
if (netproto == NET_NFS) {
/* get an NFS filehandle for our root filesystem */
pxe_setnfshandle(rootpath);
}
if (pxe_sock >= 0) {
@ -422,7 +427,6 @@ pxe_perror(int err)
return;
}
#ifdef LOADER_NFS_SUPPORT
/*
* Reach inside the libstand NFS code and dig out an NFS handle
* for the root filesystem.
@ -533,7 +537,6 @@ pxe_setnfshandle(char *rootpath)
setenv("boot.nfsroot.nfshandlelen", buf, 1);
}
#endif /* OLD_NFSV2 */
#endif /* LOADER_NFS_SUPPORT */
void
pxenv_call(int func)

View File

@ -45,10 +45,6 @@ __FBSDID("$FreeBSD$");
* XXX as libi386 and biosboot merge, some of these can become linker sets.
*/
#if defined(LOADER_NFS_SUPPORT) && defined(LOADER_TFTP_SUPPORT)
#error "Cannot have both tftp and nfs support yet."
#endif
#if defined(LOADER_FIREWIRE_SUPPORT)
extern struct devsw fwohci;
#endif

View File

@ -42,10 +42,6 @@ __FBSDID("$FreeBSD$");
* XXX as libi386 and biosboot merge, some of these can become linker sets.
*/
#if defined(LOADER_NFS_SUPPORT) && defined(LOADER_TFTP_SUPPORT)
#error "Cannot have both tftp and nfs support yet."
#endif
/* Exported for libstand */
struct devsw *devsw[] = {
&bioscd,