]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Both host and subnet6 configuration groups are now included whether a
authorDavid Hankins <dhankins@isc.org>
Wed, 30 Sep 2009 20:59:59 +0000 (20:59 +0000)
committerDavid Hankins <dhankins@isc.org>
Wed, 30 Sep 2009 20:59:59 +0000 (20:59 +0000)
  fixed-address6 (DHCPv6) is in use or not.  Host scoped configuration takes
  precedence.  This fixes two bugs, one where host scoped configuration
  would not be included from a non-fixed-address6 host record, and the equal
  and opposite bug where subnet6 scoped configuration would not be used when
  over-riding vlaues were not present in a matching fixed-address6 host
  configuration.  [ISC-Bugs #20069]

RELNOTES
server/dhcpv6.c

index f25f18d694ea2080dd4b0967db4a580d1b7d7c7b..50ee3387a9a88389c45c4033d2de0edbadc37795 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -194,6 +194,14 @@ work on other platforms. Please report any problems and suggested fixes to
 - Fixed the check in the dhcp_interface_signal_handler routine to verify
   the existence of the linked signal handler before calling it.
 
+- Both host and subnet6 configuration groups are now included whether a
+  fixed-address6 (DHCPv6) is in use or not.  Host scoped configuration takes
+  precedence.  This fixes two bugs, one where host scoped configuration
+  would not be included from a non-fixed-address6 host record, and the equal
+  and opposite bug where subnet6 scoped configuration would not be used when
+  over-riding vlaues were not present in a matching fixed-address6 host
+  configuration.
+
                        Changes since 4.1.0b1
 
 - A missing "else" in dhcrelay.c could have caused an interface not to
index b5472b0f13ae9e857485b996fb1b1c772825a972..7c029b0ebaad957c518d51400a06a3861d664de4 100644 (file)
@@ -43,6 +43,7 @@ struct reply_state {
        /* 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;
@@ -1386,6 +1387,15 @@ lease_to_client(struct data_string *reply_ret,
                                            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);
        }
 
        /*
@@ -1576,6 +1586,8 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
 
        /* 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)) {
@@ -1591,6 +1603,14 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                        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;
@@ -1870,6 +1890,8 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                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
@@ -2111,7 +2133,7 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
                        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);
@@ -2721,7 +2743,7 @@ find_client_address(struct reply_state *reply) {
 
                status = ISC_R_SUCCESS;
                scope = &global_scope;
-               group = reply->host->group;
+               group = reply->subnet->group;
                goto send_addr;
        }
 
@@ -2794,11 +2816,26 @@ reply_process_is_addressed(struct reply_state *reply,
        /* 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;
@@ -2905,6 +2942,16 @@ reply_process_is_addressed(struct reply_state *reply,
                                    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);
@@ -3356,7 +3403,6 @@ static isc_result_t
 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;
@@ -3501,13 +3547,11 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
                        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;
        }
 
        /*
@@ -3551,7 +3595,7 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
                        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;
 
@@ -3663,14 +3707,8 @@ find_client_prefix(struct reply_state *reply) {
        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;
 
@@ -3732,14 +3770,13 @@ find_client_prefix(struct reply_state *reply) {
                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;
 
@@ -3762,11 +3799,26 @@ reply_process_is_prefixed(struct reply_state *reply,
        /* 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;
@@ -3858,6 +3910,16 @@ reply_process_is_prefixed(struct reply_state *reply,
                                    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);