diff options
| author | Simon Rettberg | 2022-10-21 17:22:09 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2022-10-21 17:22:09 +0200 |
| commit | 80109b804a700384799d54134ceebf4f40a8b7a3 (patch) | |
| tree | bbdf311ed02dd2c5c1f0a8d1997519ed2c24d93e /src/core | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [tls] Add support for Ephemeral Diffie-Hellman key exchange (diff) | |
| download | ipxe-80109b804a700384799d54134ceebf4f40a8b7a3.tar.gz ipxe-80109b804a700384799d54134ceebf4f40a8b7a3.tar.xz ipxe-80109b804a700384799d54134ceebf4f40a8b7a3.zip | |
Merge branch 'master' into openslx
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/acpimac.c | 37 | ||||
| -rw-r--r-- | src/core/cachedhcp.c | 51 |
2 files changed, 79 insertions, 9 deletions
diff --git a/src/core/acpimac.c b/src/core/acpimac.c index 5920480dd..e0074ba43 100644 --- a/src/core/acpimac.c +++ b/src/core/acpimac.c @@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/base16.h> #include <ipxe/ethernet.h> #include <ipxe/if_ether.h> +#include <ipxe/settings.h> #include <ipxe/acpimac.h> /** @file @@ -249,3 +250,39 @@ int acpi_mac ( uint8_t *hw_addr ) { return -ENOENT; } + +/** + * Fetch system MAC address setting + * + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + */ +static int sysmac_fetch ( void *data, size_t len ) { + uint8_t mac[ETH_ALEN]; + int rc; + + /* Try fetching ACPI MAC address */ + if ( ( rc = acpi_mac ( mac ) ) != 0 ) + return rc; + + /* Return MAC address */ + if ( len > sizeof ( mac ) ) + len = sizeof ( mac ); + memcpy ( data, mac, len ); + return ( sizeof ( mac ) ); +} + +/** System MAC address setting */ +const struct setting sysmac_setting __setting ( SETTING_MISC, sysmac ) = { + .name = "sysmac", + .description = "System MAC", + .type = &setting_type_hex, + .scope = &builtin_scope, +}; + +/** System MAC address built-in setting */ +struct builtin_setting sysmac_builtin_setting __builtin_setting = { + .setting = &sysmac_setting, + .fetch = sysmac_fetch, +}; diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c index 2fa9b0c73..c4ca46e3a 100644 --- a/src/core/cachedhcp.c +++ b/src/core/cachedhcp.c @@ -90,29 +90,62 @@ static void cachedhcp_free ( struct cached_dhcp_packet *cache ) { */ static int cachedhcp_apply ( struct cached_dhcp_packet *cache, struct net_device *netdev ) { - struct settings *settings; + struct settings *settings = NULL; + struct ll_protocol *ll_protocol; + const uint8_t *chaddr; + uint8_t *hw_addr; + uint8_t *ll_addr; + size_t ll_addr_len; int rc; /* Do nothing if cache is empty */ if ( ! cache->dhcppkt ) return 0; + chaddr = cache->dhcppkt->dhcphdr->chaddr; - /* Do nothing unless cached packet's MAC address matches this - * network device, if specified. - */ + /* Handle association with network device, if specified */ if ( netdev ) { - if ( memcmp ( netdev->ll_addr, cache->dhcppkt->dhcphdr->chaddr, - netdev->ll_protocol->ll_addr_len ) != 0 ) { + hw_addr = netdev->hw_addr; + ll_addr = netdev->ll_addr; + ll_protocol = netdev->ll_protocol; + ll_addr_len = ll_protocol->ll_addr_len; + + /* If cached packet's MAC address matches the network + * device's permanent MAC address, then assume that + * the permanent MAC address ought to be the network + * device's current link-layer address. + * + * This situation can arise when the PXE ROM does not + * understand the system-specific mechanism for + * overriding the MAC address, and so uses the + * permanent MAC address instead. We choose to match + * this behaviour in order to minimise surprise. + */ + if ( memcmp ( hw_addr, chaddr, ll_addr_len ) == 0 ) { + if ( memcmp ( hw_addr, ll_addr, ll_addr_len ) != 0 ) { + DBGC ( colour, "CACHEDHCP %s resetting %s MAC " + "%s ", cache->name, netdev->name, + ll_protocol->ntoa ( ll_addr ) ); + DBGC ( colour, "-> %s\n", + ll_protocol->ntoa ( hw_addr ) ); + } + memcpy ( ll_addr, hw_addr, ll_addr_len ); + } + + /* Do nothing unless cached packet's MAC address + * 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 ); return 0; } DBGC ( colour, "CACHEDHCP %s is for %s\n", cache->name, netdev->name ); - } - /* Select appropriate parent settings block */ - settings = ( netdev ? netdev_settings ( netdev ) : NULL ); + /* Use network device's settings block */ + settings = netdev_settings ( netdev ); + } /* Register settings */ if ( ( rc = register_settings ( &cache->dhcppkt->settings, settings, |
