diff --git a/src/include/ipxe/dhcpv6.h b/src/include/ipxe/dhcpv6.h index 48cb76337..6e70f7e63 100644 --- a/src/include/ipxe/dhcpv6.h +++ b/src/include/ipxe/dhcpv6.h @@ -145,6 +145,21 @@ struct dhcpv6_user_class_option { /** DHCPv6 user class option */ #define DHCPV6_USER_CLASS 15 +/** DHCPv6 vendor class option */ +#define DHCPV6_VENDOR_CLASS 16 + +/** DHCPv6 PXE vendor class + * + * The DHCPv6 vendor class includes a field for an IANA enterprise + * number. The EDK2 codebase uses the value 343, with the comment: + * + * TODO: IANA TBD: temporarily using Intel's + * + * Since this "temporarily" has applied since at least 2010, we assume + * that it has become a de facto standard. + */ +#define DHCPV6_VENDOR_CLASS_PXE 343 + /** DHCPv6 DNS recursive name server option */ #define DHCPV6_DNS_SERVERS 23 @@ -170,13 +185,22 @@ struct dhcpv6_user_class_option { */ #define DHCPV6_LOG_SERVERS 0xffffffffUL +/** Construct a DHCPv6 byte value */ +#define DHCPV6_BYTE_VALUE( value ) ( (value) & 0xff ) + +/** Construct a DHCPv6 word value */ +#define DHCPV6_WORD_VALUE( value ) \ + DHCPV6_BYTE_VALUE ( (value) >> 8 ), DHCPV6_BYTE_VALUE ( (value) >> 0 ) + +/** Construct a DHCPv6 dword value */ +#define DHCPV6_DWORD_VALUE( value ) \ + DHCPV6_WORD_VALUE ( (value) >> 16 ), DHCPV6_WORD_VALUE ( (value) >> 0 ) + /** Construct a DHCPv6 option code */ -#define DHCPV6_CODE( code ) \ - ( ( (code) >> 8 ) & 0xff ), ( ( (code) >> 0 ) & 0xff ) +#define DHCPV6_CODE( code ) DHCPV6_WORD_VALUE ( code ) /** Construct a DHCPv6 option length */ -#define DHCPV6_LEN( len ) \ - ( ( (len) >> 8 ) & 0xff ), ( ( (len) >> 0 ) & 0xff ) +#define DHCPV6_LEN( len ) DHCPV6_WORD_VALUE ( len ) /** Construct a DHCPv6 option from a list of bytes */ #define DHCPV6_OPTION( ... ) \ @@ -186,16 +210,13 @@ struct dhcpv6_user_class_option { #define DHCPV6_STRING( ... ) DHCPV6_OPTION ( __VA_ARGS__ ) /** Construct a byte-valued DHCPv6 option */ -#define DHCPV6_BYTE( value ) DHCPV6_OPTION ( value ) +#define DHCPV6_BYTE( value ) DHCPV6_OPTION ( DHCPV6_BYTE_VALUE ( value ) ) /** Construct a word-valued DHCPv6 option */ -#define DHCPV6_WORD( value ) DHCPV6_OPTION ( ( ( (value) >> 8 ) & 0xff ), \ - ( ( (value) >> 0 ) & 0xff ) ) +#define DHCPV6_WORD( value ) DHCPV6_OPTION ( DHCPV6_WORD_VALUE ( value ) ) + /** Construct a dword-valued DHCPv6 option */ -#define DHCPV6_DWORD( value ) DHCPV6_OPTION ( ( ( (value) >> 24 ) & 0xff ), \ - ( ( (value) >> 16 ) & 0xff ), \ - ( ( (value) >> 8 ) & 0xff ), \ - ( ( (value) >> 0 ) & 0xff ) ) +#define DHCPV6_DWORD( value ) DHCPV6_OPTION ( DHCPV6_DWORD_VALUE ( value ) ) /** * Any DHCPv6 option diff --git a/src/net/udp/dhcpv6.c b/src/net/udp/dhcpv6.c index 8b216e9a2..ef07f54e3 100644 --- a/src/net/udp/dhcpv6.c +++ b/src/net/udp/dhcpv6.c @@ -372,6 +372,9 @@ static uint8_t dhcpv6_request_options_data[] = { DHCPV6_CODE ( DHCPV6_DOMAIN_LIST ), DHCPV6_CODE ( DHCPV6_BOOTFILE_URL ), DHCPV6_CODE ( DHCPV6_BOOTFILE_PARAM ) ), + DHCPV6_CODE ( DHCPV6_VENDOR_CLASS ), + DHCPV6_OPTION ( DHCPV6_DWORD_VALUE ( DHCPV6_VENDOR_CLASS_PXE ), + DHCPV6_STRING ( DHCP_ARCH_VENDOR_CLASS_ID ) ), DHCPV6_CODE ( DHCPV6_CLIENT_ARCHITECTURE ), DHCPV6_WORD ( DHCP_ARCH_CLIENT_ARCHITECTURE ), DHCPV6_CODE ( DHCPV6_CLIENT_NDI ),