summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorSimon Rettberg2023-04-04 15:12:41 +0200
committerSimon Rettberg2023-04-04 15:12:41 +0200
commit5ba496dce11d10198a0eae0c8440dccb256fbf32 (patch)
tree549903f1dab893870335a6e4767a4530444d2e83 /src/core
parent[vesafb] Map Unicode characters to CP437 if possible (diff)
parent[tls] Handle fragmented handshake records (diff)
downloadipxe-5ba496dce11d10198a0eae0c8440dccb256fbf32.tar.gz
ipxe-5ba496dce11d10198a0eae0c8440dccb256fbf32.tar.xz
ipxe-5ba496dce11d10198a0eae0c8440dccb256fbf32.zip
Merge branch 'master' into openslx
Diffstat (limited to 'src/core')
-rw-r--r--src/core/cachedhcp.c54
-rw-r--r--src/core/cpio.c9
-rw-r--r--src/core/image.c45
-rw-r--r--src/core/params.c21
-rw-r--r--src/core/parseopt.c2
5 files changed, 101 insertions, 30 deletions
diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c
index c4ca46e3a..60213f02d 100644
--- a/src/core/cachedhcp.c
+++ b/src/core/cachedhcp.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcppkt.h>
#include <ipxe/init.h>
#include <ipxe/netdevice.h>
+#include <ipxe/vlan.h>
#include <ipxe/cachedhcp.h>
/** @file
@@ -43,6 +44,8 @@ struct cached_dhcp_packet {
const char *name;
/** DHCP packet (if any) */
struct dhcp_packet *dhcppkt;
+ /** VLAN tag (if applicable) */
+ unsigned int vlan;
};
/** Cached DHCPACK */
@@ -136,15 +139,26 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
* matches this network device.
*/
if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
- DBGC ( colour, "CACHEDHCP %s does not match %s\n",
- cache->name, netdev->name );
+ DBGC ( colour, "CACHEDHCP %s %s does not match %s\n",
+ cache->name, ll_protocol->ntoa ( chaddr ),
+ netdev->name );
+ return 0;
+ }
+
+ /* Do nothing unless cached packet's VLAN tag matches
+ * this network device.
+ */
+ if ( vlan_tag ( netdev ) != cache->vlan ) {
+ DBGC ( colour, "CACHEDHCP %s VLAN %d does not match "
+ "%s\n", cache->name, cache->vlan,
+ netdev->name );
return 0;
}
- DBGC ( colour, "CACHEDHCP %s is for %s\n",
- cache->name, netdev->name );
/* Use network device's settings block */
settings = netdev_settings ( netdev );
+ DBGC ( colour, "CACHEDHCP %s is for %s\n",
+ cache->name, netdev->name );
}
/* Register settings */
@@ -165,12 +179,13 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
* Record cached DHCP packet
*
* @v cache Cached DHCP packet
+ * @v vlan VLAN tag, if any
* @v data DHCPACK packet buffer
* @v max_len Maximum possible length
* @ret rc Return status code
*/
-int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
- size_t max_len ) {
+int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
+ userptr_t data, size_t max_len ) {
struct dhcp_packet *dhcppkt;
struct dhcp_packet *tmp;
struct dhcphdr *dhcphdr;
@@ -225,36 +240,55 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
user_to_phys ( data, 0 ), len, max_len );
cache->dhcppkt = dhcppkt;
+ cache->vlan = vlan;
return 0;
}
/**
- * Cached DHCPACK startup function
+ * Cached DHCP packet startup function
*
*/
static void cachedhcp_startup ( void ) {
/* Apply cached ProxyDHCPOFFER, if any */
cachedhcp_apply ( &cached_proxydhcp, NULL );
+ cachedhcp_free ( &cached_proxydhcp );
/* Apply cached PXEBSACK, if any */
cachedhcp_apply ( &cached_pxebs, NULL );
+ cachedhcp_free ( &cached_pxebs );
- /* Free any remaining cached packets */
+ /* Report unclaimed DHCPACK, if any. Do not free yet, since
+ * it may still be claimed by a dynamically created device
+ * such as a VLAN device.
+ */
if ( cached_dhcpack.dhcppkt ) {
DBGC ( colour, "CACHEDHCP %s unclaimed\n",
cached_dhcpack.name );
}
+}
+
+/**
+ * Cached DHCP packet shutdown function
+ *
+ * @v booting System is shutting down for OS boot
+ */
+static void cachedhcp_shutdown ( int booting __unused ) {
+
+ /* Free cached DHCPACK, if any */
+ if ( cached_dhcpack.dhcppkt ) {
+ DBGC ( colour, "CACHEDHCP %s never claimed\n",
+ cached_dhcpack.name );
+ }
cachedhcp_free ( &cached_dhcpack );
- cachedhcp_free ( &cached_proxydhcp );
- cachedhcp_free ( &cached_pxebs );
}
/** Cached DHCPACK startup function */
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
.name = "cachedhcp",
.startup = cachedhcp_startup,
+ .shutdown = cachedhcp_shutdown,
};
/**
diff --git a/src/core/cpio.c b/src/core/cpio.c
index 27aee7581..4b607e260 100644
--- a/src/core/cpio.c
+++ b/src/core/cpio.c
@@ -77,17 +77,12 @@ size_t cpio_name_len ( struct image *image ) {
*/
static void cpio_parse_cmdline ( struct image *image,
struct cpio_header *cpio ) {
- const char *cmdline;
- char *arg;
+ const char *arg;
char *end;
unsigned int mode;
- /* Skip image filename */
- cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) );
-
/* Look for "mode=" */
- if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
- arg += 5;
+ if ( ( arg = image_argument ( image, "mode=" ) ) ) {
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
if ( *end && ( *end != ' ' ) ) {
DBGC ( image, "CPIO %p strange \"mode=\" "
diff --git a/src/core/image.c b/src/core/image.c
index 3e236ca60..b280eb4d3 100644
--- a/src/core/image.c
+++ b/src/core/image.c
@@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <libgen.h>
@@ -311,7 +312,7 @@ void unregister_image ( struct image *image ) {
struct image * find_image ( const char *name ) {
struct image *image;
- list_for_each_entry ( image, &images, list ) {
+ for_each_image ( image ) {
if ( strcmp ( image->name, name ) == 0 )
return image;
}
@@ -348,9 +349,8 @@ int image_exec ( struct image *image ) {
/* Preserve record of any currently-running image */
saved_current_image = current_image;
- /* Take out a temporary reference to the image. This allows
- * the image to unregister itself if necessary, without
- * automatically freeing itself.
+ /* Take out a temporary reference to the image, so that it
+ * does not get freed when temporarily unregistered.
*/
current_image = image_get ( image );
@@ -370,6 +370,9 @@ int image_exec ( struct image *image ) {
/* Record boot attempt */
syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );
+ /* Temporarily unregister the image during its execution */
+ unregister_image ( image );
+
/* Try executing the image */
if ( ( rc = image->type->exec ( image ) ) != 0 ) {
DBGC ( image, "IMAGE %s could not execute: %s\n",
@@ -386,6 +389,10 @@ int image_exec ( struct image *image ) {
image->name, strerror ( rc ) );
}
+ /* Re-register image (unless due to be replaced) */
+ if ( ! image->replacement )
+ register_image ( image );
+
/* Pick up replacement image before we drop the original
* image's temporary reference. The replacement image must
* already be registered, so we don't need to hold a temporary
@@ -569,3 +576,33 @@ struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
err_alloc_image:
return NULL;
}
+
+/**
+ * Find argument within image command line
+ *
+ * @v image Image
+ * @v key Argument search key (including trailing delimiter)
+ * @ret value Argument value, or NULL if not found
+ */
+const char * image_argument ( struct image *image, const char *key ) {
+ const char *cmdline = image->cmdline;
+ const char *search;
+ const char *match;
+ const char *next;
+
+ /* Find argument */
+ for ( search = cmdline ; search ; search = next ) {
+
+ /* Find next occurrence, if any */
+ match = strstr ( search, key );
+ if ( ! match )
+ break;
+ next = ( match + strlen ( key ) );
+
+ /* Check preceding delimiter, if any */
+ if ( ( match == cmdline ) || isspace ( match[-1] ) )
+ return next;
+ }
+
+ return NULL;
+}
diff --git a/src/core/params.c b/src/core/params.c
index e1f66acca..58c829f62 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
- * Form parameters
+ * Request parameters
*
*/
@@ -37,7 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static LIST_HEAD ( parameters );
/**
- * Free form parameter list
+ * Free request parameter list
*
* @v refcnt Reference count
*/
@@ -60,7 +60,7 @@ static void free_parameters ( struct refcnt *refcnt ) {
}
/**
- * Find form parameter list by name
+ * Find request parameter list by name
*
* @v name Parameter list name (may be NULL)
* @ret params Parameter list, or NULL if not found
@@ -78,7 +78,7 @@ struct parameters * find_parameters ( const char *name ) {
}
/**
- * Create form parameter list
+ * Create request parameter list
*
* @v name Parameter list name (may be NULL)
* @ret params Parameter list, or NULL on failure
@@ -118,15 +118,17 @@ struct parameters * create_parameters ( const char *name ) {
}
/**
- * Add form parameter
+ * Add request parameter
*
* @v params Parameter list
* @v key Parameter key
* @v value Parameter value
+ * @v flags Parameter flags
* @ret param Parameter, or NULL on failure
*/
struct parameter * add_parameter ( struct parameters *params,
- const char *key, const char *value ) {
+ const char *key, const char *value,
+ unsigned int flags ) {
struct parameter *param;
size_t key_len;
size_t value_len;
@@ -147,11 +149,14 @@ struct parameter * add_parameter ( struct parameters *params,
param->key = key_copy;
strcpy ( value_copy, value );
param->value = value_copy;
+ param->flags = flags;
/* Add to list of parameters */
list_add_tail ( &param->list, &params->entries );
- DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
- params->name, param->key, param->value );
+ DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
+ params->name, param->key, param->value,
+ ( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
+ ( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
return param;
}
diff --git a/src/core/parseopt.c b/src/core/parseopt.c
index 007080088..1dbfc7aef 100644
--- a/src/core/parseopt.c
+++ b/src/core/parseopt.c
@@ -302,7 +302,7 @@ int parse_autovivified_setting ( char *text, struct named_setting *setting ) {
}
/**
- * Parse form parameter list name
+ * Parse request parameter list name
*
* @v text Text
* @ret params Parameter list