From: Francis Dupont Date: Mon, 17 Mar 2008 15:35:37 +0000 (+0000) Subject: Merged IA_XXrelated structures X-Git-Tag: v4_1_0a2~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9322442f8a8f2e0f54c03876fe280f8dea9c9581;p=thirdparty%2Fdhcp.git Merged IA_XXrelated structures --- diff --git a/RELNOTES b/RELNOTES index 2d08edcee..f5a7a352e 100644 --- a/RELNOTES +++ b/RELNOTES @@ -71,6 +71,8 @@ work on other platforms. Please report any problems and suggested fixes to - Prefix pools are attached to shared network scopes. +- Merged IA_XX related structures. + Changes since 4.0.0 (new features) - Added DHCPv6 rapid commit support. diff --git a/includes/dhcpd.h b/includes/dhcpd.h index eddeb0814..75f6ffe60 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -813,7 +813,6 @@ struct shared_network { struct ipv6_pool **ipv6_pools; /* NULL-terminated array */ int last_ipv6_pool; /* offset of last IPv6 pool used to issue a lease */ - struct ipv6_ppool **ipv6_ppools; /* NULL-terminated array */ struct group *group; #if defined (FAILOVER_PROTOCOL) dhcp_failover_state_t *failover_peer; @@ -1334,19 +1333,22 @@ typedef unsigned char option_mask [16]; #define MIN_TIME 0 /* these are referenced */ -typedef struct hash_table ia_na_hash_t; +typedef struct hash_table ia_hash_t; typedef struct hash_table iaaddr_hash_t; + /* should be lease6 */ + /* shared with iaprefix */ + struct iaaddr { int refcnt; /* reference count */ - struct in6_addr addr; /* IPv6 address */ - u_int8_t plen; /* unused/placeholder */ + struct in6_addr addr; /* IPv6 address/prefix */ + u_int8_t plen; /* iaprefix prefix length */ binding_state_t state; /* state */ struct binding_scope *scope; /* "set var = value;" */ time_t hard_lifetime_end_time; /* time address expires */ time_t soft_lifetime_end_time; /* time ephemeral expires */ - struct ia_na *ia_na; /* IA for this address */ - struct ipv6_pool *ipv6_pool; /* pool for this address */ + struct ia_xx *ia; /* IA for this lease */ + struct ipv6_pool *ipv6_pool; /* pool for this lease */ /* * For now, just pick an arbitrary time to keep old hard leases * around (value in seconds). @@ -1357,23 +1359,25 @@ struct iaaddr { (internal use only) */ }; -struct ia_na { +struct ia_xx { int refcnt; /* reference count */ struct data_string iaid_duid; /* from the client */ - u_int16_t ia_type; /* IA_NA or IA_TA */ - int num_iaaddr; /* number of IAADDR for this IA_NA */ + u_int16_t ia_type; /* IA_XX */ + int num_iaaddr; /* number of IAADDR for this IA */ int max_iaaddr; /* space available for IAADDR */ struct iaaddr **iaaddr; /* pointers to the various IAADDRs */ }; -extern ia_na_hash_t *ia_na_active; -extern ia_na_hash_t *ia_ta_active; +extern ia_hash_t *ia_na_active; +extern ia_hash_t *ia_ta_active; +extern ia_hash_t *ia_pd_active; struct ipv6_pool { int refcnt; /* reference count */ + u_int16_t pool_type; /* IA_xx */ struct in6_addr start_addr; /* first IPv6 address */ -#define POOL_IS_FOR_TEMP 0x8000 int bits; /* number of bits, CIDR style */ + int units; /* allocation unit in bits */ iaaddr_hash_t *addrs; /* non-free IAADDR */ int num_active; /* count of active IAADDR */ isc_heap_t *active_timeouts; /* timeouts for active leases */ @@ -1387,54 +1391,6 @@ struct ipv6_pool { extern struct ipv6_pool **pools; extern int num_pools; -/* Sames thing for IA_PDs */ - -typedef struct hash_table ia_pd_hash_t; -typedef struct hash_table iaprefix_hash_t; - -struct iaprefix { - /* Must keep the same layout than iaaddr */ - int refcnt; /* reference count */ - struct in6_addr pref; /* IPv6 prefix */ - u_int8_t plen; /* prefix length */ - binding_state_t state; /* state */ - struct binding_scope *scope; /* "set var = value;" */ - time_t hard_lifetime_end_time; /* time prefix expires */ - time_t soft_lifetime_end_time; /* time ephemeral expires */ - struct ia_pd *ia_pd; /* IA for this prefix */ - struct ipv6_ppool *ipv6_ppool; /* pool for this prefix */ - int heap_index; /* index into heap, or -1 - (internal use only) */ -}; - -struct ia_pd { - int refcnt; /* reference count */ - struct data_string iaid_duid; /* from the client */ - int num_iaprefix; /* number of IAPREFIX for this IA_PD */ - int max_iaprefix; /* space available for IAPREFIX */ - struct iaprefix **iaprefix; /* pointers to the various IAPREFIXs */ -}; - -extern ia_pd_hash_t *ia_pd_active; - -struct ipv6_ppool { - int refcnt; /* reference count */ - struct in6_addr start_pref; /* first IPv6 prefix */ - u_int8_t pool_plen; /* pool prefix length */ - u_int8_t alloc_plen; /* allocation prefix length */ - iaprefix_hash_t *prefs; /* non-free IAPREFIX */ - int num_active; /* count of active IAPREFIX */ - isc_heap_t *active_timeouts; /* timeouts for active leases */ - int num_inactive; /* count of inactive IAADDR */ - isc_heap_t *inactive_timeouts; /* timeouts for expired or - released leases */ - struct shared_network *shared_network; /* shared_network for - this pool */ -}; - -extern struct ipv6_ppool **ppools; -extern int num_ppools; - /* External definitions... */ HASH_FUNCTIONS_DECL (group, const char *, struct group_object, group_hash_t) @@ -2590,8 +2546,7 @@ int commit_leases PROTO ((void)); void db_startup PROTO ((int)); int new_lease_file PROTO ((void)); int group_writer (struct group_object *); -int write_ia(const struct ia_na *); -int write_ia_pd(const struct ia_pd *); +int write_ia(const struct ia_xx *); /* packet.c */ u_int32_t checksum PROTO ((unsigned char *, unsigned, u_int32_t)); @@ -3240,7 +3195,7 @@ isc_result_t dhcp_failover_process_update_request_all (dhcp_failover_state_t *, failover_message_t *); isc_result_t dhcp_failover_process_update_done (dhcp_failover_state_t *, failover_message_t *); -void ia_na_remove_all_iaaddr(struct ia_na *ia_na, const char *file, int line); +void ia_remove_all_iaaddr(struct ia_xx *ia, const char *file, int line); void dhcp_failover_recover_done (void *); void failover_print PROTO ((char *, unsigned *, unsigned, const char *)); void update_partner PROTO ((struct lease *)); @@ -3268,11 +3223,8 @@ const char *binding_state_print (enum failover_state); /* mdb6.c */ -HASH_FUNCTIONS_DECL(ia_na, unsigned char *, struct ia_na, ia_na_hash_t); -HASH_FUNCTIONS_DECL(ia_pd, unsigned char *, struct ia_pd, ia_pd_hash_t); +HASH_FUNCTIONS_DECL(ia, unsigned char *, struct ia_xx, ia_hash_t); HASH_FUNCTIONS_DECL(iaaddr, struct in6_addr *, struct iaaddr, iaaddr_hash_t); -HASH_FUNCTIONS_DECL(iaprefix, struct in6_addr *, - struct iaprefix, iaaddr_hash_t); isc_result_t iaaddr_allocate(struct iaaddr **iaaddr, const char *file, int line); @@ -3281,60 +3233,31 @@ isc_result_t iaaddr_reference(struct iaaddr **iaaddr, struct iaaddr *src, isc_result_t iaaddr_dereference(struct iaaddr **iaaddr, const char *file, int line); -isc_result_t iaprefix_allocate(struct iaprefix **iaprefix, - const char *file, int line); -isc_result_t iaprefix_reference(struct iaprefix **iaprefix, - struct iaprefix *src, - const char *file, int line); -isc_result_t iaprefix_dereference(struct iaprefix **iaprefix, - const char *file, int line); - isc_result_t ia_make_key(struct data_string *key, u_int32_t iaid, const char *duid, unsigned int duid_len, const char *file, int line); -isc_result_t ia_na_allocate(struct ia_na **ia_na, u_int32_t iaid, - const char *duid, unsigned int duid_len, - const char *file, int line); -isc_result_t ia_na_reference(struct ia_na **ia_na, struct ia_na *src, - const char *file, int line); -isc_result_t ia_na_dereference(struct ia_na **ia_na, - const char *file, int line); -isc_result_t ia_na_add_iaaddr(struct ia_na *ia_na, struct iaaddr *iaaddr, - const char *file, int line); -void ia_na_remove_iaaddr(struct ia_na *ia_na, struct iaaddr *iaaddr, +isc_result_t ia_allocate(struct ia_xx **ia, u_int32_t iaid, + const char *duid, unsigned int duid_len, const char *file, int line); -isc_boolean_t ia_na_equal(const struct ia_na *a, const struct ia_na *b); - -isc_result_t ia_pd_allocate(struct ia_pd **ia_pd, u_int32_t iaid, - const char *duid, unsigned int duid_len, +isc_result_t ia_reference(struct ia_xx **ia, struct ia_xx *src, + const char *file, int line); +isc_result_t ia_dereference(struct ia_xx **ia, const char *file, int line); -isc_result_t ia_pd_reference(struct ia_pd **ia_pd, struct ia_pd *src, - const char *file, int line); -isc_result_t ia_pd_dereference(struct ia_pd **ia_pd, - const char *file, int line); -isc_result_t ia_pd_add_iaprefix(struct ia_pd *ia_pd, struct iaprefix *iaprefix, - const char *file, int line); -void ia_pd_remove_iaprefix(struct ia_pd *ia_pd, struct iaprefix *iaprefix, +isc_result_t ia_add_iaaddr(struct ia_xx *ia, struct iaaddr *iaaddr, const char *file, int line); -isc_boolean_t ia_pd_equal(const struct ia_pd *a, const struct ia_pd *b); +void ia_remove_iaaddr(struct ia_xx *ia, struct iaaddr *iaaddr, + const char *file, int line); +isc_boolean_t ia_equal(const struct ia_xx *a, const struct ia_xx *b); -isc_result_t ipv6_pool_allocate(struct ipv6_pool **pool, - const struct in6_addr *start_addr, int bits, +isc_result_t ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, + const struct in6_addr *start_addr, + int bits, int units, const char *file, int line); isc_result_t ipv6_pool_reference(struct ipv6_pool **pool, struct ipv6_pool *src, const char *file, int line); isc_result_t ipv6_pool_dereference(struct ipv6_pool **pool, const char *file, int line); -isc_result_t ipv6_ppool_allocate(struct ipv6_ppool **ppool, - const struct in6_addr *start_pref, - u_int8_t pool_plen, u_int8_t alloc_plen, - const char *file, int line); -isc_result_t ipv6_ppool_reference(struct ipv6_ppool **ppool, - struct ipv6_ppool *src, - const char *file, int line); -isc_result_t ipv6_ppool_dereference(struct ipv6_ppool **ppool, - const char *file, int line); isc_result_t create_lease6(struct ipv6_pool *pool, struct iaaddr **addr, unsigned int *attempts, @@ -3350,46 +3273,29 @@ isc_result_t release_lease6(struct ipv6_pool *pool, struct iaaddr *addr); isc_result_t decline_lease6(struct ipv6_pool *pool, struct iaaddr *addr); isc_boolean_t lease6_exists(const struct ipv6_pool *pool, const struct in6_addr *addr); -isc_result_t mark_address_unavailble(struct ipv6_pool *pool, - const struct in6_addr *addr); +isc_result_t mark_lease_unavailble(struct ipv6_pool *pool, + const struct in6_addr *addr); -isc_result_t create_prefix6(struct ipv6_ppool *ppool, - struct iaprefix **pref, +isc_result_t create_prefix6(struct ipv6_pool *pool, + struct iaaddr **pref, unsigned int *attempts, const struct data_string *uid, time_t soft_lifetime_end_time); -isc_result_t add_prefix6(struct ipv6_ppool *ppool, - struct iaprefix *pref, - time_t valid_lifetime_end_time); -isc_result_t renew_prefix6(struct ipv6_ppool *ppool, struct iaprefix *pref); -isc_result_t expire_prefix6(struct iaprefix **pref, - struct ipv6_ppool *ppool, time_t now); -isc_result_t release_prefix6(struct ipv6_ppool *ppool, struct iaprefix *pref); -isc_boolean_t prefix6_exists(const struct ipv6_ppool *ppool, +isc_boolean_t prefix6_exists(const struct ipv6_pool *pool, const struct in6_addr *pref, u_int8_t plen); isc_result_t add_ipv6_pool(struct ipv6_pool *pool); -isc_result_t find_ipv6_pool(struct ipv6_pool **pool, int temp, +isc_result_t find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *addr); -isc_boolean_t ipv6_addr_in_pool(const struct in6_addr *addr, - const struct ipv6_pool *pool); -isc_result_t add_ipv6_ppool(struct ipv6_ppool *ppool); -isc_result_t find_ipv6_ppool(struct ipv6_ppool **pool, - const struct in6_addr *pref); -isc_boolean_t ipv6_prefix_in_ppool(const struct in6_addr *pref, - const struct ipv6_ppool *ppool); - -isc_result_t renew_leases(struct ia_na *ia_na); -isc_result_t release_leases(struct ia_na *ia_na); -isc_result_t decline_leases(struct ia_na *ia_na); +isc_boolean_t ipv6_in_pool(const struct in6_addr *addr, + const struct ipv6_pool *pool); + +isc_result_t renew_leases(struct ia_xx *ia); +isc_result_t release_leases(struct ia_xx *ia); +isc_result_t decline_leases(struct ia_xx *ia); void schedule_lease_timeout(struct ipv6_pool *pool); void schedule_all_ipv6_lease_timeouts(); -isc_result_t renew_prefixes(struct ia_pd *ia_pd); -isc_result_t release_prefixes(struct ia_pd *ia_pd); -void schedule_prefix_timeout(struct ipv6_ppool *ppool); -void schedule_all_ipv6_prefix_timeouts(); - void mark_hosts_unavailable(void); void mark_phosts_unavailable(void); void mark_interfaces_unavailable(void); diff --git a/server/confpars.c b/server/confpars.c index b01638844..3a54da05c 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -590,13 +590,13 @@ int parse_statement (cfile, group, type, host_decl, declaration) case POOL: next_token (&val, (unsigned *)0, cfile); - if (type != SUBNET_DECL && type != SHARED_NET_DECL) { - parse_warn (cfile, "pool declared outside of network"); - skip_to_semi(cfile); - } else if (type == POOL_DECL) { + if (type == POOL_DECL) { parse_warn (cfile, "pool declared within pool."); skip_to_semi(cfile); - } else + } else if (type != SUBNET_DECL && type != SHARED_NET_DECL) { + parse_warn (cfile, "pool declared outside of network"); + skip_to_semi(cfile); + } else parse_pool_statement (cfile, group, type); return declaration; @@ -629,7 +629,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) next_token(NULL, NULL, cfile); if ((type != SUBNET_DECL) || (group->subnet == NULL)) { parse_warn (cfile, - "prefix6 definitions may not be scoped."); + "prefix6 declaration not allowed here."); skip_to_semi(cfile); return declaration; } @@ -3636,9 +3636,11 @@ void parse_address_range (cfile, group, type, inpool, lpchain) #ifdef DHCPv6 static void -add_ipv6_pool_to_shared_network(struct shared_network *share, +add_ipv6_pool_to_shared_network(struct shared_network *share, + u_int16_t type, struct iaddr *lo_addr, - int bits) { + int bits, + int units) { struct ipv6_pool *pool; struct in6_addr tmp_in6_addr; int num_pools; @@ -3653,8 +3655,8 @@ add_ipv6_pool_to_shared_network(struct shared_network *share, } memcpy(&tmp_in6_addr, lo_addr->iabuf, sizeof(tmp_in6_addr)); pool = NULL; - if (ipv6_pool_allocate(&pool, &tmp_in6_addr, - bits, MDL) != ISC_R_SUCCESS) { + if (ipv6_pool_allocate(&pool, type, &tmp_in6_addr, + bits, units, MDL) != ISC_R_SUCCESS) { log_fatal("Out of memory"); } @@ -3765,7 +3767,8 @@ parse_address_range6(struct parse *cfile, struct group *group) { return; } - add_ipv6_pool_to_shared_network(share, &lo, bits); + add_ipv6_pool_to_shared_network(share, D6O_IA_NA, &lo, + bits, 128); } else if (token == TEMPORARY) { /* @@ -3778,9 +3781,9 @@ parse_address_range6(struct parse *cfile, struct group *group) { skip_to_semi(cfile); return; } - bits |= POOL_IS_FOR_TEMP; - add_ipv6_pool_to_shared_network(share, &lo, bits); + add_ipv6_pool_to_shared_network(share, D6O_IA_TA, &lo, + bits, 128); } else { /* * No '/', so we are looking for the end address of @@ -3799,9 +3802,9 @@ parse_address_range6(struct parse *cfile, struct group *group) { } for (p=nets; p != NULL; p=p->next) { - add_ipv6_pool_to_shared_network(share, + add_ipv6_pool_to_shared_network(share, D6O_IA_NA, &p->cidrnet.lo_addr, - p->cidrnet.bits); + p->cidrnet.bits, 128); } free_iaddrcidrnetlist(&nets); @@ -3816,75 +3819,6 @@ parse_address_range6(struct parse *cfile, struct group *group) { } } -static void -add_ipv6_ppool_to_shared_network(struct shared_network *share, - struct iaddr *start_addr, - int pool_bits, - int alloc_bits) { - struct ipv6_ppool *ppool; - struct in6_addr tmp_in6_addr; - int num_ppools; - struct ipv6_ppool **tmp; - - /* - * Create our prefix pool. - */ - if (start_addr->len != sizeof(tmp_in6_addr)) { - log_fatal("Internal error: Attempt to add non-IPv6 prefix."); - } - memcpy(&tmp_in6_addr, start_addr->iabuf, sizeof(tmp_in6_addr)); - ppool = NULL; - if (ipv6_ppool_allocate(&ppool, &tmp_in6_addr, - (u_int8_t) pool_bits, (u_int8_t) alloc_bits, - MDL) != ISC_R_SUCCESS) { - log_fatal("Out of memory"); - } - - /* - * Add to our IPv6 prefix pool set. - */ - if (add_ipv6_ppool(ppool) != ISC_R_SUCCESS) { - log_fatal ("Out of memory"); - } - - /* - * Link our prefix pool to our shared_network. - */ - ppool->shared_network = NULL; - shared_network_reference(&ppool->shared_network, share, MDL); - - /* - * Increase our array size for ipv6_ppools in the shared_network. - */ - if (share->ipv6_ppools == NULL) { - num_ppools = 0; - } else { - num_ppools = 0; - while (share->ipv6_ppools[num_ppools] != NULL) { - num_ppools++; - } - } - tmp = dmalloc(sizeof(struct ipv6_ppool *) * (num_ppools + 2), MDL); - if (tmp == NULL) { - log_fatal("Out of memory"); - } - if (num_ppools > 0) { - memcpy(tmp, share->ipv6_ppools, - sizeof(struct ipv6_ppool *) * num_ppools); - } - if (share->ipv6_ppools != NULL) { - dfree(share->ipv6_ppools, MDL); - } - share->ipv6_ppools = tmp; - - /* - * Record this prefix pool in our array of prefix pools - * for this shared network. - */ - ipv6_ppool_reference(&share->ipv6_ppools[num_ppools], ppool, MDL); - share->ipv6_ppools[num_ppools+1] = NULL; -} - /* prefix6-declaration :== ip-address6 ip-address6 SLASH number SEMI */ void @@ -3973,9 +3907,9 @@ parse_prefix6(struct parse *cfile, struct group *group) { parse_warn(cfile, "impossible mask length"); continue; } - add_ipv6_ppool_to_shared_network(share, - &p->cidrnet.lo_addr, - p->cidrnet.bits, bits); + add_ipv6_pool_to_shared_network(share, D6O_IA_PD, + &p->cidrnet.lo_addr, + p->cidrnet.bits, bits); } free_iaddrcidrnetlist(&nets); @@ -4141,9 +4075,9 @@ parse_ia_na_declaration(struct parse *cfile) { skip_to_semi(cfile); #else /* defined(DHCPv6) */ enum dhcp_token token; - struct ia_na *ia; + struct ia_xx *ia; const char *val; - struct ia_na *old_ia; + struct ia_xx *old_ia; unsigned int len; u_int32_t iaid; struct iaddr iaddr; @@ -4179,7 +4113,7 @@ parse_ia_na_declaration(struct parse *cfile) { memcpy(&iaid, val, 4); ia = NULL; - if (ia_na_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { + if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { log_fatal("Out of memory."); } ia->ia_type = D6O_IA_NA; @@ -4379,6 +4313,7 @@ parse_ia_na_declaration(struct parse *cfile) { log_fatal("Out of memory."); } memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr)); + iaaddr->plen = 0; iaaddr->state = state; if (iaaddr->state == FTS_RELEASED) iaaddr->hard_lifetime_end_time = end_time; @@ -4389,11 +4324,12 @@ parse_ia_na_declaration(struct parse *cfile) { } /* add to our various structures */ - ia_na_add_iaaddr(ia, iaaddr, MDL); - ia_na_reference(&iaaddr->ia_na, ia, MDL); + ia_add_iaaddr(ia, iaaddr, MDL); + ia_reference(&iaaddr->ia, ia, MDL); pool = NULL; - if (find_ipv6_pool(&pool, 0, &iaaddr->addr) != ISC_R_SUCCESS) { - inet_ntop(AF_INET6, &iaaddr->addr, + if (find_ipv6_pool(&pool, D6O_IA_NA, + &iaaddr->addr) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iaaddr->addr, addr_buf, sizeof(addr_buf)); parse_warn(cfile, "no pool found for address %s", addr_buf); @@ -4408,24 +4344,24 @@ parse_ia_na_declaration(struct parse *cfile) { * If we have an existing record for this IA_NA, remove it. */ old_ia = NULL; - if (ia_na_hash_lookup(&old_ia, ia_na_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, MDL)) { - ia_na_hash_delete(ia_na_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, MDL); - ia_na_dereference(&old_ia, MDL); + if (ia_hash_lookup(&old_ia, ia_na_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL)) { + ia_hash_delete(ia_na_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL); + ia_dereference(&old_ia, MDL); } /* * If we have addresses, add this, otherwise don't bother. */ if (ia->num_iaaddr > 0) { - ia_na_hash_add(ia_na_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, ia, MDL); + ia_hash_add(ia_na_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, ia, MDL); } - ia_na_dereference(&ia, MDL); + ia_dereference(&ia, MDL); #endif /* defined(DHCPv6) */ } @@ -4436,9 +4372,9 @@ parse_ia_ta_declaration(struct parse *cfile) { skip_to_semi(cfile); #else /* defined(DHCPv6) */ enum dhcp_token token; - struct ia_na *ia; + struct ia_xx *ia; const char *val; - struct ia_na *old_ia; + struct ia_xx *old_ia; unsigned int len; u_int32_t iaid; struct iaddr iaddr; @@ -4474,7 +4410,7 @@ parse_ia_ta_declaration(struct parse *cfile) { memcpy(&iaid, val, 4); ia = NULL; - if (ia_na_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { + if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { log_fatal("Out of memory."); } ia->ia_type = D6O_IA_TA; @@ -4674,6 +4610,7 @@ parse_ia_ta_declaration(struct parse *cfile) { log_fatal("Out of memory."); } memcpy(&iaaddr->addr, iaddr.iabuf, sizeof(iaaddr->addr)); + iaaddr->plen = 0; iaaddr->state = state; if (iaaddr->state == FTS_RELEASED) iaaddr->hard_lifetime_end_time = end_time; @@ -4684,11 +4621,12 @@ parse_ia_ta_declaration(struct parse *cfile) { } /* add to our various structures */ - ia_na_add_iaaddr(ia, iaaddr, MDL); - ia_na_reference(&iaaddr->ia_na, ia, MDL); + ia_add_iaaddr(ia, iaaddr, MDL); + ia_reference(&iaaddr->ia, ia, MDL); pool = NULL; - if (find_ipv6_pool(&pool, 1, &iaaddr->addr) != ISC_R_SUCCESS) { - inet_ntop(AF_INET6, &iaaddr->addr, + if (find_ipv6_pool(&pool, D6O_IA_TA, + &iaaddr->addr) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iaaddr->addr, addr_buf, sizeof(addr_buf)); parse_warn(cfile, "no pool found for address %s", addr_buf); @@ -4703,24 +4641,24 @@ parse_ia_ta_declaration(struct parse *cfile) { * If we have an existing record for this IA_TA, remove it. */ old_ia = NULL; - if (ia_na_hash_lookup(&old_ia, ia_ta_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, MDL)) { - ia_na_hash_delete(ia_ta_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, MDL); - ia_na_dereference(&old_ia, MDL); + if (ia_hash_lookup(&old_ia, ia_ta_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL)) { + ia_hash_delete(ia_ta_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL); + ia_dereference(&old_ia, MDL); } /* * If we have addresses, add this, otherwise don't bother. */ if (ia->num_iaaddr > 0) { - ia_na_hash_add(ia_ta_active, - (unsigned char *)ia->iaid_duid.data, - ia->iaid_duid.len, ia, MDL); + ia_hash_add(ia_ta_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, ia, MDL); } - ia_na_dereference(&ia, MDL); + ia_dereference(&ia, MDL); #endif /* defined(DHCPv6) */ } @@ -4731,17 +4669,17 @@ parse_ia_pd_declaration(struct parse *cfile) { skip_to_semi(cfile); #else /* defined(DHCPv6) */ enum dhcp_token token; - struct ia_pd *ia_pd; + struct ia_xx *ia; const char *val; - struct ia_pd *old_ia_pd; + struct ia_xx *old_ia; unsigned int len; u_int32_t iaid; struct iaddr iaddr; u_int8_t plen; binding_state_t state; TIME end_time; - struct iaprefix *iapref; - struct ipv6_ppool *ppool; + struct iaaddr *iapref; + struct ipv6_pool *pool; char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; isc_boolean_t newbinding; struct binding_scope *scope=NULL; @@ -4769,10 +4707,11 @@ parse_ia_pd_declaration(struct parse *cfile) { } memcpy(&iaid, val, 4); - ia_pd = NULL; - if (ia_pd_allocate(&ia_pd, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { + ia = NULL; + if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) { log_fatal("Out of memory."); } + ia->ia_type = D6O_IA_PD; token = next_token(&val, NULL, cfile); if (token != LBRACE) { @@ -4965,10 +4904,10 @@ parse_ia_pd_declaration(struct parse *cfile) { } iapref = NULL; - if (iaprefix_allocate(&iapref, MDL) != ISC_R_SUCCESS) { + if (iaaddr_allocate(&iapref, MDL) != ISC_R_SUCCESS) { log_fatal("Out of memory."); } - memcpy(&iapref->pref, iaddr.iabuf, sizeof(iapref->pref)); + memcpy(&iapref->addr, iaddr.iabuf, sizeof(iapref->addr)); iapref->plen = plen; iapref->state = state; if (iapref->state == FTS_RELEASED) @@ -4980,43 +4919,44 @@ parse_ia_pd_declaration(struct parse *cfile) { } /* add to our various structures */ - ia_pd_add_iaprefix(ia_pd, iapref, MDL); - ia_pd_reference(&iapref->ia_pd, ia_pd, MDL); - ppool = NULL; - if (find_ipv6_ppool(&ppool, &iapref->pref) != ISC_R_SUCCESS) { - inet_ntop(AF_INET6, &iapref->pref, + ia_add_iaaddr(ia, iapref, MDL); + ia_reference(&iapref->ia, ia, MDL); + pool = NULL; + if (find_ipv6_pool(&pool, D6O_IA_PD, + &iapref->addr) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iapref->addr, addr_buf, sizeof(addr_buf)); - parse_warn(cfile, "no ppool found for address %s", + parse_warn(cfile, "no pool found for address %s", addr_buf); return; } - add_prefix6(ppool, iapref, end_time); - ipv6_ppool_dereference(&ppool, MDL); - iaprefix_dereference(&iapref, MDL); + add_lease6(pool, iapref, end_time); + ipv6_pool_dereference(&pool, MDL); + iaaddr_dereference(&iapref, MDL); } /* * If we have an existing record for this IA_PD, remove it. */ - old_ia_pd = NULL; - if (ia_pd_hash_lookup(&old_ia_pd, ia_pd_active, - (unsigned char *)ia_pd->iaid_duid.data, - ia_pd->iaid_duid.len, MDL)) { - ia_pd_hash_delete(ia_pd_active, - (unsigned char *)ia_pd->iaid_duid.data, - ia_pd->iaid_duid.len, MDL); - ia_pd_dereference(&old_ia_pd, MDL); + old_ia = NULL; + if (ia_hash_lookup(&old_ia, ia_pd_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL)) { + ia_hash_delete(ia_pd_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, MDL); + ia_dereference(&old_ia, MDL); } /* * If we have prefixes, add this, otherwise don't bother. */ - if (ia_pd->num_iaprefix > 0) { - ia_pd_hash_add(ia_pd_active, - (unsigned char *)ia_pd->iaid_duid.data, - ia_pd->iaid_duid.len, ia_pd, MDL); + if (ia->num_iaaddr > 0) { + ia_hash_add(ia_pd_active, + (unsigned char *)ia->iaid_duid.data, + ia->iaid_duid.len, ia, MDL); } - ia_pd_dereference(&ia_pd, MDL); + ia_dereference(&ia, MDL); #endif /* defined(DHCPv6) */ } diff --git a/server/db.c b/server/db.c index 563a261c9..29b140d35 100644 --- a/server/db.c +++ b/server/db.c @@ -500,7 +500,7 @@ int write_group (group) * Write an IA and the options it has. */ int -write_ia(const struct ia_na *ia) { +write_ia(const struct ia_xx *ia) { struct iaaddr *iaaddr; struct binding *bnd; int i; @@ -529,14 +529,20 @@ write_ia(const struct ia_na *ia) { if (s == NULL) { goto error_exit; } - if (ia->ia_type == D6O_IA_NA) { + switch (ia->ia_type) { + case D6O_IA_NA: fprintf_ret = fprintf(db_file, "ia-na \"%s\" {\n", s); - } else if (ia->ia_type == D6O_IA_TA) { + break; + case D6O_IA_TA: fprintf_ret = fprintf(db_file, "ia-ta \"%s\" {\n", s); - } else { - log_error("Unknown ia type %u at %s:%d", - (unsigned)ia->ia_type, MDL); - goto error_exit; + break; + case D6O_IA_PD: + fprintf_ret = fprintf(db_file, "ia-pd \"%s\" {\n", s); + break; + default: + log_error("Unknown ia type %u for \"%s\" at %s:%d", + (unsigned)ia->ia_type, s, MDL); + fprintf_ret = -1; } dfree(s, MDL); if (fprintf_ret < 0) { @@ -546,7 +552,13 @@ write_ia(const struct ia_na *ia) { iaaddr = ia->iaaddr[i]; inet_ntop(AF_INET6, &iaaddr->addr, addr_buf, sizeof(addr_buf)); - if (fprintf(db_file, " iaaddr %s {\n", addr_buf) < 0) { + if ((ia->ia_type != D6O_IA_PD) && + (fprintf(db_file, " iaaddr %s {\n", addr_buf) < 0)) { + goto error_exit; + } + if ((ia->ia_type == D6O_IA_PD) && + (fprintf(db_file, " iaprefix %s/%d {\n", + addr_buf, (int)iaaddr->plen) < 0)) { goto error_exit; } if ((iaaddr->state <= 0) || (iaaddr->state > FTS_LAST)) { @@ -607,115 +619,7 @@ write_ia(const struct ia_na *ia) { return 1; error_exit: - log_info("write_ia: unable to write ia-na"); - lease_file_is_corrupt = 1; - return 0; -} - -/* - * Write an IA_PD and the options it has. - */ -int -write_ia_pd(const struct ia_pd *ia_pd) { - struct iaprefix *iapref; - struct binding *bnd; - int i; - char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff.255.255.255.255")]; - const char *binding_state; - const char *tval; - char *s; - int fprintf_ret; - - /* - * If the lease file is corrupt, don't try to write any more - * leases until we've written a good lease file. - */ - if (lease_file_is_corrupt) { - if (!new_lease_file()) { - return 0; - } - } - - if (counting) { - ++count; - } - - - s = quotify_buf(ia_pd->iaid_duid.data, ia_pd->iaid_duid.len, MDL); - if (s == NULL) { - goto error_exit; - } - fprintf_ret = fprintf(db_file, "ia-pd \"%s\" {\n", s); - dfree(s, MDL); - if (fprintf_ret < 0) { - goto error_exit; - } - for (i=0; inum_iaprefix; i++) { - iapref = ia_pd->iaprefix[i]; - - inet_ntop(AF_INET6, &iapref->pref, addr_buf, sizeof(addr_buf)); - if (fprintf(db_file, " iaprefix %s/%d {\n", - addr_buf, (int)iapref->plen) < 0) { - goto error_exit; - } - if ((iapref->state <= 0) || (iapref->state > FTS_LAST)) { - log_fatal("Unknown iaprefix state %d at %s:%d", - iapref->state, MDL); - } - binding_state = binding_state_names[iapref->state-1]; - if (fprintf(db_file, " binding state %s;\n", - binding_state) < 0) { - goto error_exit; - } - - /* Note that from here on out, the \n is prepended to the - * next write, rather than appended to the current write. - */ - if ((iapref->state == FTS_ACTIVE) || - (iapref->state == FTS_ABANDONED)) { - tval = print_time(iapref->hard_lifetime_end_time); - } else { - tval = print_time(iapref->soft_lifetime_end_time); - } - if (tval == NULL) { - goto error_exit; - } - if (fprintf(db_file, " ends %s", tval) < 0) { - goto error_exit; - } - - /* Write out any binding scopes: note that 'ends' above does - * not have \n on the end! We want that. - */ - if (iapref->scope != NULL) - bnd = iapref->scope->bindings; - else - bnd = NULL; - - for (; bnd != NULL ; bnd = bnd->next) { - if (bnd->value == NULL) - continue; - - /* We don't do a regular error_exit because the - * lease db is not corrupt in this case. - */ - if (write_binding_scope(db_file, bnd, - "\n ") != ISC_R_SUCCESS) - goto error_exit; - - } - - if (fprintf(db_file, "\n }\n") < 0) - goto error_exit; - } - if (fprintf(db_file, "}\n\n") < 0) - goto error_exit; - - fflush(db_file); - return 1; - -error_exit: - log_info("write_ia_pd: unable to write ia-pd"); + log_info("write_ia: unable to write ia"); lease_file_is_corrupt = 1; return 0; } diff --git a/server/ddns.c b/server/ddns.c index fe8276a31..b87924bd2 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -565,8 +565,8 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, memset (&ddns_dhcid, 0, sizeof ddns_dhcid); if (lease6 != NULL) result = get_dhcid(&ddns_dhcid, 2, - lease6->ia_na->iaid_duid.data, - lease6->ia_na->iaid_duid.len); + lease6->ia->iaid_duid.data, + lease6->ia->iaid_duid.len); else if ((lease != NULL) && (lease->uid != NULL) && (lease->uid_len != 0)) result = get_dhcid (&ddns_dhcid, diff --git a/server/dhcpd.c b/server/dhcpd.c index 1d60827cf..61b8f7427 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -655,13 +655,13 @@ main(int argc, char **argv) { #ifdef DHCPv6 /* set up DHCPv6 hashes */ - if (!ia_na_new_hash(&ia_na_active, DEFAULT_HASH_SIZE, MDL)) { + if (!ia_new_hash(&ia_na_active, DEFAULT_HASH_SIZE, MDL)) { log_fatal("Out of memory creating hash for active IA_NA."); } - if (!ia_na_new_hash(&ia_ta_active, DEFAULT_HASH_SIZE, MDL)) { + if (!ia_new_hash(&ia_ta_active, DEFAULT_HASH_SIZE, MDL)) { log_fatal("Out of memory creating hash for active IA_TA."); } - if (!ia_pd_new_hash(&ia_pd_active, DEFAULT_HASH_SIZE, MDL)) { + if (!ia_new_hash(&ia_pd_active, DEFAULT_HASH_SIZE, MDL)) { log_fatal("Out of memory creating hash for active IA_PD."); } #endif /* DHCPv6 */ diff --git a/server/dhcpv6.c b/server/dhcpv6.c index a0ecec03b..2dad33ed2 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -49,26 +49,18 @@ struct reply_state { /* IA level persistent state */ unsigned ia_count; - unsigned ia_pd_count; + unsigned pd_count; unsigned client_resources; - isc_boolean_t ia_resources_included; + isc_boolean_t resources_included; isc_boolean_t static_lease; unsigned static_prefixes; - struct ia_na *ia_na; - struct ia_na *ia_ta; - union { - struct ia_na *old__ia; - struct ia_pd *old__pd; - } old; -#define old_ia old.old__ia -#define old_ia_pd old.old__pd - struct ia_pd *ia_pd; + struct ia_xx *ia; + struct ia_xx *old_ia; struct option_state *reply_ia; struct data_string fixed; - /* IAADDR/IAPREFIX level persistent state */ + /* IAADDR/PREFIX level persistent state */ struct iaaddr *lease; - struct iaprefix *prefix; /* * "t1", "t2", preferred, and valid lifetimes records for calculating @@ -122,7 +114,6 @@ static isc_result_t reply_process_try_addr(struct reply_state *reply, struct iaddr *addr); static isc_result_t find_client_address(struct reply_state *reply); static isc_result_t reply_process_is_addressed(struct reply_state *reply, - struct ia_na *ia, struct binding_scope **scope, struct group *group); static isc_result_t reply_process_send_addr(struct reply_state *reply, @@ -138,14 +129,13 @@ static isc_result_t find_client_prefix(struct reply_state *reply); static isc_result_t reply_process_try_prefix(struct reply_state *reply, struct iaddrcidrnet *pref); static isc_result_t reply_process_is_prefixed(struct reply_state *reply, - struct ia_pd *ia_pd, struct binding_scope **scope, struct group *group); static isc_result_t reply_process_send_prefix(struct reply_state *reply, struct iaddrcidrnet *pref); -static struct iaprefix *prefix_compare(struct reply_state *reply, - struct iaprefix *alpha, - struct iaprefix *beta); +static struct iaaddr *prefix_compare(struct reply_state *reply, + struct iaaddr *alpha, + struct iaaddr *beta); /* * This function returns the time since DUID time start for the @@ -965,7 +955,7 @@ try_client_v6_address(struct iaaddr **addr, return ISC_R_FAILURE; } - if (!ipv6_addr_in_pool(&tmp_addr, pool)) { + if (!ipv6_in_pool(&tmp_addr, pool)) { return ISC_R_FAILURE; } @@ -978,6 +968,7 @@ try_client_v6_address(struct iaaddr **addr, return result; } (*addr)->addr = tmp_addr; + (*addr)->plen = 0; /* Default is soft binding for 2 minutes. */ result = add_lease6(pool, *addr, cur_time + 120); @@ -1006,7 +997,7 @@ pick_v6_address(struct iaaddr **addr, struct shared_network *shared_network, char tmp_buf[INET6_ADDRSTRLEN]; /* - * No pools or all temporary, we're done. + * No address pools, we're done. */ if (shared_network->ipv6_pools == NULL) { log_debug("Unable to pick client address: " @@ -1017,11 +1008,11 @@ pick_v6_address(struct iaaddr **addr, struct shared_network *shared_network, p = shared_network->ipv6_pools[i]; if (p == NULL) { log_debug("Unable to pick client address: " - "only temporary IPv6 pools " + "no IPv6 address pools " "on this shared network"); return ISC_R_NORESOURCES; } - if ((p->bits & POOL_IS_FOR_TEMP) == 0) { + if (p->pool_type == D6O_IA_NA) { break; } } @@ -1038,7 +1029,7 @@ pick_v6_address(struct iaaddr **addr, struct shared_network *shared_network, do { p = shared_network->ipv6_pools[i]; - if (((p->bits & POOL_IS_FOR_TEMP) == 0) && + if ((p->pool_type == D6O_IA_NA) && (create_lease6(p, addr, &attempts, client_id, cur_time + 120) == ISC_R_SUCCESS)) { /* @@ -1078,12 +1069,12 @@ pick_v6_address(struct iaaddr **addr, struct shared_network *shared_network, * prefix pool. * * pref is the result (should be a pointer to NULL on entry) - * ppool is the prefix pool to search in + * pool is the prefix pool to search in * requested_pref is the address the client wants */ static isc_result_t -try_client_v6_prefix(struct iaprefix **pref, - struct ipv6_ppool *ppool, +try_client_v6_prefix(struct iaaddr **pref, + struct ipv6_pool *pool, const struct data_string *requested_pref) { u_int8_t tmp_plen; @@ -1108,26 +1099,26 @@ try_client_v6_prefix(struct iaprefix **pref, return ISC_R_FAILURE; } - if ((tmp_plen != ppool->alloc_plen) || - !ipv6_prefix_in_ppool(&tmp_pref, ppool)) { + if (((int)tmp_plen != pool->units) || + !ipv6_in_pool(&tmp_pref, pool)) { return ISC_R_FAILURE; } - if (prefix6_exists(ppool, &tmp_pref, tmp_plen)) { + if (prefix6_exists(pool, &tmp_pref, tmp_plen)) { return ISC_R_ADDRINUSE; } - result = iaprefix_allocate(pref, MDL); + result = iaaddr_allocate(pref, MDL); if (result != ISC_R_SUCCESS) { return result; } - (*pref)->pref = tmp_pref; + (*pref)->addr = tmp_pref; (*pref)->plen = tmp_plen; /* Default is soft binding for 2 minutes. */ - result = add_prefix6(ppool, *pref, cur_time + 120); + result = add_lease6(pool, *pref, cur_time + 120); if (result != ISC_R_SUCCESS) { - iaprefix_dereference(pref, MDL); + iaaddr_dereference(pref, MDL); } return result; } @@ -1142,11 +1133,11 @@ try_client_v6_prefix(struct iaprefix **pref, * client_id is the DUID for the client */ static isc_result_t -pick_v6_prefix(struct iaprefix **pref, int plen, +pick_v6_prefix(struct iaaddr **pref, int plen, struct shared_network *shared_network, const struct data_string *client_id) { - struct ipv6_ppool *p; + struct ipv6_pool *p; int i; unsigned int attempts; char tmp_buf[INET6_ADDRSTRLEN]; @@ -1154,32 +1145,47 @@ pick_v6_prefix(struct iaprefix **pref, int plen, /* * No prefix pools, we're done. */ - if (shared_network->ipv6_ppools == NULL) { + if (shared_network->ipv6_pools == NULL) { log_debug("Unable to pick client prefix: " - "no IPv6 prefix pools on this shared network"); + "no IPv6 pools on this shared network"); return ISC_R_NORESOURCES; } + for (i = 0;; i++) { + p = shared_network->ipv6_pools[i]; + if (p == NULL) { + log_debug("Unable to pick client prefix: " + "no IPv6 prefix pools " + "on this shared network"); + return ISC_R_NORESOURCES; + } + if (p->pool_type == D6O_IA_PD) { + break; + } + } /* * Otherwise try to get a prefix. */ for (i = 0;; i++) { - p = shared_network->ipv6_ppools[i]; + p = shared_network->ipv6_pools[i]; if (p == NULL) { break; } + if (p->pool_type != D6O_IA_PD) { + continue; + } /* * Try only pools with the requested prefix length if any. */ - if ((plen >= 0) && ((int) p->alloc_plen != plen)) { + if ((plen >= 0) && (p->units != plen)) { continue; } if (create_prefix6(p, pref, &attempts, client_id, cur_time + 120) == ISC_R_SUCCESS) { log_debug("Picking pool prefix %s/%u", - inet_ntop(AF_INET6, &((*pref)->pref), + inet_ntop(AF_INET6, &((*pref)->addr), tmp_buf, sizeof(tmp_buf)), (unsigned) (*pref)->plen); return ISC_R_SUCCESS; @@ -1285,7 +1291,7 @@ lease_to_client(struct data_string *reply_ret, /* Start counting resources (addresses) offered. */ reply.client_resources = 0; - reply.ia_resources_included = ISC_FALSE; + reply.resources_included = ISC_FALSE; status = reply_process_ia_na(&reply, oc); @@ -1310,7 +1316,7 @@ lease_to_client(struct data_string *reply_ret, /* Start counting resources (addresses) offered. */ reply.client_resources = 0; - reply.ia_resources_included = ISC_FALSE; + reply.resources_included = ISC_FALSE; status = reply_process_ia_ta(&reply, oc); @@ -1331,14 +1337,14 @@ lease_to_client(struct data_string *reply_ret, } /* Same for IA_PD's. */ - reply.ia_pd_count = 0; + reply.pd_count = 0; oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD); for (; oc != NULL ; oc = oc->next) { isc_result_t status; /* Start counting resources (prefixes) offered. */ reply.client_resources = 0; - reply.ia_resources_included = ISC_FALSE; + reply.resources_included = ISC_FALSE; status = reply_process_ia_pd(&reply, oc); @@ -1362,7 +1368,7 @@ lease_to_client(struct data_string *reply_ret, * Make no reply if we gave no resources and is not * for Information-Request. */ - if ((reply.ia_count == 0) && (reply.ia_pd_count == 0) && + if ((reply.ia_count == 0) && (reply.pd_count == 0) && (reply.packet->dhcpv6_msg_type != DHCPV6_INFORMATION_REQUEST)) goto exit; @@ -1519,7 +1525,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { /* Fetch the IA_NA contents. */ if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet, ia, IA_NA_OFFSET)) { - log_error("reply_process_ia_na: error evaluating ia_na"); + log_error("reply_process_ia_na: error evaluating ia"); status = ISC_R_FAILURE; goto cleanup; } @@ -1530,18 +1536,18 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { reply->rebind = getULong(ia_data.data + 8); /* Create an IA_NA structure. */ - if (ia_na_allocate(&reply->ia_na, iaid, (char *)reply->client_id.data, - reply->client_id.len, MDL) != ISC_R_SUCCESS) { - log_error("reply_process_ia_na: no memory for ia_na."); + if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data, + reply->client_id.len, MDL) != ISC_R_SUCCESS) { + log_error("reply_process_ia_na: no memory for ia."); status = ISC_R_NOMEMORY; goto cleanup; } - reply->ia_na->ia_type = D6O_IA_NA; + reply->ia->ia_type = D6O_IA_NA; /* Cache pre-existing IA, if any. */ - ia_na_hash_lookup(&reply->old_ia, ia_na_active, - (unsigned char *)reply->ia_na->iaid_duid.data, - reply->ia_na->iaid_duid.len, MDL); + ia_hash_lookup(&reply->old_ia, ia_na_active, + (unsigned char *)reply->ia->iaid_duid.data, + reply->ia->iaid_duid.len, MDL); /* * Create an option cache to carry the IA_NA option contents, and @@ -1699,7 +1705,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { * provide zero addresses including zeroed * lifetimes. */ - if (reply->ia_resources_included) + if (reply->resources_included) status = ISC_R_SUCCESS; else goto cleanup; @@ -1775,17 +1781,17 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { */ if ((status != ISC_R_CANCELED) && !reply->static_lease && (reply->buf.reply.msg_type == DHCPV6_REPLY) && - (reply->ia_na->num_iaaddr != 0)) { + (reply->ia->num_iaaddr != 0)) { struct iaaddr *tmp; struct data_string *ia_id; int i; - for (i = 0 ; i < reply->ia_na->num_iaaddr ; i++) { - tmp = reply->ia_na->iaaddr[i]; + for (i = 0 ; i < reply->ia->num_iaaddr ; i++) { + tmp = reply->ia->iaaddr[i]; - if (tmp->ia_na != NULL) - ia_na_dereference(&tmp->ia_na, MDL); - ia_na_reference(&tmp->ia_na, reply->ia_na, MDL); + if (tmp->ia != NULL) + ia_dereference(&tmp->ia, MDL); + ia_reference(&tmp->ia, reply->ia, MDL); /* Commit 'hard' bindings. */ tmp->hard_lifetime_end_time = @@ -1811,21 +1817,21 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { } } - /* Remove any old ia_na from the hash. */ + /* Remove any old ia from the hash. */ if (reply->old_ia != NULL) { ia_id = &reply->old_ia->iaid_duid; - ia_na_hash_delete(ia_na_active, - (unsigned char *)ia_id->data, - ia_id->len, MDL); - ia_na_dereference(&reply->old_ia, MDL); + ia_hash_delete(ia_na_active, + (unsigned char *)ia_id->data, + ia_id->len, MDL); + ia_dereference(&reply->old_ia, MDL); } - /* Put new ia_na into the hash. */ - ia_id = &reply->ia_na->iaid_duid; - ia_na_hash_add(ia_na_active, (unsigned char *)ia_id->data, - ia_id->len, reply->ia_na, MDL); + /* Put new ia into the hash. */ + ia_id = &reply->ia->iaid_duid; + ia_hash_add(ia_na_active, (unsigned char *)ia_id->data, + ia_id->len, reply->ia, MDL); - write_ia(reply->ia_na); + write_ia(reply->ia); } cleanup: @@ -1837,10 +1843,10 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { data_string_forget(&ia_data, MDL); if (data.data != NULL) data_string_forget(&data, MDL); - if (reply->ia_na != NULL) - ia_na_dereference(&reply->ia_na, MDL); + if (reply->ia != NULL) + ia_dereference(&reply->ia, MDL); if (reply->old_ia != NULL) - ia_na_dereference(&reply->old_ia, MDL); + ia_dereference(&reply->old_ia, MDL); if (reply->lease != NULL) iaaddr_dereference(&reply->lease, MDL); if (reply->fixed.data != NULL) @@ -1855,7 +1861,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { } /* - * Process an IAADDR within a given IA_NA, storing any IAADDR reply contents + * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED * in the event we are replying with a status code and do not wish to process * more IAADDRs within this IA. @@ -1934,9 +1940,15 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) { /* Address not found on shared network. */ if (subnet == NULL) { /* Ignore this address on 'soft' bindings. */ - if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) + if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) { + /* disable rapid commit */ + reply->buf.reply.msg_type = DHCPV6_ADVERTISE; + delete_option(&dhcpv6_universe, + reply->opt_state, + D6O_RAPID_COMMIT); /* status remains success */ goto cleanup; + } /* * RFC3315 section 18.2.1: @@ -2120,7 +2132,7 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) { goto cleanup; } - status = reply_process_is_addressed(reply, reply->ia_na, scope, group); + status = reply_process_is_addressed(reply, scope, group); if (status != ISC_R_SUCCESS) goto cleanup; @@ -2208,7 +2220,7 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { /* Fetch the IA_TA contents. */ if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet, ia, IA_TA_OFFSET)) { - log_error("reply_process_ia_ta: error evaluating ia_ta"); + log_error("reply_process_ia_ta: error evaluating ia"); status = ISC_R_FAILURE; goto cleanup; } @@ -2217,18 +2229,18 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { iaid = getULong(ia_data.data); /* Create an IA_TA structure. */ - if (ia_na_allocate(&reply->ia_ta, iaid, (char *)reply->client_id.data, - reply->client_id.len, MDL) != ISC_R_SUCCESS) { - log_error("reply_process_ia_ta: no memory for ia_ta."); + if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data, + reply->client_id.len, MDL) != ISC_R_SUCCESS) { + log_error("reply_process_ia_ta: no memory for ia."); status = ISC_R_NOMEMORY; goto cleanup; } - reply->ia_ta->ia_type = D6O_IA_TA; + reply->ia->ia_type = D6O_IA_TA; /* Cache pre-existing IA, if any. */ - ia_na_hash_lookup(&reply->old_ia, ia_ta_active, - (unsigned char *)reply->ia_ta->iaid_duid.data, - reply->ia_ta->iaid_duid.len, MDL); + ia_hash_lookup(&reply->old_ia, ia_ta_active, + (unsigned char *)reply->ia->iaid_duid.data, + reply->ia->iaid_duid.len, MDL); /* * Create an option cache to carry the IA_TA option contents, and @@ -2383,17 +2395,17 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { */ if ((status != ISC_R_CANCELED) && (reply->buf.reply.msg_type == DHCPV6_REPLY) && - (reply->ia_ta->num_iaaddr != 0)) { + (reply->ia->num_iaaddr != 0)) { struct iaaddr *tmp; struct data_string *ia_id; int i; - for (i = 0 ; i < reply->ia_ta->num_iaaddr ; i++) { - tmp = reply->ia_ta->iaaddr[i]; + for (i = 0 ; i < reply->ia->num_iaaddr ; i++) { + tmp = reply->ia->iaaddr[i]; - if (tmp->ia_na != NULL) - ia_na_dereference(&tmp->ia_na, MDL); - ia_na_reference(&tmp->ia_na, reply->ia_ta, MDL); + if (tmp->ia != NULL) + ia_dereference(&tmp->ia, MDL); + ia_reference(&tmp->ia, reply->ia, MDL); /* Commit 'hard' bindings. */ tmp->hard_lifetime_end_time = @@ -2419,21 +2431,21 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { } } - /* Remove any old ia_ta from the hash. */ + /* Remove any old ia from the hash. */ if (reply->old_ia != NULL) { ia_id = &reply->old_ia->iaid_duid; - ia_na_hash_delete(ia_ta_active, - (unsigned char *)ia_id->data, - ia_id->len, MDL); - ia_na_dereference(&reply->old_ia, MDL); + ia_hash_delete(ia_ta_active, + (unsigned char *)ia_id->data, + ia_id->len, MDL); + ia_dereference(&reply->old_ia, MDL); } - /* Put new ia_ta into the hash. */ - ia_id = &reply->ia_ta->iaid_duid; - ia_na_hash_add(ia_ta_active, (unsigned char *)ia_id->data, - ia_id->len, reply->ia_ta, MDL); + /* Put new ia into the hash. */ + ia_id = &reply->ia->iaid_duid; + ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data, + ia_id->len, reply->ia, MDL); - write_ia(reply->ia_ta); + write_ia(reply->ia); } cleanup: @@ -2447,10 +2459,10 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { data_string_forget(&ia_data, MDL); if (data.data != NULL) data_string_forget(&data, MDL); - if (reply->ia_ta != NULL) - ia_na_dereference(&reply->ia_ta, MDL); + if (reply->ia != NULL) + ia_dereference(&reply->ia, MDL); if (reply->old_ia != NULL) - ia_na_dereference(&reply->old_ia, MDL); + ia_dereference(&reply->old_ia, MDL); if (reply->lease != NULL) iaaddr_dereference(&reply->lease, MDL); @@ -2490,7 +2502,7 @@ find_client_temporaries(struct reply_state *reply) { if (p == NULL) { break; } - if ((p->bits & POOL_IS_FOR_TEMP) == 0) { + if (p->pool_type != D6O_IA_TA) { continue; } @@ -2505,7 +2517,6 @@ find_client_temporaries(struct reply_state *reply) { } status = reply_process_is_addressed(reply, - reply->ia_ta, &reply->lease->scope, reply->shared->group); if (status != ISC_R_SUCCESS) { @@ -2535,7 +2546,7 @@ find_client_temporaries(struct reply_state *reply) { */ static isc_result_t reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { - isc_result_t status = ISC_R_FAILURE; + isc_result_t status = ISC_R_NORESOURCES; struct ipv6_pool *pool; int i; struct data_string data_addr; @@ -2550,6 +2561,8 @@ reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { data_addr.data = addr->iabuf; for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) { + if (pool->pool_type != D6O_IA_NA) + continue; status = try_client_v6_address(&reply->lease, pool, &data_addr); if (status == ISC_R_SUCCESS) @@ -2617,7 +2630,7 @@ find_client_address(struct reply_state *reply) { log_error("Reclaiming abandoned addresses is not yet " "supported. Treating this as an out of space " "condition."); - /* lease_reference(&reply->lease, best_lease, MDL); */ + /* iaaddr_reference(&reply->lease, best_lease, MDL); */ } /* Give up now if we didn't find a lease. */ @@ -2634,7 +2647,7 @@ find_client_address(struct reply_state *reply) { memcpy(send_addr.iabuf, &reply->lease->addr, 16); send_addr: - status = reply_process_is_addressed(reply, reply->ia_na, scope, group); + status = reply_process_is_addressed(reply, scope, group); if (status != ISC_R_SUCCESS) return status; @@ -2647,7 +2660,7 @@ find_client_address(struct reply_state *reply) { * into the option state. */ static isc_result_t -reply_process_is_addressed(struct reply_state *reply, struct ia_na *ia, +reply_process_is_addressed(struct reply_state *reply, struct binding_scope **scope, struct group *group) { isc_result_t status = ISC_R_SUCCESS; @@ -2744,7 +2757,7 @@ reply_process_is_addressed(struct reply_state *reply, struct ia_na *ia, /* Wait before renew! */ } - status = ia_na_add_iaaddr(ia, reply->lease, MDL); + status = ia_add_iaaddr(reply->ia, reply->lease, MDL); if (status != ISC_R_SUCCESS) { log_fatal("reply_process_is_addressed: Unable to " "attach lease to new IA: %s", @@ -2754,8 +2767,8 @@ reply_process_is_addressed(struct reply_state *reply, struct ia_na *ia, /* * If this is a new lease, make sure it is attached somewhere. */ - if (reply->lease->ia_na == NULL) { - ia_na_reference(&reply->lease->ia_na, ia, MDL); + if (reply->lease->ia == NULL) { + ia_reference(&reply->lease->ia, reply->ia, MDL); } } @@ -2805,7 +2818,7 @@ reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) { goto cleanup; } - reply->ia_resources_included = ISC_TRUE; + reply->resources_included = ISC_TRUE; cleanup: if (data.data != NULL) @@ -2899,20 +2912,20 @@ lease_compare(struct iaaddr *alpha, struct iaaddr *beta) { * the reply packet being built in the reply_state structure. */ static isc_result_t -reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { +reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) { isc_result_t status = ISC_R_SUCCESS; u_int32_t iaid; unsigned ia_cursor; struct option_state *packet_ia; struct option_cache *oc; - struct data_string ia_pd_data, data; + struct data_string ia_data, data; /* Initialize values that will get cleaned up on return. */ packet_ia = NULL; - memset(&ia_pd_data, 0, sizeof(ia_pd_data)); + memset(&ia_data, 0, sizeof(ia_data)); memset(&data, 0, sizeof(data)); /* - * Note that find_client_prefix() may set reply->prefix. + * Note that find_client_prefix() may set reply->lease. */ /* Make sure there is at least room for the header. */ @@ -2923,30 +2936,31 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { /* Fetch the IA_PD contents. */ - if (!get_encapsulated_IA_state(&packet_ia, &ia_pd_data, reply->packet, - ia_pd, IA_PD_OFFSET)) { - log_error("reply_process_ia_pd: error evaluating ia_pd"); + if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet, + ia, IA_PD_OFFSET)) { + log_error("reply_process_ia_pd: error evaluating ia"); status = ISC_R_FAILURE; goto cleanup; } /* Extract IA_PD header contents. */ - iaid = getULong(ia_pd_data.data); - reply->renew = getULong(ia_pd_data.data + 4); - reply->rebind = getULong(ia_pd_data.data + 8); + iaid = getULong(ia_data.data); + reply->renew = getULong(ia_data.data + 4); + reply->rebind = getULong(ia_data.data + 8); /* Create an IA_PD structure. */ - if (ia_pd_allocate(&reply->ia_pd, iaid, (char *)reply->client_id.data, - reply->client_id.len, MDL) != ISC_R_SUCCESS) { - log_error("reply_process_ia_pd: no memory for ia_pd."); + if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data, + reply->client_id.len, MDL) != ISC_R_SUCCESS) { + log_error("reply_process_ia_pd: no memory for ia."); status = ISC_R_NOMEMORY; goto cleanup; } + reply->ia->ia_type = D6O_IA_PD; /* Cache pre-existing IA_PD, if any. */ - ia_pd_hash_lookup(&reply->old_ia_pd, ia_pd_active, - (unsigned char *)reply->ia_pd->iaid_duid.data, - reply->ia_pd->iaid_duid.len, MDL); + ia_hash_lookup(&reply->old_ia, ia_pd_active, + (unsigned char *)reply->ia->iaid_duid.data, + reply->ia->iaid_duid.len, MDL); /* * Create an option cache to carry the IA_PD option contents, and @@ -3019,7 +3033,7 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { goto cleanup; } - reply->ia_pd_count++; + reply->pd_count++; /* * If we fell through the above and never gave the client @@ -3066,7 +3080,7 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { break; default: - if (reply->ia_resources_included) + if (reply->resources_included) status = ISC_R_SUCCESS; else goto cleanup; @@ -3142,41 +3156,41 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { */ if ((status != ISC_R_CANCELED) && (reply->static_prefixes == 0) && (reply->buf.reply.msg_type == DHCPV6_REPLY) && - (reply->ia_pd->num_iaprefix != 0)) { - struct iaprefix *tmp; + (reply->ia->num_iaaddr != 0)) { + struct iaaddr *tmp; struct data_string *ia_id; int i; - for (i = 0 ; i < reply->ia_pd->num_iaprefix ; i++) { - tmp = reply->ia_pd->iaprefix[i]; + for (i = 0 ; i < reply->ia->num_iaaddr ; i++) { + tmp = reply->ia->iaaddr[i]; - if (tmp->ia_pd != NULL) - ia_pd_dereference(&tmp->ia_pd, MDL); - ia_pd_reference(&tmp->ia_pd, reply->ia_pd, MDL); + if (tmp->ia != NULL) + ia_dereference(&tmp->ia, MDL); + ia_reference(&tmp->ia, reply->ia, MDL); /* Commit 'hard' bindings. */ tmp->hard_lifetime_end_time = tmp->soft_lifetime_end_time; tmp->soft_lifetime_end_time = 0; - renew_prefix6(tmp->ipv6_ppool, tmp); - schedule_prefix_timeout(tmp->ipv6_ppool); + renew_lease6(tmp->ipv6_pool, tmp); + schedule_lease_timeout(tmp->ipv6_pool); } - /* Remove any old ia_pd from the hash. */ - if (reply->old_ia_pd != NULL) { - ia_id = &reply->old_ia_pd->iaid_duid; - ia_pd_hash_delete(ia_pd_active, - (unsigned char *)ia_id->data, - ia_id->len, MDL); - ia_pd_dereference(&reply->old_ia_pd, MDL); + /* Remove any old ia from the hash. */ + if (reply->old_ia != NULL) { + ia_id = &reply->old_ia->iaid_duid; + ia_hash_delete(ia_pd_active, + (unsigned char *)ia_id->data, + ia_id->len, MDL); + ia_dereference(&reply->old_ia, MDL); } - /* Put new ia_pd into the hash. */ - ia_id = &reply->ia_pd->iaid_duid; - ia_pd_hash_add(ia_pd_active, (unsigned char *)ia_id->data, - ia_id->len, reply->ia_pd, MDL); + /* Put new ia into the hash. */ + ia_id = &reply->ia->iaid_duid; + ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data, + ia_id->len, reply->ia, MDL); - write_ia_pd(reply->ia_pd); + write_ia(reply->ia); } cleanup: @@ -3184,16 +3198,16 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia_pd) { option_state_dereference(&packet_ia, MDL); if (reply->reply_ia != NULL) option_state_dereference(&reply->reply_ia, MDL); - if (ia_pd_data.data != NULL) - data_string_forget(&ia_pd_data, MDL); + if (ia_data.data != NULL) + data_string_forget(&ia_data, MDL); if (data.data != NULL) data_string_forget(&data, MDL); - if (reply->ia_pd != NULL) - ia_pd_dereference(&reply->ia_pd, MDL); - if (reply->old_ia_pd != NULL) - ia_pd_dereference(&reply->old_ia_pd, MDL); - if (reply->prefix != NULL) - iaprefix_dereference(&reply->prefix, MDL); + if (reply->ia != NULL) + ia_dereference(&reply->ia, MDL); + if (reply->old_ia != NULL) + ia_dereference(&reply->old_ia, MDL); + if (reply->lease != NULL) + iaaddr_dereference(&reply->lease, MDL); /* * ISC_R_CANCELED is a status code used by the prefix processing to @@ -3222,7 +3236,7 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { /* Initializes values that will be cleaned up. */ memset(&iapref, 0, sizeof(iapref)); memset(&data, 0, sizeof(data)); - /* Note that reply->prefix may be set by prefix_is_owned() */ + /* Note that reply->lease may be set by prefix_is_owned() */ /* * There is no point trying to process an incoming prefix if there @@ -3298,7 +3312,7 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { (status != ISC_R_ADDRINUSE)) goto cleanup; - if (reply->prefix == NULL) { + if (reply->lease == NULL) { if (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND) { reply->send_prefer = 0; @@ -3360,10 +3374,10 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { scope = &global_scope; group = reply->host->group; } else { - if (reply->prefix == NULL) + if (reply->lease == NULL) log_fatal("Impossible condition at %s:%d.", MDL); - scope = &reply->prefix->scope; + scope = &reply->lease->scope; group = reply->shared->group; } @@ -3408,7 +3422,7 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { goto cleanup; } - status = reply_process_is_prefixed(reply, reply->ia_pd, scope, group); + status = reply_process_is_prefixed(reply, scope, group); if (status != ISC_R_SUCCESS) goto cleanup; @@ -3420,8 +3434,8 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { data_string_forget(&iapref, MDL); if (data.data != NULL) data_string_forget(&data, MDL); - if (reply->prefix != NULL) - iaprefix_dereference(&reply->prefix, MDL); + if (reply->lease != NULL) + iaaddr_dereference(&reply->lease, MDL); return status; } @@ -3450,18 +3464,18 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { return ISC_FALSE; } - if ((reply->old_ia_pd == NULL) || - (reply->old_ia_pd->num_iaprefix == 0)) + if ((reply->old_ia == NULL) || + (reply->old_ia->num_iaaddr == 0)) return ISC_FALSE; - for (i = 0 ; i < reply->old_ia_pd->num_iaprefix ; i++) { - struct iaprefix *tmp; + for (i = 0 ; i < reply->old_ia->num_iaaddr ; i++) { + struct iaaddr *tmp; - tmp = reply->old_ia_pd->iaprefix[i]; + tmp = reply->old_ia->iaaddr[i]; if ((pref->bits == (int) tmp->plen) && - memcmp(pref->lo_addr.iabuf, &tmp->pref, 16) == 0) { - iaprefix_reference(&reply->prefix, tmp, MDL); + memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0) { + iaaddr_reference(&reply->lease, tmp, MDL); return ISC_TRUE; } } @@ -3476,14 +3490,14 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { static isc_result_t reply_process_try_prefix(struct reply_state *reply, struct iaddrcidrnet *pref) { - isc_result_t status = ISC_R_FAILURE; - struct ipv6_ppool *ppool; + isc_result_t status = ISC_R_NORESOURCES; + struct ipv6_pool *pool; int i; struct data_string data_pref; if ((reply == NULL) || (reply->shared == NULL) || - (reply->shared->ipv6_ppools == NULL) || (pref == NULL) || - (reply->prefix != NULL)) + (reply->shared->ipv6_pools == NULL) || (pref == NULL) || + (reply->lease != NULL)) return ISC_R_INVALIDARG; memset(&data_pref, 0, sizeof(data_pref)); @@ -3496,11 +3510,10 @@ reply_process_try_prefix(struct reply_state *reply, data_pref.buffer->data[0] = (u_int8_t) pref->bits; memcpy(data_pref.buffer->data + 1, pref->lo_addr.iabuf, 16); - for (i = 0 ;; i++) { - ppool = reply->shared->ipv6_ppools[i]; - if (ppool == NULL) - break; - status = try_client_v6_prefix(&reply->prefix, ppool, + for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) { + if (pool->pool_type != D6O_IA_PD) + continue; + status = try_client_v6_prefix(&reply->lease, pool, &data_pref); if (status == ISC_R_SUCCESS) break; @@ -3519,7 +3532,7 @@ static isc_result_t find_client_prefix(struct reply_state *reply) { struct iaddrcidrnet send_pref; isc_result_t status = ISC_R_NORESOURCES; - struct iaprefix *prefix, *best_prefix = NULL; + struct iaaddr *prefix, *best_prefix = NULL; struct binding_scope **scope; struct group *group; int i; @@ -3553,9 +3566,9 @@ find_client_prefix(struct reply_state *reply) { goto send_pref; } - if (reply->old_ia_pd != NULL) { - for (i = 0 ; i < reply->old_ia_pd->num_iaprefix ; i++) { - prefix = reply->old_ia_pd->iaprefix[i]; + if (reply->old_ia != NULL) { + for (i = 0 ; i < reply->old_ia->num_iaaddr ; i++) { + prefix = reply->old_ia->iaaddr[i]; best_prefix = prefix_compare(reply, prefix, best_prefix); @@ -3566,10 +3579,10 @@ find_client_prefix(struct reply_state *reply) { * abandoned prefix. */ if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) { - status = pick_v6_prefix(&reply->prefix, reply->preflen, + status = pick_v6_prefix(&reply->lease, reply->preflen, reply->shared, &reply->client_id); } else if (best_prefix != NULL) { - iaprefix_reference(&reply->prefix, best_prefix, MDL); + iaaddr_reference(&reply->lease, best_prefix, MDL); status = ISC_R_SUCCESS; } @@ -3579,25 +3592,25 @@ find_client_prefix(struct reply_state *reply) { log_error("Reclaiming abandoned prefixes is not yet " "supported. Treating this as an out of space " "condition."); - /* prefix_reference(&reply->prefix, best_prefix, MDL); */ + /* iaaddr_reference(&reply->lease, best_prefix, MDL); */ } /* Give up now if we didn't find a prefix. */ if (status != ISC_R_SUCCESS) return status; - if (reply->prefix == NULL) + if (reply->lease == NULL) log_fatal("Impossible condition at %s:%d.", MDL); - scope = &reply->prefix->scope; + scope = &reply->lease->scope; group = reply->shared->group; send_pref.lo_addr.len = 16; - memcpy(send_pref.lo_addr.iabuf, &reply->prefix->pref, 16); - send_pref.bits = (int) reply->prefix->plen; + 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, reply->ia_pd, scope, group); + status = reply_process_is_prefixed(reply, scope, group); if (status != ISC_R_SUCCESS) return status; @@ -3610,7 +3623,7 @@ find_client_prefix(struct reply_state *reply) { * into the option state. */ static isc_result_t -reply_process_is_prefixed(struct reply_state *reply, struct ia_pd *ia_pd, +reply_process_is_prefixed(struct reply_state *reply, struct binding_scope **scope, struct group *group) { isc_result_t status = ISC_R_SUCCESS; @@ -3684,15 +3697,15 @@ reply_process_is_prefixed(struct reply_state *reply, struct ia_pd *ia_pd, reply->valid = reply->send_valid; /* Perform dynamic prefix related update work. */ - if (reply->prefix != NULL) { + if (reply->lease != NULL) { /* Advance (or rewind) the valid lifetime. */ if (reply->buf.reply.msg_type == DHCPV6_REPLY) { - reply->prefix->soft_lifetime_end_time = + reply->lease->soft_lifetime_end_time = cur_time + reply->send_valid; /* Wait before renew! */ } - status = ia_pd_add_iaprefix(ia_pd, reply->prefix, MDL); + status = ia_add_iaaddr(reply->ia, reply->lease, MDL); if (status != ISC_R_SUCCESS) { log_fatal("reply_process_is_prefixed: Unable to " "attach prefix to new IA_PD: %s", @@ -3702,8 +3715,8 @@ reply_process_is_prefixed(struct reply_state *reply, struct ia_pd *ia_pd, /* * If this is a new prefix, make sure it is attached somewhere. */ - if (reply->prefix->ia_pd == NULL) { - ia_pd_reference(&reply->prefix->ia_pd, ia_pd, MDL); + if (reply->lease->ia == NULL) { + ia_reference(&reply->lease->ia, reply->ia, MDL); } } @@ -3755,7 +3768,7 @@ reply_process_send_prefix(struct reply_state *reply, goto cleanup; } - reply->ia_resources_included = ISC_TRUE; + reply->resources_included = ISC_TRUE; cleanup: if (data.data != NULL) @@ -3765,9 +3778,9 @@ reply_process_send_prefix(struct reply_state *reply, } /* Choose the better of two prefixes. */ -static struct iaprefix * +static struct iaaddr * prefix_compare(struct reply_state *reply, - struct iaprefix *alpha, struct iaprefix *beta) { + struct iaaddr *alpha, struct iaaddr *beta) { if (alpha == NULL) return beta; if (beta == NULL) @@ -4263,7 +4276,7 @@ ia_na_match_decline(const struct data_string *client_id, tmp_addr, sizeof(tmp_addr))); if (lease != NULL) { decline_lease6(lease->ipv6_pool, lease); - write_ia(lease->ia_na); + write_ia(lease->ia); } } @@ -4366,7 +4379,7 @@ iterate_over_ia_na(struct data_string *reply_ret, int reply_ofs = (int)((char *)reply->options - (char *)reply); char status_msg[32]; struct iaaddr *lease; - struct ia_na *existing_ia_na; + struct ia_xx *existing_ia_na; int i; struct data_string key; u_int32_t iaid; @@ -4548,9 +4561,9 @@ iterate_over_ia_na(struct data_string *reply_ret, } existing_ia_na = NULL; - if (ia_na_hash_lookup(&existing_ia_na, ia_na_active, - (unsigned char *)key.data, - key.len, MDL)) { + if (ia_hash_lookup(&existing_ia_na, ia_na_active, + (unsigned char *)key.data, + key.len, MDL)) { /* * Make sure this address is in the IA_NA. */ @@ -4679,7 +4692,7 @@ ia_na_match_release(const struct data_string *client_id, inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr))); if (lease != NULL) { release_lease6(lease->ipv6_pool, lease); - write_ia(lease->ia_na); + write_ia(lease->ia); } } @@ -4760,7 +4773,7 @@ exit: static void ia_pd_match_release(const struct data_string *client_id, const struct data_string *iapref, - struct iaprefix *prefix) + struct iaaddr *prefix) { char tmp_addr[INET6_ADDRSTRLEN]; @@ -4770,8 +4783,8 @@ ia_pd_match_release(const struct data_string *client_id, tmp_addr, sizeof(tmp_addr)), (unsigned) getUChar(iapref->data + 8)); if (prefix != NULL) { - release_prefix6(prefix->ipv6_ppool, prefix); - write_ia_pd(prefix->ia_pd); + release_lease6(prefix->ipv6_pool, prefix); + write_ia(prefix->ia); } } @@ -4875,8 +4888,8 @@ iterate_over_ia_pd(struct data_string *reply_ret, int iaprefix_is_found; char reply_data[65536]; int reply_ofs; - struct iaprefix *prefix; - struct ia_pd *existing_ia_pd; + struct iaaddr *prefix; + struct ia_xx *existing_ia_pd; int i; struct data_string key; u_int32_t iaid; @@ -5013,26 +5026,26 @@ iterate_over_ia_pd(struct data_string *reply_ret, } existing_ia_pd = NULL; - if (ia_pd_hash_lookup(&existing_ia_pd, ia_pd_active, - (unsigned char *)key.data, - key.len, MDL)) { + if (ia_hash_lookup(&existing_ia_pd, ia_pd_active, + (unsigned char *)key.data, + key.len, MDL)) { /* * Make sure this prefix is in the IA_PD. */ for (i = 0; - i < existing_ia_pd->num_iaprefix; + i < existing_ia_pd->num_iaaddr; i++) { - struct iaprefix *tmp; + struct iaaddr *tmp; u_int8_t plen; plen = getUChar(iaprefix.data + 8); - tmp = existing_ia_pd->iaprefix[i]; + tmp = existing_ia_pd->iaaddr[i]; if ((tmp->plen == plen) && - (memcmp(&tmp->pref, + (memcmp(&tmp->addr, iaprefix.data + 9, 16) == 0)) { - iaprefix_reference(&prefix, - tmp, MDL); + iaaddr_reference(&prefix, + tmp, MDL); break; } } @@ -5051,7 +5064,7 @@ iterate_over_ia_pd(struct data_string *reply_ret, } if (prefix != NULL) { - iaprefix_dereference(&prefix, MDL); + iaaddr_dereference(&prefix, MDL); } data_string_forget(&iaprefix, MDL); @@ -5080,7 +5093,7 @@ iterate_over_ia_pd(struct data_string *reply_ret, exit: if (prefix != NULL) { - iaprefix_dereference(&prefix, MDL); + iaaddr_dereference(&prefix, MDL); } if (host_opt_state != NULL) { option_state_dereference(&host_opt_state, MDL); @@ -5100,7 +5113,7 @@ exit: } /* - * Release means a client is done with the addresses. + * Release means a client is done with the leases. */ /* TODO: reject unicast messages, unless we set unicast option */ diff --git a/server/mdb6.c b/server/mdb6.c index 0c0a18990..021fdc37f 100644 --- a/server/mdb6.c +++ b/server/mdb6.c @@ -29,31 +29,21 @@ #include "omapip/hash.h" #include "dst/md5.h" -HASH_FUNCTIONS(ia_na, unsigned char *, struct ia_na, ia_na_hash_t, - ia_na_reference, ia_na_dereference, do_string_hash); +HASH_FUNCTIONS(ia, unsigned char *, struct ia_xx, ia_hash_t, + ia_reference, ia_dereference, do_string_hash); -ia_na_hash_t *ia_na_active; -ia_na_hash_t *ia_ta_active; - -HASH_FUNCTIONS(ia_pd, unsigned char *, struct ia_pd, ia_pd_hash_t, - ia_pd_reference, ia_pd_dereference, do_string_hash); - -ia_pd_hash_t *ia_pd_active; +ia_hash_t *ia_na_active; +ia_hash_t *ia_ta_active; +ia_hash_t *ia_pd_active; HASH_FUNCTIONS(iaaddr, struct in6_addr *, struct iaaddr, iaaddr_hash_t, iaaddr_reference, iaaddr_dereference, do_string_hash); -HASH_FUNCTIONS(iaprefix, struct in6_addr *, struct iaprefix, iaprefix_hash_t, - iaprefix_reference, iaprefix_dereference, do_string_hash); - struct ipv6_pool **pools; int num_pools; -struct ipv6_ppool **ppools; -int num_ppools; - /* - * Create a new IAADDR structure. + * Create a new IAADDR/PREFIX structure. * * - iaaddr must be a pointer to a (struct iaaddr *) pointer previously * initialized to NULL @@ -79,13 +69,14 @@ iaaddr_allocate(struct iaaddr **iaaddr, const char *file, int line) { tmp->refcnt = 1; tmp->state = FTS_FREE; tmp->heap_index = -1; + tmp->plen = 255; *iaaddr = tmp; return ISC_R_SUCCESS; } /* - * Reference an IAADDR structure. + * Reference an IAADDR/PREFIX structure. * * - iaaddr must be a pointer to a (struct iaaddr *) pointer previously * initialized to NULL @@ -112,7 +103,7 @@ iaaddr_reference(struct iaaddr **iaaddr, struct iaaddr *src, /* - * Dereference an IAADDR structure. + * Dereference an IAADDR/PREFIX structure. * * If it is the last reference, then the memory for the * structure is freed. @@ -135,8 +126,8 @@ iaaddr_dereference(struct iaaddr **iaaddr, const char *file, int line) { tmp->refcnt = 0; } if (tmp->refcnt == 0) { - if (tmp->ia_na != NULL) { - ia_na_dereference(&(tmp->ia_na), file, line); + if (tmp->ia != NULL) { + ia_dereference(&(tmp->ia), file, line); } if (tmp->ipv6_pool != NULL) { ipv6_pool_dereference(&(tmp->ipv6_pool), file, line); @@ -150,104 +141,6 @@ iaaddr_dereference(struct iaaddr **iaaddr, const char *file, int line) { return ISC_R_SUCCESS; } -/* - * Create a new IAPREFIX structure. - * - * - iapref must be a pointer to a (struct iaprefix *) pointer previously - * initialized to NULL - */ -isc_result_t -iaprefix_allocate(struct iaprefix **iapref, const char *file, int line) { - struct iaprefix *tmp; - - if (iapref == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*iapref != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = dmalloc(sizeof(*tmp), file, line); - if (tmp == NULL) { - return ISC_R_NOMEMORY; - } - - tmp->refcnt = 1; - tmp->state = FTS_FREE; - tmp->heap_index = -1; - - *iapref = tmp; - return ISC_R_SUCCESS; -} - -/* - * Reference an IAPREFIX structure. - * - * - iapref must be a pointer to a (struct iaprefix *) pointer previously - * initialized to NULL - */ -isc_result_t -iaprefix_reference(struct iaprefix **iapref, struct iaprefix *src, - const char *file, int line) { - if (iapref == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*iapref != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - if (src == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - *iapref = src; - src->refcnt++; - return ISC_R_SUCCESS; -} - - -/* - * Dereference an IAPREFIX structure. - * - * If it is the last reference, then the memory for the - * structure is freed. - */ -isc_result_t -iaprefix_dereference(struct iaprefix **iapref, const char *file, int line) { - struct iaprefix *tmp; - - if ((iapref == NULL) || (*iapref == NULL)) { - log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = *iapref; - *iapref = NULL; - - tmp->refcnt--; - if (tmp->refcnt < 0) { - log_error("%s(%d): negative refcnt", file, line); - tmp->refcnt = 0; - } - if (tmp->refcnt == 0) { - if (tmp->ia_pd != NULL) { - ia_pd_dereference(&(tmp->ia_pd), file, line); - } - if (tmp->ipv6_ppool != NULL) { - ipv6_ppool_dereference(&(tmp->ipv6_ppool), file, line); - } - if (tmp->scope != NULL) { - binding_scope_dereference(&tmp->scope, file, line); - } - dfree(tmp, file, line); - } - - return ISC_R_SUCCESS; -} - /* * Make the key that we use for IA. */ @@ -271,7 +164,7 @@ ia_make_key(struct data_string *key, u_int32_t iaid, /* * Create a new IA structure. * - * - ia must be a pointer to a (struct ia_na *) pointer previously + * - ia must be a pointer to a (struct ia_xx *) pointer previously * initialized to NULL * - iaid and duid are values from the client * @@ -280,10 +173,10 @@ ia_make_key(struct data_string *key, u_int32_t iaid, * between machines of different byte order */ isc_result_t -ia_na_allocate(struct ia_na **ia, u_int32_t iaid, - const char *duid, unsigned int duid_len, - const char *file, int line) { - struct ia_na *tmp; +ia_allocate(struct ia_xx **ia, u_int32_t iaid, + const char *duid, unsigned int duid_len, + const char *file, int line) { + struct ia_xx *tmp; if (ia == NULL) { log_error("%s(%d): NULL pointer reference", file, line); @@ -314,12 +207,12 @@ ia_na_allocate(struct ia_na **ia, u_int32_t iaid, /* * Reference an IA structure. * - * - ia must be a pointer to a (struct ia_na *) pointer previously + * - ia must be a pointer to a (struct ia_xx *) pointer previously * initialized to NULL */ isc_result_t -ia_na_reference(struct ia_na **ia, struct ia_na *src, - const char *file, int line) { +ia_reference(struct ia_xx **ia, struct ia_xx *src, + const char *file, int line) { if (ia == NULL) { log_error("%s(%d): NULL pointer reference", file, line); return ISC_R_INVALIDARG; @@ -344,8 +237,8 @@ ia_na_reference(struct ia_na **ia, struct ia_na *src, * structure is freed. */ isc_result_t -ia_na_dereference(struct ia_na **ia, const char *file, int line) { - struct ia_na *tmp; +ia_dereference(struct ia_xx **ia, const char *file, int line) { + struct ia_xx *tmp; int i; if ((ia == NULL) || (*ia == NULL)) { @@ -377,11 +270,11 @@ ia_na_dereference(struct ia_na **ia, const char *file, int line) { /* - * Add an IAADDR entry to an IA structure. + * Add an IAADDR/PREFIX entry to an IA structure. */ isc_result_t -ia_na_add_iaaddr(struct ia_na *ia, struct iaaddr *iaaddr, - const char *file, int line) { +ia_add_iaaddr(struct ia_xx *ia, struct iaaddr *iaaddr, + const char *file, int line) { int max; struct iaaddr **new; @@ -389,8 +282,8 @@ ia_na_add_iaaddr(struct ia_na *ia, struct iaaddr *iaaddr, * Grow our array if we need to. * * Note: we pick 4 as the increment, as that seems a reasonable - * guess as to how many addresses we might expect on an - * interface. + * guess as to how many addresses/prefixes we might expect + * on an interface. */ if (ia->max_iaaddr <= ia->num_iaaddr) { max = ia->max_iaaddr + 4; @@ -412,13 +305,13 @@ ia_na_add_iaaddr(struct ia_na *ia, struct iaaddr *iaaddr, } /* - * Remove an IAADDR entry to an IA structure. + * Remove an IAADDR/PREFIX entry to an IA structure. * * Note: if an IAADDR appears more than once, then only ONE will be removed. */ void -ia_na_remove_iaaddr(struct ia_na *ia, struct iaaddr *iaaddr, - const char *file, int line) { +ia_remove_iaaddr(struct ia_xx *ia, struct iaaddr *iaaddr, + const char *file, int line) { int i, j; for (i=0; inum_iaaddr; i++) { @@ -431,23 +324,23 @@ ia_na_remove_iaaddr(struct ia_na *ia, struct iaaddr *iaaddr, } /* decrease our total count */ /* remove the back-reference in the IAADDR itself */ - ia_na_dereference(&iaaddr->ia_na, file, line); + ia_dereference(&iaaddr->ia, file, line); ia->num_iaaddr--; return; } } - log_error("%s(%d): IAADDR not in IA", file, line); + log_error("%s(%d): IAADDR/PREFIX not in IA", file, line); } /* - * Remove all addresses from an IA. + * Remove all addresses/prefixes from an IA. */ void -ia_na_remove_all_iaaddr(struct ia_na *ia, const char *file, int line) { +ia_remove_all_iaaddr(struct ia_xx *ia, const char *file, int line) { int i; for (i=0; inum_iaaddr; i++) { - ia_na_dereference(&(ia->iaaddr[i]->ia_na), file, line); + ia_dereference(&(ia->iaaddr[i]->ia), file, line); iaaddr_dereference(&(ia->iaaddr[i]), file, line); } ia->num_iaaddr = 0; @@ -457,7 +350,7 @@ ia_na_remove_all_iaaddr(struct ia_na *ia, const char *file, int line) { * Compare two IA. */ isc_boolean_t -ia_na_equal(const struct ia_na *a, const struct ia_na *b) +ia_equal(const struct ia_xx *a, const struct ia_xx *b) { isc_boolean_t found; int i, j; @@ -492,18 +385,20 @@ ia_na_equal(const struct ia_na *a, const struct ia_na *b) } /* - * Make sure we have the same number of addresses in each. + * Make sure we have the same number of addresses/prefixes in each. */ if (a->num_iaaddr != b->num_iaaddr) { return ISC_FALSE; } /* - * Check that each address is present in both. + * Check that each address/prefix is present in both. */ for (i=0; inum_iaaddr; i++) { found = ISC_FALSE; for (j=0; jnum_iaaddr; j++) { + if (a->iaaddr[i]->plen != b->iaaddr[i]->plen) + continue; if (memcmp(&(a->iaaddr[i]->addr), &(b->iaaddr[j]->addr), sizeof(struct in6_addr)) == 0) { @@ -522,260 +417,9 @@ ia_na_equal(const struct ia_na *a, const struct ia_na *b) return ISC_TRUE; } -/* - * Create a new IA_PD structure. - * - * - ia_pd must be a pointer to a (struct ia_pd *) pointer previously - * initialized to NULL - * - iaid and duid are values from the client - * - * XXXsk: we don't concern ourself with the byte order of the IAID, - * which might be a problem if we transfer this structure - * between machines of different byte order - */ -isc_result_t -ia_pd_allocate(struct ia_pd **ia_pd, u_int32_t iaid, - const char *duid, unsigned int duid_len, - const char *file, int line) { - struct ia_pd *tmp; - - if (ia_pd == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*ia_pd != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = dmalloc(sizeof(*tmp), file, line); - if (tmp == NULL) { - return ISC_R_NOMEMORY; - } - - if (ia_make_key(&tmp->iaid_duid, iaid, - duid, duid_len, file, line) != ISC_R_SUCCESS) { - dfree(tmp, file, line); - return ISC_R_NOMEMORY; - } - - tmp->refcnt = 1; - - *ia_pd = tmp; - return ISC_R_SUCCESS; -} - -/* - * Reference an IA_PD structure. - * - * - ia_pd must be a pointer to a (struct ia_pd *) pointer previously - * initialized to NULL - */ -isc_result_t -ia_pd_reference(struct ia_pd **ia_pd, struct ia_pd *src, - const char *file, int line) { - if (ia_pd == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*ia_pd != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - if (src == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - *ia_pd = src; - src->refcnt++; - return ISC_R_SUCCESS; -} - -/* - * Dereference an IA_PD structure. - * - * If it is the last reference, then the memory for the - * structure is freed. - */ -isc_result_t -ia_pd_dereference(struct ia_pd **ia_pd, const char *file, int line) { - struct ia_pd *tmp; - int i; - - if ((ia_pd == NULL) || (*ia_pd == NULL)) { - log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = *ia_pd; - *ia_pd = NULL; - - tmp->refcnt--; - if (tmp->refcnt < 0) { - log_error("%s(%d): negative refcnt", file, line); - tmp->refcnt = 0; - } - if (tmp->refcnt == 0) { - if (tmp->iaprefix != NULL) { - for (i=0; inum_iaprefix; i++) { - iaprefix_dereference(&(tmp->iaprefix[i]), - file, line); - } - dfree(tmp->iaprefix, file, line); - } - data_string_forget(&(tmp->iaid_duid), file, line); - dfree(tmp, file, line); - } - return ISC_R_SUCCESS; -} - - -/* - * Add an IAPREFIX entry to an IA_PD structure. - */ -isc_result_t -ia_pd_add_iaprefix(struct ia_pd *ia_pd, struct iaprefix *iapref, - const char *file, int line) { - int max; - struct iaprefix **new; - - /* - * Grow our array if we need to. - * - * Note: we pick 4 as the increment, as that seems a reasonable - * guess as to how many prefixes we might expect on an - * interface. - */ - if (ia_pd->max_iaprefix <= ia_pd->num_iaprefix) { - max = ia_pd->max_iaprefix + 4; - new = dmalloc(max * sizeof(struct iaprefix *), file, line); - if (new == NULL) { - return ISC_R_NOMEMORY; - } - memcpy(new, ia_pd->iaprefix, - ia_pd->num_iaprefix * sizeof(struct iaprefix *)); - ia_pd->iaprefix = new; - ia_pd->max_iaprefix = max; - } - - iaprefix_reference(&(ia_pd->iaprefix[ia_pd->num_iaprefix]), iapref, - file, line); - ia_pd->num_iaprefix++; - - return ISC_R_SUCCESS; -} - -/* - * Remove an IAPREFIX entry to an IA_PD structure. - * - * Note: if an IAPREFIX appears more than once, then only ONE will be removed. - */ -void -ia_pd_remove_iaprefix(struct ia_pd *ia_pd, struct iaprefix *iapref, - const char *file, int line) { - int i, j; - - for (i=0; inum_iaprefix; i++) { - if (ia_pd->iaprefix[i] == iapref) { - /* remove this IAPREFIX */ - iaprefix_dereference(&(ia_pd->iaprefix[i]), - file, line); - /* move remaining IAPREFIX pointers down one */ - for (j=i+1; j < ia_pd->num_iaprefix; j++) { - ia_pd->iaprefix[j-1] = ia_pd->iaprefix[j]; - } - /* decrease our total count */ - /* remove the back-reference in the IAPREFIX itself */ - ia_pd_dereference(&iapref->ia_pd, file, line); - ia_pd->num_iaprefix--; - return; - } - } - log_error("%s(%d): IAPREFIX not in IA_PD", file, line); -} - -/* - * Remove all prefixes from an IA_PD. - */ -void -ia_pd_remove_all_iaprefix(struct ia_pd *ia_pd, const char *file, int line) { - int i; - - for (i=0; inum_iaprefix; i++) { - ia_pd_dereference(&(ia_pd->iaprefix[i]->ia_pd), file, line); - iaprefix_dereference(&(ia_pd->iaprefix[i]), file, line); - } - ia_pd->num_iaprefix = 0; -} - -/* - * Compare two IA_PD. - */ -isc_boolean_t -ia_pd_equal(const struct ia_pd *a, const struct ia_pd *b) -{ - isc_boolean_t found; - int i, j; - - /* - * Handle cases where one or both of the inputs is NULL. - */ - if (a == NULL) { - if (b == NULL) { - return ISC_TRUE; - } else { - return ISC_FALSE; - } - } - - /* - * Check the DUID is the same. - */ - if (a->iaid_duid.len != b->iaid_duid.len) { - return ISC_FALSE; - } - if (memcmp(a->iaid_duid.data, - b->iaid_duid.data, a->iaid_duid.len) != 0) { - return ISC_FALSE; - } - - /* - * Make sure we have the same number of prefixes in each. - */ - if (a->num_iaprefix != b->num_iaprefix) { - return ISC_FALSE; - } - - /* - * Check that each prefix is present in both. - */ - for (i=0; inum_iaprefix; i++) { - found = ISC_FALSE; - for (j=0; jnum_iaprefix; j++) { - if (a->iaprefix[i]->plen != b->iaprefix[i]->plen) - continue; - if (memcmp(&(a->iaprefix[i]->pref), - &(b->iaprefix[j]->pref), - sizeof(struct in6_addr)) == 0) { - found = ISC_TRUE; - break; - } - } - if (!found) { - return ISC_FALSE; - } - } - - /* - * These are the same in every way we care about. - */ - return ISC_TRUE; -} - /* * Helper function for lease heaps. * Makes the top of the heap the oldest lease. - * Note: this relies on the unique layout for leases! */ static isc_boolean_t lease_older(void *a, void *b) { @@ -792,34 +436,25 @@ lease_older(void *a, void *b) { } /* - * Helper function for lease address heaps. + * Helper function for lease address/prefix heaps. * Callback when an address's position in the heap changes. */ static void -lease_address_index_changed(void *iaaddr, unsigned int new_heap_index) { +lease_index_changed(void *iaaddr, unsigned int new_heap_index) { ((struct iaaddr *)iaaddr)-> heap_index = new_heap_index; } -/* - * Helper function for lease prefix heaps. - * Callback when a prefix's position in the heap changes. - */ -static void -lease_prefix_index_changed(void *iapref, unsigned int new_heap_index) { - ((struct iaprefix *)iapref)-> heap_index = new_heap_index; -} - /* - * Create a new IPv6 lease (address) pool structure. + * Create a new IPv6 lease pool structure. * * - pool must be a pointer to a (struct ipv6_pool *) pointer previously * initialized to NULL */ isc_result_t -ipv6_pool_allocate(struct ipv6_pool **pool, +ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *start_addr, int bits, - const char *file, int line) { + int units, const char *file, int line) { struct ipv6_pool *tmp; if (pool == NULL) { @@ -837,19 +472,21 @@ ipv6_pool_allocate(struct ipv6_pool **pool, } tmp->refcnt = 1; + tmp->pool_type = type; tmp->start_addr = *start_addr; tmp->bits = bits; + tmp->units = units; if (!iaaddr_new_hash(&tmp->addrs, DEFAULT_HASH_SIZE, file, line)) { dfree(tmp, file, line); return ISC_R_NOMEMORY; } - if (isc_heap_create(lease_older, lease_address_index_changed, + if (isc_heap_create(lease_older, lease_index_changed, 0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) { iaaddr_free_hash_table(&(tmp->addrs), file, line); dfree(tmp, file, line); return ISC_R_NOMEMORY; } - if (isc_heap_create(lease_older, lease_address_index_changed, + if (isc_heap_create(lease_older, lease_index_changed, 0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) { isc_heap_destroy(&(tmp->active_timeouts)); iaaddr_free_hash_table(&(tmp->addrs), file, line); @@ -888,7 +525,7 @@ ipv6_pool_reference(struct ipv6_pool **pool, struct ipv6_pool *src, } /* - * Note: Each IAADDR in a pool is referenced by the pool. This is needed + * Note: Each IAADDR/PREFIX in a pool is referenced by the pool. This is needed * to prevent the IAADDR from being garbage collected out from under the * pool. * @@ -958,156 +595,6 @@ ipv6_pool_dereference(struct ipv6_pool **pool, const char *file, int line) { return ISC_R_SUCCESS; } -/* - * Create a new IPv6 lease (prefix) pool structure. - * - * - ppool must be a pointer to a (struct ipv6_ppool *) pointer previously - * initialized to NULL - */ -isc_result_t -ipv6_ppool_allocate(struct ipv6_ppool **ppool, - const struct in6_addr *start_pref, - u_int8_t pool_plen, u_int8_t alloc_plen, - const char *file, int line) { - struct ipv6_ppool *tmp; - - if (ppool == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*ppool != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = dmalloc(sizeof(*tmp), file, line); - if (tmp == NULL) { - return ISC_R_NOMEMORY; - } - - tmp->refcnt = 1; - tmp->start_pref = *start_pref; - tmp->pool_plen = pool_plen; - tmp->alloc_plen = alloc_plen; - if (!iaprefix_new_hash(&tmp->prefs, DEFAULT_HASH_SIZE, file, line)) { - dfree(tmp, file, line); - return ISC_R_NOMEMORY; - } - if (isc_heap_create(lease_older, lease_prefix_index_changed, - 0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) { - iaprefix_free_hash_table(&(tmp->prefs), file, line); - dfree(tmp, file, line); - return ISC_R_NOMEMORY; - } - if (isc_heap_create(lease_older, lease_prefix_index_changed, - 0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) { - isc_heap_destroy(&(tmp->active_timeouts)); - iaprefix_free_hash_table(&(tmp->prefs), file, line); - dfree(tmp, file, line); - return ISC_R_NOMEMORY; - } - - *ppool = tmp; - return ISC_R_SUCCESS; -} - -/* - * Reference an IPv6 prefix pool structure. - * - * - ppool must be a pointer to a (struct ppool *) pointer previously - * initialized to NULL - */ -isc_result_t -ipv6_ppool_reference(struct ipv6_ppool **ppool, struct ipv6_ppool *src, - const char *file, int line) { - if (ppool == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - if (*ppool != NULL) { - log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - if (src == NULL) { - log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; - } - *ppool = src; - src->refcnt++; - return ISC_R_SUCCESS; -} - -/* - * Note: Each IAPREFIX in a pool is referenced by the pool. This is needed - * to prevent the IAPREFIX from being garbage collected out from under the - * pool. - * - * The references are made from the hash and from the heap. The following - * helper functions dereference these when a pool is destroyed. - */ - -/* - * Helper function for prefix pool cleanup. - * Dereference each of the hash entries in a pool. - */ -static isc_result_t -dereference_phash_entry(const void *name, unsigned len, void *value) { - struct iaprefix *iapref = (struct iaprefix *)value; - - iaprefix_dereference(&iapref, MDL); - return ISC_R_SUCCESS; -} - -/* - * Helper function for prefix pool cleanup. - * Dereference each of the heap entries in a pool. - */ -static void -dereference_pheap_entry(void *value, void *dummy) { - struct iaprefix *iapref = (struct iaprefix *)value; - - iaprefix_dereference(&iapref, MDL); -} - - -/* - * Dereference an IPv6 prefix pool structure. - * - * If it is the last reference, then the memory for the - * structure is freed. - */ -isc_result_t -ipv6_ppool_dereference(struct ipv6_ppool **ppool, const char *file, int line) { - struct ipv6_ppool *tmp; - - if ((ppool == NULL) || (*ppool == NULL)) { - log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; - } - - tmp = *ppool; - *ppool = NULL; - - tmp->refcnt--; - if (tmp->refcnt < 0) { - log_error("%s(%d): negative refcnt", file, line); - tmp->refcnt = 0; - } - if (tmp->refcnt == 0) { - iaprefix_hash_foreach(tmp->prefs, dereference_phash_entry); - iaprefix_free_hash_table(&(tmp->prefs), file, line); - isc_heap_foreach(tmp->active_timeouts, - dereference_pheap_entry, NULL); - isc_heap_destroy(&(tmp->active_timeouts)); - isc_heap_foreach(tmp->inactive_timeouts, - dereference_pheap_entry, NULL); - isc_heap_destroy(&(tmp->inactive_timeouts)); - dfree(tmp, file, line); - } - - return ISC_R_SUCCESS; -} - /* * Create an address by hashing the input, and using that for * the non-network part. @@ -1265,13 +752,25 @@ create_lease6(struct ipv6_pool *pool, struct iaaddr **addr, } /* - * Build an address or a temporary address. + * Build a resource. */ - if ((pool->bits & POOL_IS_FOR_TEMP) == 0) { + switch (pool->pool_type) { + case D6O_IA_NA: + /* address */ build_address6(&tmp, &pool->start_addr, pool->bits, &ds); - } else { + break; + case D6O_IA_TA: + /* temporary address */ build_temporary6(&tmp, &pool->start_addr, &ds); + break; + case D6O_IA_PD: + /* prefix */ + log_error("create_lease6: prefix pool."); + return ISC_R_INVALIDARG; + default: + log_error("create_lease6: untyped pool."); + return ISC_R_INVALIDARG; } /* @@ -1328,6 +827,7 @@ create_lease6(struct ipv6_pool *pool, struct iaaddr **addr, if (result != ISC_R_SUCCESS) { return result; } + iaaddr->plen = 0; memcpy(&iaaddr->addr, &tmp, sizeof(iaaddr->addr)); /* @@ -1359,7 +859,7 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr, ipv6_pool_reference(&iaaddr->ipv6_pool, pool, MDL); /* - * If this IAADDR is already in our structures, remove the + * If this IAADDR/PREFIX is already in our structures, remove the * old one. */ test_iaaddr = NULL; @@ -1399,7 +899,7 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr, } /* - * Add IAADDR to our structures. + * Add IAADDR/PREFIX to our structures. */ tmp_iaaddr = NULL; iaaddr_reference(&tmp_iaaddr, iaaddr, MDL); @@ -1475,8 +975,8 @@ move_lease_to_active(struct ipv6_pool *pool, struct iaaddr *addr) { /* * Renew an lease in the pool. * - * To do this, first set the new hard_lifetime_end_time for the address, - * and then invoke renew_lease() on the address. + * To do this, first set the new hard_lifetime_end_time for the resource, + * and then invoke renew_lease() on it. * * WARNING: lease times must only be extended, never reduced!!! */ @@ -1510,7 +1010,9 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iaaddr *addr, insert_result = isc_heap_insert(pool->inactive_timeouts, addr); if (insert_result == ISC_R_SUCCESS) { /* Process events upon expiration. */ - ddns_removals(NULL, addr); + if (pool->pool_type != D6O_IA_PD) { + ddns_removals(NULL, addr); + } /* Binding scopes are no longer valid after expiry or * release. @@ -1666,7 +1168,7 @@ build_prefix6(struct in6_addr *pref, /* * Create a lease for the given prefix and client duid. * - * - ppool must be a pointer to a (struct ppool *) pointer previously + * - pool must be a pointer to a (struct pool *) pointer previously * initialized to NULL * * Right now we simply hash the DUID, and if we get a collision, we hash @@ -1685,15 +1187,15 @@ build_prefix6(struct in6_addr *pref, * the long term. */ isc_result_t -create_prefix6(struct ipv6_ppool *ppool, struct iaprefix **pref, +create_prefix6(struct ipv6_pool *pool, struct iaaddr **pref, unsigned int *attempts, const struct data_string *uid, time_t soft_lifetime_end_time) { struct data_string ds; struct in6_addr tmp; - struct iaprefix *test_iapref; + struct iaaddr *test_iapref; struct data_string new_ds; - struct iaprefix *iapref; + struct iaaddr *iapref; isc_result_t result; /* @@ -1715,313 +1217,89 @@ create_prefix6(struct ipv6_ppool *ppool, struct iaprefix **pref, /* * Build a prefix */ - build_prefix6(&tmp, &ppool->start_pref, - (int)ppool->pool_plen, (int)ppool->alloc_plen, - &ds); + build_prefix6(&tmp, &pool->start_addr, + pool->bits, pool->units, &ds); /* * If this prefix is not in use, we're happy with it */ test_iapref = NULL; - if (iaprefix_hash_lookup(&test_iapref, ppool->prefs, - &tmp, sizeof(tmp), MDL) == 0) { + if (iaaddr_hash_lookup(&test_iapref, pool->addrs, + &tmp, sizeof(tmp), MDL) == 0) { break; } - iaprefix_dereference(&test_iapref, MDL); + iaaddr_dereference(&test_iapref, MDL); /* * Otherwise, we create a new input, adding the prefix */ memset(&new_ds, 0, sizeof(new_ds)); - new_ds.len = ds.len + sizeof(tmp); - if (!buffer_allocate(&new_ds.buffer, new_ds.len, MDL)) { - data_string_forget(&ds, MDL); - return ISC_R_NOMEMORY; - } - new_ds.data = new_ds.buffer->data; - memcpy(new_ds.buffer->data, ds.data, ds.len); - memcpy(new_ds.buffer->data + ds.len, &tmp, sizeof(tmp)); - data_string_forget(&ds, MDL); - data_string_copy(&ds, &new_ds, MDL); - data_string_forget(&new_ds, MDL); - } - - data_string_forget(&ds, MDL); - - /* - * We're happy with the prefix, create an IAPREFIX - * to hold it. - */ - iapref = NULL; - result = iaprefix_allocate(&iapref, MDL); - if (result != ISC_R_SUCCESS) { - return result; - } - iapref->plen = ppool->alloc_plen; - memcpy(&iapref->pref, &tmp, sizeof(iapref->pref)); - - /* - * Add the prefix to the pool (note state is free, not active?!). - */ - result = add_prefix6(ppool, iapref, soft_lifetime_end_time); - if (result == ISC_R_SUCCESS) { - iaprefix_reference(pref, iapref, MDL); - } - iaprefix_dereference(&iapref, MDL); - return result; -} - -/* - * Put a prefix in the pool directly. This is intended to be used when - * loading leases from the file. - */ -isc_result_t -add_prefix6(struct ipv6_ppool *ppool, struct iaprefix *iapref, - time_t valid_lifetime_end_time) { - isc_result_t insert_result; - struct iaprefix *test_iapref; - struct iaprefix *tmp_iapref; - - /* If a state was not assigned by the caller, assume active. */ - if (iapref->state == 0) - iapref->state = FTS_ACTIVE; - - ipv6_ppool_reference(&iapref->ipv6_ppool, ppool, MDL); - - /* - * If this IAPREFIX is already in our structures, remove the - * old one. - */ - test_iapref = NULL; - if (iaprefix_hash_lookup(&test_iapref, ppool->prefs, - &iapref->pref, sizeof(iapref->pref), MDL)) { - /* XXX: we should probably ask the iaprefix what heap it is on - * (as a consistency check). - * XXX: we should probably have one function to "put this - * prefix on its heap" rather than doing these if's - * everywhere. If you add more states to this list, don't. - */ - if ((test_iapref->state == FTS_ACTIVE) || - (test_iapref->state == FTS_ABANDONED)) { - isc_heap_delete(ppool->active_timeouts, - test_iapref->heap_index); - ppool->num_active--; - } else { - isc_heap_delete(ppool->inactive_timeouts, - test_iapref->heap_index); - ppool->num_inactive--; - } - - iaprefix_hash_delete(ppool->prefs, &test_iapref->pref, - sizeof(test_iapref->pref), MDL); - - /* - * We're going to do a bit of evil trickery here. - * - * We need to dereference the entry once to remove our - * current reference (in test_iapref), and then one - * more time to remove the reference left when the - * prefix was added to the pool before. - */ - tmp_iapref = test_iapref; - iaprefix_dereference(&test_iapref, MDL); - iaprefix_dereference(&tmp_iapref, MDL); - } - - /* - * Add IAPREFIX to our structures. - */ - tmp_iapref = NULL; - iaprefix_reference(&tmp_iapref, iapref, MDL); - if ((tmp_iapref->state == FTS_ACTIVE) || - (tmp_iapref->state == FTS_ABANDONED)) { - tmp_iapref->hard_lifetime_end_time = valid_lifetime_end_time; - iaprefix_hash_add(ppool->prefs, &tmp_iapref->pref, - sizeof(tmp_iapref->pref), iapref, MDL); - insert_result = isc_heap_insert(ppool->active_timeouts, - tmp_iapref); - if (insert_result == ISC_R_SUCCESS) - ppool->num_active++; - } else { - tmp_iapref->soft_lifetime_end_time = valid_lifetime_end_time; - insert_result = isc_heap_insert(ppool->inactive_timeouts, - tmp_iapref); - if (insert_result == ISC_R_SUCCESS) - ppool->num_inactive++; - } - if (insert_result != ISC_R_SUCCESS) { - iaprefix_hash_delete(ppool->prefs, &iapref->pref, - sizeof(iapref->pref), MDL); - iaprefix_dereference(&tmp_iapref, MDL); - return insert_result; - } - - /* - * Note: we intentionally leave tmp_iapref referenced; there - * is a reference in the heap/hash, after all. - */ - - return ISC_R_SUCCESS; -} - -/* - * Determine if a prefix is present in a pool or not. - */ -isc_boolean_t -prefix6_exists(const struct ipv6_ppool *ppool, - const struct in6_addr *pref, u_int8_t plen) { - struct iaprefix *test_iapref; - - if (plen != ppool->alloc_plen) - return ISC_FALSE; - - test_iapref = NULL; - if (iaprefix_hash_lookup(&test_iapref, ppool->prefs, - (void *)pref, sizeof(*pref), MDL)) { - iaprefix_dereference(&test_iapref, MDL); - return ISC_TRUE; - } else { - return ISC_FALSE; - } -} - -/* - * Put the prefix on our active pool. - */ -static isc_result_t -move_prefix_to_active(struct ipv6_ppool *ppool, struct iaprefix *pref) { - isc_result_t insert_result; - int old_heap_index; - - old_heap_index = pref->heap_index; - insert_result = isc_heap_insert(ppool->active_timeouts, pref); - if (insert_result == ISC_R_SUCCESS) { - iaprefix_hash_add(ppool->prefs, &pref->pref, - sizeof(pref->pref), pref, MDL); - isc_heap_delete(ppool->inactive_timeouts, old_heap_index); - ppool->num_active++; - ppool->num_inactive--; - pref->state = FTS_ACTIVE; - } - return insert_result; -} - -/* - * Renew a prefix in the pool. - * - * To do this, first set the new hard_lifetime_end_time for the prefix, - * and then invoke renew_prefix() on the prefix. - * - * WARNING: lease times must only be extended, never reduced!!! - */ -isc_result_t -renew_prefix6(struct ipv6_ppool *ppool, struct iaprefix *pref) { - /* - * If we're already active, then we can just move our expiration - * time down the heap. - * - * Otherwise, we have to move from the inactive heap to the - * active heap. - */ - if (pref->state == FTS_ACTIVE) { - isc_heap_decreased(ppool->active_timeouts, pref->heap_index); - return ISC_R_SUCCESS; - } else { - return move_prefix_to_active(ppool, pref); - } -} - -/* - * Put the prefix on our inactive pool, with the specified state. - */ -static isc_result_t -move_prefix_to_inactive(struct ipv6_ppool *ppool, struct iaprefix *pref, - binding_state_t state) { - isc_result_t insert_result; - int old_heap_index; - - old_heap_index = pref->heap_index; - insert_result = isc_heap_insert(ppool->inactive_timeouts, pref); - if (insert_result == ISC_R_SUCCESS) { - /* Process events upon expiration. */ - /* No DDNS for prefixes. */ - - /* Binding scopes are no longer valid after expiry or - * release. - */ - if (pref->scope != NULL) { - binding_scope_dereference(&pref->scope, MDL); + new_ds.len = ds.len + sizeof(tmp); + if (!buffer_allocate(&new_ds.buffer, new_ds.len, MDL)) { + data_string_forget(&ds, MDL); + return ISC_R_NOMEMORY; } - - iaprefix_hash_delete(ppool->prefs, - &pref->pref, sizeof(pref->pref), MDL); - isc_heap_delete(ppool->active_timeouts, old_heap_index); - pref->state = state; - ppool->num_active--; - ppool->num_inactive++; + new_ds.data = new_ds.buffer->data; + memcpy(new_ds.buffer->data, ds.data, ds.len); + memcpy(new_ds.buffer->data + ds.len, &tmp, sizeof(tmp)); + data_string_forget(&ds, MDL); + data_string_copy(&ds, &new_ds, MDL); + data_string_forget(&new_ds, MDL); } - return insert_result; -} -/* - * Expire the oldest prefix if it's lifetime_end_time is - * older than the given time. - * - * - iapref must be a pointer to a (struct iaprefix *) pointer previously - * initialized to NULL - * - * On return iapref has a reference to the removed entry. It is left - * pointing to NULL if the oldest prefix has not expired. - */ -isc_result_t -expire_prefix6(struct iaprefix **pref, struct ipv6_ppool *ppool, time_t now) { - struct iaprefix *tmp; - isc_result_t result; + data_string_forget(&ds, MDL); - if (pref == NULL) { - log_error("%s(%d): NULL pointer reference", MDL); - return ISC_R_INVALIDARG; - } - if (*pref != NULL) { - log_error("%s(%d): non-NULL pointer", MDL); - return ISC_R_INVALIDARG; + /* + * We're happy with the prefix, create an IAPREFIX + * to hold it. + */ + iapref = NULL; + result = iaaddr_allocate(&iapref, MDL); + if (result != ISC_R_SUCCESS) { + return result; } + iapref->plen = (u_int8_t)pool->units; + memcpy(&iapref->addr, &tmp, sizeof(iapref->addr)); - if (ppool->num_active > 0) { - tmp = (struct iaprefix *) - isc_heap_element(ppool->active_timeouts, 1); - if (now > tmp->hard_lifetime_end_time) { - result = move_prefix_to_inactive(ppool, tmp, - FTS_EXPIRED); - if (result == ISC_R_SUCCESS) { - iaprefix_reference(pref, tmp, MDL); - } - return result; - } + /* + * Add the prefix to the pool (note state is free, not active?!). + */ + result = add_lease6(pool, iapref, soft_lifetime_end_time); + if (result == ISC_R_SUCCESS) { + iaaddr_reference(pref, iapref, MDL); } - return ISC_R_SUCCESS; + iaaddr_dereference(&iapref, MDL); + return result; } - /* - * Put the returned prefix on our inactive pool. + * Determine if a prefix is present in a pool or not. */ -isc_result_t -release_prefix6(struct ipv6_ppool *ppool, struct iaprefix *pref) { - if (pref->state == FTS_ACTIVE) { - return move_prefix_to_inactive(ppool, pref, FTS_RELEASED); +isc_boolean_t +prefix6_exists(const struct ipv6_pool *pool, + const struct in6_addr *pref, u_int8_t plen) { + struct iaaddr *test_iapref; + + if ((int)plen != pool->units) + return ISC_FALSE; + + test_iapref = NULL; + if (iaaddr_hash_lookup(&test_iapref, pool->addrs, + (void *)pref, sizeof(*pref), MDL)) { + iaaddr_dereference(&test_iapref, MDL); + return ISC_TRUE; } else { - return ISC_R_SUCCESS; + return ISC_FALSE; } } /* - * Mark an IPv6 address as unavailable from a pool. + * Mark an IPv6 address/prefix as unavailable from a pool. * * This is used for host entries and the addresses of the server itself. */ isc_result_t -mark_address_unavailable(struct ipv6_pool *pool, const struct in6_addr *addr) { +mark_lease_unavailable(struct ipv6_pool *pool, const struct in6_addr *addr) { struct iaaddr *dummy_iaaddr; isc_result_t result; @@ -2035,27 +1313,6 @@ mark_address_unavailable(struct ipv6_pool *pool, const struct in6_addr *addr) { return result; } -/* - * Mark an IPv6 prefix as unavailable from a prefix pool. - * - * This is used for host entries. - */ -isc_result_t -mark_prefix_unavailable(struct ipv6_ppool *ppool, - const struct in6_addr *pref) { - struct iaprefix *dummy_iapref; - isc_result_t result; - - dummy_iapref = NULL; - result = iaprefix_allocate(&dummy_iapref, MDL); - if (result == ISC_R_SUCCESS) { - dummy_iapref->pref = *pref; - iaprefix_hash_add(ppool->prefs, &dummy_iapref->pref, - sizeof(*pref), dummy_iapref, MDL); - } - return result; -} - /* * Add a pool. */ @@ -2081,38 +1338,11 @@ add_ipv6_pool(struct ipv6_pool *pool) { return ISC_R_SUCCESS; } -/* - * Add a prefix pool. - */ -isc_result_t -add_ipv6_ppool(struct ipv6_ppool *ppool) { - struct ipv6_ppool **new_ppools; - - new_ppools = dmalloc(sizeof(struct ipv6_ppool *) * (num_ppools + 1), - MDL); - if (new_ppools == NULL) { - return ISC_R_NOMEMORY; - } - - if (num_ppools > 0) { - memcpy(new_ppools, ppools, - sizeof(struct ipv6_ppool *) * num_ppools); - dfree(ppools, MDL); - } - ppools = new_ppools; - - ppools[num_ppools] = NULL; - ipv6_ppool_reference(&ppools[num_ppools], ppool, MDL); - num_ppools++; - return ISC_R_SUCCESS; -} - - static void cleanup_old_expired(struct ipv6_pool *pool) { struct iaaddr *tmp; - struct ia_na *ia; - struct ia_na *ia_active; + struct ia_xx *ia; + struct ia_xx *ia_active; unsigned char *tmpd; time_t timeout; @@ -2132,36 +1362,42 @@ cleanup_old_expired(struct ipv6_pool *pool) { isc_heap_delete(pool->inactive_timeouts, tmp->heap_index); pool->num_inactive--; - if (tmp->ia_na != NULL) { + if (tmp->ia != NULL) { /* - * Check to see if this IA is in the active list, - * but has no remaining addresses. If so, remove it + * Check to see if this IA is in an active list, + * but has no remaining resources. If so, remove it * from the active list. */ ia = NULL; - ia_na_reference(&ia, tmp->ia_na, MDL); - ia_na_remove_iaaddr(ia, tmp, MDL); + ia_reference(&ia, tmp->ia, MDL); + ia_remove_iaaddr(ia, tmp, MDL); ia_active = NULL; tmpd = (unsigned char *)ia->iaid_duid.data; if ((ia->ia_type == D6O_IA_NA) && (ia->num_iaaddr <= 0) && - (ia_na_hash_lookup(&ia_active, ia_na_active, tmpd, - ia->iaid_duid.len, - MDL) == 0) && + (ia_hash_lookup(&ia_active, ia_na_active, tmpd, + ia->iaid_duid.len, MDL) == 0) && (ia_active == ia)) { - ia_na_hash_delete(ia_na_active, tmpd, - ia->iaid_duid.len, MDL); + ia_hash_delete(ia_na_active, tmpd, + ia->iaid_duid.len, MDL); } if ((ia->ia_type == D6O_IA_TA) && (ia->num_iaaddr <= 0) && - (ia_na_hash_lookup(&ia_active, ia_ta_active, tmpd, - ia->iaid_duid.len, - MDL) == 0) && + (ia_hash_lookup(&ia_active, ia_ta_active, tmpd, + ia->iaid_duid.len, MDL) == 0) && + (ia_active == ia)) { + ia_hash_delete(ia_ta_active, tmpd, + ia->iaid_duid.len, MDL); + } + if ((ia->ia_type == D6O_IA_PD) && + (ia->num_iaaddr <= 0) && + (ia_hash_lookup(&ia_active, ia_pd_active, tmpd, + ia->iaid_duid.len, MDL) == 0) && (ia_active == ia)) { - ia_na_hash_delete(ia_ta_active, tmpd, - ia->iaid_duid.len, MDL); + ia_hash_delete(ia_pd_active, tmpd, + ia->iaid_duid.len, MDL); } - ia_na_dereference(&ia, MDL); + ia_dereference(&ia, MDL); } iaaddr_dereference(&tmp, MDL); } @@ -2195,9 +1431,11 @@ lease_timeout_support(void *vpool) { * DH: Do we want to do this on a special 'depref' * timer rather than expiration timer? */ - ddns_removals(NULL, addr); + if (pool->pool_type != D6O_IA_PD) { + ddns_removals(NULL, addr); + } - write_ia(addr->ia_na); + write_ia(addr->ia); iaaddr_dereference(&addr, MDL); } @@ -2269,151 +1507,6 @@ schedule_all_ipv6_lease_timeouts(void) { } } -static void -cleanup_old_pexpired(struct ipv6_ppool *ppool) { - struct iaprefix *tmp; - struct ia_pd *ia_pd; - struct ia_pd *ia_active; - unsigned char *tmpd; - time_t timeout; - - while (ppool->num_inactive > 0) { - tmp = (struct iaprefix *) - isc_heap_element(ppool->inactive_timeouts, 1); - if (tmp->hard_lifetime_end_time != 0) { - timeout = tmp->hard_lifetime_end_time; - timeout += EXPIRED_IPV6_CLEANUP_TIME; - } else { - timeout = tmp->soft_lifetime_end_time; - } - if (cur_time < timeout) { - break; - } - - isc_heap_delete(ppool->inactive_timeouts, tmp->heap_index); - ppool->num_inactive--; - - if (tmp->ia_pd != NULL) { - /* - * Check to see if this IA_PD is in the active list, - * but has no remaining prefixes. If so, remove it - * from the active list. - */ - ia_pd = NULL; - ia_pd_reference(&ia_pd, tmp->ia_pd, MDL); - ia_pd_remove_iaprefix(ia_pd, tmp, MDL); - ia_active = NULL; - tmpd = (unsigned char *)ia_pd->iaid_duid.data; - if ((ia_pd->num_iaprefix <= 0) && - (ia_pd_hash_lookup(&ia_active, ia_pd_active, - tmpd, ia_pd->iaid_duid.len, - MDL) == 0) && - (ia_active == ia_pd)) { - ia_pd_hash_delete(ia_pd_active, tmpd, - ia_pd->iaid_duid.len, MDL); - } - ia_pd_dereference(&ia_pd, MDL); - } - iaprefix_dereference(&tmp, MDL); - } -} - -static void -prefix_timeout_support(void *vppool) { - struct ipv6_ppool *ppool; - struct iaprefix *pref; - - ppool = (struct ipv6_ppool *)vppool; - for (;;) { - /* - * Get the next prefix scheduled to expire. - * - * Note that if there are no prefixes in the pool, - * expire_prefix6() will return ISC_R_SUCCESS with - * a NULL prefix. - */ - pref = NULL; - if (expire_prefix6(&pref, ppool, cur_time) != ISC_R_SUCCESS) { - break; - } - if (pref == NULL) { - break; - } - - /* No DDNS for prefixes. */ - - write_ia_pd(pref->ia_pd); - - iaprefix_dereference(&pref, MDL); - } - - /* - * Do some cleanup of our expired prefixes. - */ - cleanup_old_pexpired(ppool); - - /* - * Schedule next round of expirations. - */ - schedule_prefix_timeout(ppool); -} - -/* - * For a given prefix pool, add a timer that will remove the next - * prefix to expire. - */ -void -schedule_prefix_timeout(struct ipv6_ppool *ppool) { - struct iaprefix *tmp; - time_t timeout; - time_t next_timeout; - struct timeval tv; - - next_timeout = MAX_TIME; - - if (ppool->num_active > 0) { - tmp = (struct iaprefix *) - isc_heap_element(ppool->active_timeouts, 1); - if (tmp->hard_lifetime_end_time < next_timeout) { - next_timeout = tmp->hard_lifetime_end_time + 1; - } - } - - if (ppool->num_inactive > 0) { - tmp = (struct iaprefix *) - isc_heap_element(ppool->inactive_timeouts, 1); - if (tmp->hard_lifetime_end_time != 0) { - timeout = tmp->hard_lifetime_end_time; - timeout += EXPIRED_IPV6_CLEANUP_TIME; - } else { - timeout = tmp->soft_lifetime_end_time + 1; - } - if (timeout < next_timeout) { - next_timeout = timeout; - } - } - - if (next_timeout < MAX_TIME) { - tv.tv_sec = next_timeout; - tv.tv_usec = 0; - add_timeout(&tv, prefix_timeout_support, ppool, - (tvref_t)ipv6_ppool_reference, - (tvunref_t)ipv6_ppool_dereference); - } -} - -/* - * Schedule timeouts across all pools. - */ -void -schedule_all_ipv6_prefix_timeouts(void) { - int i; - - for (i=0; ibits & ~POOL_IS_FOR_TEMP); + + ipv6_network_portion(&tmp, addr, pool->bits); if (memcmp(&tmp, &pool->start_addr, sizeof(tmp)) == 0) { return ISC_TRUE; } else { @@ -2489,7 +1582,7 @@ ipv6_addr_in_pool(const struct in6_addr *addr, const struct ipv6_pool *pool) { * initialized to NULL */ isc_result_t -find_ipv6_pool(struct ipv6_pool **pool, int temp, +find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *addr) { int i; @@ -2503,13 +1596,9 @@ find_ipv6_pool(struct ipv6_pool **pool, int temp, } for (i=0; ibits & POOL_IS_FOR_TEMP) == 0)) { - continue; - } - if (!temp && ((pools[i]->bits & POOL_IS_FOR_TEMP) != 0)) { + if (pools[i]->pool_type != type) continue; - } - if (ipv6_addr_in_pool(addr, pools[i])) { + if (ipv6_in_pool(addr, pools[i])) { ipv6_pool_reference(pool, pools[i], MDL); return ISC_R_SUCCESS; } @@ -2522,28 +1611,21 @@ find_ipv6_pool(struct ipv6_pool **pool, int temp, * pools. */ static isc_result_t -change_leases(struct ia_na *ia, +change_leases(struct ia_xx *ia, isc_result_t (*change_func)(struct ipv6_pool *, struct iaaddr*)) { isc_result_t retval; isc_result_t renew_retval; struct ipv6_pool *pool; struct in6_addr *addr; - int temp, i; + int i; retval = ISC_R_SUCCESS; - if (ia->ia_type == D6O_IA_NA) { - temp = 0; - } else if (ia->ia_type == D6O_IA_TA) { - temp = 1; - } else { - log_error("IA without type."); - return ISC_R_INVALIDARG; - } for (i=0; inum_iaaddr; i++) { pool = NULL; addr = &ia->iaaddr[i]->addr; - if (find_ipv6_pool(&pool, temp, addr) == ISC_R_SUCCESS) { - renew_retval = change_func(pool, ia->iaaddr[i]); + if (find_ipv6_pool(&pool, ia->ia_type, + addr) == ISC_R_SUCCESS) { + renew_retval = change_func(pool, ia->iaaddr[i]); if (renew_retval != ISC_R_SUCCESS) { retval = renew_retval; } @@ -2556,12 +1638,12 @@ change_leases(struct ia_na *ia, /* * Renew all leases in an IA from all pools. * - * The new hard_lifetime_end_time should be updated for the addresses. + * The new hard_lifetime_end_time should be updated for the addresses/prefixes. * * WARNING: lease times must only be extended, never reduced!!! */ isc_result_t -renew_leases(struct ia_na *ia) { +renew_leases(struct ia_xx *ia) { return change_leases(ia, renew_lease6); } @@ -2569,7 +1651,7 @@ renew_leases(struct ia_na *ia) { * Release all leases in an IA from all pools. */ isc_result_t -release_leases(struct ia_na *ia) { +release_leases(struct ia_xx *ia) { return change_leases(ia, release_lease6); } @@ -2577,103 +1659,10 @@ release_leases(struct ia_na *ia) { * Decline all leases in an IA from all pools. */ isc_result_t -decline_leases(struct ia_na *ia) { +decline_leases(struct ia_xx *ia) { return change_leases(ia, decline_lease6); } -/* - * Determine if the given prefix is in the pool. - */ -isc_boolean_t -ipv6_prefix_in_ppool(const struct in6_addr *pref, - const struct ipv6_ppool *ppool) { - struct in6_addr tmp; - - ipv6_network_portion(&tmp, pref, (int)ppool->pool_plen); - if (memcmp(&tmp, &ppool->start_pref, sizeof(tmp)) == 0) { - return ISC_TRUE; - } else { - return ISC_FALSE; - } -} - -/* - * Find the pool that contains the given prefix. - * - * - pool must be a pointer to a (struct ipv6_ppool *) pointer previously - * initialized to NULL - */ -isc_result_t -find_ipv6_ppool(struct ipv6_ppool **ppool, const struct in6_addr *pref) { - int i; - - if (ppool == NULL) { - log_error("%s(%d): NULL pointer reference", MDL); - return ISC_R_INVALIDARG; - } - if (*ppool != NULL) { - log_error("%s(%d): non-NULL pointer", MDL); - return ISC_R_INVALIDARG; - } - - for (i=0; inum_iaprefix; i++) { - ppool = NULL; - pref = &ia_pd->iaprefix[i]->pref; - if (find_ipv6_ppool(&ppool, pref) == ISC_R_SUCCESS) { - renew_retval = change_func(ppool, ia_pd->iaprefix[i]); - if (renew_retval != ISC_R_SUCCESS) { - retval = renew_retval; - } - } - /* XXXsk: should we warn if we don't find a pool? */ - } - return retval; -} - -/* - * Renew all prefixes in an IA_PD from all pools. - * - * The new hard_lifetime_end_time should be updated for the addresses. - * - * WARNING: lease times must only be extended, never reduced!!! - */ -isc_result_t -renew_prefixes(struct ia_pd *ia_pd) { - return change_prefixes(ia_pd, renew_prefix6); -} - -/* - * Release all prefixes in an IA_PD from all pools. - */ -isc_result_t -release_prefixes(struct ia_pd *ia_pd) { - return change_prefixes(ia_pd, release_prefix6); -} - #ifdef DHCPv6 /* * Helper function to output leases. @@ -2682,7 +1671,7 @@ static int write_error; static isc_result_t write_ia_leases(const void *name, unsigned len, void *value) { - struct ia_na *ia = (struct ia_na *)value; + struct ia_xx *ia = (struct ia_xx *)value; if (!write_error) { if (!write_ia(ia)) { @@ -2692,21 +1681,6 @@ write_ia_leases(const void *name, unsigned len, void *value) { return ISC_R_SUCCESS; } -/* - * Helper function to output prefixes. - */ -static isc_result_t -write_ia_pd_prefixes(const void *name, unsigned len, void *value) { - struct ia_pd *ia_pd = (struct ia_pd *)value; - - if (!write_error) { - if (!write_ia_pd(ia_pd)) { - write_error = 1; - } - } - return ISC_R_SUCCESS; -} - /* * Write all DHCPv6 information. */ @@ -2714,15 +1688,15 @@ int write_leases6(void) { write_error = 0; write_server_duid(); - ia_na_hash_foreach(ia_na_active, write_ia_leases); + ia_hash_foreach(ia_na_active, write_ia_leases); if (write_error) { return 0; } - ia_na_hash_foreach(ia_ta_active, write_ia_leases); + ia_hash_foreach(ia_ta_active, write_ia_leases); if (write_error) { return 0; } - ia_pd_hash_foreach(ia_pd_active, write_ia_pd_prefixes); + ia_hash_foreach(ia_pd_active, write_ia_leases); if (write_error) { return 0; } @@ -2770,12 +1744,12 @@ mark_hosts_unavailable_support(const void *name, unsigned len, void *value) { * sit in any pool.) */ p = NULL; - if (find_ipv6_pool(&p, 0, &addr) == ISC_R_SUCCESS) { - mark_address_unavailable(p, &addr); + if (find_ipv6_pool(&p, D6O_IA_NA, &addr) == ISC_R_SUCCESS) { + mark_lease_unavailable(p, &addr); ipv6_pool_dereference(&p, MDL); } - if (find_ipv6_pool(&p, 1, &addr) == ISC_R_SUCCESS) { - mark_address_unavailable(p, &addr); + if (find_ipv6_pool(&p, D6O_IA_TA, &addr) == ISC_R_SUCCESS) { + mark_lease_unavailable(p, &addr); ipv6_pool_dereference(&p, MDL); } @@ -2792,7 +1766,7 @@ mark_phosts_unavailable_support(const void *name, unsigned len, void *value) { struct host_decl *h; struct iaddrcidrnetlist *l; struct in6_addr pref; - struct ipv6_ppool *p; + struct ipv6_pool *p; h = (struct host_decl *)value; @@ -2818,15 +1792,15 @@ mark_phosts_unavailable_support(const void *name, unsigned len, void *value) { * sit in any pool.) */ p = NULL; - if (find_ipv6_ppool(&p, &pref) != ISC_R_SUCCESS) { + if (find_ipv6_pool(&p, D6O_IA_PD, &pref) != ISC_R_SUCCESS) { continue; } - if (l->cidrnet.bits != (int) p->alloc_plen) { - ipv6_ppool_dereference(&p, MDL); + if (l->cidrnet.bits != p->units) { + ipv6_pool_dereference(&p, MDL); continue; } - mark_prefix_unavailable(p, &pref); - ipv6_ppool_dereference(&p, MDL); + mark_lease_unavailable(p, &pref); + ipv6_pool_dereference(&p, MDL); } return ISC_R_SUCCESS; @@ -2847,16 +1821,16 @@ mark_interfaces_unavailable(void) { while (ip != NULL) { for (i=0; iv6address_count; i++) { p = NULL; - if (find_ipv6_pool(&p, 0, &ip->v6addresses[i]) + if (find_ipv6_pool(&p, D6O_IA_NA, &ip->v6addresses[i]) == ISC_R_SUCCESS) { - mark_address_unavailable(p, - &ip->v6addresses[i]); + mark_lease_unavailable(p, + &ip->v6addresses[i]); ipv6_pool_dereference(&p, MDL); } - if (find_ipv6_pool(&p, 1, &ip->v6addresses[i]) + if (find_ipv6_pool(&p, D6O_IA_TA, &ip->v6addresses[i]) == ISC_R_SUCCESS) { - mark_address_unavailable(p, - &ip->v6addresses[i]); + mark_lease_unavailable(p, + &ip->v6addresses[i]); ipv6_pool_dereference(&p, MDL); } } @@ -2873,8 +1847,8 @@ main(int argc, char *argv[]) { struct iaaddr *iaaddr; struct iaaddr *iaaddr_copy; u_int32_t iaid; - struct ia_na *ia_na; - struct ia_na *ia_na_copy; + struct ia_xx *ia_na; + struct ia_xx *ia_na_copy; int i; struct in6_addr addr; struct ipv6_pool *pool; @@ -2970,8 +1944,8 @@ main(int argc, char *argv[]) { */ iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } if (memcmp(ia_na->iaid_duid.data, &iaid, sizeof(iaid)) != 0) { @@ -2987,8 +1961,8 @@ main(int argc, char *argv[]) { return 1; } ia_na_copy = NULL; - if (ia_na_reference(&ia_na_copy, ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_reference() %s:%d\n", MDL); + if (ia_reference(&ia_na_copy, ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_reference() %s:%d\n", MDL); return 1; } iaaddr = NULL; @@ -2996,21 +1970,21 @@ main(int argc, char *argv[]) { printf("ERROR: iaaddr_allocate() %s:%d\n", MDL); return 1; } - if (ia_na_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_add_iaaddr() %s:%d\n", MDL); + if (ia_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_add_iaaddr() %s:%d\n", MDL); return 1; } - ia_na_remove_iaaddr(ia_na, iaaddr, MDL); + ia_remove_iaaddr(ia_na, iaaddr, MDL); if (iaaddr_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) { printf("ERROR: iaaddr_reference() %s:%d\n", MDL); return 1; } - if (ia_na_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } - if (ia_na_dereference(&ia_na_copy, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(&ia_na_copy, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } @@ -3021,8 +1995,8 @@ main(int argc, char *argv[]) { /* lots of iaaddr that we delete */ iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } for (i=0; i<100; i++) { @@ -3031,8 +2005,8 @@ main(int argc, char *argv[]) { printf("ERROR: iaaddr_allocate() %s:%d\n", MDL); return 1; } - if (ia_na_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_add_iaaddr() %s:%d\n", MDL); + if (ia_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_add_iaaddr() %s:%d\n", MDL); return 1; } if (iaaddr_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) { @@ -3042,18 +2016,18 @@ main(int argc, char *argv[]) { } for (i=0; i<100; i++) { iaaddr = ia_na->iaaddr[random() % ia_na->num_iaaddr]; - ia_na_remove_iaaddr(ia_na, iaaddr, MDL); + ia_remove_iaaddr(ia_na, iaaddr, MDL); } - if (ia_na_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } /* lots of iaaddr, let dereference cleanup */ iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } for (i=0; i<100; i++) { @@ -3062,8 +2036,8 @@ main(int argc, char *argv[]) { printf("ERROR: iaaddr_allocate() %s:%d\n", MDL); return 1; } - if (ia_na_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_add_iaaddr() %s:%d\n", MDL); + if (ia_add_iaaddr(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_add_iaaddr() %s:%d\n", MDL); return 1; } if (iaaddr_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) { @@ -3071,8 +2045,8 @@ main(int argc, char *argv[]) { return 1; } } - if (ia_na_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } @@ -3080,58 +2054,58 @@ main(int argc, char *argv[]) { * Test 4: Errors in ia_na. */ /* bogus allocate arguments */ - if (ia_na_allocate(NULL, 123, "", 0, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(NULL, 123, "", 0, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } ia_na = (struct ia_na *)1; - if (ia_na_allocate(&ia_na, 456, "", 0, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, 456, "", 0, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } /* bogus reference arguments */ iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } - if (ia_na_reference(NULL, ia_na, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_reference() %s:%d\n", MDL); + if (ia_reference(NULL, ia_na, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_reference() %s:%d\n", MDL); return 1; } ia_na_copy = (struct ia_na *)1; - if (ia_na_reference(&ia_na_copy, ia_na, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_reference() %s:%d\n", MDL); + if (ia_reference(&ia_na_copy, ia_na, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_reference() %s:%d\n", MDL); return 1; } ia_na_copy = NULL; - if (ia_na_reference(&ia_na_copy, NULL, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_reference() %s:%d\n", MDL); + if (ia_reference(&ia_na_copy, NULL, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_reference() %s:%d\n", MDL); return 1; } - if (ia_na_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } /* bogus dereference arguments */ - if (ia_na_dereference(NULL, MDL) != ISC_R_INVALIDARG) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + if (ia_dereference(NULL, MDL) != ISC_R_INVALIDARG) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } /* bogus remove */ iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; } - ia_na_remove_iaaddr(ia_na, NULL, MDL); - if (ia_na_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_dereference() %s:%d\n", MDL); + ia_remove_iaaddr(ia_na, NULL, MDL); + if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_dereference() %s:%d\n", MDL); return 1; } @@ -3142,7 +2116,7 @@ main(int argc, char *argv[]) { /* allocate, reference */ inet_pton(AF_INET6, "1:2:3:4::", &addr); pool = NULL; - if (ipv6_pool_allocate(&pool, &addr, 64, MDL) != ISC_R_SUCCESS) { + if (ipv6_pool_allocate(&pool, 0, &addr, 64, 128, MDL) != ISC_R_SUCCESS) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } @@ -3292,12 +2266,12 @@ main(int argc, char *argv[]) { /* * Test 6: Error ipv6_pool manipulation */ - if (ipv6_pool_allocate(NULL, &addr, 64, MDL) != ISC_R_INVALIDARG) { + if (ipv6_pool_allocate(NULL, 0, &addr, 64, 128, MDL) != ISC_R_INVALIDARG) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } pool = (struct ipv6_pool *)1; - if (ipv6_pool_allocate(&pool, &addr, 64, MDL) != ISC_R_INVALIDARG) { + if (ipv6_pool_allocate(&pool, 0, &addr, 64, 128, MDL) != ISC_R_INVALIDARG) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } @@ -3328,7 +2302,7 @@ main(int argc, char *argv[]) { * Test 7: order of expiration */ pool = NULL; - if (ipv6_pool_allocate(&pool, &addr, 64, MDL) != ISC_R_SUCCESS) { + if (ipv6_pool_allocate(&pool, 0, &addr, 64, 128, MDL) != ISC_R_SUCCESS) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } @@ -3399,7 +2373,7 @@ main(int argc, char *argv[]) { */ pool = NULL; addr.s6_addr[14] = 0x81; - if (ipv6_pool_allocate(&pool, &addr, 127, MDL) != ISC_R_SUCCESS) { + if (ipv6_pool_allocate(&pool, 0, &addr, 127, 128, MDL) != ISC_R_SUCCESS) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } @@ -3444,7 +2418,7 @@ main(int argc, char *argv[]) { * Test 9: functions across all pools */ pool = NULL; - if (ipv6_pool_allocate(&pool, &addr, 64, MDL) != ISC_R_SUCCESS) { + if (ipv6_pool_allocate(&pool, 0, &addr, 64, 128, MDL) != ISC_R_SUCCESS) { printf("ERROR: ipv6_pool_allocate() %s:%d\n", MDL); return 1; } @@ -3490,8 +2464,8 @@ main(int argc, char *argv[]) { /* iaid = 666; ia_na = NULL; - if (ia_na_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { - printf("ERROR: ia_na_allocate() %s:%d\n", MDL); + if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) { + printf("ERROR: ia_allocate() %s:%d\n", MDL); return 1; }*/ @@ -3512,7 +2486,7 @@ main(int argc, char *argv[]) { for (j = i + 1; j < 49; j++) { memset(&r, 0, sizeof(r)); memset(buf, 0, 64); - create_prefix(&r, &addr, i, j, &ds); + build_prefix6(&r, &addr, i, j, &ds); inet_ntop(AF_INET6, &r, buf, 64); printf("%d,%d-> %s/%d\n", i, j, buf, j); }