diff options
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_auth.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_auth.c | 960 |
1 files changed, 612 insertions, 348 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c index fcd891f..5a2ebec 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ b/sys/contrib/ipfilter/netinet/ip_auth.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -19,6 +19,9 @@ #if !defined(_KERNEL) # include <stdio.h> # include <stdlib.h> +# ifdef _STDC_C99 +# include <stdbool.h> +# endif # include <string.h> # define _KERNEL # ifdef __OpenBSD__ @@ -52,7 +55,7 @@ struct file; # include <sys/stream.h> # include <sys/kmem.h> #endif -#if (defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802) || \ +#if (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802)) || \ (defined(__FreeBSD_version) &&(__FreeBSD_version >= 400000)) # include <sys/queue.h> #endif @@ -62,11 +65,14 @@ struct file; #if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) # include <sys/proc.h> #endif +#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 400000) && \ + !defined(_KERNEL) +# include <stdbool.h> +#endif #include <net/if.h> #ifdef sun # include <net/af.h> #endif -#include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -125,71 +131,249 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif + +typedef struct ipf_auth_softc_s { #if SOLARIS && defined(_KERNEL) -extern kcondvar_t ipfauthwait; -extern struct pollhead iplpollhead[IPL_LOGSIZE]; + kcondvar_t ipf_auth_wait; #endif /* SOLARIS */ #if defined(linux) && defined(_KERNEL) -wait_queue_head_t fr_authnext_linux; + wait_queue_head_t ipf_auth_next_linux; #endif + ipfrwlock_t ipf_authlk; + ipfmutex_t ipf_auth_mx; + int ipf_auth_size; + int ipf_auth_used; + int ipf_auth_replies; + int ipf_auth_defaultage; + int ipf_auth_lock; + ipf_authstat_t ipf_auth_stats; + frauth_t *ipf_auth; + mb_t **ipf_auth_pkts; + int ipf_auth_start; + int ipf_auth_end; + int ipf_auth_next; + frauthent_t *ipf_auth_entries; + frentry_t *ipf_auth_ip; + frentry_t *ipf_auth_rules; +} ipf_auth_softc_t; + + +static void ipf_auth_deref __P((frauthent_t **)); +static void ipf_auth_deref_unlocked __P((ipf_auth_softc_t *, frauthent_t **)); +static int ipf_auth_geniter __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *, ipfobj_t *)); +static int ipf_auth_reply __P((ipf_main_softc_t *, ipf_auth_softc_t *, char *)); +static int ipf_auth_wait __P((ipf_main_softc_t *, ipf_auth_softc_t *, char *)); +static int ipf_auth_flush __P((void *)); + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_main_load */ +/* Returns: int - 0 == success, else error */ +/* Parameters: None */ +/* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_main_load() +{ + return 0; +} -int fr_authsize = FR_NUMAUTH; -int fr_authused = 0; -int fr_defaultauthage = 600; -int fr_auth_lock = 0; -int fr_auth_init = 0; -fr_authstat_t fr_authstats; -static frauth_t *fr_auth = NULL; -mb_t **fr_authpkts = NULL; -int fr_authstart = 0, fr_authend = 0, fr_authnext = 0; -frauthent_t *fae_list = NULL; -frentry_t *ipauth = NULL, - *fr_authlist = NULL; - -void fr_authderef __P((frauthent_t **)); -int fr_authgeniter __P((ipftoken_t *, ipfgeniter_t *)); -int fr_authreply __P((char *)); -int fr_authwait __P((char *)); /* ------------------------------------------------------------------------ */ -/* Function: fr_authinit */ +/* Function: ipf_auth_main_unload */ /* Returns: int - 0 == success, else error */ /* Parameters: None */ /* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_main_unload() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_create */ +/* Returns: int - NULL = failure, else success */ +/* Parameters: softc(I) - pointer to soft context data */ +/* */ +/* Create a structre to store all of the run-time data for packet auth in */ +/* and initialise some fields to their defaults. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_auth_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_auth_softc_t *softa; + + KMALLOC(softa, ipf_auth_softc_t *); + if (softa == NULL) + return NULL; + + bzero((char *)softa, sizeof(*softa)); + + softa->ipf_auth_size = FR_NUMAUTH; + softa->ipf_auth_defaultage = 600; + + RWLOCK_INIT(&softa->ipf_authlk, "ipf IP User-Auth rwlock"); + MUTEX_INIT(&softa->ipf_auth_mx, "ipf auth log mutex"); +#if SOLARIS && defined(_KERNEL) + cv_init(&softa->ipf_auth_wait, "ipf auth condvar", CV_DRIVER, NULL); +#endif + + return softa; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_init */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ /* Allocate memory and initialise data structures used in handling auth */ /* rules. */ /* ------------------------------------------------------------------------ */ -int fr_authinit() +int +ipf_auth_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - KMALLOCS(fr_auth, frauth_t *, fr_authsize * sizeof(*fr_auth)); - if (fr_auth != NULL) - bzero((char *)fr_auth, fr_authsize * sizeof(*fr_auth)); - else + ipf_auth_softc_t *softa = arg; + + KMALLOCS(softa->ipf_auth, frauth_t *, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); + if (softa->ipf_auth == NULL) return -1; + bzero((char *)softa->ipf_auth, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); - KMALLOCS(fr_authpkts, mb_t **, fr_authsize * sizeof(*fr_authpkts)); - if (fr_authpkts != NULL) - bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - else + KMALLOCS(softa->ipf_auth_pkts, mb_t **, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); + if (softa->ipf_auth_pkts == NULL) return -2; + bzero((char *)softa->ipf_auth_pkts, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); - MUTEX_INIT(&ipf_authmx, "ipf auth log mutex"); - RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock"); -#if SOLARIS && defined(_KERNEL) - cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); -#endif #if defined(linux) && defined(_KERNEL) - init_waitqueue_head(&fr_authnext_linux); + init_waitqueue_head(&softa->ipf_auth_next_linux); #endif - fr_auth_init = 1; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_fini */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ +/* Free all network buffer memory used to keep saved packets that have been */ +/* connectedd to the soft soft context structure *but* do not free that: it */ +/* is free'd by _destroy(). */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_auth_softc_t *softa = arg; + frauthent_t *fae, **faep; + frentry_t *fr, **frp; + mb_t *m; + int i; + + if (softa->ipf_auth != NULL) { + KFREES(softa->ipf_auth, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); + softa->ipf_auth = NULL; + } + + if (softa->ipf_auth_pkts != NULL) { + for (i = 0; i < softa->ipf_auth_size; i++) { + m = softa->ipf_auth_pkts[i]; + if (m != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } + } + KFREES(softa->ipf_auth_pkts, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); + softa->ipf_auth_pkts = NULL; + } + + faep = &softa->ipf_auth_entries; + while ((fae = *faep) != NULL) { + *faep = fae->fae_next; + KFREE(fae); + } + softa->ipf_auth_ip = NULL; + + if (softa->ipf_auth_rules != NULL) { + for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) { + if (fr->fr_ref == 1) { + *frp = fr->fr_next; + MUTEX_DESTROY(&fr->fr_lock); + KFREE(fr); + } else + frp = &fr->fr_next; + } + } return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_checkauth */ +/* Function: ipf_auth_soft_destroy */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ +/* Undo what was done in _create() - i.e. free the soft context data. */ +/* ------------------------------------------------------------------------ */ +void +ipf_auth_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_auth_softc_t *softa = arg; + +# if SOLARIS && defined(_KERNEL) + cv_destroy(&softa->ipf_auth_wait); +# endif + MUTEX_DESTROY(&softa->ipf_auth_mx); + RW_DESTROY(&softa->ipf_authlk); + + KFREE(softa); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_setlock */ +/* Returns: void */ +/* Paramters: arg(I) - pointer to soft context data */ +/* tmp(I) - value to assign to auth lock */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_auth_setlock(arg, tmp) + void *arg; + int tmp; +{ + ipf_auth_softc_t *softa = arg; + + softa->ipf_auth_lock = tmp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_check */ /* Returns: frentry_t* - pointer to ipf rule if match found, else NULL */ /* Parameters: fin(I) - pointer to ipftoken structure */ /* passp(I) - pointer to ipfgeniter structure */ @@ -198,10 +382,13 @@ int fr_authinit() /* authorization result and that would result in a feedback loop (i.e. it */ /* will end up returning FR_AUTH) then return FR_BLOCK instead. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_checkauth(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_auth_check(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frentry_t *fr; frauth_t *fra; u_32_t pass; @@ -209,27 +396,29 @@ u_32_t *passp; ip_t *ip; int i; - if (fr_auth_lock || !fr_authused) + if (softa->ipf_auth_lock || !softa->ipf_auth_used) return NULL; ip = fin->fin_ip; id = ip->ip_id; - READ_ENTER(&ipf_auth); - for (i = fr_authstart; i != fr_authend; ) { + READ_ENTER(&softa->ipf_authlk); + for (i = softa->ipf_auth_start; i != softa->ipf_auth_end; ) { /* * index becomes -2 only after an SIOCAUTHW. Check this in * case the same packet gets sent again and it hasn't yet been * auth'd. */ - fra = fr_auth + i; + fra = softa->ipf_auth + i; if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) && !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) { /* * Avoid feedback loop. */ - if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) + if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) { pass = FR_BLOCK; + fin->fin_reason = FRB_AUTHFEEDBACK; + } /* * Create a dummy rule for the stateful checking to * use and return. Zero out any values we don't @@ -249,60 +438,65 @@ u_32_t *passp; fr->fr_ifas[1] = NULL; fr->fr_ifas[2] = NULL; fr->fr_ifas[3] = NULL; + MUTEX_INIT(&fr->fr_lock, + "ipf auth rule"); } } else fr = fra->fra_info.fin_fr; fin->fin_fr = fr; - RWLOCK_EXIT(&ipf_auth); + fin->fin_flx |= fra->fra_flx; + RWLOCK_EXIT(&softa->ipf_authlk); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); /* - * fr_authlist is populated with the rules malloc'd + * ipf_auth_rules is populated with the rules malloc'd * above and only those. */ if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) { - fr->fr_next = fr_authlist; - fr_authlist = fr; + fr->fr_next = softa->ipf_auth_rules; + softa->ipf_auth_rules = fr; } - fr_authstats.fas_hits++; + softa->ipf_auth_stats.fas_hits++; fra->fra_index = -1; - fr_authused--; - if (i == fr_authstart) { + softa->ipf_auth_used--; + softa->ipf_auth_replies--; + if (i == softa->ipf_auth_start) { while (fra->fra_index == -1) { i++; fra++; - if (i == fr_authsize) { + if (i == softa->ipf_auth_size) { i = 0; - fra = fr_auth; + fra = softa->ipf_auth; } - fr_authstart = i; - if (i == fr_authend) + softa->ipf_auth_start = i; + if (i == softa->ipf_auth_end) break; } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; + if (softa->ipf_auth_start == + softa->ipf_auth_end) { + softa->ipf_auth_next = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); if (passp != NULL) *passp = pass; - ATOMIC_INC64(fr_authstats.fas_hits); + softa->ipf_auth_stats.fas_hits++; return fr; } i++; - if (i == fr_authsize) + if (i == softa->ipf_auth_size) i = 0; } - fr_authstats.fas_miss++; - RWLOCK_EXIT(&ipf_auth); - ATOMIC_INC64(fr_authstats.fas_miss); + RWLOCK_EXIT(&softa->ipf_authlk); + softa->ipf_auth_stats.fas_miss++; return NULL; } /* ------------------------------------------------------------------------ */ -/* Function: fr_newauth */ +/* Function: ipf_auth_new */ /* Returns: int - 1 == success, 0 = did not put packet on auth queue */ /* Parameters: m(I) - pointer to mb_t with packet in it */ /* fin(I) - pointer to packet information */ @@ -311,10 +505,13 @@ u_32_t *passp; /* packet. If we do, store it and wake up any user programs which are */ /* waiting to hear about these events. */ /* ------------------------------------------------------------------------ */ -int fr_newauth(m, fin) -mb_t *m; -fr_info_t *fin; +int +ipf_auth_new(m, fin) + mb_t *m; + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_auth_softc_t *softa = softc->ipf_auth_soft; #if defined(_KERNEL) && defined(MENTAT) qpktinfo_t *qpi = fin->fin_qpi; #endif @@ -324,31 +521,33 @@ fr_info_t *fin; #endif int i; - if (fr_auth_lock) + if (softa->ipf_auth_lock) return 0; - WRITE_ENTER(&ipf_auth); - if (((fr_authend + 1) % fr_authsize) == fr_authstart) { - fr_authstats.fas_nospace++; - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + if (((softa->ipf_auth_end + 1) % softa->ipf_auth_size) == + softa->ipf_auth_start) { + softa->ipf_auth_stats.fas_nospace++; + RWLOCK_EXIT(&softa->ipf_authlk); return 0; } - fr_authstats.fas_added++; - fr_authused++; - i = fr_authend++; - if (fr_authend == fr_authsize) - fr_authend = 0; - fra = fr_auth + i; - fra->fra_index = i; - RWLOCK_EXIT(&ipf_auth); + softa->ipf_auth_stats.fas_added++; + softa->ipf_auth_used++; + i = softa->ipf_auth_end++; + if (softa->ipf_auth_end == softa->ipf_auth_size) + softa->ipf_auth_end = 0; + fra = softa->ipf_auth + i; + fra->fra_index = i; if (fin->fin_fr != NULL) fra->fra_pass = fin->fin_fr->fr_flags; else fra->fra_pass = 0; - fra->fra_age = fr_defaultauthage; + fra->fra_age = softa->ipf_auth_defaultage; bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin)); + fra->fra_flx = fra->fra_info.fin_flx & (FI_STATE|FI_NATED); + fra->fra_info.fin_flx &= ~(FI_STATE|FI_NATED); #if !defined(sparc) && !defined(m68k) /* * No need to copyback here as we want to undo the changes, not keep @@ -370,24 +569,24 @@ fr_info_t *fin; #if SOLARIS && defined(_KERNEL) COPYIFNAME(fin->fin_v, fin->fin_ifp, fra->fra_info.fin_ifname); m->b_rptr -= qpi->qpi_off; - fr_authpkts[i] = *(mblk_t **)fin->fin_mp; -# if !defined(_INET_IP_STACK_H) fra->fra_q = qpi->qpi_q; /* The queue can disappear! */ -# endif fra->fra_m = *fin->fin_mp; fra->fra_info.fin_mp = &fra->fra_m; - cv_signal(&ipfauthwait); - pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM); + softa->ipf_auth_pkts[i] = *(mblk_t **)fin->fin_mp; + RWLOCK_EXIT(&softa->ipf_authlk); + cv_signal(&softa->ipf_auth_wait); + pollwakeup(&softc->ipf_poll_head[IPL_LOGAUTH], POLLIN|POLLRDNORM); #else - fr_authpkts[i] = m; - WAKEUP(&fr_authnext,0); + softa->ipf_auth_pkts[i] = m; + RWLOCK_EXIT(&softa->ipf_authlk); + WAKEUP(&softa->ipf_auth_next, 0); #endif return 1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_auth_ioctl */ +/* Function: ipf_auth_ioctl */ /* Returns: int - 0 == success, else error */ /* Parameters: data(IO) - pointer to ioctl data */ /* cmd(I) - ioctl command */ @@ -396,14 +595,17 @@ fr_info_t *fin; /* ctx(I) - pointer for context */ /* */ /* This function handles all of the ioctls recognised by the auth component */ -/* in IPFilter - ie ioctls called on an open fd for /dev/ipauth */ +/* in IPFilter - ie ioctls called on an open fd for /dev/ipf_auth */ /* ------------------------------------------------------------------------ */ -int fr_auth_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_auth_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; int error = 0, i; SPL_INT(s); @@ -413,18 +615,23 @@ void *ctx; { ipftoken_t *token; ipfgeniter_t iter; + ipfobj_t obj; - error = fr_inobj(data, &iter, IPFOBJ_GENITER); + error = ipf_inobj(softc, data, &obj, &iter, IPFOBJ_GENITER); if (error != 0) break; SPL_SCHED(s); - token = ipf_findtoken(IPFGENITER_AUTH, uid, ctx); + token = ipf_token_find(softc, IPFGENITER_AUTH, uid, ctx); if (token != NULL) - error = fr_authgeniter(token, &iter); - else + error = ipf_auth_geniter(softc, token, &iter, &obj); + else { + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + IPFERROR(10001); error = ESRCH; - RWLOCK_EXIT(&ipf_tokens); + } SPL_X(s); break; @@ -432,46 +639,52 @@ void *ctx; case SIOCADAFR : case SIOCRMAFR : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(10002); error = EPERM; - else - error = frrequest(IPL_LOGAUTH, cmd, data, - fr_active, 1); + } else + error = frrequest(softc, IPL_LOGAUTH, cmd, data, + softc->ipf_active, 1); break; case SIOCSTLCK : if (!(mode & FWRITE)) { + IPFERROR(10003); error = EPERM; - break; + } else { + error = ipf_lock(data, &softa->ipf_auth_lock); } - error = fr_lock(data, &fr_auth_lock); break; case SIOCATHST: - fr_authstats.fas_faelist = fae_list; - error = fr_outobj(data, &fr_authstats, IPFOBJ_AUTHSTAT); + softa->ipf_auth_stats.fas_faelist = softa->ipf_auth_entries; + error = ipf_outobj(softc, data, &softa->ipf_auth_stats, + IPFOBJ_AUTHSTAT); break; case SIOCIPFFL: SPL_NET(s); - WRITE_ENTER(&ipf_auth); - i = fr_authflush(); - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + i = ipf_auth_flush(softa); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); - error = BCOPYOUT((char *)&i, data, sizeof(i)); - if (error != 0) + error = BCOPYOUT(&i, data, sizeof(i)); + if (error != 0) { + IPFERROR(10004); error = EFAULT; + } break; case SIOCAUTHW: - error = fr_authwait(data); + error = ipf_auth_wait(softc, softa, data); break; case SIOCAUTHR: - error = fr_authreply(data); + error = ipf_auth_reply(softc, softa, data); break; default : + IPFERROR(10005); error = EINVAL; break; } @@ -480,75 +693,18 @@ void *ctx; /* ------------------------------------------------------------------------ */ -/* Function: fr_authunload */ -/* Returns: None */ -/* Parameters: None */ -/* */ -/* Free all network buffer memory used to keep saved packets. */ -/* ------------------------------------------------------------------------ */ -void fr_authunload() -{ - register int i; - register frauthent_t *fae, **faep; - frentry_t *fr, **frp; - mb_t *m; - - if (fr_auth != NULL) { - KFREES(fr_auth, fr_authsize * sizeof(*fr_auth)); - fr_auth = NULL; - } - - if (fr_authpkts != NULL) { - for (i = 0; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - } - } - KFREES(fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - fr_authpkts = NULL; - } - - faep = &fae_list; - while ((fae = *faep) != NULL) { - *faep = fae->fae_next; - KFREE(fae); - } - ipauth = NULL; - - if (fr_authlist != NULL) { - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { - if (fr->fr_ref == 1) { - *frp = fr->fr_next; - KFREE(fr); - } else - frp = &fr->fr_next; - } - } - - if (fr_auth_init == 1) { -# if SOLARIS && defined(_KERNEL) - cv_destroy(&ipfauthwait); -# endif - MUTEX_DESTROY(&ipf_authmx); - RW_DESTROY(&ipf_auth); - - fr_auth_init = 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_authexpire */ +/* Function: ipf_auth_expire */ /* Returns: None */ /* Parameters: None */ /* */ /* Slowly expire held auth records. Timeouts are set in expectation of */ /* this being called twice per second. */ /* ------------------------------------------------------------------------ */ -void fr_authexpire() +void +ipf_auth_expire(softc) + ipf_main_softc_t *softc; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, **faep; frentry_t *fr, **frp; frauth_t *fra; @@ -556,70 +712,81 @@ void fr_authexpire() int i; SPL_INT(s); - if (fr_auth_lock) + if (softa->ipf_auth_lock) return; - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - for (i = 0, fra = fr_auth; i < fr_authsize; i++, fra++) { + WRITE_ENTER(&softa->ipf_authlk); + for (i = 0, fra = softa->ipf_auth; i < softa->ipf_auth_size; + i++, fra++) { fra->fra_age--; - if ((fra->fra_age == 0) && (m = fr_authpkts[i])) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; - fr_authstats.fas_expire++; - fr_authused--; + if ((fra->fra_age == 0) && + (softa->ipf_auth[i].fra_index != -1)) { + if ((m = softa->ipf_auth_pkts[i]) != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } else if (softa->ipf_auth[i].fra_index == -2) { + softa->ipf_auth_replies--; + } + softa->ipf_auth[i].fra_index = -1; + softa->ipf_auth_stats.fas_expire++; + softa->ipf_auth_used--; } } /* * Expire pre-auth rules */ - for (faep = &fae_list; ((fae = *faep) != NULL); ) { + for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) { fae->fae_age--; if (fae->fae_age == 0) { - fr_authderef(&fae); - fr_authstats.fas_expire++; + ipf_auth_deref(&fae); + softa->ipf_auth_stats.fas_expire++; } else faep = &fae->fae_next; } - if (fae_list != NULL) - ipauth = &fae_list->fae_fr; + if (softa->ipf_auth_entries != NULL) + softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr; else - ipauth = NULL; + softa->ipf_auth_ip = NULL; - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { + for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) { if (fr->fr_ref == 1) { *frp = fr->fr_next; + MUTEX_DESTROY(&fr->fr_lock); KFREE(fr); } else frp = &fr->fr_next; } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: fr_preauthcmd */ +/* Function: ipf_auth_precmd */ /* Returns: int - 0 == success, else error */ /* Parameters: cmd(I) - ioctl command for rule */ /* fr(I) - pointer to ipf rule */ /* fptr(I) - pointer to caller's 'fr' */ /* */ /* ------------------------------------------------------------------------ */ -int fr_preauthcmd(cmd, fr, frptr) -ioctlcmd_t cmd; -frentry_t *fr, **frptr; +int +ipf_auth_precmd(softc, cmd, fr, frptr) + ipf_main_softc_t *softc; + ioctlcmd_t cmd; + frentry_t *fr, **frptr; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, **faep; int error = 0; SPL_INT(s); - if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) + if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) { + IPFERROR(10006); return EIO; + } - for (faep = &fae_list; ((fae = *faep) != NULL); ) { + for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) { if (&fae->fae_fr == fr) break; else @@ -627,17 +794,22 @@ frentry_t *fr, **frptr; } if (cmd == (ioctlcmd_t)SIOCRMAFR) { - if (fr == NULL || frptr == NULL) + if (fr == NULL || frptr == NULL) { + IPFERROR(10007); error = EINVAL; - else if (fae == NULL) + + } else if (fae == NULL) { + IPFERROR(10008); error = ESRCH; - else { + + } else { SPL_NET(s); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); *faep = fae->fae_next; - if (ipauth == &fae->fae_fr) - ipauth = fae_list ? &fae_list->fae_fr : NULL; - RWLOCK_EXIT(&ipf_auth); + if (softa->ipf_auth_ip == &fae->fae_fr) + softa->ipf_auth_ip = softa->ipf_auth_entries ? + &softa->ipf_auth_entries->fae_fr : NULL; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); KFREE(fae); @@ -648,161 +820,199 @@ frentry_t *fr, **frptr; bcopy((char *)fr, (char *)&fae->fae_fr, sizeof(*fr)); SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fae->fae_age = fr_defaultauthage; + WRITE_ENTER(&softa->ipf_authlk); + fae->fae_age = softa->ipf_auth_defaultage; fae->fae_fr.fr_hits = 0; fae->fae_fr.fr_next = *frptr; fae->fae_ref = 1; *frptr = &fae->fae_fr; fae->fae_next = *faep; *faep = fae; - ipauth = &fae_list->fae_fr; - RWLOCK_EXIT(&ipf_auth); + softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); - } else + } else { + IPFERROR(10009); error = ENOMEM; - } else + } + } else { + IPFERROR(10010); error = EINVAL; + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authflush */ +/* Function: ipf_auth_flush */ /* Returns: int - number of auth entries flushed */ /* Parameters: None */ -/* Locks: WRITE(ipf_auth) */ +/* Locks: WRITE(ipf_authlk) */ /* */ -/* This function flushs the fr_authpkts array of any packet data with */ +/* This function flushs the ipf_auth_pkts array of any packet data with */ /* references still there. */ /* It is expected that the caller has already acquired the correct locks or */ /* set the priority level correctly for this to block out other code paths */ /* into these data structures. */ /* ------------------------------------------------------------------------ */ -int fr_authflush() +static int +ipf_auth_flush(arg) + void *arg; { - register int i, num_flushed; + ipf_auth_softc_t *softa = arg; + int i, num_flushed; mb_t *m; - if (fr_auth_lock) + if (softa->ipf_auth_lock) return -1; num_flushed = 0; - for (i = 0 ; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; + for (i = 0 ; i < softa->ipf_auth_size; i++) { + if (softa->ipf_auth[i].fra_index != -1) { + m = softa->ipf_auth_pkts[i]; + if (m != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } + + softa->ipf_auth[i].fra_index = -1; /* perhaps add & use a flush counter inst.*/ - fr_authstats.fas_expire++; - fr_authused--; + softa->ipf_auth_stats.fas_expire++; num_flushed++; } } - fr_authstart = 0; - fr_authend = 0; - fr_authnext = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; + softa->ipf_auth_next = 0; + softa->ipf_auth_used = 0; + softa->ipf_auth_replies = 0; return num_flushed; } /* ------------------------------------------------------------------------ */ -/* Function: fr_auth_waiting */ -/* Returns: int - 0 = no packets waiting, 1 = packets waiting. */ +/* Function: ipf_auth_waiting */ +/* Returns: int - number of packets in the auth queue */ /* Parameters: None */ /* */ /* Simple truth check to see if there are any packets waiting in the auth */ /* queue. */ /* ------------------------------------------------------------------------ */ -int fr_auth_waiting() +int +ipf_auth_waiting(softc) + ipf_main_softc_t *softc; { - return (fr_authused != 0); + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + return (softa->ipf_auth_used != 0); } /* ------------------------------------------------------------------------ */ -/* Function: fr_authgeniter */ +/* Function: ipf_auth_geniter */ /* Returns: int - 0 == success, else error */ /* Parameters: token(I) - pointer to ipftoken structure */ /* itp(I) - pointer to ipfgeniter structure */ +/* objp(I) - pointer to ipf object destription */ /* */ +/* Iterate through the list of entries in the auth queue list. */ +/* objp is used here to get the location of where to do the copy out to. */ +/* Stomping over various fields with new information will not harm anything */ /* ------------------------------------------------------------------------ */ -int fr_authgeniter(token, itp) -ipftoken_t *token; -ipfgeniter_t *itp; +static int +ipf_auth_geniter(softc, token, itp, objp) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; + ipfobj_t *objp; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, *next, zero; int error; - if (itp->igi_data == NULL) + if (itp->igi_data == NULL) { + IPFERROR(10011); return EFAULT; + } - if (itp->igi_type != IPFGENITER_AUTH) + if (itp->igi_type != IPFGENITER_AUTH) { + IPFERROR(10012); return EINVAL; + } + + objp->ipfo_type = IPFOBJ_FRAUTH; + objp->ipfo_ptr = itp->igi_data; + objp->ipfo_size = sizeof(frauth_t); + + READ_ENTER(&softa->ipf_authlk); fae = token->ipt_data; - READ_ENTER(&ipf_auth); if (fae == NULL) { - next = fae_list; + next = softa->ipf_auth_entries; } else { next = fae->fae_next; } + /* + * If we found an auth entry to use, bump its reference count + * so that it can be used for is_next when we come back. + */ if (next != NULL) { - /* - * If we find an auth entry to use, bump its reference count - * so that it can be used for is_next when we come back. - */ ATOMIC_INC(next->fae_ref); - if (next->fae_next == NULL) { - ipf_freetoken(token); - token = NULL; - } else { - token->ipt_data = next; - } + token->ipt_data = next; } else { bzero(&zero, sizeof(zero)); next = &zero; + token->ipt_data = NULL; } - RWLOCK_EXIT(&ipf_auth); - /* - * If we had a prior pointer to an auth entry, release it. - */ - if (fae != NULL) { - WRITE_ENTER(&ipf_auth); - fr_authderef(&fae); - RWLOCK_EXIT(&ipf_auth); - } + RWLOCK_EXIT(&softa->ipf_authlk); - /* - * This should arguably be via fr_outobj() so that the auth - * structure can (if required) be massaged going out. - */ - error = COPYOUT(next, itp->igi_data, sizeof(*next)); - if (error != 0) - error = EFAULT; + error = ipf_outobjk(softc, objp, next); + if (fae != NULL) + ipf_auth_deref_unlocked(softa, &fae); + if (next->fae_next == NULL) + ipf_token_mark_complete(token); return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authderef */ +/* Function: ipf_auth_deref_unlocked */ /* Returns: None */ /* Parameters: faep(IO) - pointer to caller's frauthent_t pointer */ -/* Locks: WRITE(ipf_auth) */ +/* */ +/* Wrapper for ipf_auth_deref for when a write lock on ipf_authlk is not */ +/* held. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_auth_deref_unlocked(softa, faep) + ipf_auth_softc_t *softa; + frauthent_t **faep; +{ + WRITE_ENTER(&softa->ipf_authlk); + ipf_auth_deref(faep); + RWLOCK_EXIT(&softa->ipf_authlk); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_deref */ +/* Returns: None */ +/* Parameters: faep(IO) - pointer to caller's frauthent_t pointer */ +/* Locks: WRITE(ipf_authlk) */ /* */ /* This function unconditionally sets the pointer in the caller to NULL, */ /* to make it clear that it should no longer use that pointer, and drops */ /* the reference count on the structure by 1. If it reaches 0, free it up. */ /* ------------------------------------------------------------------------ */ -void fr_authderef(faep) -frauthent_t **faep; +static void +ipf_auth_deref(faep) + frauthent_t **faep; { frauthent_t *fae; @@ -817,30 +1027,30 @@ frauthent_t **faep; /* ------------------------------------------------------------------------ */ -/* Function: fr_authwait */ +/* Function: ipf_auth_wait_pkt */ /* Returns: int - 0 == success, else error */ /* Parameters: data(I) - pointer to data from ioctl call */ /* */ /* This function is called when an application is waiting for a packet to */ /* match an "auth" rule by issuing an SIOCAUTHW ioctl. If there is already */ /* a packet waiting on the queue then we will return that _one_ immediately.*/ -/* If there are no packets present in the queue (fr_authpkts) then we go to */ -/* sleep. */ +/* If there are no packets present in the queue (ipf_auth_pkts) then we go */ +/* to sleep. */ /* ------------------------------------------------------------------------ */ -int fr_authwait(data) -char *data; +static int +ipf_auth_wait(softc, softa, data) + ipf_main_softc_t *softc; + ipf_auth_softc_t *softa; + char *data; { frauth_t auth, *au = &auth; int error, len, i; mb_t *m; char *t; -#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ - (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000)) SPL_INT(s); -#endif -fr_authioctlloop: - error = fr_inobj(data, au, IPFOBJ_FRAUTH); +ipf_auth_ioctlloop: + error = ipf_inobj(softc, data, NULL, au, IPFOBJ_FRAUTH); if (error != 0) return error; @@ -850,30 +1060,36 @@ fr_authioctlloop: * we are trying to guard against here is an error in the copyout * steps should not cause the packet to "disappear" from the queue. */ - READ_ENTER(&ipf_auth); + SPL_NET(s); + READ_ENTER(&softa->ipf_authlk); /* - * If fr_authnext is not equal to fr_authend it will be because there - * is a packet waiting to be delt with in the fr_authpkts array. We - * copy as much of that out to user space as requested. + * If ipf_auth_next is not equal to ipf_auth_end it will be because + * there is a packet waiting to be delt with in the ipf_auth_pkts + * array. We copy as much of that out to user space as requested. */ - if (fr_authused > 0) { - while (fr_authpkts[fr_authnext] == NULL) { - fr_authnext++; - if (fr_authnext == fr_authsize) - fr_authnext = 0; + if (softa->ipf_auth_used > 0) { + while (softa->ipf_auth_pkts[softa->ipf_auth_next] == NULL) { + softa->ipf_auth_next++; + if (softa->ipf_auth_next == softa->ipf_auth_size) + softa->ipf_auth_next = 0; } - error = fr_outobj(data, &fr_auth[fr_authnext], IPFOBJ_FRAUTH); - if (error != 0) + error = ipf_outobj(softc, data, + &softa->ipf_auth[softa->ipf_auth_next], + IPFOBJ_FRAUTH); + if (error != 0) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); return error; + } if (auth.fra_len != 0 && auth.fra_buf != NULL) { /* * Copy packet contents out to user space if * requested. Bail on an error. */ - m = fr_authpkts[fr_authnext]; + m = softa->ipf_auth_pkts[softa->ipf_auth_next]; len = MSGDSIZE(m); if (len > auth.fra_len) len = auth.fra_len; @@ -881,62 +1097,69 @@ fr_authioctlloop: for (t = auth.fra_buf; m && (len > 0); ) { i = MIN(M_LEN(m), len); - error = copyoutptr(MTOD(m, char *), &t, i); + error = copyoutptr(softc, MTOD(m, char *), + &t, i); len -= i; t += i; - if (error != 0) + if (error != 0) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); return error; + } m = m->m_next; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fr_authnext++; - if (fr_authnext == fr_authsize) - fr_authnext = 0; - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + softa->ipf_auth_next++; + if (softa->ipf_auth_next == softa->ipf_auth_size) + softa->ipf_auth_next = 0; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); return 0; } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); - MUTEX_ENTER(&ipf_authmx); + MUTEX_ENTER(&softa->ipf_auth_mx); #ifdef _KERNEL # if SOLARIS error = 0; - if (!cv_wait_sig(&ipfauthwait, &ipf_authmx.ipf_lk)) + if (!cv_wait_sig(&softa->ipf_auth_wait, &softa->ipf_auth_mx.ipf_lk)) { + IPFERROR(10014); error = EINTR; + } # else /* SOLARIS */ # ifdef __hpux { lock_t *l; - l = get_sleep_lock(&fr_authnext); - error = sleep(&fr_authnext, PZERO+1); + l = get_sleep_lock(&softa->ipf_auth_next); + error = sleep(&softa->ipf_auth_next, PZERO+1); spinunlock(l); } # else # ifdef __osf__ - error = mpsleep(&fr_authnext, PSUSP|PCATCH, "fr_authnext", 0, - &ipf_authmx, MS_LOCK_SIMPLE); + error = mpsleep(&softa->ipf_auth_next, PSUSP|PCATCH, "ipf_auth_next", + 0, &softa->ipf_auth_mx, MS_LOCK_SIMPLE); # else - error = SLEEP(&fr_authnext, "fr_authnext"); + error = SLEEP(&softa->ipf_auth_next, "ipf_auth_next"); # endif /* __osf__ */ # endif /* __hpux */ # endif /* SOLARIS */ #endif - MUTEX_EXIT(&ipf_authmx); + MUTEX_EXIT(&softa->ipf_auth_mx); if (error == 0) - goto fr_authioctlloop; + goto ipf_auth_ioctlloop; return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authreply */ +/* Function: ipf_auth_reply */ /* Returns: int - 0 == success, else error */ /* Parameters: data(I) - pointer to data from ioctl call */ /* */ @@ -945,23 +1168,27 @@ fr_authioctlloop: /* received information using an SIOCAUTHW. The decision returned in the */ /* form of flags, the same as those used in each rule. */ /* ------------------------------------------------------------------------ */ -int fr_authreply(data) -char *data; +static int +ipf_auth_reply(softc, softa, data) + ipf_main_softc_t *softc; + ipf_auth_softc_t *softa; + char *data; { frauth_t auth, *au = &auth, *fra; + fr_info_t fin; int error, i; mb_t *m; SPL_INT(s); - error = fr_inobj(data, &auth, IPFOBJ_FRAUTH); + error = ipf_inobj(softc, data, NULL, &auth, IPFOBJ_FRAUTH); if (error != 0) return error; SPL_NET(s); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); i = au->fra_index; - fra = fr_auth + i; + fra = softa->ipf_auth + i; error = 0; /* @@ -969,19 +1196,27 @@ char *data; * checks. First, the auth index value should be within the size of * the array and second the packet id being returned should also match. */ - if ((i < 0) || (i >= fr_authsize) || - (fra->fra_info.fin_id != au->fra_info.fin_id)) { - RWLOCK_EXIT(&ipf_auth); + if ((i < 0) || (i >= softa->ipf_auth_size)) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); + IPFERROR(10015); + return ESRCH; + } + if (fra->fra_info.fin_id != au->fra_info.fin_id) { + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); + IPFERROR(10019); return ESRCH; } - m = fr_authpkts[i]; + m = softa->ipf_auth_pkts[i]; fra->fra_index = -2; fra->fra_pass = au->fra_pass; - fr_authpkts[i] = NULL; + softa->ipf_auth_pkts[i] = NULL; + softa->ipf_auth_replies++; + bcopy(&fra->fra_info, &fin, sizeof(fin)); - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); /* * Re-insert the packet back into the packet stream flowing through @@ -992,22 +1227,25 @@ char *data; */ #ifdef _KERNEL if ((m != NULL) && (au->fra_info.fin_out != 0)) { - error = ipf_inject(&fra->fra_info, m); + error = ipf_inject(&fin, m); if (error != 0) { + IPFERROR(10016); error = ENOBUFS; - fr_authstats.fas_sendfail++; + softa->ipf_auth_stats.fas_sendfail++; } else { - fr_authstats.fas_sendok++; + softa->ipf_auth_stats.fas_sendok++; } } else if (m) { - error = ipf_inject(&fra->fra_info, m); + error = ipf_inject(&fin, m); if (error != 0) { + IPFERROR(10017); error = ENOBUFS; - fr_authstats.fas_quefail++; + softa->ipf_auth_stats.fas_quefail++; } else { - fr_authstats.fas_queok++; + softa->ipf_auth_stats.fas_queok++; } } else { + IPFERROR(10018); error = EINVAL; } @@ -1016,28 +1254,54 @@ char *data; * not being processed, make sure we advance to the next one. */ if (error == ENOBUFS) { - WRITE_ENTER(&ipf_auth); - fr_authused--; + WRITE_ENTER(&softa->ipf_authlk); + softa->ipf_auth_used--; fra->fra_index = -1; fra->fra_pass = 0; - if (i == fr_authstart) { + if (i == softa->ipf_auth_start) { while (fra->fra_index == -1) { i++; - if (i == fr_authsize) + if (i == softa->ipf_auth_size) i = 0; - fr_authstart = i; - if (i == fr_authend) + softa->ipf_auth_start = i; + if (i == softa->ipf_auth_end) break; } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; + if (softa->ipf_auth_start == softa->ipf_auth_end) { + softa->ipf_auth_next = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); } #endif /* _KERNEL */ SPL_X(s); return 0; } + + +u_32_t +ipf_auth_pre_scanlist(softc, fin, pass) + ipf_main_softc_t *softc; + fr_info_t *fin; + u_32_t pass; +{ + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + if (softa->ipf_auth_ip != NULL) + return ipf_scanlist(fin, softc->ipf_pass); + + return pass; +} + + +frentry_t ** +ipf_auth_rulehead(softc) + ipf_main_softc_t *softc; +{ + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + return &softa->ipf_auth_ip; +} |