]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Make sure we return the IPv6 address we suggested in response to a
authorShane Kerr <shane@isc.org>
Wed, 3 Oct 2007 10:20:25 +0000 (10:20 +0000)
committerShane Kerr <shane@isc.org>
Wed, 3 Oct 2007 10:20:25 +0000 (10:20 +0000)
SOLICIT. Also do not put the address in the "used" pool list when
loading from file.

See RT ticket #17153 for more.

RELNOTES
server/dhcpv6.c
server/mdb6.c

index 7bc7a1deec6e83267576a81013dd6ad89d5ba96d..ecee1c59f0c53356f4cffb950f0f4a8f517bab5f 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -61,6 +61,10 @@ suggested fixes to <dhcp-users@isc.org>.
 - Log messages when failover peer names mismatch have been improved to
   point out the problem.
 
+- Bug where server advertised a IPv6 address in response to a SOLICIT 
+  but would not return the address in response to a REQUEST. Thanks to
+  Dennis Kou for finding the bug.
+
                        Changes since 4.0.0a2
 
 - Fix for startup where there are no IPv4 addresses on an interface.
index 292e3092c00e2250ae167af3a753e53eb18d1262..e4eb6e9113733f3f84775a27d3d41ba2158bd668 100644 (file)
@@ -834,6 +834,7 @@ pick_v6_address(struct iaaddr **addr,
        int i;
        int start_pool;
        unsigned int attempts;
+       char tmp_buf[INET6_ADDRSTRLEN];
 
        /*
         * First, find the link address where the packet from the client
@@ -861,7 +862,8 @@ pick_v6_address(struct iaaddr **addr,
                       first_link_addr, sizeof(*first_link_addr));
                subnet = NULL;
                if (!find_subnet(&subnet, tmp_addr, MDL)) {
-                       log_debug("No subnet found for link-address %s.",
+                       log_debug("Unable to pick client address: "
+                                 "no subnet found for link-address %s.",
                                  piaddr(tmp_addr));
                        return ISC_R_NOTFOUND;
                }
@@ -887,6 +889,8 @@ pick_v6_address(struct iaaddr **addr,
         */
        if (shared_network->ipv6_pools == NULL) {
                shared_network_dereference(&shared_network, MDL);
+               log_debug("Unable to pick client address: "
+                         "no IPv6 pools on this shared network");
                return ISC_R_NORESOURCES;
        }
 
@@ -903,9 +907,16 @@ pick_v6_address(struct iaaddr **addr,
                                ipv6_pool_reference(pool, p, MDL);
                                shared_network_dereference(&shared_network, 
                                                           MDL);
+                               log_debug("Picking requested address %s",
+                                         inet_ntop(AF_INET6, 
+                                                   requested_iaaddr->data,
+                                                   tmp_buf, sizeof(tmp_buf)));
                                return ISC_R_SUCCESS;
                        }
                }
+               log_debug("NOT picking requested address %s",
+                         inet_ntop(AF_INET6, requested_iaaddr->data,
+                                   tmp_buf, sizeof(tmp_buf)));
        }
 
        /*
@@ -937,6 +948,9 @@ pick_v6_address(struct iaaddr **addr,
                        shared_network->last_ipv6_pool = i;
 
                        shared_network_dereference(&shared_network, MDL);
+                       log_debug("Picking pool address %s",
+                                 inet_ntop(AF_INET6, &((*addr)->addr),
+                                           tmp_buf, sizeof(tmp_buf)));
                        return ISC_R_SUCCESS;
                }
 
@@ -951,6 +965,7 @@ pick_v6_address(struct iaaddr **addr,
         * Presumably that means we have no addresses for the client.
         */
        shared_network_dereference(&shared_network, MDL);
+       log_debug("Unable to pick client address: no addresses available");
        return ISC_R_NORESOURCES;
 }
 
@@ -1617,6 +1632,12 @@ lease_to_client(struct data_string *reply_ret,
                                                     lease, /* XXX */ NULL,
                                                     opt_state);
                                }
+                       /* 
+                        * On SOLICIT, we want to forget this lease since we're
+                        * not actually doing anything with it.
+                        */
+                       } else {
+                               release_lease6(lease->ipv6_pool, lease);
                        }
 
                } else {
index 6e1def3db313d94249abfaafc95a5d157deca0a7..13764a5fe5052a1b6ccf000920ec96d416e71609 100644 (file)
@@ -724,10 +724,10 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr,
         */
        tmp_iaaddr = NULL;
        iaaddr_reference(&tmp_iaaddr, iaaddr, MDL);
-       iaaddr_hash_add(pool->addrs, &tmp_iaaddr->addr, 
-                       sizeof(tmp_iaaddr->addr), iaaddr, MDL);
        if ((tmp_iaaddr->state == FTS_ACTIVE) ||
            (tmp_iaaddr->state == FTS_ABANDONED)) {
+               iaaddr_hash_add(pool->addrs, &tmp_iaaddr->addr, 
+                               sizeof(tmp_iaaddr->addr), iaaddr, MDL);
                insert_result = isc_heap_insert(pool->active_timeouts,
                                                tmp_iaaddr);
                if (insert_result == ISC_R_SUCCESS)