diff options
author | Francis Dupont <fdupont@isc.org> | 2007-12-28 09:46:42 +0000 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2007-12-28 09:46:42 +0000 |
commit | 0674055a497f77f0f0ea83e3d178292fba45475e (patch) | |
tree | d029e83ae5f882a9d4ab08023f4ba8ed4b4f6a18 | |
parent | bb7b6f763372abd9b500ab672ac91233b24814f2 (diff) | |
download | isc-dhcp-0674055a497f77f0f0ea83e3d178292fba45475e.tar.gz |
Better control over allocated IID
-rw-r--r-- | RELNOTES | 3 | ||||
-rw-r--r-- | server/mdb6.c | 35 |
2 files changed, 35 insertions, 3 deletions
@@ -78,6 +78,9 @@ suggested fixes to <dhcp-users@isc.org>. - Some definitions not in phase with the IANA registry were updated. +- Allocated interface IDs are better controlled ('u' bit set to zero, + reserved IDs avoided). + Changes since 4.0.0b3 - The reverse dns name for PTR updates on IPv6 addresses has been fixed to 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 |