summaryrefslogtreecommitdiff
path: root/server/mdb6.c
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2007-12-28 09:46:42 +0000
committerFrancis Dupont <fdupont@isc.org>2007-12-28 09:46:42 +0000
commit0674055a497f77f0f0ea83e3d178292fba45475e (patch)
treed029e83ae5f882a9d4ab08023f4ba8ed4b4f6a18 /server/mdb6.c
parentbb7b6f763372abd9b500ab672ac91233b24814f2 (diff)
downloadisc-dhcp-0674055a497f77f0f0ea83e3d178292fba45475e.tar.gz
Better control over allocated IID
Diffstat (limited to 'server/mdb6.c')
-rw-r--r--server/mdb6.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/server/mdb6.c b/server/mdb6.c
index 524c09f3..73912262 100644
--- a/server/mdb6.c
+++ b/server/mdb6.c
@@ -617,8 +617,20 @@ create_address(struct in6_addr *addr,
case 6: str[i] = (str[i] & 0x03) | (net_str[i] & 0xFC); break;
case 7: str[i] = (str[i] & 0x01) | (net_str[i] & 0xFE); break;
}
+ /* set the 'u' bit to zero for /64s. */
+ if (net_bits == 64)
+ str[8] &= ~0x02;
}
+/* Reserved Subnet Router Anycast ::0:0:0:0. */
+static struct in6_addr rtany = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* Reserved Subnet Anycasts ::fdff:ffff:ffff:ff80-::fdff:ffff:ffff:ffff. */
+static struct in6_addr resany = {
+ 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80
+};
+
/*
* Create a lease for the given address and client duid.
*
@@ -650,6 +662,7 @@ activate_lease6(struct ipv6_pool *pool, struct iaaddr **addr,
struct data_string new_ds;
struct iaaddr *iaaddr;
isc_result_t result;
+ isc_boolean_t reserved_iid;
/*
* Use the UID as our initial seed for the hash
@@ -673,14 +686,30 @@ activate_lease6(struct ipv6_pool *pool, struct iaaddr **addr,
create_address(&tmp, &pool->start_addr, pool->bits, &ds);
/*
+ * Avoid reserved interface IDs.
+ * (cf. draft-krishnan-ipv6-reserved-iids-02.txt)
+ */
+ reserved_iid = ISC_FALSE;
+ if (memcmp(&tmp, &rtany, 16) == 0) {
+ reserved_iid = ISC_TRUE;
+ }
+ if (!reserved_iid &&
+ (memcmp(&tmp, &resany, 15) == 0) &&
+ (tmp.s6_addr[15] & 0x80 == 0x80)) {
+ reserved_iid = ISC_TRUE;
+ }
+
+ /*
* If this address is not in use, we're happy with it
*/
test_iaaddr = NULL;
- if (iaaddr_hash_lookup(&test_iaaddr, pool->addrs,
- &tmp, sizeof(tmp), MDL) == 0) {
+ if (!reserved_iid &&
+ (iaaddr_hash_lookup(&test_iaaddr, pool->addrs,
+ &tmp, sizeof(tmp), MDL) == 0)) {
break;
}
- iaaddr_dereference(&test_iaaddr, MDL);
+ if (test_iaaddr != NULL)
+ iaaddr_dereference(&test_iaaddr, MDL);
/*
* Otherwise, we create a new input, adding the address