mirror of https://github.com/ipxe/ipxe.git
[Settings] copy_settings() should not fail if some settings are missing!
parent
978865da2f
commit
23e077666b
|
@ -498,40 +498,6 @@ unsigned long fetch_uintz_setting ( struct settings *settings,
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy setting
|
|
||||||
*
|
|
||||||
* @v dest Destination settings block
|
|
||||||
* @v dest_tag Destination setting tag number
|
|
||||||
* @v source Source settings block
|
|
||||||
* @v source_tag Source setting tag number
|
|
||||||
* @ret rc Return status code
|
|
||||||
*/
|
|
||||||
int copy_setting ( struct settings *dest, unsigned int dest_tag,
|
|
||||||
struct settings *source, unsigned int source_tag ) {
|
|
||||||
int len;
|
|
||||||
int check_len;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
len = fetch_setting_len ( source, source_tag );
|
|
||||||
if ( len < 0 )
|
|
||||||
return len;
|
|
||||||
|
|
||||||
{
|
|
||||||
char buf[len];
|
|
||||||
|
|
||||||
check_len = fetch_setting ( source, source_tag, buf,
|
|
||||||
sizeof ( buf ) );
|
|
||||||
assert ( check_len == len );
|
|
||||||
|
|
||||||
if ( ( rc = store_setting ( dest, dest_tag, buf,
|
|
||||||
sizeof ( buf ) ) ) != 0 )
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy settings
|
* Copy settings
|
||||||
*
|
*
|
||||||
|
@ -545,6 +511,8 @@ static int copy_encap_settings ( struct settings *dest,
|
||||||
unsigned int encapsulator ) {
|
unsigned int encapsulator ) {
|
||||||
unsigned int subtag;
|
unsigned int subtag;
|
||||||
unsigned int tag;
|
unsigned int tag;
|
||||||
|
int len;
|
||||||
|
int check_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
|
for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
|
||||||
|
@ -552,16 +520,26 @@ static int copy_encap_settings ( struct settings *dest,
|
||||||
switch ( tag ) {
|
switch ( tag ) {
|
||||||
case DHCP_EB_ENCAP:
|
case DHCP_EB_ENCAP:
|
||||||
case DHCP_VENDOR_ENCAP:
|
case DHCP_VENDOR_ENCAP:
|
||||||
/* Process encapsulated options field */
|
/* Process encapsulated settings */
|
||||||
if ( ( rc = copy_encap_settings ( dest, source,
|
if ( ( rc = copy_encap_settings ( dest, source,
|
||||||
tag ) ) != 0 )
|
tag ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Copy option to reassembled packet */
|
/* Copy setting, if present */
|
||||||
if ( ( rc = copy_setting ( dest, tag, source,
|
len = fetch_setting_len ( source, tag );
|
||||||
tag ) ) != 0 )
|
if ( len < 0 )
|
||||||
return rc;
|
break;
|
||||||
|
{
|
||||||
|
char buf[len];
|
||||||
|
|
||||||
|
check_len = fetch_setting ( source, tag, buf,
|
||||||
|
sizeof ( buf ) );
|
||||||
|
assert ( check_len == len );
|
||||||
|
if ( ( rc = store_setting ( dest, tag, buf,
|
||||||
|
sizeof(buf) )) !=0)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,8 +163,6 @@ extern int store_setting ( struct settings *settings, unsigned int tag,
|
||||||
const void *data, size_t len );
|
const void *data, size_t len );
|
||||||
extern int fetch_setting ( struct settings *settings, unsigned int tag,
|
extern int fetch_setting ( struct settings *settings, unsigned int tag,
|
||||||
void *data, size_t len );
|
void *data, size_t len );
|
||||||
extern int copy_setting ( struct settings *dest, unsigned int dest_tag,
|
|
||||||
struct settings *source, unsigned int source_tag );
|
|
||||||
extern int copy_settings ( struct settings *dest, struct settings *source );
|
extern int copy_settings ( struct settings *dest, struct settings *source );
|
||||||
extern int fetch_setting_len ( struct settings *settings, unsigned int tag );
|
extern int fetch_setting_len ( struct settings *settings, unsigned int tag );
|
||||||
extern int fetch_string_setting ( struct settings *settings, unsigned int tag,
|
extern int fetch_string_setting ( struct settings *settings, unsigned int tag,
|
||||||
|
|
|
@ -255,20 +255,34 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
|
||||||
|
|
||||||
/* Copy any required options from previous server repsonse */
|
/* Copy any required options from previous server repsonse */
|
||||||
if ( dhcpoffer ) {
|
if ( dhcpoffer ) {
|
||||||
if ( ( rc = copy_setting ( &dhcppkt->settings,
|
struct in_addr server_id;
|
||||||
DHCP_SERVER_IDENTIFIER,
|
struct in_addr requested_ip;
|
||||||
&dhcpoffer->settings,
|
|
||||||
DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
|
if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
|
||||||
DBG ( "DHCP could not set server identifier "
|
DHCP_SERVER_IDENTIFIER,
|
||||||
"option: %s\n", strerror ( rc ) );
|
&server_id ) ) < 0 ) {
|
||||||
|
DBG ( "DHCP offer missing server identifier\n" );
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
|
||||||
|
DHCP_EB_YIADDR,
|
||||||
|
&requested_ip ) ) < 0 ) {
|
||||||
|
DBG ( "DHCP offer missing IP address\n" );
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if ( ( rc = store_setting ( &dhcppkt->settings,
|
||||||
|
DHCP_SERVER_IDENTIFIER, &server_id,
|
||||||
|
sizeof ( server_id ) ) ) != 0 ) {
|
||||||
|
DBG ( "DHCP could not set server identifier: %s\n ",
|
||||||
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if ( ( rc = copy_setting ( &dhcppkt->settings,
|
if ( ( rc = store_setting ( &dhcppkt->settings,
|
||||||
DHCP_REQUESTED_ADDRESS,
|
DHCP_REQUESTED_ADDRESS,
|
||||||
&dhcpoffer->settings,
|
&requested_ip,
|
||||||
DHCP_EB_YIADDR ) ) != 0 ) {
|
sizeof ( requested_ip ) ) ) != 0 ){
|
||||||
DBG ( "DHCP could not set requested address "
|
DBG ( "DHCP could not set requested address: %s\n",
|
||||||
"option: %s\n", strerror ( rc ) );
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,8 +349,16 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
|
||||||
int create_dhcpdiscover ( struct net_device *netdev,
|
int create_dhcpdiscover ( struct net_device *netdev,
|
||||||
void *data, size_t max_len ) {
|
void *data, size_t max_len ) {
|
||||||
struct dhcp_packet dhcppkt;
|
struct dhcp_packet dhcppkt;
|
||||||
|
int rc;
|
||||||
|
|
||||||
return create_dhcp_request ( &dhcppkt, netdev, NULL, data, max_len );
|
if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data,
|
||||||
|
max_len ) ) != 0 ) {
|
||||||
|
DBG ( "Could not create DHCPDISCOVER: %s\n",
|
||||||
|
strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,18 +378,26 @@ int create_dhcpack ( struct net_device *netdev,
|
||||||
|
|
||||||
/* Create base DHCPACK packet */
|
/* Create base DHCPACK packet */
|
||||||
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
|
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
|
||||||
data, max_len ) ) != 0 )
|
data, max_len ) ) != 0 ) {
|
||||||
|
DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Merge in globally-scoped settings, then netdev-specific
|
/* Merge in globally-scoped settings, then netdev-specific
|
||||||
* settings. Do it in this order so that netdev-specific
|
* settings. Do it in this order so that netdev-specific
|
||||||
* settings take precedence regardless of stated priorities.
|
* settings take precedence regardless of stated priorities.
|
||||||
*/
|
*/
|
||||||
if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 )
|
if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) {
|
||||||
|
DBG ( "Could not set DHCPACK global settings: %s\n",
|
||||||
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
if ( ( rc = copy_settings ( &dhcppkt.settings,
|
if ( ( rc = copy_settings ( &dhcppkt.settings,
|
||||||
netdev_settings ( netdev ) ) ) != 0 )
|
netdev_settings ( netdev ) ) ) != 0 ) {
|
||||||
|
DBG ( "Could not set DHCPACK netdev settings: %s\n",
|
||||||
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -399,12 +429,18 @@ int create_proxydhcpack ( struct net_device *netdev,
|
||||||
|
|
||||||
/* Create base DHCPACK packet */
|
/* Create base DHCPACK packet */
|
||||||
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
|
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
|
||||||
data, max_len ) ) != 0 )
|
data, max_len ) ) != 0 ) {
|
||||||
|
DBG ( "Could not create ProxyDHCPACK: %s\n",
|
||||||
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Merge in ProxyDHCP options */
|
/* Merge in ProxyDHCP options */
|
||||||
if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 )
|
if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) {
|
||||||
|
DBG ( "Could not set ProxyDHCPACK settings: %s\n",
|
||||||
|
strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue