Browse Source

[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>
tags/v1.0.0-rc1
Shao Miller 14 years ago
parent
commit
cf5e79adc9
1 changed files with 15 additions and 4 deletions
  1. 15
    4
      src/net/dhcpopts.c

+ 15
- 4
src/net/dhcpopts.c View File

@@ -103,7 +103,7 @@ static unsigned int dhcp_option_len ( struct dhcp_option *option ) {
103 103
  * DHCP option block.  Encapsulated options may be searched for by
104 104
  * using DHCP_ENCAP_OPT() to construct the tag value.
105 105
  *
106
- * If the option is encapsulated, and @c encapsulator is non-NULL, it
106
+ * If the option is encapsulated, and @c encap_offset is non-NULL, it
107 107
  * will be filled in with the offset of the encapsulating option.
108 108
  *
109 109
  * 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,
136 136
 		if ( remaining < 0 )
137 137
 			break;
138 138
 		/* Check for explicit end marker */
139
-		if ( option->tag == DHCP_END )
140
-			break;
139
+		if ( option->tag == DHCP_END ) {
140
+			if ( tag == DHCP_END )
141
+				/* Special case where the caller is interested
142
+				 * in whether we have this marker or not.
143
+				 */
144
+				return offset;
145
+			else
146
+				break;
147
+		}
141 148
 		/* Check for matching tag */
142 149
 		if ( option->tag == tag ) {
143 150
 			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,
256 263
 	static const uint8_t empty_encapsulator[] = { DHCP_END };
257 264
 	int offset;
258 265
 	int encap_offset = -1;
259
-	int creation_offset = 0;
266
+	int creation_offset;
260 267
 	struct dhcp_option *option;
261 268
 	unsigned int encap_tag = DHCP_ENCAPSULATOR ( tag );
262 269
 	size_t old_len = 0;
@@ -267,6 +274,10 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag,
267 274
 	if ( tag == DHCP_PAD )
268 275
 		return -ENOTTY;
269 276
 
277
+	creation_offset = find_dhcp_option_with_encap ( options, DHCP_END,
278
+							NULL );
279
+	if ( creation_offset < 0 )
280
+		creation_offset = options->len;
270 281
 	/* Find old instance of this option, if any */
271 282
 	offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
272 283
 	if ( offset >= 0 ) {

Loading…
Cancel
Save