Deleted Added
full compact
0a1,2
> /* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 145522 2005-04-25 18:43:14Z darrenr $ */
>
2c4
< * Copyright (C) 1998-2001 by Darren Reed & Guido van Rooij.
---
> * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij.
6,7c8,12
< #if defined(__sgi) && (IRIX > 602)
< # include <sys/ptimers.h>
---
> #if defined(KERNEL) || defined(_KERNEL)
> # undef KERNEL
> # undef _KERNEL
> # define KERNEL 1
> # define _KERNEL 1
14c19
< #if !defined(_KERNEL) && !defined(KERNEL)
---
> #if !defined(_KERNEL)
17a23,28
> # define _KERNEL
> # ifdef __OpenBSD__
> struct file;
> # endif
> # include <sys/uio.h>
> # undef _KERNEL
19c30
< #if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
---
> #if defined(_KERNEL) && (__FreeBSD_version >= 220000)
25c36
< #ifndef linux
---
> #if !defined(linux)
29c40
< #if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
---
> #if defined(_KERNEL)
31,33c42
< #endif
< #if !defined(__SVR4) && !defined(__svr4__)
< # ifndef linux
---
> # if !defined(__SVR4) && !defined(__svr4__) && !defined(linux)
36c45,46
< #else
---
> #endif
> #if defined(__SVR4) || defined(__svr4__)
50a61,63
> #if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)
> # include <sys/proc.h>
> #endif
59c72
< #ifndef KERNEL
---
> #if !defined(_KERNEL) && !defined(__osf__) && !defined(__sgi)
60a74
> # define _KERNEL
63c77
< #ifndef linux
---
> #if !defined(linux)
66a81
> # undef _KERNEL
69,73d83
< #ifdef __sgi
< # ifdef IFF_DRVRLOCK /* IRIX6 */
< # include <sys/hashing.h>
< # endif
< #endif
75c85
< #if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
---
> #if defined(IRIX) && (IRIX < 60516) /* IRIX < 6 */
78c88
< # ifndef linux
---
> # if !defined(__hpux) && !defined(linux)
80a91,94
> # if __FreeBSD_version >= 500042
> # define IF_QFULL _IF_QFULL
> # define IF_DROP _IF_DROP
> # endif /* __FreeBSD_version >= 500042 */
92c106
< #if !SOLARIS && !defined(linux)
---
> #if !defined(MENTAT) && !defined(linux)
100c114
< # if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
---
> # if defined(_KERNEL) && !defined(IPFILTER_LKM)
104a119
> /* END OF INCLUDES */
107,108c122,123
< /* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.12 2001/07/18 14:57:08 darrenr Exp $"; */
< static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 139327 2004-12-26 09:09:29Z darrenr $";
---
> static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 145522 2005-04-25 18:43:14Z darrenr $";
> static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp";
112,115c127
< #ifdef USE_MUTEX
< extern KRWLOCK_T ipf_auth, ipf_mutex;
< extern kmutex_t ipf_authmx;
< # if SOLARIS
---
> #if SOLARIS
117c129,131
< # endif
---
> #endif /* SOLARIS */
> #if defined(linux) && defined(_KERNEL)
> wait_queue_head_t fr_authnext_linux;
119,121d132
< #ifdef linux
< static struct wait_queue *ipfauthwait = NULL;
< #endif
126a138
> int fr_auth_init = 0;
128,131c140,143
< static frauth_t fr_auth[FR_NUMAUTH];
< mb_t *fr_authpkts[FR_NUMAUTH];
< static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
< static frauthent_t *fae_list = NULL;
---
> 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;
135a148,176
> int fr_authinit()
> {
> KMALLOCS(fr_auth, frauth_t *, fr_authsize * sizeof(*fr_auth));
> if (fr_auth != NULL)
> bzero((char *)fr_auth, fr_authsize * sizeof(*fr_auth));
> else
> return -1;
>
> KMALLOCS(fr_authpkts, mb_t **, fr_authsize * sizeof(*fr_authpkts));
> if (fr_authpkts != NULL)
> bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts));
> else
> return -2;
>
> 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);
> #endif
>
> fr_auth_init = 1;
>
> return 0;
> }
>
>
141,142c182
< u_32_t fr_checkauth(ip, fin)
< ip_t *ip;
---
> frentry_t *fr_checkauth(fin, passp)
143a184
> u_32_t *passp;
145d185
< u_short id = ip->ip_id;
148a189,190
> u_short id;
> ip_t *ip;
152c194
< return 0;
---
> return NULL;
153a196,198
> ip = fin->fin_ip;
> id = ip->ip_id;
>
167c212
< if (!(pass = fra->fra_pass) || (pass & FR_AUTH))
---
> if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass)))
175c220
< (fin->fin_fi.fi_fl & FI_FRAG))) {
---
> (fin->fin_flx & FI_FRAG))) {
179c224
< fr, sizeof(*fr));
---
> (char *)fr, sizeof(*fr));
185,187c230,232
< #if BSD >= 199306
< fr->fr_oifa = NULL;
< #endif
---
> fr->fr_ifas[1] = NULL;
> fr->fr_ifas[2] = NULL;
> fr->fr_ifas[3] = NULL;
194c239
< if (fr && fr != fra->fra_info.fin_fr) {
---
> if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) {
205c250
< if (i == FR_NUMAUTH) {
---
> if (i == fr_authsize) {
219c264,267
< return pass;
---
> if (passp != NULL)
> *passp = pass;
> ATOMIC_INC64(fr_authstats.fas_hits);
> return fr;
222c270
< if (i == FR_NUMAUTH)
---
> if (i == fr_authsize)
227c275,276
< return 0;
---
> ATOMIC_INC64(fr_authstats.fas_miss);
> return NULL;
236c285
< int fr_newauth(m, fin, ip)
---
> int fr_newauth(m, fin)
239d287
< ip_t *ip;
241,242c289,290
< #if defined(_KERNEL) && SOLARIS
< qif_t *qif = fin->fin_qif;
---
> #if defined(_KERNEL) && defined(MENTAT)
> qpktinfo_t *qpi = fin->fin_qpi;
244a293,295
> #if !defined(sparc) && !defined(m68k)
> ip_t *ip;
> #endif
256c307
< if (fr_authused == FR_NUMAUTH) {
---
> if (fr_authused == fr_authsize) {
266c317
< if (fr_authend == FR_NUMAUTH)
---
> if (fr_authend == fr_authsize)
268a320
>
274,275c326
< #if SOLARIS && defined(_KERNEL)
< # if !defined(sparc)
---
> #if !defined(sparc) && !defined(m68k)
280c331,334
< if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
---
> ip = fin->fin_ip;
> # if defined(MENTAT) && defined(_KERNEL)
> if ((ip == (ip_t *)m->b_rptr) && (fin->fin_v == 4))
> # endif
289,290c343,345
< # endif
< m->b_rptr -= qif->qf_off;
---
> #endif
> #if SOLARIS && defined(_KERNEL)
> m->b_rptr -= qpi->qpi_off;
292c347
< fra->fra_q = qif->qf_q;
---
> fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
296c351
< if (fin->fin_out == 0) {
---
> if (!fin->fin_out) {
302c357
< WAKEUP(&fr_authnext);
---
> WAKEUP(&fr_authnext,0);
308c363
< int fr_auth_ioctl(data, mode, cmd)
---
> int fr_auth_ioctl(data, cmd, mode)
309a365
> ioctlcmd_t cmd;
311,315d366
< #if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
< u_long cmd;
< #else
< int cmd;
< #endif
318,319c369,370
< #if defined(_KERNEL) && !SOLARIS
< # if !defined(__FreeBSD_version) || (__FreeBSD_version < 501104)
---
> #if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \
> (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
321c372
< # endif
---
> # ifdef USE_SPL
322a374
> # endif /* USE_SPL */
325c377,378
< int i, error = 0;
---
> int i, error = 0, len;
> char *t;
334c387
< error = fr_lock(data, &fr_auth_lock);
---
> fr_lock(data, &fr_auth_lock);
336,348c389
< case SIOCINIFR :
< case SIOCRMIFR :
< case SIOCADIFR :
< error = EINVAL;
< break;
< case SIOCINAFR :
< error = EINVAL;
< break;
< case SIOCRMAFR :
< case SIOCADAFR :
< /* These commands go via request to fr_preauthcmd */
< error = EINVAL;
< break;
---
>
351,352c392
< error = IWCOPYPTR((char *)&fr_authstats, data,
< sizeof(fr_authstats));
---
> error = fr_outobj(data, &fr_authstats, IPFOBJ_AUTHSTAT);
353a394,403
>
> case SIOCIPFFL:
> SPL_NET(s);
> WRITE_ENTER(&ipf_auth);
> i = fr_authflush();
> RWLOCK_EXIT(&ipf_auth);
> SPL_X(s);
> error = copyoutptr((char *)&i, data, sizeof(i));
> break;
>
355,358d404
< if (!(mode & FWRITE)) {
< error = EPERM;
< break;
< }
359a406
> error = fr_inobj(data, au, IPFOBJ_FRAUTH);
362,363c409,430
< error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data,
< sizeof(frauth_t));
---
> error = fr_outobj(data, &fr_auth[fr_authnext],
> IPFOBJ_FRAUTH);
> 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];
> len = MSGDSIZE(m);
> if (len > auth.fra_len)
> len = auth.fra_len;
> auth.fra_len = len;
> for (t = auth.fra_buf; m && (len > 0); ) {
> i = MIN(M_LEN(m), len);
> error = copyoutptr(MTOD(m, char *),
> t, i);
> len -= i;
> t += i;
> if (error != 0)
> break;
> }
> }
365c432
< if (error)
---
> if (error != 0)
367d433
< WRITE_ENTER(&ipf_auth);
368a435
> WRITE_ENTER(&ipf_auth);
370c437
< if (fr_authnext == FR_NUMAUTH)
---
> if (fr_authnext == fr_authsize)
372d438
< SPL_X(s);
373a440
> SPL_X(s);
376a444,454
> /*
> * We exit ipf_global here because a program that enters in
> * here will have a lock on it and goto sleep having this lock.
> * If someone were to do an 'ipf -D' the system would then
> * deadlock. The catch with releasing it here is that the
> * caller of this function expects it to be held when we
> * return so we have to reacquire it in here.
> */
> RWLOCK_EXIT(&ipf_global);
>
> MUTEX_ENTER(&ipf_authmx);
379,382c457,467
< mutex_enter(&ipf_authmx);
< if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) {
< mutex_exit(&ipf_authmx);
< return EINTR;
---
> error = 0;
> if (!cv_wait_sig(&ipfauthwait, &ipf_authmx.ipf_lk))
> error = EINTR;
> # else /* SOLARIS */
> # ifdef __hpux
> {
> lock_t *l;
>
> l = get_sleep_lock(&fr_authnext);
> error = sleep(&fr_authnext, PZERO+1);
> spinunlock(l);
384,385c469,473
< mutex_exit(&ipf_authmx);
< # else
---
> # else
> # ifdef __osf__
> error = mpsleep(&fr_authnext, PSUSP|PCATCH, "fr_authnext", 0,
> &ipf_authmx, MS_LOCK_SIMPLE);
> # else
387c475,477
< # endif
---
> # endif /* __osf__ */
> # endif /* __hpux */
> # endif /* SOLARIS */
389c479,482
< if (!error)
---
> MUTEX_EXIT(&ipf_authmx);
> READ_ENTER(&ipf_global);
> if (error == 0) {
> READ_ENTER(&ipf_auth);
390a484
> }
391a486
>
393,398c488,489
< if (!(mode & FWRITE)) {
< error = EPERM;
< break;
< }
< error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth));
< if (error)
---
> error = fr_inobj(data, &auth, IPFOBJ_FRAUTH);
> if (error != 0)
400d490
< WRITE_ENTER(&ipf_auth);
401a492
> WRITE_ENTER(&ipf_auth);
404c495
< if ((i < 0) || (i > FR_NUMAUTH) ||
---
> if ((i < 0) || (i >= fr_authsize) ||
406d496
< SPL_X(s);
408c498,499
< return EINVAL;
---
> SPL_X(s);
> return ESRCH;
416,427c507,511
< if (m && au->fra_info.fin_out) {
< # if SOLARIS
< error = (fr_qout(fra->fra_q, m) == 0) ? EINVAL : 0;
< # else /* SOLARIS */
< struct route ro;
<
< bzero((char *)&ro, sizeof(ro));
< # if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
< defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
< (__FreeBSD_version >= 470102)
< error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
< NULL);
---
> if ((m != NULL) && (au->fra_info.fin_out != 0)) {
> # ifdef MENTAT
> error = !putq(fra->fra_q, m);
> # else /* MENTAT */
> # ifdef linux
429,435c513,523
< error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL);
< # endif
< if (ro.ro_rt) {
< RTFREE(ro.ro_rt);
< }
< # endif /* SOLARIS */
< if (error)
---
> # if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \
> (defined(__sgi) && (IRIX >= 60500) || \
> (defined(__FreeBSD__) && (__FreeBSD_version >= 470102)))
> error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
> NULL);
> # else
> error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
> # endif
> # endif /* Linux */
> # endif /* MENTAT */
> if (error != 0)
440,443c528,543
< # if SOLARIS
< error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
< # else /* SOLARIS */
< if (! netisr_queue(NETISR_IP, m))
---
> # ifdef MENTAT
> error = !putq(fra->fra_q, m);
> # else /* MENTAT */
> # ifdef linux
> # else
> # if __FreeBSD_version >= 501000
> netisr_dispatch(NETISR_IP, m);
> # else
> # if IRIX >= 60516
> ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd;
> # else
> ifq = &ipintrq;
> # endif
> if (IF_QFULL(ifq)) {
> IF_DROP(ifq);
> FREE_MB_T(m);
445,446c545,554
< # endif /* SOLARIS */
< if (error)
---
> } else {
> IF_ENQUEUE(ifq, m);
> # if IRIX < 60500
> schednetisr(NETISR_IP);
> # endif
> }
> # endif
> # endif /* Linux */
> # endif /* MENTAT */
> if (error != 0)
452,453c560,561
< # if SOLARIS
< if (error)
---
> # ifdef MENTAT
> if (error != 0)
455c563
< # else
---
> # else /* MENTAT */
459c567
< */
---
> */
467c575
< if (i == FR_NUMAUTH)
---
> if (i == fr_authsize)
479c587
< # endif
---
> # endif /* MENTAT */
482a591
>
501,506c610,621
< WRITE_ENTER(&ipf_auth);
< for (i = 0; i < FR_NUMAUTH; i++) {
< if ((m = fr_authpkts[i])) {
< FREE_MB_T(m);
< fr_authpkts[i] = NULL;
< fr_auth[i].fra_index = -1;
---
> 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;
> }
507a623,624
> KFREES(fr_authpkts, fr_authsize * sizeof(*fr_authpkts));
> fr_authpkts = NULL;
510,511c627,628
<
< for (faep = &fae_list; (fae = *faep); ) {
---
> faep = &fae_list;
> while ((fae = *faep) != NULL) {
516d632
< RWLOCK_EXIT(&ipf_auth);
518,527c634,635
< if (fr_authlist) {
< /*
< * We *MuST* reget ipf_auth because otherwise we won't get the
< * locks in the right order and risk deadlock.
< * We need ipf_mutex here to prevent a rule from using it
< * inside fr_check().
< */
< WRITE_ENTER(&ipf_mutex);
< WRITE_ENTER(&ipf_auth);
< for (frp = &fr_authlist; (fr = *frp); ) {
---
> if (fr_authlist != NULL) {
> for (frp = &fr_authlist; ((fr = *frp) != NULL); ) {
534,535d641
< RWLOCK_EXIT(&ipf_auth);
< RWLOCK_EXIT(&ipf_mutex);
536a643,652
>
> 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;
> }
551c667
< #if !SOLARIS && defined(_KERNEL)
---
> # if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
553c669
< #endif
---
> # endif
560,561c676,678
< for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
< if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
---
> for (i = 0, fra = fr_auth; i < fr_authsize; i++, fra++) {
> fra->fra_age--;
> if ((fra->fra_age == 0) && (m = fr_authpkts[i])) {
570,571c687,689
< for (faep = &fae_list; (fae = *faep); ) {
< if (!--fae->fae_age) {
---
> for (faep = &fae_list; ((fae = *faep) != NULL); ) {
> fae->fae_age--;
> if (fae->fae_age == 0) {
583c701
< for (frp = &fr_authlist; (fr = *frp); ) {
---
> for (frp = &fr_authlist; ((fr = *frp) != NULL); ) {
595,600c713
< #if defined(__NetBSD__) || defined(__OpenBSD__) || \
< (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
< u_long cmd;
< #else
< int cmd;
< #endif
---
> ioctlcmd_t cmd;
605c718
< #if defined(KERNEL) && !SOLARIS
---
> # if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
609,611c722
< if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) {
< /* Should not happen */
< printf("fr_preauthcmd called with bad cmd 0x%lx", (u_long)cmd);
---
> if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR))
613d723
< }
615c725
< for (faep = &fae_list; (fae = *faep); )
---
> for (faep = &fae_list; ((fae = *faep) != NULL); ) {
620,621c730,733
< if (cmd == SIOCRMAFR) {
< if (!fr || !frptr)
---
> }
>
> if (cmd == (ioctlcmd_t)SIOCRMAFR) {
> if (fr == NULL || frptr == NULL)
623c735
< else if (!fae)
---
> else if (fae == NULL)
626d737
< WRITE_ENTER(&ipf_auth);
627a739
> WRITE_ENTER(&ipf_auth);
629,630c741,742
< *frptr = fr->fr_next;
< SPL_X(s);
---
> if (ipauth == &fae->fae_fr)
> ipauth = fae_list ? &fae_list->fae_fr : NULL;
631a744,745
> SPL_X(s);
>
634c748
< } else if (fr && frptr) {
---
> } else if (fr != NULL && frptr != NULL) {
639d752
< WRITE_ENTER(&ipf_auth);
640a754
> WRITE_ENTER(&ipf_auth);
648d761
< SPL_X(s);
649a763
> SPL_X(s);
655a770,805
>
>
> /*
> * Flush held packets.
> * Must already be properly SPL'ed and Locked on &ipf_auth.
> *
> */
> int fr_authflush()
> {
> register int i, num_flushed;
> mb_t *m;
>
> if (fr_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;
> /* perhaps add & use a flush counter inst.*/
> fr_authstats.fas_expire++;
> fr_authused--;
> num_flushed++;
> }
> }
>
> fr_authstart = 0;
> fr_authend = 0;
> fr_authnext = 0;
>
> return num_flushed;
> }