summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELNOTES10
-rw-r--r--common/tables.c10
-rw-r--r--includes/tree.h2
-rw-r--r--server/dhcp.c70
-rw-r--r--server/stables.c4
5 files changed, 93 insertions, 3 deletions
diff --git a/RELNOTES b/RELNOTES
index d4585604..f60f5fa3 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -98,6 +98,16 @@ suggested fixes to <dhcp-users@isc.org>.
'address' parameter (the server's local address) did not resolve to an
IPv4 address.
+- The minimum site code value was set to 224 in 3.1.0 to track RFC3942. This
+ broke a lot of legacy site local configurations. The new code in place will
+ track site local space minimum option codes and logs a warning to encourage
+ updates and exploration of site local code migration problems. Option
+ codes less than 128 in site local spaces remain inaccessible.
+
+- A possible relay agent option bug was repaired where random server
+ initialization state may have been used to signal the relay agent
+ information options sub-option code for the 'END' of the option space.
+
Changes since 4.0.0b3
- The reverse dns name for PTR updates on IPv6 addresses has been fixed to
diff --git a/common/tables.c b/common/tables.c
index 46874207..9259332d 100644
--- a/common/tables.c
+++ b/common/tables.c
@@ -961,6 +961,7 @@ void initialize_common_option_spaces()
dhcp_universe.store_tag = putUChar;
dhcp_universe.get_length = getUChar;
dhcp_universe.store_length = putUChar;
+ dhcp_universe.site_code_min = 0;
dhcp_universe.end = DHO_END;
dhcp_universe.index = universe_count++;
universes [dhcp_universe.index] = &dhcp_universe;
@@ -1001,6 +1002,7 @@ void initialize_common_option_spaces()
nwip_universe.store_tag = putUChar;
nwip_universe.get_length = getUChar;
nwip_universe.store_length = putUChar;
+ nwip_universe.site_code_min = 0;
nwip_universe.end = 0;
code = DHO_NWIP_SUBOPTIONS;
nwip_universe.enc_opt = NULL;
@@ -1046,6 +1048,7 @@ void initialize_common_option_spaces()
fqdn_universe.store_tag = putUChar;
fqdn_universe.get_length = getUChar;
fqdn_universe.store_length = putUChar;
+ fqdn_universe.site_code_min = 0;
fqdn_universe.end = 0;
fqdn_universe.index = universe_count++;
code = DHO_FQDN;
@@ -1093,6 +1096,7 @@ void initialize_common_option_spaces()
vendor_class_universe.store_tag = putULong;
vendor_class_universe.get_length = getUChar;
vendor_class_universe.store_length = putUChar;
+ vendor_class_universe.site_code_min = 0;
vendor_class_universe.end = 0;
code = DHO_VIVCO_SUBOPTIONS;
vendor_class_universe.enc_opt = NULL;
@@ -1139,6 +1143,7 @@ void initialize_common_option_spaces()
vendor_universe.store_tag = putULong;
vendor_universe.get_length = getUChar;
vendor_universe.store_length = putUChar;
+ vendor_universe.site_code_min = 0;
vendor_universe.end = 0;
code = DHO_VIVSO_SUBOPTIONS;
vendor_universe.enc_opt = NULL;
@@ -1185,6 +1190,7 @@ void initialize_common_option_spaces()
isc_universe.store_tag = putUShort;
isc_universe.get_length = getUShort;
isc_universe.store_length = putUShort;
+ isc_universe.site_code_min = 0;
isc_universe.end = 0;
code = VENDOR_ISC_SUBOPTIONS;
isc_universe.enc_opt = NULL;
@@ -1230,6 +1236,7 @@ void initialize_common_option_spaces()
dhcpv6_universe.store_tag = putUShort;
dhcpv6_universe.get_length = getUShort;
dhcpv6_universe.store_length = putUShort;
+ dhcpv6_universe.site_code_min = 0;
/* DHCPv6 has no END option. */
dhcpv6_universe.end = 0x00;
dhcpv6_universe.index = universe_count++;
@@ -1270,6 +1277,7 @@ void initialize_common_option_spaces()
vsio_universe.store_tag = putULong;
vsio_universe.get_length = NULL;
vsio_universe.store_length = NULL;
+ vsio_universe.site_code_min = 0;
/* No END option. */
vsio_universe.end = 0x00;
code = D6O_VENDOR_OPTS;
@@ -1310,6 +1318,7 @@ void initialize_common_option_spaces()
isc6_universe.store_tag = putULong;
isc6_universe.get_length = NULL;
isc6_universe.store_length = NULL;
+ isc6_universe.site_code_min = 0;
/* No END option. */
isc6_universe.end = 0x00;
code = 2495;
@@ -1353,6 +1362,7 @@ void initialize_common_option_spaces()
fqdn6_universe.store_tag = NULL;
fqdn6_universe.get_length = NULL;
fqdn6_universe.store_length = NULL;
+ fqdn6_universe.site_code_min = 0;
fqdn6_universe.end = 0;
fqdn6_universe.index = universe_count++;
code = D6O_CLIENT_FQDN;
diff --git a/includes/tree.h b/includes/tree.h
index ef8f3baf..2df11ceb 100644
--- a/includes/tree.h
+++ b/includes/tree.h
@@ -334,7 +334,7 @@ struct universe {
u_int32_t (*get_length) (const unsigned char *);
void (*store_length) PROTO ((unsigned char *, u_int32_t));
int tag_size, length_size;
- unsigned end;
+ unsigned site_code_min, end;
option_name_hash_t *name_hash;
option_code_hash_t *code_hash;
struct option *enc_opt;
diff --git a/server/dhcp.c b/server/dhcp.c
index 65c55860..3b8d2cb4 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -39,6 +39,10 @@
int outstanding_pings;
static char dhcp_message [256];
+static int site_code_min;
+
+static int find_min_site_code(struct universe *);
+static isc_result_t lowest_site_code(const void *, unsigned, void *);
static const char *dhcp_type_names [] = {
"DHCPDISCOVER",
@@ -1136,7 +1140,7 @@ void dhcpinform (packet, ms_nulltp)
}
options -> site_universe = u -> index;
- options -> site_code_min = 224; /* From RFC3942 */
+ options->site_code_min = find_min_site_code(u);
data_string_forget (&d1, MDL);
} else {
options -> site_universe = dhcp_universe.index;
@@ -2732,7 +2736,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
}
state -> options -> site_universe = u -> index;
- state -> options -> site_code_min = 224; /* From RFC3942 */
+ state->options->site_code_min = find_min_site_code(u);
data_string_forget (&d1, MDL);
} else {
state -> options -> site_code_min = 0;
@@ -4028,3 +4032,65 @@ get_server_source_address(struct in_addr *from,
}
}
+/*
+ * Look for the lowest numbered site code number and
+ * apply a log warning if it is less than 224. Do not
+ * permit site codes less than 128 (old code never did).
+ *
+ * Note that we could search option codes 224 down to 128
+ * on the hash table, but the table is (probably) smaller
+ * than that if it was declared as a standalone table with
+ * defaults. So we traverse the option code hash.
+ */
+static int
+find_min_site_code(struct universe *u)
+{
+ if (u->site_code_min)
+ return u->site_code_min;
+
+ /*
+ * Note that site_code_min has to be global as we can't pass an
+ * argument through hash_foreach(). The value 224 is taken from
+ * RFC 3942.
+ */
+ site_code_min = 224;
+ option_code_hash_foreach(u->code_hash, lowest_site_code);
+
+ if (site_code_min < 224) {
+ log_error("WARNING: site-local option codes less than 224 have "
+ "been deprecated by RFC3942. You have options "
+ "listed in site local space %s that number as low as "
+ "%d. Please investigate if these should be declared "
+ "as regular options rather than site-local options, "
+ "or migrated up past 224.",
+ u->name, site_code_min);
+ }
+
+ /*
+ * don't even bother logging, this is just silly, and never worked
+ * on any old version of software.
+ */
+ if (site_code_min < 128)
+ site_code_min = 128;
+
+ /*
+ * Cache the determined minimum site code on the universe structure.
+ * Note that due to the < 128 check above, a value of zero is
+ * impossible.
+ */
+ u->site_code_min = site_code_min;
+
+ return site_code_min;
+}
+
+static isc_result_t
+lowest_site_code(const void *key, unsigned len, void *object)
+{
+ struct option *option = object;
+
+ if (option->code < site_code_min)
+ site_code_min = option->code;
+
+ return ISC_R_SUCCESS;
+}
+
diff --git a/server/stables.c b/server/stables.c
index 3e1dffdc..a2d76c79 100644
--- a/server/stables.c
+++ b/server/stables.c
@@ -347,6 +347,8 @@ void initialize_server_option_spaces()
agent_universe.store_tag = putUChar;
agent_universe.get_length = getUChar;
agent_universe.store_length = putUChar;
+ agent_universe.site_code_min = 0;
+ agent_universe.end = 0;
universes [agent_universe.index] = &agent_universe;
if (!option_name_new_hash(&agent_universe.name_hash,
AGENT_HASH_SIZE, MDL) ||
@@ -385,6 +387,8 @@ void initialize_server_option_spaces()
server_universe.tag_size = 4;
server_universe.store_tag = putUChar;
server_universe.store_length = putUChar;
+ server_universe.site_code_min = 0;
+ server_universe.end = 0;
server_universe.index = universe_count++;
universes [server_universe.index] = &server_universe;
if (!option_name_new_hash(&server_universe.name_hash,