Commit fe71bba3 authored by Simon Kelley's avatar Simon Kelley

Tweak UEFI workaround code.

parent cbc100fc
...@@ -1367,8 +1367,9 @@ either from itself ( ...@@ -1367,8 +1367,9 @@ either from itself (
must be set for this to work) or another TFTP server if the final server must be set for this to work) or another TFTP server if the final server
address/name is given. address/name is given.
Note that the "layer" Note that the "layer"
suffix (normally ".0") is supplied by PXE, and should not be added to suffix (normally ".0") is supplied by PXE, and need not be added to
the basename. If an integer boot service type, rather than a basename the basename. Alternatively, the basename may be a filename, complete with suffix, in which case
no layer suffix is added. If an integer boot service type, rather than a basename
is given, then the PXE client will search for a is given, then the PXE client will search for a
suitable boot service for that type on the network. This search may be done 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/name is provided. by broadcast, or direct to a server if its IP address/name is provided.
......
...@@ -63,7 +63,7 @@ static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char ...@@ -63,7 +63,7 @@ static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char
static int prune_vendor_opts(struct dhcp_netid *netid); 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, time_t now); 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); struct dhcp_boot *find_boot(struct dhcp_netid *netid);
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now); static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now, int pxe);
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback) size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback)
...@@ -824,7 +824,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, ...@@ -824,7 +824,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
else else
mess->siaddr = context->local; mess->siaddr = context->local;
snprintf((char *)mess->file, sizeof(mess->file), "%s.%d", service->basename, layer); snprintf((char *)mess->file, sizeof(mess->file),
strchr(service->basename, '.') ? "%s" :"%s.%d",
service->basename, layer);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK); option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid);
...@@ -879,11 +882,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, ...@@ -879,11 +882,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
clear_packet(mess, end); clear_packet(mess, end);
/* Only do workaround for replies to 4011 */ /* Redirect the client to port 4011 */
if (!pxe) mess->siaddr = tmp->local;
mess->siaddr = tmp->local; /* Returns true if only one matching service is available. On port 4011,
else it also inserts the boot file and server name. */
workaround = pxe_uefi_workaround(pxearch, tagif_netid, mess, tmp->local, now); workaround = pxe_uefi_workaround(pxearch, tagif_netid, mess, tmp->local, now, pxe);
if (!workaround && boot) if (!workaround && boot)
{ {
...@@ -903,7 +906,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, ...@@ -903,7 +906,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(tmp->local.s_addr)); option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(tmp->local.s_addr));
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid);
prune_vendor_opts(tagif_netid); prune_vendor_opts(tagif_netid);
if (!workaround) if (pxe && !workaround)
do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0); do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->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", NULL, mess->xid); log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
...@@ -1989,7 +1992,7 @@ static int prune_vendor_opts(struct dhcp_netid *netid) ...@@ -1989,7 +1992,7 @@ static int prune_vendor_opts(struct dhcp_netid *netid)
and jamb the data direct into the DHCP file, siaddr and sname fields. and jamb the data direct into the DHCP file, siaddr and sname fields.
Note that in this case, we have to assume that layer zero would be requested Note that in this case, we have to assume that layer zero would be requested
by the client PXE stack. */ by the client PXE stack. */
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now) static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now, int pxe)
{ {
struct pxe_service *service, *found; struct pxe_service *service, *found;
...@@ -1998,7 +2001,7 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh ...@@ -1998,7 +2001,7 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh
return 0; return 0;
for (found = NULL, service = daemon->pxe_services; service; service = service->next) for (found = NULL, service = daemon->pxe_services; service; service = service->next)
if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1)) if (pxe_arch == service->CSA && service->basename && match_netid(service->netid, netid, 1))
{ {
if (found) if (found)
return 0; /* More than one relevant menu item */ return 0; /* More than one relevant menu item */
...@@ -2009,6 +2012,9 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh ...@@ -2009,6 +2012,9 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh
if (!found) if (!found)
return 0; /* No relevant menu items. */ return 0; /* No relevant menu items. */
if (!pxe)
return 1;
if (found->sname) if (found->sname)
{ {
mess->siaddr = a_record_from_hosts(found->sname, now); mess->siaddr = a_record_from_hosts(found->sname, now);
...@@ -2024,8 +2030,9 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh ...@@ -2024,8 +2030,9 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh
inet_ntop(AF_INET, &mess->siaddr, (char *)mess->sname, INET_ADDRSTRLEN); inet_ntop(AF_INET, &mess->siaddr, (char *)mess->sname, INET_ADDRSTRLEN);
} }
snprintf((char *)mess->file, sizeof(mess->file), "%s.0", found->basename); snprintf((char *)mess->file, sizeof(mess->file),
strchr(found->basename, '.') ? "%s" : "%s.0", found->basename);
return 1; return 1;
} }
...@@ -2563,7 +2570,7 @@ static void do_options(struct dhcp_context *context, ...@@ -2563,7 +2570,7 @@ static void do_options(struct dhcp_context *context,
if (context && pxe_arch != -1) if (context && pxe_arch != -1)
{ {
pxe_misc(mess, end, uuid); pxe_misc(mess, end, uuid);
if (!pxe_uefi_workaround(pxe_arch, tagif, mess, context->local, now)) if (!pxe_uefi_workaround(pxe_arch, tagif, mess, context->local, now, 0))
config_opts = pxe_opts(pxe_arch, tagif, context->local, now); config_opts = pxe_opts(pxe_arch, tagif, context->local, now);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment