svn commit: r305125 - in head: lib/libstand sys/boot/common sys/boot/efi/libefi sys/boot/efi/loader sys/boot/i386/libi386 sys/boot/i386/loader sys/boot/pc98/loader

Baptiste Daroussin bapt at FreeBSD.org
Wed Aug 31 13:16:43 UTC 2016


Author: bapt
Date: Wed Aug 31 13:16:40 2016
New Revision: 305125
URL: https://svnweb.freebsd.org/changeset/base/305125

Log:
  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

Modified:
  head/lib/libstand/bootp.c
  head/lib/libstand/bootp.h
  head/lib/libstand/globals.c
  head/lib/libstand/net.h
  head/lib/libstand/nfs.c
  head/lib/libstand/tftp.c
  head/sys/boot/common/dev_net.c
  head/sys/boot/efi/libefi/Makefile
  head/sys/boot/efi/loader/Makefile
  head/sys/boot/efi/loader/conf.c
  head/sys/boot/i386/libi386/pxe.c
  head/sys/boot/i386/loader/conf.c
  head/sys/boot/pc98/loader/conf.c

Modified: head/lib/libstand/bootp.c
==============================================================================
--- head/lib/libstand/bootp.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/bootp.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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;
 	}

Modified: head/lib/libstand/bootp.h
==============================================================================
--- head/lib/libstand/bootp.h	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/bootp.h	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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)

Modified: head/lib/libstand/globals.c
==============================================================================
--- head/lib/libstand/globals.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/globals.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -25,12 +25,14 @@ char	hostname[FNAME_SIZE];		/* our hostn
 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 */

Modified: head/lib/libstand/net.h
==============================================================================
--- head/lib/libstand/net.h	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/net.h	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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

Modified: head/lib/libstand/nfs.c
==============================================================================
--- head/lib/libstand/nfs.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/nfs.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -458,6 +458,9 @@ nfs_open(const char *upath, struct open_
 	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_
 	int error;
 	char *path;
 
+	if (netproto != NET_NFS)
+		return (EINVAL);
+
 #ifdef NFS_DEBUG
  	if (debug)
  	    printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);

Modified: head/lib/libstand/tftp.c
==============================================================================
--- head/lib/libstand/tftp.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/lib/libstand/tftp.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -402,6 +402,9 @@ tftp_open(const char *path, struct open_
 	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)

Modified: head/sys/boot/common/dev_net.c
==============================================================================
--- head/sys/boot/common/dev_net.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/common/dev_net.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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);
 }

Modified: head/sys/boot/efi/libefi/Makefile
==============================================================================
--- head/sys/boot/efi/libefi/Makefile	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/efi/libefi/Makefile	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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

Modified: head/sys/boot/efi/loader/Makefile
==============================================================================
--- head/sys/boot/efi/loader/Makefile	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/efi/loader/Makefile	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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

Modified: head/sys/boot/efi/loader/conf.c
==============================================================================
--- head/sys/boot/efi/loader/conf.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/efi/loader/conf.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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

Modified: head/sys/boot/i386/libi386/pxe.c
==============================================================================
--- head/sys/boot/i386/libi386/pxe.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/i386/libi386/pxe.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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)

Modified: head/sys/boot/i386/loader/conf.c
==============================================================================
--- head/sys/boot/i386/loader/conf.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/i386/loader/conf.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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

Modified: head/sys/boot/pc98/loader/conf.c
==============================================================================
--- head/sys/boot/pc98/loader/conf.c	Wed Aug 31 12:29:04 2016	(r305124)
+++ head/sys/boot/pc98/loader/conf.c	Wed Aug 31 13:16:40 2016	(r305125)
@@ -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,


More information about the svn-src-head mailing list