diff options
Diffstat (limited to 'contrib/ipfilter/ip_pool.c')
-rw-r--r-- | contrib/ipfilter/ip_pool.c | 786 |
1 files changed, 0 insertions, 786 deletions
diff --git a/contrib/ipfilter/ip_pool.c b/contrib/ipfilter/ip_pool.c deleted file mode 100644 index b6e111b..0000000 --- a/contrib/ipfilter/ip_pool.c +++ /dev/null @@ -1,786 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__osf__) -# define _PROTO_NET_H_ -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -#else -# include <sys/systm.h> -# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) -# include <sys/proc.h> -# endif -#endif -#include <sys/time.h> -#if !defined(linux) -# include <sys/protosw.h> -#endif -#include <sys/socket.h> -#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) -# include <sys/mbuf.h> -#endif -#if defined(__SVR4) || defined(__svr4__) -# include <sys/filio.h> -# include <sys/byteorder.h> -# ifdef _KERNEL -# include <sys/dditypes.h> -# endif -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include <sys/malloc.h> -#endif - -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include <net/radix.h> -# endif -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include <net/if.h> -#include <netinet/in.h> - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_pool.h" - -#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \ - ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int rn_freenode __P((struct radix_node *, void *)); -#endif - -/* END OF INCLUDES */ - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_pool.c,v 2.55.2.12 2005/02/01 04:04:46 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP - -# ifndef RADIX_NODE_HEAD_LOCK -# define RADIX_NODE_HEAD_LOCK(x) ; -# endif -# ifndef RADIX_NODE_HEAD_UNLOCK -# define RADIX_NODE_HEAD_UNLOCK(x) ; -# endif - -ip_pool_stat_t ipoolstat; -ipfrwlock_t ip_poolrw; - -/* - * Binary tree routines from Sedgewick and enhanced to do ranges of addresses. - * NOTE: Insertion *MUST* be from greatest range to least for it to work! - * These should be replaced, eventually, by something else - most notably a - * interval searching method. The important feature is to be able to find - * the best match. - * - * So why not use a radix tree for this? As the first line implies, it - * has been written to work with a _range_ of addresses. A range is not - * necessarily a match with any given netmask so what we end up dealing - * with is an interval tree. Implementations of these are hard to find - * and the one herein is far from bug free. - * - * Sigh, in the end I became convinced that the bugs the code contained did - * not make it worthwhile not using radix trees. For now the radix tree from - * 4.4 BSD is used, but this is not viewed as a long term solution. - */ -ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL }; - - -#ifdef TEST_POOL -void treeprint __P((ip_pool_t *)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - addrfamily_t a, b; - iplookupop_t op; - ip_pool_t *ipo; - i6addr_t ip; - - RWLOCK_INIT(&ip_poolrw, "poolrw"); - ip_pool_init(); - - bzero((char *)&a, sizeof(a)); - bzero((char *)&b, sizeof(b)); - bzero((char *)&ip, sizeof(ip)); - bzero((char *)&op, sizeof(op)); - strcpy(op.iplo_name, "0"); - - if (ip_pool_create(&op) == 0) - ipo = ip_pool_find(0, "0"); - - a.adf_addr.in4.s_addr = 0x0a010203; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a000000; - b.adf_addr.in4.s_addr = 0xff000000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - - a.adf_addr.in4.s_addr = 0x0a010100; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a010200; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - - a.adf_addr.in4.s_addr = 0x0a010000; - b.adf_addr.in4.s_addr = 0xffff0000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a01020f; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - ip.in4.s_addr = 0x0a00aabb; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000001; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000101; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010001; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010101; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010201; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010203; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a01020f; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0b00aabb; - printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - - ip_pool_fini(); - - return 0; -} - - -void -treeprint(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *c; - - for (c = ipo->ipo_list; c != NULL; c = c->ipn_next) - printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n", - c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr, - c->ipn_mask.adf_addr.in4.s_addr, - c->ipn_info, c->ipn_hits); -} -#endif /* TEST_POOL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_init */ -/* Returns: int - 0 = success, else error */ -/* */ -/* Initialise the routing table data structures where required. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_init() -{ - - bzero((char *)&ipoolstat, sizeof(ipoolstat)); - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_init(); -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_fini */ -/* Returns: int - 0 = success, else error */ -/* Locks: WRITE(ipf_global) */ -/* */ -/* Clean up all the pool data structures allocated and call the cleanup */ -/* function for the radix tree that supports the pools. ip_pool_destroy() is*/ -/* used to delete the pools one by one to ensure they're properly freed up. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_fini() -{ - ip_pool_t *p, *q; - iplookupop_t op; - int i; - - ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0); - - for (i = 0; i <= IPL_LOGMAX; i++) { - for (q = ip_pool_list[i]; (p = q) != NULL; ) { - op.iplo_unit = i; - (void)strncpy(op.iplo_name, p->ipo_name, - sizeof(op.iplo_name)); - q = p->ipo_next; - (void) ip_pool_destroy(&op); - } - } - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_fini(); -#endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_statistics */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to lookup operation arguments */ -/* */ -/* Copy the current statistics out into user space, collecting pool list */ -/* pointers as appropriate for later use. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_statistics(op) -iplookupop_t *op; -{ - ip_pool_stat_t stats; - int unit, i, err = 0; - - if (op->iplo_size != sizeof(ipoolstat)) - return EINVAL; - - bcopy((char *)&ipoolstat, (char *)&stats, sizeof(stats)); - unit = op->iplo_unit; - if (unit == IPL_LOGALL) { - for (i = 0; i < IPL_LOGSIZE; i++) - stats.ipls_list[i] = ip_pool_list[i]; - } else if (unit >= 0 && unit < IPL_LOGSIZE) { - if (op->iplo_name[0] != '\0') - stats.ipls_list[unit] = ip_pool_find(unit, - op->iplo_name); - else - stats.ipls_list[unit] = ip_pool_list[unit]; - } else - err = EINVAL; - if (err == 0) - err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); - return err; -} - - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_find */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* */ -/* Find a matching pool inside the collection of pools for a particular */ -/* device, indicated by the unit number. */ -/* ------------------------------------------------------------------------ */ -void *ip_pool_find(unit, name) -int unit; -char *name; -{ - ip_pool_t *p; - - for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) - if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) - break; - return p; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_findeq */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - pointer to address information to delete */ -/* mask(I) - */ -/* */ -/* Searches for an exact match of an entry in the pool. */ -/* ------------------------------------------------------------------------ */ -ip_pool_node_t *ip_pool_findeq(ipo, addr, mask) -ip_pool_t *ipo; -addrfamily_t *addr, *mask; -{ - struct radix_node *n; -#ifdef USE_SPL - int s; - - SPL_NET(s); -#endif - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - SPL_X(s); - return (ip_pool_node_t *)n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_search */ -/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ -/* version(I) - IP protocol version (4 or 6) */ -/* dptr(I) - pointer to address information */ -/* */ -/* Search the pool for a given address and return a search result. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_search(tptr, version, dptr) -void *tptr; -int version; -void *dptr; -{ - struct radix_node *rn; - ip_pool_node_t *m; - i6addr_t *addr; - addrfamily_t v; - ip_pool_t *ipo; - int rv; - - ipo = tptr; - if (ipo == NULL) - return -1; - - rv = 1; - m = NULL; - addr = (i6addr_t *)dptr; - bzero(&v, sizeof(v)); - v.adf_len = offsetof(addrfamily_t, adf_addr); - - if (version == 4) { - v.adf_len += sizeof(addr->in4); - v.adf_addr.in4 = addr->in4; -#ifdef USE_INET6 - } else if (version == 6) { - v.adf_len += sizeof(addr->in6); - v.adf_addr.in6 = addr->in6; -#endif - } else - return -1; - - READ_ENTER(&ip_poolrw); - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - - if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { - m = (ip_pool_node_t *)rn; - ipo->ipo_hits++; - m->ipn_hits++; - rv = m->ipn_info; - } - RWLOCK_EXIT(&ip_poolrw); - return rv; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_insert */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - address being added as a node */ -/* mask(I) - netmask to with the node being added */ -/* info(I) - extra information to store in this node. */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Add another node to the pool given by ipo. The three parameters passed */ -/* in (addr, mask, info) shold all be stored in the node. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_insert(ipo, addr, mask, info) -ip_pool_t *ipo; -i6addr_t *addr, *mask; -int info; -{ - struct radix_node *rn; - ip_pool_node_t *x; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(x, ip_pool_node_t *); - if (x == NULL) { - return ENOMEM; - } - - bzero(x, sizeof(*x)); - - x->ipn_info = info; - (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); - - bcopy(addr, &x->ipn_addr.adf_addr, sizeof(*addr)); - x->ipn_addr.adf_len = sizeof(x->ipn_addr); - bcopy(mask, &x->ipn_mask.adf_addr, sizeof(*mask)); - x->ipn_mask.adf_len = sizeof(x->ipn_mask); - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask, - ipo->ipo_head, x->ipn_nodes); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); -#ifdef DEBUG_POOL - printf("Added %p at %p\n", x, rn); -#endif - - if (rn == NULL) { - KFREE(x); - return ENOMEM; - } - - x->ipn_next = ipo->ipo_list; - x->ipn_pnext = &ipo->ipo_list; - if (ipo->ipo_list != NULL) - ipo->ipo_list->ipn_pnext = &x->ipn_next; - ipo->ipo_list = x; - - ipoolstat.ipls_nodes++; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_create */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to iplookup struct with call details */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Creates a new group according to the paramters passed in via the */ -/* iplookupop structure. Does not check to see if the group already exists */ -/* when being inserted - assume this has already been done. If the pool is */ -/* marked as being anonymous, give it a new, unique, identifier. Call any */ -/* other functions required to initialise the structure. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_create(op) -iplookupop_t *op; -{ - char name[FR_GROUPLEN]; - int poolnum, unit; - ip_pool_t *h; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(h, ip_pool_t *); - if (h == NULL) - return ENOMEM; - bzero(h, sizeof(*h)); - - if (rn_inithead((void **)&h->ipo_head, - offsetof(addrfamily_t, adf_addr) << 3) == 0) { - KFREE(h); - return ENOMEM; - } - - unit = op->iplo_unit; - - if ((op->iplo_arg & IPOOL_ANON) != 0) { - ip_pool_t *p; - - poolnum = IPOOL_ANON; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - - for (p = ip_pool_list[unit]; p != NULL; ) { - if (strncmp(name, p->ipo_name, - sizeof(p->ipo_name)) == 0) { - poolnum++; -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - p = ip_pool_list[unit]; - } else - p = p->ipo_next; - } - - (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); - } else { - (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); - } - - h->ipo_ref = 1; - h->ipo_list = NULL; - h->ipo_unit = unit; - h->ipo_next = ip_pool_list[unit]; - if (ip_pool_list[unit] != NULL) - ip_pool_list[unit]->ipo_pnext = &h->ipo_next; - h->ipo_pnext = &ip_pool_list[unit]; - ip_pool_list[unit] = h; - - ipoolstat.ipls_pools++; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_remove */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool to remove the node from. */ -/* ipe(I) - address being deleted as a node */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Add another node to the pool given by ipo. The three parameters passed */ -/* in (addr, mask, info) shold all be stored in the node. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_remove(ipo, ipe) -ip_pool_t *ipo; -ip_pool_node_t *ipe; -{ - ip_pool_node_t **ipp, *n; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) { - if (ipe == n) { - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - break; - } - } - - if (n == NULL) - return ENOENT; - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - KFREE(n); - - ipoolstat.ipls_nodes--; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_destroy */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - information about the pool to remove */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Search for a pool using paramters passed in and if it's not otherwise */ -/* busy, free it. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_destroy(op) -iplookupop_t *op; -{ - ip_pool_t *ipo; - - ipo = ip_pool_find(op->iplo_unit, op->iplo_name); - if (ipo == NULL) - return ESRCH; - - if (ipo->ipo_ref != 1) - return EBUSY; - - ip_pool_free(ipo); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_flush */ -/* Returns: int - number of pools deleted */ -/* Parameters: fp(I) - which pool(s) to flush */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Free all pools associated with the device that matches the unit number */ -/* passed in with operation. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_flush(fp) -iplookupflush_t *fp; -{ - int i, num = 0, unit, err; - ip_pool_t *p, *q; - iplookupop_t op; - - unit = fp->iplf_unit; - - for (i = 0; i <= IPL_LOGMAX; i++) { - if (unit != IPLT_ALL && i != unit) - continue; - for (q = ip_pool_list[i]; (p = q) != NULL; ) { - op.iplo_unit = i; - (void)strncpy(op.iplo_name, p->ipo_name, - sizeof(op.iplo_name)); - q = p->ipo_next; - err = ip_pool_destroy(&op); - if (err == 0) - num++; - else - break; - } - } - return num; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_free */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Deletes the pool strucutre passed in from the list of pools and deletes */ -/* all of the address information stored in it, including any tree data */ -/* structures also allocated. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_free(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *n; - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - while ((n = ipo->ipo_list) != NULL) { - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - - KFREE(n); - - ipoolstat.ipls_nodes--; - } - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - - ipo->ipo_list = NULL; - if (ipo->ipo_next != NULL) - ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; - *ipo->ipo_pnext = ipo->ipo_next; - rn_freehead(ipo->ipo_head); - KFREE(ipo); - - ipoolstat.ipls_pools--; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_deref */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Drop the number of known references to this pool structure by one and if */ -/* we arrive at zero known references, free it. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_deref(ipo) -ip_pool_t *ipo; -{ - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - ipo->ipo_ref--; - if (ipo->ipo_ref == 0) - ip_pool_free(ipo); -} - - -# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int -rn_freenode(struct radix_node *n, void *p) -{ - struct radix_node_head *rnh = p; - struct radix_node *d; - - d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); - if (d != NULL) { - FreeS(d, max_keylen + 2 * sizeof (*d)); - } - return 0; -} - - -void -rn_freehead(rnh) - struct radix_node_head *rnh; -{ - - RADIX_NODE_HEAD_LOCK(rnh); - (*rnh->rnh_walktree)(rnh, rn_freenode, rnh); - - rnh->rnh_addaddr = NULL; - rnh->rnh_deladdr = NULL; - rnh->rnh_matchaddr = NULL; - rnh->rnh_lookup = NULL; - rnh->rnh_walktree = NULL; - RADIX_NODE_HEAD_UNLOCK(rnh); - - Free(rnh); -} -# endif - -#endif /* IPFILTER_LOOKUP */ |