17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate * 6*ab25eeb5Syz * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 77c478bd9Sstevel@tonic-gate * Use is subject to license terms. 87c478bd9Sstevel@tonic-gate */ 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL) 137c478bd9Sstevel@tonic-gate # undef KERNEL 147c478bd9Sstevel@tonic-gate # undef _KERNEL 157c478bd9Sstevel@tonic-gate # define KERNEL 1 167c478bd9Sstevel@tonic-gate # define _KERNEL 1 177c478bd9Sstevel@tonic-gate #endif 18*ab25eeb5Syz #if defined(__osf__) 19*ab25eeb5Syz # define _PROTO_NET_H_ 20*ab25eeb5Syz #endif 217c478bd9Sstevel@tonic-gate #include <sys/errno.h> 227c478bd9Sstevel@tonic-gate #include <sys/types.h> 237c478bd9Sstevel@tonic-gate #include <sys/param.h> 247c478bd9Sstevel@tonic-gate #include <sys/file.h> 257c478bd9Sstevel@tonic-gate #if !defined(_KERNEL) && !defined(__KERNEL__) 267c478bd9Sstevel@tonic-gate # include <stdio.h> 277c478bd9Sstevel@tonic-gate # include <stdlib.h> 287c478bd9Sstevel@tonic-gate # include <string.h> 297c478bd9Sstevel@tonic-gate # define _KERNEL 307c478bd9Sstevel@tonic-gate # ifdef __OpenBSD__ 317c478bd9Sstevel@tonic-gate struct file; 327c478bd9Sstevel@tonic-gate # endif 337c478bd9Sstevel@tonic-gate # include <sys/uio.h> 347c478bd9Sstevel@tonic-gate # undef _KERNEL 357c478bd9Sstevel@tonic-gate #else 367c478bd9Sstevel@tonic-gate # include <sys/systm.h> 377c478bd9Sstevel@tonic-gate # if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) 387c478bd9Sstevel@tonic-gate # include <sys/proc.h> 397c478bd9Sstevel@tonic-gate # endif 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate #include <sys/time.h> 427c478bd9Sstevel@tonic-gate #if !defined(linux) 437c478bd9Sstevel@tonic-gate # include <sys/protosw.h> 447c478bd9Sstevel@tonic-gate #endif 457c478bd9Sstevel@tonic-gate #include <sys/socket.h> 467c478bd9Sstevel@tonic-gate #if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) 477c478bd9Sstevel@tonic-gate # include <sys/mbuf.h> 487c478bd9Sstevel@tonic-gate #endif 497c478bd9Sstevel@tonic-gate #if defined(__SVR4) || defined(__svr4__) 507c478bd9Sstevel@tonic-gate # include <sys/filio.h> 517c478bd9Sstevel@tonic-gate # include <sys/byteorder.h> 527c478bd9Sstevel@tonic-gate # ifdef _KERNEL 537c478bd9Sstevel@tonic-gate # include <sys/dditypes.h> 547c478bd9Sstevel@tonic-gate # endif 557c478bd9Sstevel@tonic-gate # include <sys/stream.h> 567c478bd9Sstevel@tonic-gate # include <sys/kmem.h> 577c478bd9Sstevel@tonic-gate #endif 587c478bd9Sstevel@tonic-gate #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 597c478bd9Sstevel@tonic-gate # include <sys/malloc.h> 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate 62*ab25eeb5Syz #if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \ 63*ab25eeb5Syz defined(__hpux) || defined(__sgi)) 64*ab25eeb5Syz # ifdef __osf__ 65*ab25eeb5Syz # include <net/radix.h> 66*ab25eeb5Syz # endif 67*ab25eeb5Syz # include "radix_ipf_local.h" 68*ab25eeb5Syz # define _RADIX_H_ 69*ab25eeb5Syz #endif 707c478bd9Sstevel@tonic-gate #include <net/if.h> 717c478bd9Sstevel@tonic-gate #include <netinet/in.h> 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 747c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 757c478bd9Sstevel@tonic-gate #include "netinet/ip_pool.h" 76*ab25eeb5Syz 77*ab25eeb5Syz #if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \ 78*ab25eeb5Syz ((BSD >= 198911) && !defined(__osf__) && \ 79*ab25eeb5Syz !defined(__hpux) && !defined(__sgi)) 80*ab25eeb5Syz static int rn_freenode __P((struct radix_node *, void *)); 817c478bd9Sstevel@tonic-gate #endif 82*ab25eeb5Syz 837c478bd9Sstevel@tonic-gate /* END OF INCLUDES */ 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate #if !defined(lint) 867c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 87*ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.14 2005/06/12 07:18:26 darrenr Exp $"; 887c478bd9Sstevel@tonic-gate #endif 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #ifdef IPFILTER_LOOKUP 917c478bd9Sstevel@tonic-gate 92*ab25eeb5Syz # ifndef RADIX_NODE_HEAD_LOCK 93*ab25eeb5Syz # define RADIX_NODE_HEAD_LOCK(x) ; 94*ab25eeb5Syz # endif 95*ab25eeb5Syz # ifndef RADIX_NODE_HEAD_UNLOCK 96*ab25eeb5Syz # define RADIX_NODE_HEAD_UNLOCK(x) ; 97*ab25eeb5Syz # endif 98*ab25eeb5Syz 997c478bd9Sstevel@tonic-gate ip_pool_stat_t ipoolstat; 100*ab25eeb5Syz ipfrwlock_t ip_poolrw; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* 1037c478bd9Sstevel@tonic-gate * Binary tree routines from Sedgewick and enhanced to do ranges of addresses. 1047c478bd9Sstevel@tonic-gate * NOTE: Insertion *MUST* be from greatest range to least for it to work! 1057c478bd9Sstevel@tonic-gate * These should be replaced, eventually, by something else - most notably a 1067c478bd9Sstevel@tonic-gate * interval searching method. The important feature is to be able to find 1077c478bd9Sstevel@tonic-gate * the best match. 1087c478bd9Sstevel@tonic-gate * 1097c478bd9Sstevel@tonic-gate * So why not use a radix tree for this? As the first line implies, it 1107c478bd9Sstevel@tonic-gate * has been written to work with a _range_ of addresses. A range is not 1117c478bd9Sstevel@tonic-gate * necessarily a match with any given netmask so what we end up dealing 1127c478bd9Sstevel@tonic-gate * with is an interval tree. Implementations of these are hard to find 1137c478bd9Sstevel@tonic-gate * and the one herein is far from bug free. 1147c478bd9Sstevel@tonic-gate * 1157c478bd9Sstevel@tonic-gate * Sigh, in the end I became convinced that the bugs the code contained did 1167c478bd9Sstevel@tonic-gate * not make it worthwhile not using radix trees. For now the radix tree from 1177c478bd9Sstevel@tonic-gate * 4.4 BSD is used, but this is not viewed as a long term solution. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, 1207c478bd9Sstevel@tonic-gate NULL, NULL, NULL, NULL }; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate #ifdef TEST_POOL 1247c478bd9Sstevel@tonic-gate void treeprint __P((ip_pool_t *)); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate int 1277c478bd9Sstevel@tonic-gate main(argc, argv) 1287c478bd9Sstevel@tonic-gate int argc; 1297c478bd9Sstevel@tonic-gate char *argv[]; 1307c478bd9Sstevel@tonic-gate { 1317c478bd9Sstevel@tonic-gate addrfamily_t a, b; 1327c478bd9Sstevel@tonic-gate iplookupop_t op; 1337c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 1347c478bd9Sstevel@tonic-gate i6addr_t ip; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate RWLOCK_INIT(&ip_poolrw, "poolrw"); 1377c478bd9Sstevel@tonic-gate ip_pool_init(); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate bzero((char *)&a, sizeof(a)); 1407c478bd9Sstevel@tonic-gate bzero((char *)&b, sizeof(b)); 1417c478bd9Sstevel@tonic-gate bzero((char *)&ip, sizeof(ip)); 1427c478bd9Sstevel@tonic-gate bzero((char *)&op, sizeof(op)); 1437c478bd9Sstevel@tonic-gate strcpy(op.iplo_name, "0"); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (ip_pool_create(&op) == 0) 1467c478bd9Sstevel@tonic-gate ipo = ip_pool_find(0, "0"); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a010203; 1497c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xffffffff; 1507663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1517663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a000000; 1547c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xff000000; 1557663b816Sml ip_pool_insert(ipo, &a, &b, 0); 1567663b816Sml ip_pool_insert(ipo, &a, &b, 0); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a010100; 1597c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xffffff00; 1607663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1617663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a010200; 1647c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xffffff00; 1657663b816Sml ip_pool_insert(ipo, &a, &b, 0); 1667663b816Sml ip_pool_insert(ipo, &a, &b, 0); 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a010000; 1697c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xffff0000; 1707663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1717663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate a.adf_addr.in4.s_addr = 0x0a01020f; 1747c478bd9Sstevel@tonic-gate b.adf_addr.in4.s_addr = 0xffffffff; 1757663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1767663b816Sml ip_pool_insert(ipo, &a, &b, 1); 1777c478bd9Sstevel@tonic-gate #ifdef DEBUG_POOL 1787c478bd9Sstevel@tonic-gate treeprint(ipo); 1797c478bd9Sstevel@tonic-gate #endif 1807c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a00aabb; 1817c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (0)\n", ip.in4.s_addr, 1827c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a000001; 1857c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (0)\n", ip.in4.s_addr, 1867c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a000101; 1897c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (0)\n", ip.in4.s_addr, 1907c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a010001; 1937c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (1)\n", ip.in4.s_addr, 1947c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a010101; 1977c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (1)\n", ip.in4.s_addr, 1987c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a010201; 2017c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (0)\n", ip.in4.s_addr, 2027c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a010203; 2057c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (1)\n", ip.in4.s_addr, 2067c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0a01020f; 2097c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (1)\n", ip.in4.s_addr, 2107c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate ip.in4.s_addr = 0x0b00aabb; 2137c478bd9Sstevel@tonic-gate printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, 2147c478bd9Sstevel@tonic-gate ip_pool_search(ipo, 4, &ip)); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate #ifdef DEBUG_POOL 2177c478bd9Sstevel@tonic-gate treeprint(ipo); 2187c478bd9Sstevel@tonic-gate #endif 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate ip_pool_fini(); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate return 0; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate void 2277c478bd9Sstevel@tonic-gate treeprint(ipo) 2287c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate ip_pool_node_t *c; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate for (c = ipo->ipo_list; c != NULL; c = c->ipn_next) 2337c478bd9Sstevel@tonic-gate printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n", 2347c478bd9Sstevel@tonic-gate c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr, 2357c478bd9Sstevel@tonic-gate c->ipn_mask.adf_addr.in4.s_addr, 2367c478bd9Sstevel@tonic-gate c->ipn_info, c->ipn_hits); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate #endif /* TEST_POOL */ 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2427c478bd9Sstevel@tonic-gate /* Function: ip_pool_init */ 2437c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 2447c478bd9Sstevel@tonic-gate /* */ 2457c478bd9Sstevel@tonic-gate /* Initialise the routing table data structures where required. */ 2467c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2477c478bd9Sstevel@tonic-gate int ip_pool_init() 2487c478bd9Sstevel@tonic-gate { 249*ab25eeb5Syz 25008254dd3Syz bzero((char *)&ipoolstat, sizeof(ipoolstat)); 2517c478bd9Sstevel@tonic-gate 252*ab25eeb5Syz #if (!defined(_KERNEL) || (BSD < 199306)) 2537c478bd9Sstevel@tonic-gate rn_init(); 2547c478bd9Sstevel@tonic-gate #endif 2557c478bd9Sstevel@tonic-gate return 0; 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2607c478bd9Sstevel@tonic-gate /* Function: ip_pool_fini */ 2617c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 2627c478bd9Sstevel@tonic-gate /* Locks: WRITE(ipf_global) */ 2637c478bd9Sstevel@tonic-gate /* */ 2647c478bd9Sstevel@tonic-gate /* Clean up all the pool data structures allocated and call the cleanup */ 2657c478bd9Sstevel@tonic-gate /* function for the radix tree that supports the pools. ip_pool_destroy() is*/ 2667c478bd9Sstevel@tonic-gate /* used to delete the pools one by one to ensure they're properly freed up. */ 2677c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2687c478bd9Sstevel@tonic-gate void ip_pool_fini() 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate ip_pool_t *p, *q; 2717c478bd9Sstevel@tonic-gate iplookupop_t op; 2727c478bd9Sstevel@tonic-gate int i; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0); 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate for (i = 0; i <= IPL_LOGMAX; i++) { 2777c478bd9Sstevel@tonic-gate for (q = ip_pool_list[i]; (p = q) != NULL; ) { 2787c478bd9Sstevel@tonic-gate op.iplo_unit = i; 2797c478bd9Sstevel@tonic-gate (void)strncpy(op.iplo_name, p->ipo_name, 2807c478bd9Sstevel@tonic-gate sizeof(op.iplo_name)); 2817c478bd9Sstevel@tonic-gate q = p->ipo_next; 2827c478bd9Sstevel@tonic-gate (void) ip_pool_destroy(&op); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 286*ab25eeb5Syz #if (!defined(_KERNEL) || (BSD < 199306)) 2877c478bd9Sstevel@tonic-gate rn_fini(); 2887c478bd9Sstevel@tonic-gate #endif 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 291*ab25eeb5Syz 2927663b816Sml /* ------------------------------------------------------------------------ */ 2937663b816Sml /* Function: ip_pool_statistics */ 2947663b816Sml /* Returns: int - 0 = success, else error */ 2957663b816Sml /* Parameters: op(I) - pointer to lookup operation arguments */ 2967663b816Sml /* */ 2977663b816Sml /* Copy the current statistics out into user space, collecting pool list */ 2987663b816Sml /* pointers as appropriate for later use. */ 2997663b816Sml /* ------------------------------------------------------------------------ */ 3007663b816Sml int ip_pool_statistics(op) 3017663b816Sml iplookupop_t *op; 3027663b816Sml { 3037663b816Sml ip_pool_stat_t stats; 3047663b816Sml int unit, i, err = 0; 3057663b816Sml 3067663b816Sml if (op->iplo_size != sizeof(ipoolstat)) 3077663b816Sml return EINVAL; 3087663b816Sml 3097663b816Sml bcopy((char *)&ipoolstat, (char *)&stats, sizeof(stats)); 3107663b816Sml unit = op->iplo_unit; 3117663b816Sml if (unit == IPL_LOGALL) { 3127663b816Sml for (i = 0; i < IPL_LOGSIZE; i++) 3137663b816Sml stats.ipls_list[i] = ip_pool_list[i]; 3147663b816Sml } else if (unit >= 0 && unit < IPL_LOGSIZE) { 315*ab25eeb5Syz if (op->iplo_name[0] != '\0') 316*ab25eeb5Syz stats.ipls_list[unit] = ip_pool_find(unit, 317*ab25eeb5Syz op->iplo_name); 318*ab25eeb5Syz else 319*ab25eeb5Syz stats.ipls_list[unit] = ip_pool_list[unit]; 3207663b816Sml } else 3217663b816Sml err = EINVAL; 3227663b816Sml if (err == 0) 3237663b816Sml err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); 3247663b816Sml return err; 3257663b816Sml } 3267663b816Sml 3277c478bd9Sstevel@tonic-gate 328*ab25eeb5Syz 3297c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3307c478bd9Sstevel@tonic-gate /* Function: ip_pool_find */ 3317c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 3327c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to the pool getting the new node. */ 3337c478bd9Sstevel@tonic-gate /* */ 3347c478bd9Sstevel@tonic-gate /* Find a matching pool inside the collection of pools for a particular */ 3357c478bd9Sstevel@tonic-gate /* device, indicated by the unit number. */ 3367c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3377c478bd9Sstevel@tonic-gate void *ip_pool_find(unit, name) 3387c478bd9Sstevel@tonic-gate int unit; 3397c478bd9Sstevel@tonic-gate char *name; 3407c478bd9Sstevel@tonic-gate { 3417c478bd9Sstevel@tonic-gate ip_pool_t *p; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) 344*ab25eeb5Syz if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) 3457c478bd9Sstevel@tonic-gate break; 3467c478bd9Sstevel@tonic-gate return p; 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3517c478bd9Sstevel@tonic-gate /* Function: ip_pool_findeq */ 3527c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 3537c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to the pool getting the new node. */ 354*ab25eeb5Syz /* addr(I) - pointer to address information to delete */ 3557c478bd9Sstevel@tonic-gate /* mask(I) - */ 3567c478bd9Sstevel@tonic-gate /* */ 3577c478bd9Sstevel@tonic-gate /* Searches for an exact match of an entry in the pool. */ 3587c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3597c478bd9Sstevel@tonic-gate ip_pool_node_t *ip_pool_findeq(ipo, addr, mask) 3607c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 3617663b816Sml addrfamily_t *addr, *mask; 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate struct radix_node *n; 364*ab25eeb5Syz SPL_INT(s); 3657c478bd9Sstevel@tonic-gate 366*ab25eeb5Syz SPL_NET(s); 367*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(ipo->ipo_head); 3687c478bd9Sstevel@tonic-gate n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); 369*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); 370*ab25eeb5Syz SPL_X(s); 3717c478bd9Sstevel@tonic-gate return (ip_pool_node_t *)n; 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3767c478bd9Sstevel@tonic-gate /* Function: ip_pool_search */ 377*ab25eeb5Syz /* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ 3787c478bd9Sstevel@tonic-gate /* Parameters: tptr(I) - pointer to the pool to search */ 3797c478bd9Sstevel@tonic-gate /* version(I) - IP protocol version (4 or 6) */ 3807c478bd9Sstevel@tonic-gate /* dptr(I) - pointer to address information */ 3817c478bd9Sstevel@tonic-gate /* */ 3827c478bd9Sstevel@tonic-gate /* Search the pool for a given address and return a search result. */ 3837c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 3847c478bd9Sstevel@tonic-gate int ip_pool_search(tptr, version, dptr) 3857c478bd9Sstevel@tonic-gate void *tptr; 3867c478bd9Sstevel@tonic-gate int version; 3877c478bd9Sstevel@tonic-gate void *dptr; 3887c478bd9Sstevel@tonic-gate { 3897c478bd9Sstevel@tonic-gate struct radix_node *rn; 3907c478bd9Sstevel@tonic-gate ip_pool_node_t *m; 3917c478bd9Sstevel@tonic-gate i6addr_t *addr; 3927c478bd9Sstevel@tonic-gate addrfamily_t v; 3937c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 3947c478bd9Sstevel@tonic-gate int rv; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate ipo = tptr; 3977c478bd9Sstevel@tonic-gate if (ipo == NULL) 3987c478bd9Sstevel@tonic-gate return -1; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate rv = 1; 4017c478bd9Sstevel@tonic-gate m = NULL; 4027c478bd9Sstevel@tonic-gate addr = (i6addr_t *)dptr; 4037c478bd9Sstevel@tonic-gate bzero(&v, sizeof(v)); 4047c478bd9Sstevel@tonic-gate v.adf_len = offsetof(addrfamily_t, adf_addr); 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate if (version == 4) { 4077c478bd9Sstevel@tonic-gate v.adf_len += sizeof(addr->in4); 4087c478bd9Sstevel@tonic-gate v.adf_addr.in4 = addr->in4; 4097c478bd9Sstevel@tonic-gate #ifdef USE_INET6 4107c478bd9Sstevel@tonic-gate } else if (version == 6) { 4117c478bd9Sstevel@tonic-gate v.adf_len += sizeof(addr->in6); 4127c478bd9Sstevel@tonic-gate v.adf_addr.in6 = addr->in6; 4137c478bd9Sstevel@tonic-gate #endif 4147c478bd9Sstevel@tonic-gate } else 4157c478bd9Sstevel@tonic-gate return -1; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate READ_ENTER(&ip_poolrw); 4187c478bd9Sstevel@tonic-gate 419*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(ipo->ipo_head); 4207c478bd9Sstevel@tonic-gate rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head); 421*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { 4247c478bd9Sstevel@tonic-gate m = (ip_pool_node_t *)rn; 4257c478bd9Sstevel@tonic-gate ipo->ipo_hits++; 4267c478bd9Sstevel@tonic-gate m->ipn_hits++; 4277c478bd9Sstevel@tonic-gate rv = m->ipn_info; 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate RWLOCK_EXIT(&ip_poolrw); 4307c478bd9Sstevel@tonic-gate return rv; 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4357c478bd9Sstevel@tonic-gate /* Function: ip_pool_insert */ 4367c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 4377c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to the pool getting the new node. */ 4387663b816Sml /* addr(I) - IPv4/6 address being added as a node */ 4397663b816Sml /* mask(I) - IPv4/6 netmask to with the node being added */ 4407c478bd9Sstevel@tonic-gate /* info(I) - extra information to store in this node. */ 4417c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) */ 4427c478bd9Sstevel@tonic-gate /* */ 4437c478bd9Sstevel@tonic-gate /* Add another node to the pool given by ipo. The three parameters passed */ 4447c478bd9Sstevel@tonic-gate /* in (addr, mask, info) shold all be stored in the node. */ 4457c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4467c478bd9Sstevel@tonic-gate int ip_pool_insert(ipo, addr, mask, info) 4477c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 4487663b816Sml addrfamily_t *addr, *mask; 4497c478bd9Sstevel@tonic-gate int info; 4507c478bd9Sstevel@tonic-gate { 4517c478bd9Sstevel@tonic-gate struct radix_node *rn; 4527c478bd9Sstevel@tonic-gate ip_pool_node_t *x; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate KMALLOC(x, ip_pool_node_t *); 4577c478bd9Sstevel@tonic-gate if (x == NULL) { 4587c478bd9Sstevel@tonic-gate return ENOMEM; 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate bzero(x, sizeof(*x)); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate x->ipn_info = info; 4647c478bd9Sstevel@tonic-gate (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); 4657c478bd9Sstevel@tonic-gate 4667663b816Sml bcopy(addr, &x->ipn_addr, sizeof(*addr)); 4677c478bd9Sstevel@tonic-gate x->ipn_addr.adf_len = sizeof(x->ipn_addr); 4687663b816Sml bcopy(mask, &x->ipn_mask, sizeof(*mask)); 4697c478bd9Sstevel@tonic-gate x->ipn_mask.adf_len = sizeof(x->ipn_mask); 4707c478bd9Sstevel@tonic-gate 471*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(ipo->ipo_head); 4727c478bd9Sstevel@tonic-gate rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask, 4737c478bd9Sstevel@tonic-gate ipo->ipo_head, x->ipn_nodes); 474*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); 4757c478bd9Sstevel@tonic-gate #ifdef DEBUG_POOL 4767c478bd9Sstevel@tonic-gate printf("Added %p at %p\n", x, rn); 4777c478bd9Sstevel@tonic-gate #endif 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate if (rn == NULL) { 4807c478bd9Sstevel@tonic-gate KFREE(x); 4817c478bd9Sstevel@tonic-gate return ENOMEM; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate x->ipn_next = ipo->ipo_list; 4857c478bd9Sstevel@tonic-gate x->ipn_pnext = &ipo->ipo_list; 4867c478bd9Sstevel@tonic-gate if (ipo->ipo_list != NULL) 4877c478bd9Sstevel@tonic-gate ipo->ipo_list->ipn_pnext = &x->ipn_next; 4887c478bd9Sstevel@tonic-gate ipo->ipo_list = x; 4897c478bd9Sstevel@tonic-gate 49008254dd3Syz ipoolstat.ipls_nodes++; 49108254dd3Syz 4927c478bd9Sstevel@tonic-gate return 0; 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4977c478bd9Sstevel@tonic-gate /* Function: ip_pool_create */ 4987c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 4997c478bd9Sstevel@tonic-gate /* Parameters: op(I) - pointer to iplookup struct with call details */ 5007c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) */ 5017c478bd9Sstevel@tonic-gate /* */ 5027c478bd9Sstevel@tonic-gate /* Creates a new group according to the paramters passed in via the */ 5037c478bd9Sstevel@tonic-gate /* iplookupop structure. Does not check to see if the group already exists */ 5047c478bd9Sstevel@tonic-gate /* when being inserted - assume this has already been done. If the pool is */ 5057c478bd9Sstevel@tonic-gate /* marked as being anonymous, give it a new, unique, identifier. Call any */ 5067c478bd9Sstevel@tonic-gate /* other functions required to initialise the structure. */ 5077c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 5087c478bd9Sstevel@tonic-gate int ip_pool_create(op) 5097c478bd9Sstevel@tonic-gate iplookupop_t *op; 5107c478bd9Sstevel@tonic-gate { 5117c478bd9Sstevel@tonic-gate char name[FR_GROUPLEN]; 5127c478bd9Sstevel@tonic-gate int poolnum, unit; 5137c478bd9Sstevel@tonic-gate ip_pool_t *h; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate KMALLOC(h, ip_pool_t *); 5187c478bd9Sstevel@tonic-gate if (h == NULL) 5197c478bd9Sstevel@tonic-gate return ENOMEM; 5207c478bd9Sstevel@tonic-gate bzero(h, sizeof(*h)); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if (rn_inithead((void **)&h->ipo_head, 5237c478bd9Sstevel@tonic-gate offsetof(addrfamily_t, adf_addr) << 3) == 0) { 5247c478bd9Sstevel@tonic-gate KFREE(h); 5257c478bd9Sstevel@tonic-gate return ENOMEM; 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate unit = op->iplo_unit; 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate if ((op->iplo_arg & IPOOL_ANON) != 0) { 5317c478bd9Sstevel@tonic-gate ip_pool_t *p; 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate poolnum = IPOOL_ANON; 534*ab25eeb5Syz 535*ab25eeb5Syz #if defined(SNPRINTF) && defined(_KERNEL) 536*ab25eeb5Syz (void)SNPRINTF(name, sizeof(name), "%x", poolnum); 537*ab25eeb5Syz #else 5387c478bd9Sstevel@tonic-gate (void)sprintf(name, "%x", poolnum); 539*ab25eeb5Syz #endif 540*ab25eeb5Syz 5417c478bd9Sstevel@tonic-gate for (p = ip_pool_list[unit]; p != NULL; ) { 542*ab25eeb5Syz if (strncmp(name, p->ipo_name, 543*ab25eeb5Syz sizeof(p->ipo_name)) == 0) { 5447c478bd9Sstevel@tonic-gate poolnum++; 545*ab25eeb5Syz #if defined(SNPRINTF) && defined(_KERNEL) 546*ab25eeb5Syz (void)SNPRINTF(name, sizeof(name), "%x", poolnum); 547*ab25eeb5Syz #else 5487c478bd9Sstevel@tonic-gate (void)sprintf(name, "%x", poolnum); 549*ab25eeb5Syz #endif 5507c478bd9Sstevel@tonic-gate p = ip_pool_list[unit]; 5517c478bd9Sstevel@tonic-gate } else 5527c478bd9Sstevel@tonic-gate p = p->ipo_next; 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); 5567c478bd9Sstevel@tonic-gate } else { 5577c478bd9Sstevel@tonic-gate (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate h->ipo_ref = 1; 5617c478bd9Sstevel@tonic-gate h->ipo_list = NULL; 5627c478bd9Sstevel@tonic-gate h->ipo_unit = unit; 5637c478bd9Sstevel@tonic-gate h->ipo_next = ip_pool_list[unit]; 5647c478bd9Sstevel@tonic-gate if (ip_pool_list[unit] != NULL) 5657c478bd9Sstevel@tonic-gate ip_pool_list[unit]->ipo_pnext = &h->ipo_next; 5667c478bd9Sstevel@tonic-gate h->ipo_pnext = &ip_pool_list[unit]; 5677c478bd9Sstevel@tonic-gate ip_pool_list[unit] = h; 56808254dd3Syz 5697c478bd9Sstevel@tonic-gate ipoolstat.ipls_pools++; 57008254dd3Syz 5717c478bd9Sstevel@tonic-gate return 0; 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 5767c478bd9Sstevel@tonic-gate /* Function: ip_pool_remove */ 5777c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 5787c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to the pool to remove the node from. */ 5797c478bd9Sstevel@tonic-gate /* ipe(I) - address being deleted as a node */ 5807c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) */ 5817c478bd9Sstevel@tonic-gate /* */ 5827c478bd9Sstevel@tonic-gate /* Add another node to the pool given by ipo. The three parameters passed */ 5837c478bd9Sstevel@tonic-gate /* in (addr, mask, info) shold all be stored in the node. */ 5847c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 5857c478bd9Sstevel@tonic-gate int ip_pool_remove(ipo, ipe) 5867c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 5877c478bd9Sstevel@tonic-gate ip_pool_node_t *ipe; 5887c478bd9Sstevel@tonic-gate { 5897c478bd9Sstevel@tonic-gate ip_pool_node_t **ipp, *n; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) { 5947c478bd9Sstevel@tonic-gate if (ipe == n) { 5957c478bd9Sstevel@tonic-gate *n->ipn_pnext = n->ipn_next; 5967c478bd9Sstevel@tonic-gate if (n->ipn_next) 5977c478bd9Sstevel@tonic-gate n->ipn_next->ipn_pnext = n->ipn_pnext; 5987c478bd9Sstevel@tonic-gate break; 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate if (n == NULL) 6037c478bd9Sstevel@tonic-gate return ENOENT; 6047c478bd9Sstevel@tonic-gate 605*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(ipo->ipo_head); 6067c478bd9Sstevel@tonic-gate ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, 6077c478bd9Sstevel@tonic-gate ipo->ipo_head); 608*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); 6097c478bd9Sstevel@tonic-gate KFREE(n); 61008254dd3Syz 611*ab25eeb5Syz ipoolstat.ipls_nodes--; 61208254dd3Syz 6137c478bd9Sstevel@tonic-gate return 0; 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 6187c478bd9Sstevel@tonic-gate /* Function: ip_pool_destroy */ 6197c478bd9Sstevel@tonic-gate /* Returns: int - 0 = success, else error */ 6207c478bd9Sstevel@tonic-gate /* Parameters: op(I) - information about the pool to remove */ 6217c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ 6227c478bd9Sstevel@tonic-gate /* */ 6237c478bd9Sstevel@tonic-gate /* Search for a pool using paramters passed in and if it's not otherwise */ 6247c478bd9Sstevel@tonic-gate /* busy, free it. */ 6257c478bd9Sstevel@tonic-gate /* */ 6267c478bd9Sstevel@tonic-gate /* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ 6277c478bd9Sstevel@tonic-gate /* may not be initialised, we can't use an ASSERT to enforce the locking */ 6287c478bd9Sstevel@tonic-gate /* assertion that one of the two (ip_poolrw,ipf_global) is held. */ 6297c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 6307c478bd9Sstevel@tonic-gate int ip_pool_destroy(op) 6317c478bd9Sstevel@tonic-gate iplookupop_t *op; 6327c478bd9Sstevel@tonic-gate { 6337c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate ipo = ip_pool_find(op->iplo_unit, op->iplo_name); 6367c478bd9Sstevel@tonic-gate if (ipo == NULL) 6377c478bd9Sstevel@tonic-gate return ESRCH; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate if (ipo->ipo_ref != 1) 6407c478bd9Sstevel@tonic-gate return EBUSY; 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate ip_pool_free(ipo); 6437c478bd9Sstevel@tonic-gate return 0; 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate 647*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 648*ab25eeb5Syz /* Function: ip_pool_flush */ 649*ab25eeb5Syz /* Returns: int - number of pools deleted */ 650*ab25eeb5Syz /* Parameters: fp(I) - which pool(s) to flush */ 651*ab25eeb5Syz /* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ 652*ab25eeb5Syz /* */ 653*ab25eeb5Syz /* Free all pools associated with the device that matches the unit number */ 654*ab25eeb5Syz /* passed in with operation. */ 655*ab25eeb5Syz /* */ 656*ab25eeb5Syz /* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ 657*ab25eeb5Syz /* may not be initialised, we can't use an ASSERT to enforce the locking */ 658*ab25eeb5Syz /* assertion that one of the two (ip_poolrw,ipf_global) is held. */ 659*ab25eeb5Syz /* ------------------------------------------------------------------------ */ 660*ab25eeb5Syz int ip_pool_flush(fp) 661*ab25eeb5Syz iplookupflush_t *fp; 662*ab25eeb5Syz { 663*ab25eeb5Syz int i, num = 0, unit, err; 664*ab25eeb5Syz ip_pool_t *p, *q; 665*ab25eeb5Syz iplookupop_t op; 666*ab25eeb5Syz 667*ab25eeb5Syz unit = fp->iplf_unit; 668*ab25eeb5Syz 669*ab25eeb5Syz for (i = 0; i <= IPL_LOGMAX; i++) { 670*ab25eeb5Syz if (unit != IPLT_ALL && i != unit) 671*ab25eeb5Syz continue; 672*ab25eeb5Syz for (q = ip_pool_list[i]; (p = q) != NULL; ) { 673*ab25eeb5Syz op.iplo_unit = i; 674*ab25eeb5Syz (void)strncpy(op.iplo_name, p->ipo_name, 675*ab25eeb5Syz sizeof(op.iplo_name)); 676*ab25eeb5Syz q = p->ipo_next; 677*ab25eeb5Syz err = ip_pool_destroy(&op); 678*ab25eeb5Syz if (err == 0) 679*ab25eeb5Syz num++; 680*ab25eeb5Syz else 681*ab25eeb5Syz break; 682*ab25eeb5Syz } 683*ab25eeb5Syz } 684*ab25eeb5Syz return num; 685*ab25eeb5Syz } 686*ab25eeb5Syz 687*ab25eeb5Syz 6887c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 6897c478bd9Sstevel@tonic-gate /* Function: ip_pool_free */ 6907c478bd9Sstevel@tonic-gate /* Returns: void */ 6917c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to pool structure */ 6927c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ 6937c478bd9Sstevel@tonic-gate /* */ 6947c478bd9Sstevel@tonic-gate /* Deletes the pool strucutre passed in from the list of pools and deletes */ 6957c478bd9Sstevel@tonic-gate /* all of the address information stored in it, including any tree data */ 6967c478bd9Sstevel@tonic-gate /* structures also allocated. */ 6977c478bd9Sstevel@tonic-gate /* */ 6987c478bd9Sstevel@tonic-gate /* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ 6997c478bd9Sstevel@tonic-gate /* may not be initialised, we can't use an ASSERT to enforce the locking */ 7007c478bd9Sstevel@tonic-gate /* assertion that one of the two (ip_poolrw,ipf_global) is held. */ 7017c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 7027c478bd9Sstevel@tonic-gate void ip_pool_free(ipo) 7037c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate ip_pool_node_t *n; 7067c478bd9Sstevel@tonic-gate 707*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(ipo->ipo_head); 7087c478bd9Sstevel@tonic-gate while ((n = ipo->ipo_list) != NULL) { 7097c478bd9Sstevel@tonic-gate ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, 7107c478bd9Sstevel@tonic-gate ipo->ipo_head); 711*ab25eeb5Syz 7127c478bd9Sstevel@tonic-gate *n->ipn_pnext = n->ipn_next; 7137c478bd9Sstevel@tonic-gate if (n->ipn_next) 7147c478bd9Sstevel@tonic-gate n->ipn_next->ipn_pnext = n->ipn_pnext; 715*ab25eeb5Syz 7167c478bd9Sstevel@tonic-gate KFREE(n); 71708254dd3Syz 71808254dd3Syz ipoolstat.ipls_nodes--; 7197c478bd9Sstevel@tonic-gate } 720*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate ipo->ipo_list = NULL; 7237c478bd9Sstevel@tonic-gate if (ipo->ipo_next != NULL) 7247c478bd9Sstevel@tonic-gate ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; 7257c478bd9Sstevel@tonic-gate *ipo->ipo_pnext = ipo->ipo_next; 7267c478bd9Sstevel@tonic-gate rn_freehead(ipo->ipo_head); 7277c478bd9Sstevel@tonic-gate KFREE(ipo); 72808254dd3Syz 72908254dd3Syz ipoolstat.ipls_pools--; 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 7347c478bd9Sstevel@tonic-gate /* Function: ip_pool_deref */ 7357c478bd9Sstevel@tonic-gate /* Returns: void */ 7367c478bd9Sstevel@tonic-gate /* Parameters: ipo(I) - pointer to pool structure */ 7377c478bd9Sstevel@tonic-gate /* Locks: WRITE(ip_poolrw) */ 7387c478bd9Sstevel@tonic-gate /* */ 7397c478bd9Sstevel@tonic-gate /* Drop the number of known references to this pool structure by one and if */ 7407c478bd9Sstevel@tonic-gate /* we arrive at zero known references, free it. */ 7417c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 7427c478bd9Sstevel@tonic-gate void ip_pool_deref(ipo) 7437c478bd9Sstevel@tonic-gate ip_pool_t *ipo; 7447c478bd9Sstevel@tonic-gate { 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate ipo->ipo_ref--; 7497c478bd9Sstevel@tonic-gate if (ipo->ipo_ref == 0) 7507c478bd9Sstevel@tonic-gate ip_pool_free(ipo); 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate 754*ab25eeb5Syz # if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \ 755*ab25eeb5Syz !defined(__hpux) && !defined(__sgi)) 7567c478bd9Sstevel@tonic-gate static int 7577c478bd9Sstevel@tonic-gate rn_freenode(struct radix_node *n, void *p) 7587c478bd9Sstevel@tonic-gate { 7597c478bd9Sstevel@tonic-gate struct radix_node_head *rnh = p; 7607c478bd9Sstevel@tonic-gate struct radix_node *d; 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); 7637c478bd9Sstevel@tonic-gate if (d != NULL) { 7647c478bd9Sstevel@tonic-gate FreeS(d, max_keylen + 2 * sizeof (*d)); 7657c478bd9Sstevel@tonic-gate } 7667c478bd9Sstevel@tonic-gate return 0; 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate void 7717c478bd9Sstevel@tonic-gate rn_freehead(rnh) 7727c478bd9Sstevel@tonic-gate struct radix_node_head *rnh; 7737c478bd9Sstevel@tonic-gate { 7747c478bd9Sstevel@tonic-gate 775*ab25eeb5Syz RADIX_NODE_HEAD_LOCK(rnh); 776*ab25eeb5Syz (*rnh->rnh_walktree)(rnh, rn_freenode, rnh); 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate rnh->rnh_addaddr = NULL; 7797c478bd9Sstevel@tonic-gate rnh->rnh_deladdr = NULL; 7807c478bd9Sstevel@tonic-gate rnh->rnh_matchaddr = NULL; 7817c478bd9Sstevel@tonic-gate rnh->rnh_lookup = NULL; 7827c478bd9Sstevel@tonic-gate rnh->rnh_walktree = NULL; 783*ab25eeb5Syz RADIX_NODE_HEAD_UNLOCK(rnh); 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate Free(rnh); 7867c478bd9Sstevel@tonic-gate } 7877c478bd9Sstevel@tonic-gate # endif 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOOKUP */ 790