Index: lib/libstand/bootp.h =================================================================== --- lib/libstand/bootp.h +++ lib/libstand/bootp.h @@ -106,6 +106,7 @@ #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) Index: lib/libstand/bootp.c =================================================================== --- lib/libstand/bootp.c +++ lib/libstand/bootp.c @@ -411,6 +411,10 @@ 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; } Index: lib/libstand/globals.c =================================================================== --- lib/libstand/globals.c +++ lib/libstand/globals.c @@ -25,12 +25,14 @@ 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 */ Index: lib/libstand/net.h =================================================================== --- lib/libstand/net.h +++ lib/libstand/net.h @@ -36,6 +36,8 @@ * $FreeBSD$ */ +#ifndef _STAND_NET_H +#define _STAND_NET_H #ifndef _KERNEL /* XXX - see */ #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 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 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 @@ /* Machine-dependent functions: */ time_t getsecs(void); +#endif Index: lib/libstand/nfs.c =================================================================== --- lib/libstand/nfs.c +++ lib/libstand/nfs.c @@ -458,6 +458,9 @@ 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 @@ int error; char *path; + if (netproto != NET_NFS) + return (EINVAL); + #ifdef NFS_DEBUG if (debug) printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath); Index: lib/libstand/tftp.c =================================================================== --- lib/libstand/tftp.c +++ lib/libstand/tftp.c @@ -402,6 +402,9 @@ 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) Index: sys/boot/common/dev_net.c =================================================================== --- sys/boot/common/dev_net.c +++ sys/boot/common/dev_net.c @@ -167,13 +167,14 @@ 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 @@ 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); } Index: sys/boot/efi/libefi/Makefile =================================================================== --- sys/boot/efi/libefi/Makefile +++ sys/boot/efi/libefi/Makefile @@ -13,10 +13,6 @@ 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 Index: sys/boot/efi/loader/Makefile =================================================================== --- sys/boot/efi/loader/Makefile +++ sys/boot/efi/loader/Makefile @@ -21,10 +21,6 @@ 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 Index: sys/boot/efi/loader/conf.c =================================================================== --- sys/boot/efi/loader/conf.c +++ sys/boot/efi/loader/conf.c @@ -51,11 +51,8 @@ &dosfs_fsops, &ufs_fsops, &cd9660_fsops, -#ifdef LOADER_TFTP_SUPPORT &tftp_fsops, -#else &nfs_fsops, -#endif &gzipfs_fsops, &bzipfs_fsops, NULL Index: sys/boot/i386/libi386/pxe.c =================================================================== --- sys/boot/i386/libi386/pxe.c +++ sys/boot/i386/libi386/pxe.c @@ -288,10 +288,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ setenv("boot.nfsroot.nfshandlelen", buf, 1); } #endif /* OLD_NFSV2 */ -#endif /* LOADER_NFS_SUPPORT */ void pxenv_call(int func) Index: sys/boot/i386/loader/conf.c =================================================================== --- sys/boot/i386/loader/conf.c +++ sys/boot/i386/loader/conf.c @@ -45,10 +45,6 @@ * 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 Index: sys/boot/pc98/loader/conf.c =================================================================== --- sys/boot/pc98/loader/conf.c +++ sys/boot/pc98/loader/conf.c @@ -42,10 +42,6 @@ * 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,