2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00
Modify the class and subclass code to allow for dynamic addition and
removal of subclasses.  See 27452 for details.
This commit is contained in:
Shawn Routhier 2013-06-05 18:15:49 -07:00
parent 360cc6d993
commit 08b2d34783
6 changed files with 290 additions and 269 deletions

View File

@ -87,6 +87,11 @@ work on other platforms. Please report any problems and suggested fixes to
Thanks to Paolo Pellegrino for finding the issue and a suggestion Thanks to Paolo Pellegrino for finding the issue and a suggestion
for the patch. for the patch.
[ISC-Bugs #33351] [ISC-Bugs #33351]
- Fix several problems with using OMAPI to manipulate class and subclass
objects.
[ISC-Bugs #27452]
Changes since 4.2.4 Changes since 4.2.4
- Correct code to calculate timing values in client to compare - Correct code to calculate timing values in client to compare

View File

@ -3,7 +3,8 @@
Definitions for the object management API and protocol... */ Definitions for the object management API and protocol... */
/* /*
* Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2009,2013 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium * Copyright (c) 1996-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -353,7 +354,9 @@ isc_result_t omapi_connection_put_name (omapi_object_t *, const char *);
isc_result_t omapi_connection_put_string (omapi_object_t *, const char *); isc_result_t omapi_connection_put_string (omapi_object_t *, const char *);
isc_result_t omapi_connection_put_handle (omapi_object_t *c, isc_result_t omapi_connection_put_handle (omapi_object_t *c,
omapi_object_t *h); omapi_object_t *h);
isc_result_t omapi_connection_put_named_uint32 (omapi_object_t *,
const char *,
u_int32_t);
isc_result_t omapi_listen (omapi_object_t *, unsigned, int); isc_result_t omapi_listen (omapi_object_t *, unsigned, int);
isc_result_t omapi_listen_addr (omapi_object_t *, isc_result_t omapi_listen_addr (omapi_object_t *,
omapi_addr_t *, int); omapi_addr_t *, int);

View File

@ -3,7 +3,7 @@
Buffer access functions for the object management protocol... */ Buffer access functions for the object management protocol... */
/* /*
* Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2009,2012-2013 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium * Copyright (c) 1999-2003 by Internet Software Consortium
* *
@ -720,3 +720,22 @@ isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
return status; return status;
return omapi_connection_put_uint32 (c, handle); return omapi_connection_put_uint32 (c, handle);
} }
isc_result_t omapi_connection_put_named_uint32 (omapi_object_t *c,
const char *name,
u_int32_t value)
{
isc_result_t status;
status = omapi_connection_put_name(c, name);
if (status != ISC_R_SUCCESS)
return (status);
status = omapi_connection_put_uint32(c, sizeof(u_int32_t));
if (status != ISC_R_SUCCESS)
return (status);
status = omapi_connection_put_uint32(c, value);
return (status);
}

View File

@ -1995,13 +1995,13 @@ int parse_class_declaration (cp, cfile, group, type)
{ {
const char *val; const char *val;
enum dhcp_token token; enum dhcp_token token;
struct class *class = (struct class *)0, *pc = (struct class *)0; struct class *class = NULL, *pc = NULL;
int declaration = 0; int declaration = 0;
int lose = 0; int lose = 0;
struct data_string data; struct data_string data;
char *name; char *name;
const char *tname; const char *tname;
struct executable_statement *stmt = (struct executable_statement *)0; struct executable_statement *stmt = NULL;
int new = 1; int new = 1;
isc_result_t status = ISC_R_FAILURE; isc_result_t status = ISC_R_FAILURE;
int matchedonce = 0; int matchedonce = 0;
@ -2014,7 +2014,7 @@ int parse_class_declaration (cp, cfile, group, type)
"for DHCPv6."); "for DHCPv6.");
} }
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, NULL, cfile);
if (token != STRING) { if (token != STRING) {
parse_warn (cfile, "Expecting class name"); parse_warn (cfile, "Expecting class name");
skip_to_semi (cfile); skip_to_semi (cfile);
@ -2047,7 +2047,7 @@ int parse_class_declaration (cp, cfile, group, type)
the vendor class or user class. */ the vendor class or user class. */
if ((type == CLASS_TYPE_VENDOR) || (type == CLASS_TYPE_USER)) { if ((type == CLASS_TYPE_VENDOR) || (type == CLASS_TYPE_USER)) {
data.len = strlen (val); data.len = strlen (val);
data.buffer = (struct buffer *)0; data.buffer = NULL;
if (!buffer_allocate (&data.buffer, data.len + 1, MDL)) if (!buffer_allocate (&data.buffer, data.len + 1, MDL))
log_fatal ("no memory for class name."); log_fatal ("no memory for class name.");
data.data = &data.buffer -> data [0]; data.data = &data.buffer -> data [0];
@ -2057,7 +2057,7 @@ int parse_class_declaration (cp, cfile, group, type)
} else if (type == CLASS_TYPE_CLASS) { } else if (type == CLASS_TYPE_CLASS) {
tname = val; tname = val;
} else { } else {
tname = (const char *)0; tname = NULL;
} }
if (tname) { if (tname) {
@ -2066,14 +2066,15 @@ int parse_class_declaration (cp, cfile, group, type)
log_fatal ("No memory for class name %s.", tname); log_fatal ("No memory for class name %s.", tname);
strcpy (name, val); strcpy (name, val);
} else } else
name = (char *)0; name = NULL;
/* If this is a straight subclass, parse the hash string. */ /* If this is a straight subclass, parse the hash string. */
if (type == CLASS_TYPE_SUBCLASS) { if (type == CLASS_TYPE_SUBCLASS) {
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, NULL, cfile);
if (token == STRING) { if (token == STRING) {
skip_token(&val, &data.len, cfile); skip_token(&val, &data.len, cfile);
data.buffer = (struct buffer *)0; data.buffer = NULL;
if (!buffer_allocate (&data.buffer, if (!buffer_allocate (&data.buffer,
data.len + 1, MDL)) { data.len + 1, MDL)) {
if (pc) if (pc)
@ -2109,7 +2110,11 @@ int parse_class_declaration (cp, cfile, group, type)
/* If we didn't find an existing class, allocate a new one. */ /* If we didn't find an existing class, allocate a new one. */
if (!class) { if (!class) {
/* Allocate the class structure... */ /* Allocate the class structure... */
if (type == CLASS_TYPE_SUBCLASS) {
status = subclass_allocate (&class, MDL);
} else {
status = class_allocate (&class, MDL); status = class_allocate (&class, MDL);
}
if (pc) { if (pc) {
group_reference (&class -> group, pc -> group, MDL); group_reference (&class -> group, pc -> group, MDL);
class_reference (&class -> superclass, pc, MDL); class_reference (&class -> superclass, pc, MDL);
@ -2143,7 +2148,7 @@ int parse_class_declaration (cp, cfile, group, type)
statement that causes the vendor or user class ID to statement that causes the vendor or user class ID to
be sent back in the reply. */ be sent back in the reply. */
if (type == CLASS_TYPE_VENDOR || type == CLASS_TYPE_USER) { if (type == CLASS_TYPE_VENDOR || type == CLASS_TYPE_USER) {
stmt = (struct executable_statement *)0; stmt = NULL;
if (!executable_statement_allocate (&stmt, MDL)) if (!executable_statement_allocate (&stmt, MDL))
log_fatal ("no memory for class statement."); log_fatal ("no memory for class statement.");
stmt -> op = supersede_option_statement; stmt -> op = supersede_option_statement;
@ -2172,9 +2177,10 @@ int parse_class_declaration (cp, cfile, group, type)
/* Spawned classes don't have to have their own settings. */ /* Spawned classes don't have to have their own settings. */
if (class -> superclass) { if (class -> superclass) {
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, NULL, cfile);
if (token == SEMI) { if (token == SEMI) {
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
if (cp) if (cp)
status = class_reference (cp, class, MDL); status = class_reference (cp, class, MDL);
class_dereference (&class, MDL); class_dereference (&class, MDL);
@ -2196,23 +2202,23 @@ int parse_class_declaration (cp, cfile, group, type)
} }
do { do {
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, NULL, cfile);
if (token == RBRACE) { if (token == RBRACE) {
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
break; break;
} else if (token == END_OF_FILE) { } else if (token == END_OF_FILE) {
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
parse_warn (cfile, "unexpected end of file"); parse_warn (cfile, "unexpected end of file");
break; break;
} else if (token == DYNAMIC) { } else if (token == DYNAMIC) {
class->flags |= CLASS_DECL_DYNAMIC; class->flags |= CLASS_DECL_DYNAMIC;
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
break; break;
continue; continue;
} else if (token == TOKEN_DELETED) { } else if (token == TOKEN_DELETED) {
class->flags |= CLASS_DECL_DELETED; class->flags |= CLASS_DECL_DELETED;
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
break; break;
continue; continue;
@ -2223,11 +2229,11 @@ int parse_class_declaration (cp, cfile, group, type)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, NULL, cfile);
if (token != IF) if (token != IF)
goto submatch; goto submatch;
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
if (matchedonce) { if (matchedonce) {
parse_warn(cfile, "A class may only have " parse_warn(cfile, "A class may only have "
"one 'match if' clause."); "one 'match if' clause.");
@ -2252,7 +2258,7 @@ int parse_class_declaration (cp, cfile, group, type)
parse_semi (cfile); parse_semi (cfile);
} }
} else if (token == SPAWN) { } else if (token == SPAWN) {
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
if (pc) { if (pc) {
parse_warn (cfile, parse_warn (cfile,
"invalid spawn in subclass."); "invalid spawn in subclass.");
@ -2260,7 +2266,7 @@ int parse_class_declaration (cp, cfile, group, type)
break; break;
} }
class -> spawning = 1; class -> spawning = 1;
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, NULL, cfile);
if (token != WITH) { if (token != WITH) {
parse_warn (cfile, parse_warn (cfile,
"expecting with after spawn"); "expecting with after spawn");
@ -2293,15 +2299,15 @@ int parse_class_declaration (cp, cfile, group, type)
parse_semi (cfile); parse_semi (cfile);
} }
} else if (token == LEASE) { } else if (token == LEASE) {
skip_token(&val, (unsigned *)0, cfile); skip_token(&val, NULL, cfile);
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, NULL, cfile);
if (token != LIMIT) { if (token != LIMIT) {
parse_warn (cfile, "expecting \"limit\""); parse_warn (cfile, "expecting \"limit\"");
if (token != SEMI) if (token != SEMI)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, NULL, cfile);
if (token != NUMBER) { if (token != NUMBER) {
parse_warn (cfile, "expecting a number"); parse_warn (cfile, "expecting a number");
if (token != SEMI) if (token != SEMI)
@ -2323,8 +2329,7 @@ int parse_class_declaration (cp, cfile, group, type)
parse_semi (cfile); parse_semi (cfile);
} else { } else {
declaration = parse_statement (cfile, class -> group, declaration = parse_statement (cfile, class -> group,
CLASS_DECL, CLASS_DECL, NULL,
(struct host_decl *)0,
declaration); declaration);
} }
} while (1); } while (1);

View File

@ -3,7 +3,7 @@
Server-specific in-memory database support. */ Server-specific in-memory database support. */
/* /*
* Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2011-2013 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium * Copyright (c) 1996-2003 by Internet Software Consortium
* *
@ -443,9 +443,18 @@ isc_result_t delete_class (cp, commit)
return ISC_R_IOERROR; return ISC_R_IOERROR;
} }
unlink_class(&cp); /* remove from collections */ /*
* If this is a subclass remove it from the class's hash table
*/
if (cp->superclass) {
class_hash_delete(cp->superclass->hash,
(const char *)cp->hash_string.data,
cp->hash_string.len,
MDL);
}
class_dereference(&cp, MDL); /* remove from collections */
unlink_class(&cp);
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }

View File

@ -3,7 +3,8 @@
OMAPI object interfaces for the DHCP server. */ OMAPI object interfaces for the DHCP server. */
/* /*
* Copyright (c) 2004-2009,2012,2013 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2012-2013 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium * Copyright (c) 1999-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -514,15 +515,10 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
/* Write out all the values. */ /* Write out all the values. */
status = omapi_connection_put_name (c, "state"); status = omapi_connection_put_named_uint32(c, "state",
lease->binding_state);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, lease -> binding_state);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_name (c, "ip-address"); status = omapi_connection_put_name (c, "ip-address");
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
@ -615,16 +611,10 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
status = omapi_connection_put_name (c, "hardware-type"); status = omapi_connection_put_named_uint32(c, "hardware-type",
lease->hardware_addr.hbuf[0]);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32
(c, lease -> hardware_addr.hbuf [0]);
if (status != ISC_R_SUCCESS)
return status;
} }
/* TIME values may be 64-bit, depending on system architecture. /* TIME values may be 64-bit, depending on system architecture.
@ -638,68 +628,32 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
* 32-bit, code. * 32-bit, code.
*/ */
bouncer = (u_int32_t)lease->ends; bouncer = (u_int32_t)lease->ends;
status = omapi_connection_put_name(c, "ends"); status = omapi_connection_put_named_uint32(c, "ends", bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
bouncer = (u_int32_t)lease->starts; bouncer = (u_int32_t)lease->starts;
status = omapi_connection_put_name(c, "starts"); status = omapi_connection_put_named_uint32(c, "starts", bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
bouncer = (u_int32_t)lease->tstp; bouncer = (u_int32_t)lease->tstp;
status = omapi_connection_put_name(c, "tstp"); status = omapi_connection_put_named_uint32(c, "tstp", bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
bouncer = (u_int32_t)lease->tsfp; bouncer = (u_int32_t)lease->tsfp;
status = omapi_connection_put_name(c, "tsfp"); status = omapi_connection_put_named_uint32(c, "tsfp", bouncer);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
bouncer = (u_int32_t)lease->atsfp; bouncer = (u_int32_t)lease->atsfp;
status = omapi_connection_put_name(c, "atsfp"); status = omapi_connection_put_named_uint32(c, "atsfp", bouncer);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
bouncer = (u_int32_t)lease->cltt; bouncer = (u_int32_t)lease->cltt;
status = omapi_connection_put_name(c, "cltt"); status = omapi_connection_put_named_uint32(c, "cltt", bouncer);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
@ -1327,14 +1281,8 @@ isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
status = omapi_connection_put_name (c, "hardware-type"); status = omapi_connection_put_named_uint32(c, "hardware-type",
if (status != ISC_R_SUCCESS) host->interface.hbuf[0]);
return status;
status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_put_uint32
(c, host -> interface.hbuf [0]));
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
} }
@ -1711,23 +1659,46 @@ isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
omapi_object_t *id, omapi_object_t *id,
omapi_object_t *h) omapi_object_t *h)
{ {
/* h should point to (struct pool *) */ struct pool *pool;
isc_result_t status; isc_result_t status;
if (h->type != dhcp_type_pool) if (h->type != dhcp_type_pool)
return DHCP_R_INVALIDARG; return (DHCP_R_INVALIDARG);
pool = (struct pool *)h;
/* Can't stuff pool values yet. */ /*
* I don't think we can actually find a pool yet
* but include the output of interesting values
* for when we do
*/
status = omapi_connection_put_named_uint32(c, "lease-count",
((u_int32_t)
pool->lease_count));
if (status != ISC_R_SUCCESS)
return (status);
status = omapi_connection_put_named_uint32(c, "free-leases",
((u_int32_t)
pool->free_leases));
if (status != ISC_R_SUCCESS)
return (status);
status = omapi_connection_put_named_uint32(c, "backup-leases",
((u_int32_t)
pool->backup_leases));
if (status != ISC_R_SUCCESS)
return (status);
/* we could add time stamps but lets wait on those */
/* Write out the inner object, if any. */ /* Write out the inner object, if any. */
if (h->inner && h->inner->type->stuff_values) { if (h->inner && h->inner->type->stuff_values) {
status = ((*(h->inner->type->stuff_values)) status = ((*(h->inner->type->stuff_values))
(c, id, h->inner)); (c, id, h->inner));
if (status == ISC_R_SUCCESS) if (status == ISC_R_SUCCESS)
return status; return (status);
} }
return ISC_R_SUCCESS; return (ISC_R_SUCCESS);
} }
isc_result_t dhcp_pool_lookup (omapi_object_t **lp, isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
@ -1789,8 +1760,23 @@ class_set_value (omapi_object_t *h,
if (class->superclass != NULL) if (class->superclass != NULL)
class_dereference(&class->superclass, MDL); class_dereference(&class->superclass, MDL);
class_reference(&class->superclass, superclass, MDL); class_reference(&class->superclass, superclass, MDL);
if (class->group != NULL)
group_dereference(&class->group, MDL);
group_reference(&class->group, superclass->group, MDL);
class->lease_limit = superclass->lease_limit;
if (class->lease_limit != 0) {
class->billed_leases =
dmalloc(class->lease_limit *
sizeof(struct lease *),
MDL);
if (class->billed_leases == NULL) {
return ISC_R_NOMEMORY;
}
}
} else if (value->type == omapi_datatype_data || } else if (value->type == omapi_datatype_data ||
value->type == omapi_datatype_string) { value->type == omapi_datatype_string) {
class->name = dmalloc(value->u.buffer.len + 1, MDL); class->name = dmalloc(value->u.buffer.len + 1, MDL);
@ -1946,10 +1932,8 @@ isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass) if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
return DHCP_R_INVALIDARG; return DHCP_R_INVALIDARG;
#if defined (DEBUG_MEMORY_LEAKAGE) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
struct class *class = (struct class *)h; struct class *class = (struct class *)h;
if (class -> nic) if (class -> nic)
class_dereference (&class -> nic, file, line); class_dereference (&class -> nic, file, line);
if (class -> superclass) if (class -> superclass)
@ -1986,7 +1970,6 @@ isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
file, line); file, line);
if (class -> superclass) if (class -> superclass)
class_dereference (&class -> superclass, file, line); class_dereference (&class -> superclass, file, line);
#endif
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
@ -2024,13 +2007,12 @@ class_signal_handler(omapi_object_t *h,
class_new_hash(&class->superclass->hash, class_new_hash(&class->superclass->hash,
SCLASS_HASH_SIZE, MDL); SCLASS_HASH_SIZE, MDL);
add_hash (class -> superclass -> hash, class_hash_add(class->superclass->hash,
class -> hash_string.data, (const char *)class->hash_string.data,
class->hash_string.len, class->hash_string.len,
(void *)class, MDL); (void *)class, MDL);
} }
#ifdef DEBUG_OMAPI #ifdef DEBUG_OMAPI
if (issubclass) { if (issubclass) {
log_debug ("OMAPI added subclass %s", log_debug ("OMAPI added subclass %s",
@ -2070,41 +2052,70 @@ isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
return class_signal_handler(h, name, ap); return class_signal_handler(h, name, ap);
} }
isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
/*
* Routine to put out generic class & subclass information
*/
isc_result_t class_stuff_values (omapi_object_t *c,
omapi_object_t *id, omapi_object_t *id,
omapi_object_t *h) omapi_object_t *h)
{ {
/* h should point to (struct class *) */ struct class *class;
isc_result_t status; isc_result_t status;
if (h -> type != dhcp_type_class) class = (struct class *)h;
return DHCP_R_INVALIDARG;
/* Can't stuff class values yet. */ status = omapi_connection_put_named_uint32(c, "lease-limit",
((u_int32_t)
class->lease_limit));
if (status != ISC_R_SUCCESS)
return (status);
status = omapi_connection_put_named_uint32(c, "leases-used",
((u_int32_t)
class->leases_consumed));
if (status != ISC_R_SUCCESS)
return (status);
/* Write out the inner object, if any. */ /* Write out the inner object, if any. */
if (h->inner && h->inner->type->stuff_values) { if (h->inner && h->inner->type->stuff_values) {
status = ((*(h->inner->type->stuff_values)) status = ((*(h->inner->type->stuff_values))
(c, id, h->inner)); (c, id, h->inner));
if (status == ISC_R_SUCCESS) if (status == ISC_R_SUCCESS)
return status; return (status);
} }
return ISC_R_SUCCESS; return (ISC_R_SUCCESS);
}
isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
omapi_object_t *id,
omapi_object_t *h)
{
if (h->type != dhcp_type_class)
return (DHCP_R_INVALIDARG);
/* add any class specific items here */
return (class_stuff_values(c, id, h));
} }
static isc_result_t class_lookup (omapi_object_t **lp, static isc_result_t class_lookup (omapi_object_t **lp,
omapi_object_t *id, omapi_object_t *ref, omapi_object_t *id, omapi_object_t *ref,
omapi_object_type_t *typewanted) omapi_object_type_t *typewanted)
{ {
omapi_value_t *nv = (omapi_value_t *)0; omapi_value_t *nv = NULL;
omapi_value_t *hv = (omapi_value_t *)0; omapi_value_t *hv = NULL;
isc_result_t status; isc_result_t status;
struct class *class = 0; struct class *class = 0;
struct class *subclass = 0; struct class *subclass = 0;
*lp = NULL; *lp = NULL;
if (ref == NULL)
return (DHCP_R_NOKEYS);
/* see if we have a name */ /* see if we have a name */
status = omapi_get_value_str(ref, id, "name", &nv); status = omapi_get_value_str(ref, id, "name", &nv);
if (status == ISC_R_SUCCESS) { if (status == ISC_R_SUCCESS) {
@ -2120,7 +2131,7 @@ static isc_result_t class_lookup (omapi_object_t **lp,
dfree(name, MDL); dfree(name, MDL);
if (class == NULL) { if (class == NULL) {
return ISC_R_NOTFOUND; return (ISC_R_NOTFOUND);
} }
if (typewanted == dhcp_type_subclass) { if (typewanted == dhcp_type_subclass) {
@ -2128,14 +2139,14 @@ static isc_result_t class_lookup (omapi_object_t **lp,
"hashstring", &hv); "hashstring", &hv);
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
class_dereference(&class, MDL); class_dereference(&class, MDL);
return DHCP_R_NOKEYS; return (DHCP_R_NOKEYS);
} }
if (hv->value->type != omapi_datatype_data && if (hv->value->type != omapi_datatype_data &&
hv->value->type != omapi_datatype_string) { hv->value->type != omapi_datatype_string) {
class_dereference(&class, MDL); class_dereference(&class, MDL);
omapi_value_dereference(&hv, MDL); omapi_value_dereference(&hv, MDL);
return DHCP_R_NOKEYS; return (DHCP_R_NOKEYS);
} }
class_hash_lookup(&subclass, class->hash, class_hash_lookup(&subclass, class->hash,
@ -2148,30 +2159,31 @@ static isc_result_t class_lookup (omapi_object_t **lp,
class_dereference(&class, MDL); class_dereference(&class, MDL);
if (subclass == NULL) { if (subclass == NULL) {
return ISC_R_NOTFOUND; return (ISC_R_NOTFOUND);
} }
class_reference(&class, subclass, MDL); class_reference(&class, subclass, MDL);
class_dereference(&subclass, MDL); class_dereference(&subclass, MDL);
} }
/* Don't return the object if the type is wrong. */ /* Don't return the object if the type is wrong. */
if (class->type != typewanted) { if (class->type != typewanted) {
class_dereference(&class, MDL); class_dereference(&class, MDL);
return DHCP_R_INVALIDARG; return (DHCP_R_INVALIDARG);
} }
if (class->flags & CLASS_DECL_DELETED) { if (class->flags & CLASS_DECL_DELETED) {
class_dereference(&class, MDL); class_dereference(&class, MDL);
return (ISC_R_NOTFOUND);
} }
omapi_object_reference(lp, (omapi_object_t *)class, MDL); omapi_object_reference(lp, (omapi_object_t *)class, MDL);
class_dereference(&class, MDL);
return ISC_R_SUCCESS; return (ISC_R_SUCCESS);
} }
return DHCP_R_NOKEYS; return (DHCP_R_NOKEYS);
} }
@ -2189,13 +2201,13 @@ isc_result_t dhcp_class_create (omapi_object_t **lp,
status = class_allocate(&cp, MDL); status = class_allocate(&cp, MDL);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return (status);
group_reference (&cp -> group, root_group, MDL); clone_group(&cp->group, root_group, MDL);
cp->flags = CLASS_DECL_DYNAMIC; cp->flags = CLASS_DECL_DYNAMIC;
status = omapi_object_reference(lp, (omapi_object_t *)cp, MDL); status = omapi_object_reference(lp, (omapi_object_t *)cp, MDL);
class_dereference(&cp, MDL); class_dereference(&cp, MDL);
return status; return (status);
} }
isc_result_t dhcp_class_remove (omapi_object_t *lp, isc_result_t dhcp_class_remove (omapi_object_t *lp,
@ -2266,26 +2278,16 @@ isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
omapi_object_t *h) omapi_object_t *h)
{ {
struct class *subclass; struct class *subclass;
isc_result_t status;
if (h -> type != dhcp_type_class) if (h->type != dhcp_type_subclass)
return DHCP_R_INVALIDARG; return (DHCP_R_INVALIDARG);
subclass = (struct class *)h; subclass = (struct class *)h;
if (subclass->name != 0) if (subclass->name != 0)
return DHCP_R_INVALIDARG; return (DHCP_R_INVALIDARG);
/* add any subclass specific items here */
/* Can't stuff subclass values yet. */ return (class_stuff_values(c, id, h));
/* Write out the inner object, if any. */
if (h -> inner && h -> inner -> type -> stuff_values) {
status = ((*(h -> inner -> type -> stuff_values))
(c, id, h -> inner));
if (status == ISC_R_SUCCESS)
return status;
}
return ISC_R_SUCCESS;
} }
isc_result_t dhcp_subclass_lookup (omapi_object_t **lp, isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
@ -2303,19 +2305,6 @@ isc_result_t dhcp_subclass_create (omapi_object_t **lp,
struct class *cp = 0; struct class *cp = 0;
isc_result_t status; isc_result_t status;
/*
* XXX
* NOTE: subclasses and classes have the same internal type, which makes it
* difficult to tell them apart. Specifically, in this function we need to
* create a class object (because there is no such thing as a subclass
* object), but one field of the class object is the type (which has the
* value dhcp_type_class), and it is from here that all the other omapi
* functions are accessed. So, even though there's a whole suite of
* subclass functions registered, they won't get used. Now we could change
* the type pointer after creating the class object, but I'm not certain
* that won't break something else.
*/
status = subclass_allocate(&cp, MDL); status = subclass_allocate(&cp, MDL);
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
@ -2331,13 +2320,6 @@ isc_result_t dhcp_subclass_create (omapi_object_t **lp,
isc_result_t dhcp_subclass_remove (omapi_object_t *lp, isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
omapi_object_t *id) omapi_object_t *id)
{ {
#if 1
log_fatal("calling dhcp_subclass_set_value");
/* this should never be called see dhcp_subclass_create for why */
#else
struct class *cp; struct class *cp;
if (lp -> type != dhcp_type_subclass) if (lp -> type != dhcp_type_subclass)
return DHCP_R_INVALIDARG; return DHCP_R_INVALIDARG;
@ -2349,8 +2331,6 @@ isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
delete_class (cp, 1); delete_class (cp, 1);
#endif
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }