diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-01-15 21:36:08 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-01-15 21:36:08 +0000 |
commit | 5a2fa6040e17562ce742df09aa20b8774b3879c5 (patch) | |
tree | 608b47590365c52ca7e6c767d32d6487689e7312 /src/usr | |
parent | c4c03e5be867a9b7be4dc48fe6576deca1dce8d8 (diff) | |
download | ipxe-5a2fa6040e17562ce742df09aa20b8774b3879c5.tar.gz |
[autoboot] Include VLAN tag in filter for identifying autoboot device
When chainloading iPXE from a VLAN device, the MAC address of the
loaded image's device handle will match the MAC address of the trunk
device created by iPXE, and the autoboot process will then erroneously
consider the trunk device to be an autoboot device.
Fix by recording the VLAN tag along with the MAC address, and treating
the VLAN tag as part of the filter used to match the MAC address
against candidate network devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/autoboot.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index 24043ae69..d1f259621 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdio.h> #include <errno.h> #include <ipxe/netdevice.h> +#include <ipxe/vlan.h> #include <ipxe/dhcp.h> #include <ipxe/settings.h> #include <ipxe/image.h> @@ -57,6 +58,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Link-layer address of preferred autoboot device, if known */ static uint8_t autoboot_ll_addr[MAX_LL_ADDR_LEN]; +/** VLAN tag of preferred autoboot device, if known */ +static unsigned int autoboot_vlan; + /** Device location of preferred autoboot device, if known */ static struct device_description autoboot_desc; @@ -494,8 +498,9 @@ void set_autoboot_busloc ( unsigned int bus_type, unsigned int location ) { */ static int is_autoboot_ll_addr ( struct net_device *netdev ) { - return ( memcmp ( netdev->ll_addr, autoboot_ll_addr, - netdev->ll_protocol->ll_addr_len ) == 0 ); + return ( ( memcmp ( netdev->ll_addr, autoboot_ll_addr, + netdev->ll_protocol->ll_addr_len ) == 0 ) && + ( vlan_tag ( netdev ) == autoboot_vlan ) ); } /** @@ -503,14 +508,19 @@ static int is_autoboot_ll_addr ( struct net_device *netdev ) { * * @v ll_addr Link-layer address * @v len Length of link-layer address + * @v vlan VLAN tag */ -void set_autoboot_ll_addr ( const void *ll_addr, size_t len ) { +void set_autoboot_ll_addr ( const void *ll_addr, size_t len, + unsigned int vlan ) { /* Record autoboot link-layer address (truncated if necessary) */ if ( len > sizeof ( autoboot_ll_addr ) ) len = sizeof ( autoboot_ll_addr ); memcpy ( autoboot_ll_addr, ll_addr, len ); + /* Record autoboot VLAN tag */ + autoboot_vlan = vlan; + /* Mark autoboot device as present */ is_autoboot_device = is_autoboot_ll_addr; } |