mirror of https://github.com/ipxe/ipxe.git
[dhcp] Append new DHCP options versus prepend
Change the behaviour for adding DHCP options into a DHCP packet so that we now append options, rather than insert them in front of whatever options might already be present. Apparently, the DHCP relay logic on a Nortel 470-48T layer 2 switch cares about the order of DHCP options. If we build a DHCP packet pre-populated with some options, their order will now be preserved, except for encapsulated options. Signed-off-by: Marty Connor <mdc@etherboot.org>pull/1/head
parent
9de525c34c
commit
cf5e79adc9
|
@ -103,7 +103,7 @@ static unsigned int dhcp_option_len ( struct dhcp_option *option ) {
|
||||||
* DHCP option block. Encapsulated options may be searched for by
|
* DHCP option block. Encapsulated options may be searched for by
|
||||||
* using DHCP_ENCAP_OPT() to construct the tag value.
|
* using DHCP_ENCAP_OPT() to construct the tag value.
|
||||||
*
|
*
|
||||||
* If the option is encapsulated, and @c encapsulator is non-NULL, it
|
* If the option is encapsulated, and @c encap_offset is non-NULL, it
|
||||||
* will be filled in with the offset of the encapsulating option.
|
* will be filled in with the offset of the encapsulating option.
|
||||||
*
|
*
|
||||||
* This routine is designed to be paranoid. It does not assume that
|
* This routine is designed to be paranoid. It does not assume that
|
||||||
|
@ -136,8 +136,15 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options,
|
||||||
if ( remaining < 0 )
|
if ( remaining < 0 )
|
||||||
break;
|
break;
|
||||||
/* Check for explicit end marker */
|
/* Check for explicit end marker */
|
||||||
if ( option->tag == DHCP_END )
|
if ( option->tag == DHCP_END ) {
|
||||||
break;
|
if ( tag == DHCP_END )
|
||||||
|
/* Special case where the caller is interested
|
||||||
|
* in whether we have this marker or not.
|
||||||
|
*/
|
||||||
|
return offset;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* Check for matching tag */
|
/* Check for matching tag */
|
||||||
if ( option->tag == tag ) {
|
if ( option->tag == tag ) {
|
||||||
DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
|
DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
|
||||||
|
@ -256,7 +263,7 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
|
||||||
static const uint8_t empty_encapsulator[] = { DHCP_END };
|
static const uint8_t empty_encapsulator[] = { DHCP_END };
|
||||||
int offset;
|
int offset;
|
||||||
int encap_offset = -1;
|
int encap_offset = -1;
|
||||||
int creation_offset = 0;
|
int creation_offset;
|
||||||
struct dhcp_option *option;
|
struct dhcp_option *option;
|
||||||
unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag );
|
unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag );
|
||||||
size_t old_len = 0;
|
size_t old_len = 0;
|
||||||
|
@ -267,6 +274,10 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
|
||||||
if ( tag == DHCP_PAD )
|
if ( tag == DHCP_PAD )
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
|
creation_offset = find_dhcp_option_with_encap ( options, DHCP_END,
|
||||||
|
NULL );
|
||||||
|
if ( creation_offset < 0 )
|
||||||
|
creation_offset = options->len;
|
||||||
/* Find old instance of this option, if any */
|
/* Find old instance of this option, if any */
|
||||||
offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
|
offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
|
||||||
if ( offset >= 0 ) {
|
if ( offset >= 0 ) {
|
||||||
|
|
Loading…
Reference in New Issue