/* root level persistent state */
struct shared_network *shared;
struct host_decl *host;
+ struct subnet *subnet; /* Used to match fixed-addrs to subnet scopes. */
struct option_state *opt_state;
struct packet *packet;
struct data_string client_id;
reply.packet->options,
reply.opt_state, &global_scope,
reply.shared->group, root_group);
+
+ /* Bring in any configuration from a host record. */
+ if (reply.host != NULL)
+ execute_statements_in_scope(NULL, reply.packet, NULL,
+ NULL, reply.packet->options,
+ reply.opt_state,
+ &global_scope,
+ reply.host->group,
+ reply.shared->group);
}
/*
/* Check & cache the fixed host record. */
if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
+ struct iaddr tmp_addr;
+
if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
NULL, NULL, &global_scope,
reply->host->fixed_addr, MDL)) {
goto cleanup;
}
+ /* Find the static lease's subnet. */
+ tmp_addr.len = 16;
+ memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
+
+ if (find_grouped_subnet(&reply->subnet, reply->shared,
+ tmp_addr, MDL) == 0)
+ log_fatal("Impossible condition at %s:%d.", MDL);
+
reply->static_lease = ISC_TRUE;
} else
reply->static_lease = ISC_FALSE;
iasubopt_dereference(&reply->lease, MDL);
if (reply->fixed.data != NULL)
data_string_forget(&reply->fixed, MDL);
+ if (reply->subnet != NULL)
+ subnet_dereference(&reply->subnet, MDL);
/*
* ISC_R_CANCELED is a status code used by the addr processing to
log_fatal("Impossible condition at %s:%d.", MDL);
scope = &global_scope;
- group = reply->host->group;
+ group = reply->subnet->group;
} else {
if (reply->lease == NULL)
log_fatal("Impossible condition at %s:%d.", MDL);
status = ISC_R_SUCCESS;
scope = &global_scope;
- group = reply->host->group;
+ group = reply->subnet->group;
goto send_addr;
}
/* Initialize values we will cleanup. */
memset(&data, 0, sizeof(data));
- /* Execute relevant options into root scope. */
+ /*
+ * Bring configured options into the root packet level cache - start
+ * with the lease's closest enclosing group (passed in by the caller
+ * as 'group').
+ */
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
reply->packet->options, reply->opt_state,
scope, group, root_group);
+ /*
+ * If there is a host record, over-ride with values configured there,
+ * without re-evaluating configuration from the previously executed
+ * group or its common enclosers.
+ */
+ if (reply->host != NULL)
+ execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+ reply->packet->options,
+ reply->opt_state, scope,
+ reply->host->group, group);
+
/* Determine valid lifetime. */
if (reply->client_valid == 0)
reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
reply->packet->options, reply->reply_ia,
scope, group, root_group);
+ /*
+ * And bring in host record configuration, if any, but not to overlap
+ * the previous group or its common enclosers.
+ */
+ if (reply->host != NULL)
+ execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+ reply->packet->options,
+ reply->reply_ia, scope,
+ reply->host->group, group);
+
cleanup:
if (data.data != NULL)
data_string_forget(&data, MDL);
reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
u_int32_t pref_life, valid_life;
struct binding_scope **scope;
- struct group *group;
struct iaddrcidrnet tmp_pref;
struct option_cache *oc;
struct data_string iapref, data;
log_fatal("Impossible condition at %s:%d.", MDL);
scope = &global_scope;
- group = reply->host->group;
} else {
if (reply->lease == NULL)
log_fatal("Impossible condition at %s:%d.", MDL);
scope = &reply->lease->scope;
- group = reply->shared->group;
}
/*
goto cleanup;
}
- status = reply_process_is_prefixed(reply, scope, group);
+ status = reply_process_is_prefixed(reply, scope, reply->shared->group);
if (status != ISC_R_SUCCESS)
goto cleanup;
isc_result_t status = ISC_R_NORESOURCES;
struct iasubopt *prefix, *best_prefix = NULL;
struct binding_scope **scope;
- struct group *group;
int i;
- if (reply->host != NULL)
- group = reply->host->group;
- else
- group = reply->shared->group;
-
if (reply->static_prefixes > 0) {
struct iaddrcidrnetlist *l;
log_fatal("Impossible condition at %s:%d.", MDL);
scope = &reply->lease->scope;
- group = reply->shared->group;
send_pref.lo_addr.len = 16;
memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
send_pref.bits = (int) reply->lease->plen;
send_pref:
- status = reply_process_is_prefixed(reply, scope, group);
+ status = reply_process_is_prefixed(reply, scope, reply->shared->group);
if (status != ISC_R_SUCCESS)
return status;
/* Initialize values we will cleanup. */
memset(&data, 0, sizeof(data));
- /* Execute relevant options into root scope. */
+ /*
+ * Bring configured options into the root packet level cache - start
+ * with the lease's closest enclosing group (passed in by the caller
+ * as 'group').
+ */
execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
reply->packet->options, reply->opt_state,
scope, group, root_group);
+ /*
+ * If there is a host record, over-ride with values configured there,
+ * without re-evaluating configuration from the previously executed
+ * group or its common enclosers.
+ */
+ if (reply->host != NULL)
+ execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+ reply->packet->options,
+ reply->opt_state, scope,
+ reply->host->group, group);
+
/* Determine valid lifetime. */
if (reply->client_valid == 0)
reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
reply->packet->options, reply->reply_ia,
scope, group, root_group);
+ /*
+ * And bring in host record configuration, if any, but not to overlap
+ * the previous group or its common enclosers.
+ */
+ if (reply->host != NULL)
+ execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+ reply->packet->options,
+ reply->reply_ia, scope,
+ reply->host->group, group);
+
cleanup:
if (data.data != NULL)
data_string_forget(&data, MDL);