ip_pool.c revision de22af4e795d4c10cbff9a60ec725aab46c03afe
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Copyright (C) 1993-2001, 2003 by Darren Reed.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * See the IPFILTER.LICENCE file for details on licencing.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(KERNEL) || defined(_KERNEL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# undef KERNEL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# undef _KERNEL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# define KERNEL 1
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# define _KERNEL 1
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(__osf__)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# define _PROTO_NET_H_
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/errno.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/types.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/param.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/file.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if !defined(_KERNEL) && !defined(__KERNEL__)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <stdio.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <stdlib.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <string.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# define _KERNEL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# ifdef __OpenBSD__
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestruct file;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/uio.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# undef _KERNEL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/systm.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/proc.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/time.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if !defined(linux)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/protosw.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <sys/socket.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/mbuf.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(__SVR4) || defined(__svr4__)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/filio.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/byteorder.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# ifdef _KERNEL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/dditypes.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/stream.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/kmem.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <sys/malloc.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse defined(__hpux) || defined(__sgi))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# ifdef __osf__
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include <net/radix.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# include "radix_ipf_local.h"
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# define _RADIX_H_
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <net/if.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include <netinet/in.h>
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include "netinet/ipf_stack.h"
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include "netinet/ip_compat.h"
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include "netinet/ip_fil.h"
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#include "netinet/ip_pool.h"
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ((BSD >= 198911) && !defined(__osf__) && \
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse !defined(__hpux) && !defined(__sgi))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int rn_freenode __P((struct radix_node *, void *));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* END OF INCLUDES */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if !defined(lint)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.14 2005/06/12 07:18:26 darrenr Exp $";
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef IPFILTER_LOOKUP
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Binary tree routines from Sedgewick and enhanced to do ranges of addresses.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * NOTE: Insertion *MUST* be from greatest range to least for it to work!
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * These should be replaced, eventually, by something else - most notably a
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * interval searching method. The important feature is to be able to find
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * the best match.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * So why not use a radix tree for this? As the first line implies, it
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * has been written to work with a _range_ of addresses. A range is not
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * necessarily a match with any given netmask so what we end up dealing
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * with is an interval tree. Implementations of these are hard to find
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * and the one herein is far from bug free.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Sigh, in the end I became convinced that the bugs the code contained did
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * not make it worthwhile not using radix trees. For now the radix tree from
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * 4.4 BSD is used, but this is not viewed as a long term solution.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef TEST_POOL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid treeprint __P((ip_pool_t *));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassemain(argc, argv)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int argc;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char *argv[];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse addrfamily_t a, b;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse iplookupop_t op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse i6addr_t ip;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse fr_info_t fin;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_INIT(&ifs->ifs_ip_poolrw, "poolrw");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_init(ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&a, sizeof(a));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&b, sizeof(b));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&ip, sizeof(ip));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&op, sizeof(op));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse strcpy(op.iplo_name, "0");
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ip_pool_create(&op, ifs) == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = ip_pool_find(0, "0", ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a010203;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xffffffff;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a000000;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xff000000;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 0, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 0, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a010100;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xffffff00;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a010200;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xffffff00;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 0, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 0, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a010000;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xffff0000;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse a.adf_addr.in4.s_addr = 0x0a01020f;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse b.adf_addr.in4.s_addr = 0xffffffff;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_insert(ipo, &a, &b, 1, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef DEBUG_POOL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassetreeprint(ipo);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse fin.fin_plen = 20;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a00aabb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (0)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a000001;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (0)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a000101;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (0)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a010001;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (1)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a010101;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (1)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a010201;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (0)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a010203;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (1)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0a01020f;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (1)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip.in4.s_addr = 0x0b00aabb;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("search(%#x) = %d (-1)\n", ip.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_search(ipo, 4, &ip, &fin, ifs));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef DEBUG_POOL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassetreeprint(ipo);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_fini(ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassetreeprint(ipo)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t *c;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (c = ipo->ipo_list; c != NULL; c = c->ipn_next)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n",
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c->ipn_mask.adf_addr.in4.s_addr,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse c->ipn_info, c->ipn_hits);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif /* TEST_POOL */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_init */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Initialise the routing table data structures where required. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_init(ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero(&ifs->ifs_ipoolstat, sizeof (ip_pool_stat_t));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if !defined(_KERNEL) || ((BSD < 199306) && (SOLARIS2 < 10))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rn_init();
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_fini */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ipf_global) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Clean up all the pool data structures allocated and call the cleanup */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* function for the radix tree that supports the pools. ip_pool_destroy() is*/
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* used to delete the pools one by one to ensure they're properly freed up. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid ip_pool_fini(ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *p, *q;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse iplookupop_t op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ASSERT(rw_read_locked(&ifs->ifs_ipf_global.ipf_lk) == 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i <= IPL_LOGMAX; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (q = ifs->ifs_ip_pool_list[i]; (p = q) != NULL; ) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse op.iplo_unit = i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)strncpy(op.iplo_name, p->ipo_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof(op.iplo_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse q = p->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) ip_pool_destroy(&op, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if !defined(_KERNEL) || ((BSD < 199306) && (SOLARIS2 < 10))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rn_fini();
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_statistics */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: op(I) - pointer to lookup operation arguments */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Copy the current statistics out into user space, collecting pool list */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* pointers as appropriate for later use. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_statistics(op, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseiplookupop_t *op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_stat_t stats;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int unit, i, err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (op->iplo_size != sizeof(ip_pool_stat_t))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return EINVAL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bcopy((char *)&ifs->ifs_ipoolstat, (char *)&stats, sizeof(stats));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse unit = op->iplo_unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (unit == IPL_LOGALL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i < IPL_LOGSIZE; i++)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse stats.ipls_list[i] = ifs->ifs_ip_pool_list[i];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (unit >= 0 && unit < IPL_LOGSIZE) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (op->iplo_name[0] != '\0')
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse stats.ipls_list[unit] = ip_pool_find(unit,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse op->iplo_name, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse stats.ipls_list[unit] = ifs->ifs_ip_pool_list[unit];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = EINVAL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = COPYOUT(&stats, op->iplo_struct, sizeof(stats));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_find */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to the pool getting the new node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Find a matching pool inside the collection of pools for a particular */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* device, indicated by the unit number. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid *ip_pool_find(unit, name, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassechar *name;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *p;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (p = ifs->ifs_ip_pool_list[unit]; p != NULL; p = p->ipo_next)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return p;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_findeq */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to the pool getting the new node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* addr(I) - pointer to address information to delete */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* mask(I) - */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Searches for an exact match of an entry in the pool. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_node_t *ip_pool_findeq(ipo, addr, mask)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseaddrfamily_t *addr, *mask;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node *n;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse SPL_INT(s);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse SPL_NET(s);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse SPL_X(s);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return (ip_pool_node_t *)n;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_search */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: tptr(I) - pointer to the pool to search */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* version(I) - IP protocol version (4 or 6) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* dptr(I) - pointer to address information */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* fin - pointer to packet information */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ifs - ipf stack instance */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Search the pool for a given address and return a search result. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_search(tptr, version, dptr, fin, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid *tptr;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint version;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid *dptr;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassefr_info_t *fin;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node *rn;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t *m;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse i6addr_t *addr;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse addrfamily_t v;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int rv;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = tptr;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return -1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rv = 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse m = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse addr = (i6addr_t *)dptr;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero(&v, sizeof(v));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse v.adf_len = offsetof(addrfamily_t, adf_addr);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (version == 4) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse v.adf_len += sizeof(addr->in4);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse v.adf_addr.in4 = addr->in4;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef USE_INET6
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else if (version == 6) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse v.adf_len += sizeof(addr->in6);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse v.adf_addr.in6 = addr->in6;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return -1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse READ_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse m = (ip_pool_node_t *)rn;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_hits++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse m->ipn_hits++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse m->ipn_bytes += fin->fin_plen;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rv = m->ipn_info;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return rv;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_insert */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to the pool getting the new node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* addr(I) - IPv4/6 address being added as a node */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* mask(I) - IPv4/6 netmask to with the node being added */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* info(I) - extra information to store in this node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Add another node to the pool given by ipo. The three parameters passed */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* in (addr, mask, info) shold all be stored in the node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_insert(ipo, addr, mask, info, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseaddrfamily_t *addr, *mask;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint info;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node *rn;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t *x;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ASSERT(rw_read_locked(&ifs->ifs_ip_poolrw.ipf_lk) == 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KMALLOC(x, ip_pool_node_t *);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (x == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ENOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero(x, sizeof(*x));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_info = info;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bcopy(addr, &x->ipn_addr, sizeof(*addr));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_addr.adf_len = sizeof(x->ipn_addr);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bcopy(mask, &x->ipn_mask, sizeof(*mask));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_mask.adf_len = sizeof(x->ipn_mask);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_head, x->ipn_nodes);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#ifdef DEBUG_POOL
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse printf("Added %p at %p\n", x, rn);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rn == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(x);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ENOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_ref = 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_next = ipo->ipo_list;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse x->ipn_pnext = &ipo->ipo_list;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo->ipo_list != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_list->ipn_pnext = &x->ipn_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_list = x;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_nodes++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_create */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: op(I) - pointer to iplookup struct with call details */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Creates a new group according to the paramters passed in via the */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* iplookupop structure. Does not check to see if the group already exists */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* when being inserted - assume this has already been done. If the pool is */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* marked as being anonymous, give it a new, unique, identifier. Call any */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* other functions required to initialise the structure. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_create(op, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseiplookupop_t *op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse char name[FR_GROUPLEN];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int poolnum, unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *h;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ASSERT(rw_read_locked(&ifs->ifs_ip_poolrw.ipf_lk) == 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KMALLOC(h, ip_pool_t *);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (h == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ENOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero(h, sizeof(*h));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (rn_inithead((void **)&h->ipo_head,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse offsetof(addrfamily_t, adf_addr) << 3) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(h);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ENOMEM;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse unit = op->iplo_unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if ((op->iplo_arg & IPOOL_ANON) != 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *p;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse poolnum = IPOOL_ANON;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(SNPRINTF) && defined(_KERNEL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)SNPRINTF(name, sizeof(name), "%x", poolnum);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)sprintf(name, "%x", poolnum);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (p = ifs->ifs_ip_pool_list[unit]; p != NULL; ) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (strncmp(name, p->ipo_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof(p->ipo_name)) == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse poolnum++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#if defined(SNPRINTF) && defined(_KERNEL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)SNPRINTF(name, sizeof(name), "%x", poolnum);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)sprintf(name, "%x", poolnum);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse p = ifs->ifs_ip_pool_list[unit];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse p = p->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse h->ipo_ref = 1;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse h->ipo_list = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse h->ipo_unit = unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse h->ipo_next = ifs->ifs_ip_pool_list[unit];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ifs->ifs_ip_pool_list[unit] != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ip_pool_list[unit]->ipo_pnext = &h->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse h->ipo_pnext = &ifs->ifs_ip_pool_list[unit];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ip_pool_list[unit] = h;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_pools++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_remove */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to the pool to remove the node from. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ipe(I) - address being deleted as a node */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Add another node to the pool given by ipo. The three parameters passed */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* in (addr, mask, info) shold all be stored in the node. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_remove(ipo, ipe, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_node_t *ipe;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t **ipp, *n;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ASSERT(rw_read_locked(&ifs->ifs_ip_poolrw.ipf_lk) == 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipe == n) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *n->ipn_pnext = n->ipn_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (n->ipn_next)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse n->ipn_next->ipn_pnext = n->ipn_pnext;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (n == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ENOENT;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_head);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(n);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_nodes--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_destroy */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - 0 = success, else error */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: op(I) - information about the pool to remove */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Search for a pool using paramters passed in and if it's not otherwise */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* busy, free it. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* may not be initialised, we can't use an ASSERT to enforce the locking */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* assertion that one of the two (ip_poolrw,ipf_global) is held. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_destroy(op, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseiplookupop_t *op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = ip_pool_find(op->iplo_unit, op->iplo_name, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return ESRCH;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo->ipo_ref != 1)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return EBUSY;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_free(ipo, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_flush */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: int - number of pools deleted */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: fp(I) - which pool(s) to flush */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Free all pools associated with the device that matches the unit number */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* passed in with operation. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* may not be initialised, we can't use an ASSERT to enforce the locking */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* assertion that one of the two (ip_poolrw,ipf_global) is held. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_flush(fp, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseiplookupflush_t *fp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int i, num = 0, unit, err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *p, *q;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse iplookupop_t op;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse unit = fp->iplf_unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (i = 0; i <= IPL_LOGMAX; i++) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (unit != IPLT_ALL && i != unit)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse continue;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse for (q = ifs->ifs_ip_pool_list[i]; (p = q) != NULL; ) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse op.iplo_unit = i;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (void)strncpy(op.iplo_name, p->ipo_name,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse sizeof(op.iplo_name));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse q = p->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = ip_pool_destroy(&op, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse num++;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return num;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_free */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: void */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to pool structure */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Deletes the pool strucutre passed in from the list of pools and deletes */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* all of the address information stored in it, including any tree data */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* structures also allocated. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* may not be initialised, we can't use an ASSERT to enforce the locking */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* assertion that one of the two (ip_poolrw,ipf_global) is held. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid ip_pool_free(ipo, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t *n;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse while ((n = ipo->ipo_list) != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask,
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_head);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *n->ipn_pnext = n->ipn_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (n->ipn_next)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse n->ipn_next->ipn_pnext = n->ipn_pnext;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(n);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_nodes--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_list = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo->ipo_next != NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_next->ipo_pnext = ipo->ipo_pnext;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *ipo->ipo_pnext = ipo->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rn_freehead(ipo->ipo_head);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(ipo);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_pools--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Function: ip_pool_deref */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Returns: void */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Parameters: ipo(I) - pointer to pool structure */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Locks: WRITE(ip_poolrw) */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* Drop the number of known references to this pool structure by one and if */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* we arrive at zero known references, free it. */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse/* ------------------------------------------------------------------------ */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid ip_pool_deref(ipo, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_t *ipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ASSERT(rw_read_locked(&ifs->ifs_ip_poolrw.ipf_lk) == 0);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo->ipo_ref--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo->ipo_ref == 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_free(ipo, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid ip_pool_node_deref(ipn, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseip_pool_node_t *ipn;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipn->ipn_ref--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipn->ipn_ref == 0) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse KFREE(ipn);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ifs->ifs_ipoolstat.ipls_nodes--;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint ip_pool_getnext(token, ilp, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipftoken_t *token;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipflookupiter_t *ilp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_t *node, zn, *nextnode;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_t *ipo, zp, *nextipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse int err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse node = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextnode = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextipo = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse READ_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Get "previous" entry from the token and find the next entry.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse *
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * If we found an entry, add a reference to it and update the token.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Otherwise, zero out data to be returned and NULL out token.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (ilp->ili_otype)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_LIST :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = token->ipt_data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextipo = ifs->ifs_ip_pool_list[(int)ilp->ili_unit];
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextipo = ipo->ipo_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (nextipo != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ATOMIC_INC(nextipo->ipo_ref);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse token->ipt_data = nextipo;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&zp, sizeof(zp));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextipo = &zp;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse token->ipt_data = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_NODE :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse node = token->ipt_data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (node == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = ip_pool_find(ilp->ili_unit, ilp->ili_name, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = ESRCH;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextnode = ipo->ipo_list;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipo = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextnode = node->ipn_next;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (nextnode != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ATOMIC_INC(nextnode->ipn_ref);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse token->ipt_data = nextnode;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse bzero((char *)&zn, sizeof(zn));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse nextnode = &zn;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse token->ipt_data = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = EINVAL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Now that we have ref, it's save to give up lock.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err != 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse /*
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse * Copy out the data and update the references and token as needed.
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (ilp->ili_otype)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_LIST :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = COPYOUT(nextipo, ilp->ili_data, sizeof(*nextipo));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err != 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = EFAULT;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (token->ipt_data == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipf_freetoken(token, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (ipo != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse WRITE_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_deref(ipo, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (nextipo->ipo_next == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipf_freetoken(token, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_NODE :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (err != 0)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse err = EFAULT;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (token->ipt_data == NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipf_freetoken(token, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse } else {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (node != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse WRITE_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_deref(node, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (nextnode->ipn_next == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ipf_freetoken(token, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return err;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid ip_pool_iterderef(otype, unit, data, ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseu_int otype;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseint unit;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid *data;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasseipf_stack_t *ifs;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (data == NULL)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (unit < 0 || unit > IPL_LOGMAX)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse switch (otype)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_LIST :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse WRITE_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_deref((ip_pool_t *)data, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse case IPFLOOKUPITER_NODE :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse WRITE_ENTER(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse ip_pool_node_deref((ip_pool_node_t *)data, ifs);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse RWLOCK_EXIT(&ifs->ifs_ip_poolrw);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse default :
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse break;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse !defined(__hpux) && !defined(__sgi))
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassestatic int
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassern_freenode(struct radix_node *n, void *p, ipf_stack_t *ifs)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node_head *rnh = p;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node *d;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse d = rnh->rnh_deladdr(n->rn_key, NULL, rnh);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse if (d != NULL) {
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse FreeS(d, ifs->ifs_max_keylen + 2 * sizeof (*d));
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse }
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse return 0;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassevoid
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagassern_freehead(rnh)
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse struct radix_node_head *rnh;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse{
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse (*rnh->rnh_walktree)(rnh, rn_freenode, rnh);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rnh->rnh_addaddr = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rnh->rnh_deladdr = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rnh->rnh_matchaddr = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rnh->rnh_lookup = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse rnh->rnh_walktree = NULL;
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse Free(rnh);
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse}
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse# endif
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse#endif /* IPFILTER_LOOKUP */
f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2Glenn Lagasse