- 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.
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;
#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).
(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 */
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)
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));
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 *));
/* 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);
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,
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);
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;
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;
}
#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;
}
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");
}
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) {
/*
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
}
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);
}
}
-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
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);
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;
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;
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;
}
/* 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);
* 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) */
}
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;
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;
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;
}
/* 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);
* 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) */
}
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;
}
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) {
}
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)
}
/* 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) */
}
* 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;
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) {
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)) {
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; i<ia_pd->num_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;
}
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,
#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 */
/* 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
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,
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
return ISC_R_FAILURE;
}
- if (!ipv6_addr_in_pool(&tmp_addr, pool)) {
+ if (!ipv6_in_pool(&tmp_addr, pool)) {
return ISC_R_FAILURE;
}
return result;
}
(*addr)->addr = tmp_addr;
+ (*addr)->plen = 0;
/* Default is soft binding for 2 minutes. */
result = add_lease6(pool, *addr, cur_time + 120);
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: "
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;
}
}
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)) {
/*
* 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;
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;
}
* 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];
/*
* 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;
/* 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);
/* 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);
}
/* 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);
* 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;
/* 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;
}
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
* provide zero addresses including zeroed
* lifetimes.
*/
- if (reply->ia_resources_included)
+ if (reply->resources_included)
status = ISC_R_SUCCESS;
else
goto cleanup;
*/
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 =
}
}
- /* 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:
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)
}
/*
- * 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.
/* 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:
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;
/* 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;
}
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
*/
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 =
}
}
- /* 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:
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);
if (p == NULL) {
break;
}
- if ((p->bits & POOL_IS_FOR_TEMP) == 0) {
+ if (p->pool_type != D6O_IA_TA) {
continue;
}
}
status = reply_process_is_addressed(reply,
- reply->ia_ta,
&reply->lease->scope,
reply->shared->group);
if (status != ISC_R_SUCCESS) {
*/
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;
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)
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. */
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;
* 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;
/* 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",
/*
* 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);
}
}
goto cleanup;
}
- reply->ia_resources_included = ISC_TRUE;
+ reply->resources_included = ISC_TRUE;
cleanup:
if (data.data != NULL)
* 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. */
/* 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
goto cleanup;
}
- reply->ia_pd_count++;
+ reply->pd_count++;
/*
* If we fell through the above and never gave the client
break;
default:
- if (reply->ia_resources_included)
+ if (reply->resources_included)
status = ISC_R_SUCCESS;
else
goto cleanup;
*/
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:
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
/* 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
(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;
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;
}
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;
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;
}
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;
}
}
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));
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;
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;
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);
* 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;
}
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;
* 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;
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",
/*
* 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);
}
}
goto cleanup;
}
- reply->ia_resources_included = ISC_TRUE;
+ reply->resources_included = ISC_TRUE;
cleanup:
if (data.data != NULL)
}
/* 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)
tmp_addr, sizeof(tmp_addr)));
if (lease != NULL) {
decline_lease6(lease->ipv6_pool, lease);
- write_ia(lease->ia_na);
+ write_ia(lease->ia);
}
}
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;
}
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.
*/
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);
}
}
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];
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);
}
}
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;
}
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;
}
}
}
if (prefix != NULL) {
- iaprefix_dereference(&prefix, MDL);
+ iaaddr_dereference(&prefix, MDL);
}
data_string_forget(&iaprefix, MDL);
exit:
if (prefix != NULL) {
- iaprefix_dereference(&prefix, MDL);
+ iaaddr_dereference(&prefix, MDL);
}
if (host_opt_state != NULL) {
option_state_dereference(&host_opt_state, MDL);
}
/*
- * 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 */
#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
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
/*
- * Dereference an IAADDR structure.
+ * Dereference an IAADDR/PREFIX structure.
*
* If it is the last reference, then the memory for the
* structure is freed.
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);
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.
*/
/*
* 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
*
* 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);
/*
* 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;
* 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)) {
/*
- * 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;
* 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;
}
/*
- * 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; i<ia->num_iaaddr; i++) {
}
/* 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; i<ia->num_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;
* 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;
}
/*
- * 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; i<a->num_iaaddr; i++) {
found = ISC_FALSE;
for (j=0; j<a->num_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) {
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; i<tmp->num_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; i<ia_pd->num_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; i<ia_pd->num_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; i<a->num_iaprefix; i++) {
- found = ISC_FALSE;
- for (j=0; j<a->num_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) {
}
/*
- * 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) {
}
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);
}
/*
- * 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.
*
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.
}
/*
- * 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;
}
/*
if (result != ISC_R_SUCCESS) {
return result;
}
+ iaaddr->plen = 0;
memcpy(&iaaddr->addr, &tmp, sizeof(iaaddr->addr));
/*
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;
}
/*
- * Add IAADDR to our structures.
+ * Add IAADDR/PREFIX to our structures.
*/
tmp_iaaddr = NULL;
iaaddr_reference(&tmp_iaaddr, iaaddr, MDL);
/*
* 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!!!
*/
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.
/*
* 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
* 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;
/*
/*
* 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;
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.
*/
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;
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);
}
* 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);
}
}
}
-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; i<num_ppools; i++) {
- schedule_prefix_timeout(ppools[i]);
- }
-}
-
/*
* Given an address and the length of the network mask, return
* only the network portion.
}
/*
- * Determine if the given address is in the pool.
+ * Determine if the given address/prefix is in the pool.
*/
isc_boolean_t
-ipv6_addr_in_pool(const struct in6_addr *addr, const struct ipv6_pool *pool) {
+ipv6_in_pool(const struct in6_addr *addr, const struct ipv6_pool *pool) {
struct in6_addr tmp;
-
- ipv6_network_portion(&tmp, addr, pool->bits & ~POOL_IS_FOR_TEMP);
+
+ ipv6_network_portion(&tmp, addr, pool->bits);
if (memcmp(&tmp, &pool->start_addr, sizeof(tmp)) == 0) {
return ISC_TRUE;
} else {
* 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;
}
for (i=0; i<num_pools; i++) {
- if (temp && ((pools[i]->bits & 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;
}
* 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; i<ia->num_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;
}
/*
* 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);
}
* 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);
}
* 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; i<num_ppools; i++) {
- if (ipv6_prefix_in_ppool(pref, ppools[i])) {
- ipv6_ppool_reference(ppool, ppools[i], MDL);
- return ISC_R_SUCCESS;
- }
- }
- return ISC_R_NOTFOUND;
-}
-
-/*
- * Helper function for the various functions that act across all
- * prefix pools.
- */
-static isc_result_t
-change_prefixes(struct ia_pd *ia_pd,
- isc_result_t (*change_func)(struct ipv6_ppool *,
- struct iaprefix*)) {
- isc_result_t retval;
- isc_result_t renew_retval;
- struct ipv6_ppool *ppool;
- struct in6_addr *pref;
- int i;
-
- retval = ISC_R_SUCCESS;
- for (i=0; i<ia_pd->num_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.
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)) {
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.
*/
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;
}
* 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);
}
struct host_decl *h;
struct iaddrcidrnetlist *l;
struct in6_addr pref;
- struct ipv6_ppool *p;
+ struct ipv6_pool *p;
h = (struct host_decl *)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;
while (ip != NULL) {
for (i=0; i<ip->v6address_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);
}
}
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;
*/
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) {
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;
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;
}
/* 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++) {
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) {
}
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++) {
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) {
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;
}
* 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;
}
/* 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;
}
/*
* 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;
}
* 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;
}
*/
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;
}
* 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;
}
/* 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 (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);
}