From de2c6fa240fc3b42c91c06775de6a26eb4aa3faf Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 20 Mar 2017 13:58:59 +0200 Subject: [PATCH] [dhcp] Allow vendor class to be changed in DHCP requests Allow the DHCPv4 vendor class to be specified via the "vendor-class" setting. Signed-off-by: Michael Brown --- src/core/settings.c | 9 +++++++++ src/include/ipxe/settings.h | 2 ++ src/net/udp/dhcp.c | 34 +++++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/core/settings.c b/src/core/settings.c index e60a882a..f5be5c4e 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -2429,6 +2429,15 @@ const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA, .type = &setting_type_string, }; +/** DHCP vendor class setting */ +const struct setting vendor_class_setting __setting ( SETTING_HOST_EXTRA, + vendor-class ) = { + .name = "vendor-class", + .description = "DHCP vendor class", + .tag = DHCP_VENDOR_CLASS_ID, + .type = &setting_type_string, +}; + /****************************************************************************** * * Built-in settings block diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h index 341fc3c7..521efa99 100644 --- a/src/include/ipxe/settings.h +++ b/src/include/ipxe/settings.h @@ -468,6 +468,8 @@ busid_setting __setting ( SETTING_NETDEV, busid ); extern const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA, user-class ); extern const struct setting +vendor_class_setting __setting ( SETTING_HOST_EXTRA, vendor-class ); +extern const struct setting manufacturer_setting __setting ( SETTING_HOST_EXTRA, manufacturer ); extern const struct setting product_setting __setting ( SETTING_HOST_EXTRA, product ); diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 95f80821..3a3666c9 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -99,6 +99,12 @@ static uint8_t dhcp_request_options_data[] = { DHCP_END }; +/** Settings copied in to all DHCP requests */ +static const struct setting * dhcp_request_settings[] = { + &user_class_setting, + &vendor_class_setting, +}; + /** DHCP server address setting */ const struct setting dhcp_server_setting __setting ( SETTING_MISC, dhcp-server ) = { @@ -975,11 +981,13 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt, struct dhcp_netdev_desc dhcp_desc; struct dhcp_client_id client_id; struct dhcp_client_uuid client_uuid; + const struct setting *setting; uint8_t *dhcp_features; size_t dhcp_features_len; size_t ll_addr_len; - void *user_class; + void *raw; ssize_t len; + unsigned int i; int rc; /* Create DHCP packet */ @@ -1047,19 +1055,23 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt, } } - /* Add user class, if we have one. */ - if ( ( len = fetch_raw_setting_copy ( NULL, &user_class_setting, - &user_class ) ) >= 0 ) { - if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_USER_CLASS_ID, - user_class, len ) ) != 0 ) { - DBG ( "DHCP could not set user class: %s\n", - strerror ( rc ) ); - goto err_store_user_class; + /* Add request settings, if applicable */ + for ( i = 0 ; i < ( sizeof ( dhcp_request_settings ) / + sizeof ( dhcp_request_settings[0] ) ) ; i++ ) { + setting = dhcp_request_settings[i]; + if ( ( len = fetch_raw_setting_copy ( NULL, setting, + &raw ) ) >= 0 ) { + rc = dhcppkt_store ( dhcppkt, setting->tag, raw, len ); + free ( raw ); + if ( rc != 0 ) { + DBG ( "DHCP could not set %s: %s\n", + setting->name, strerror ( rc ) ); + goto err_store_raw; + } } } - err_store_user_class: - free ( user_class ); + err_store_raw: err_store_client_uuid: err_store_client_id: err_store_busid: