Allow the TFP server or boot server in --pxe-service, to

be a domain name instead of an IP address. This allows for
 round-robin to multiple servers, in the same way as
 --dhcp-boot.
This commit is contained in:
Simon Kelley
2012-02-10 15:24:51 +00:00
parent 9bbc88762b
commit 751d6f4ae6
5 changed files with 34 additions and 16 deletions

View File

@@ -40,6 +40,11 @@ version 2.60
Fix shell-scripting bug in bld/pkg-wrapper. Thanks to
Mark Mitchell for the patch.
Allow the TFP server or boot server in --pxe-service, to
be a domain name instead of an IP address. This allows for
round-robin to multiple servers, in the same way as
--dhcp-boot. A good suggestion from Cristiano Cumer.
version 2.59
Fix regression in 2.58 which caused failure to start up

View File

@@ -888,7 +888,7 @@ address, and setting this flag enables this mode. Note that in the
sequential mode, clients which allow a lease to expire are much more
likely to move IP address; for this reason it should not be generally used.
.TP
.B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>]
.B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>|<server_name>]
Most uses of PXE boot-ROMS simply allow the PXE
system to obtain an IP address and then download the file specified by
.B dhcp-boot
@@ -904,17 +904,19 @@ parameter after the menu text may be a file name, in which case dnsmasq acts as
boot server and directs the PXE client to download the file by TFTP,
either from itself (
.B enable-tftp
must be set for this to work) or another TFTP server if the final IP
address is given.
must be set for this to work) or another TFTP server if the final server
address/name is given.
Note that the "layer"
suffix (normally ".0") is supplied by PXE, and should not be added to
the basename. If an integer boot service type, rather than a basename
is given, then the PXE client will search for a
suitable boot service for that type on the network. This search may be done
by broadcast, or direct to a server if its IP address is provided.
by broadcast, or direct to a server if its IP address/name is provided.
If no boot service type or filename is provided (or a boot service type of 0 is specified)
then the menu entry will abort the net boot procedure and
continue booting from local media.
continue booting from local media. The server address can be given as a domain
name which is looked up in /etc/hosts. This name can be associated in
/etc/hosts with multiple IP addresses, which are used round-robin.
.TP
.B --pxe-prompt=[tag:<tag>,]<prompt>[,<timeout>]
Setting this provides a prompt to be displayed after PXE boot. If the

View File

@@ -547,7 +547,7 @@ struct dhcp_boot {
struct pxe_service {
unsigned short CSA, type;
char *menu, *basename;
char *menu, *basename, *sname;
struct in_addr server;
struct dhcp_netid *netid;
struct pxe_service *next;

View File

@@ -2384,6 +2384,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
static int boottype = 32768;
new->netid = NULL;
new->sname = NULL;
new->server.s_addr = 0;
while (is_tag_prefix(arg))
@@ -2430,8 +2431,15 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
new->basename = opt_string_alloc(arg);
}
if (comma && (new->server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
option = '?';
if (comma)
{
if (!inet_pton(AF_INET, comma, &new->server))
{
new->server.s_addr = 0;
new->sname = opt_string_alloc(comma);
}
}
}
/* Order matters */

View File

@@ -63,7 +63,7 @@ static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
static int do_encap_opts(struct dhcp_opt *opts, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid);
static int prune_vendor_opts(struct dhcp_netid *netid);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
@@ -799,7 +799,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
mess->yiaddr = mess->ciaddr;
mess->ciaddr.s_addr = 0;
if (service->server.s_addr != 0)
if (service->sname)
mess->siaddr = a_record_from_hosts(service->sname, now);
else if (service->server.s_addr != 0)
mess->siaddr = service->server;
else
mess->siaddr = context->local;
@@ -868,7 +870,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
pxe_misc(mess, end, uuid);
prune_vendor_opts(tagif_netid);
do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", mess->xid);
log_tags(tagif_netid, mess);
@@ -2048,7 +2050,7 @@ static int prune_vendor_opts(struct dhcp_netid *netid)
return force;
}
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local)
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now)
{
#define NUM_OPTS 4
@@ -2105,7 +2107,8 @@ static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct
return daemon->dhcp_opts;
}
boot_server = service->basename ? local : service->server;
boot_server = service->basename ? local :
(service->sname ? a_record_from_hosts(service->sname, now) : service->server);
if (boot_server.s_addr != 0)
{
@@ -2579,7 +2582,7 @@ static void do_options(struct dhcp_context *context,
if (context && pxe_arch != -1)
{
pxe_misc(mess, end, uuid);
config_opts = pxe_opts(pxe_arch, tagif, context->local);
config_opts = pxe_opts(pxe_arch, tagif, context->local, now);
}
if ((force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT)) &&