Support URI scheme for root-path in netbooting

Rather that previous attempts to add tftpfs support at the same time as NFS
support. This time decide on a proper URI parser rather than hacks.

root-path can now be define the following way:
For tftpfs:

tftp://ip/path
tftp:/path (this one will consider the tftp server is the same as the one where
the pxeboot file was fetched from)

For nfs:
nfs:/path
nfs://ip/path

The historical
ip:/path
/path

are kept on NFS

Reviewed by:	tsoom, rgrimes
Differential Revision:	https://reviews.freebsd.org/D10947
This commit is contained in:
bapt 2017-05-27 12:06:52 +00:00
parent 0ab8a789e7
commit f5db8ffa45

View File

@ -97,6 +97,14 @@ struct devsw netdev = {
net_cleanup
};
static struct uri_scheme {
const char *scheme;
int proto;
} uri_schemes[] = {
{ "tftp:/", NET_TFTP },
{ "nfs:/", NET_NFS },
};
static int
net_init(void)
{
@ -334,11 +342,8 @@ net_getparams(int sock)
return (EIO);
}
exit:
netproto = NET_TFTP;
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) {
netproto = NET_NFS;
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
rootip.s_addr = rootaddr;
}
#ifdef NETIF_DEBUG
if (debug) {
@ -387,14 +392,51 @@ net_print(int verbose)
uint32_t
net_parse_rootpath()
{
n_long addr = INADDR_NONE;
char *ptr;
n_long addr = htonl(INADDR_NONE);
size_t i;
char ip[FNAME_SIZE];
char *ptr, *val;
netproto = NET_NONE;
for (i = 0; i < nitems(uri_schemes); i++) {
if (strncmp(rootpath, uri_schemes[i].scheme,
strlen(uri_schemes[i].scheme)) != 0)
continue;
netproto = uri_schemes[i].proto;
break;
}
ptr = rootpath;
(void)strsep(&ptr, ":");
if (ptr != NULL) {
addr = inet_addr(rootpath);
bcopy(ptr, rootpath, strlen(ptr) + 1);
/* Fallback for compatibility mode */
if (netproto == NET_NONE) {
netproto = NET_NFS;
(void)strsep(&ptr, ":");
if (ptr != NULL) {
addr = inet_addr(rootpath);
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
} else {
ptr += strlen(uri_schemes[i].scheme);
if (*ptr == '/') {
/* we are in the form <scheme>://, we do expect an ip */
ptr++;
/*
* XXX when http will be there we will need to check for
* a port, but right now we do not need it yet
*/
val = strchr(ptr, '/');
if (val != NULL) {
snprintf(ip, sizeof(ip), "%.*s",
(int)((uintptr_t)val - (uintptr_t)ptr), ptr);
printf("%s\n", ip);
addr = inet_addr(ip);
bcopy(val, rootpath, strlen(val) + 1);
}
} else {
ptr--;
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
}
return (addr);