| 1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 145522 2005-04-25 18:43:14Z darrenr $ */ 2
|
1/*
| 3/*
|
2 * Copyright (C) 1998-2001 by Darren Reed & Guido van Rooij.
| 4 * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij.
|
3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 */
| 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */
|
6#if defined(__sgi) && (IRIX > 602) 7# include <sys/ptimers.h>
| 8#if defined(KERNEL) || defined(_KERNEL) 9# undef KERNEL 10# undef _KERNEL 11# define KERNEL 1 12# define _KERNEL 1
|
8#endif 9#include <sys/errno.h> 10#include <sys/types.h> 11#include <sys/param.h> 12#include <sys/time.h> 13#include <sys/file.h>
| 13#endif 14#include <sys/errno.h> 15#include <sys/types.h> 16#include <sys/param.h> 17#include <sys/time.h> 18#include <sys/file.h>
|
14#if !defined(_KERNEL) && !defined(KERNEL)
| 19#if !defined(_KERNEL)
|
15# include <stdio.h> 16# include <stdlib.h> 17# include <string.h>
| 20# include <stdio.h> 21# include <stdlib.h> 22# include <string.h>
|
| 23# define _KERNEL 24# ifdef __OpenBSD__ 25struct file; 26# endif 27# include <sys/uio.h> 28# undef _KERNEL
|
18#endif
| 29#endif
|
19#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
| 30#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
|
20# include <sys/filio.h> 21# include <sys/fcntl.h> 22#else 23# include <sys/ioctl.h> 24#endif
| 31# include <sys/filio.h> 32# include <sys/fcntl.h> 33#else 34# include <sys/ioctl.h> 35#endif
|
25#ifndef linux
| 36#if !defined(linux)
|
26# include <sys/protosw.h> 27#endif 28#include <sys/socket.h>
| 37# include <sys/protosw.h> 38#endif 39#include <sys/socket.h>
|
29#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
| 40#if defined(_KERNEL)
|
30# include <sys/systm.h>
| 41# include <sys/systm.h>
|
31#endif 32#if !defined(__SVR4) && !defined(__svr4__) 33# ifndef linux
| 42# if !defined(__SVR4) && !defined(__svr4__) && !defined(linux)
|
34# include <sys/mbuf.h> 35# endif
| 43# include <sys/mbuf.h> 44# endif
|
36#else
| 45#endif 46#if defined(__SVR4) || defined(__svr4__)
|
37# include <sys/filio.h> 38# include <sys/byteorder.h> 39# ifdef _KERNEL 40# include <sys/dditypes.h> 41# endif 42# include <sys/stream.h> 43# include <sys/kmem.h> 44#endif 45#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000) 46# include <sys/queue.h> 47#endif 48#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi) 49# include <machine/cpu.h> 50#endif
| 47# include <sys/filio.h> 48# include <sys/byteorder.h> 49# ifdef _KERNEL 50# include <sys/dditypes.h> 51# endif 52# include <sys/stream.h> 53# include <sys/kmem.h> 54#endif 55#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000) 56# include <sys/queue.h> 57#endif 58#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi) 59# include <machine/cpu.h> 60#endif
|
| 61#if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) 62# include <sys/proc.h> 63#endif
|
51#include <net/if.h> 52#ifdef sun 53# include <net/af.h> 54#endif 55#include <net/route.h> 56#include <netinet/in.h> 57#include <netinet/in_systm.h> 58#include <netinet/ip.h>
| 64#include <net/if.h> 65#ifdef sun 66# include <net/af.h> 67#endif 68#include <net/route.h> 69#include <netinet/in.h> 70#include <netinet/in_systm.h> 71#include <netinet/ip.h>
|
59#ifndef KERNEL
| 72#if !defined(_KERNEL) && !defined(__osf__) && !defined(__sgi)
|
60# define KERNEL
| 73# define KERNEL
|
| 74# define _KERNEL
|
61# define NOT_KERNEL 62#endif
| 75# define NOT_KERNEL 76#endif
|
63#ifndef linux
| 77#if !defined(linux)
|
64# include <netinet/ip_var.h> 65#endif 66#ifdef NOT_KERNEL
| 78# include <netinet/ip_var.h> 79#endif 80#ifdef NOT_KERNEL
|
| 81# undef _KERNEL
|
67# undef KERNEL 68#endif
| 82# undef KERNEL 83#endif
|
69#ifdef __sgi 70# ifdef IFF_DRVRLOCK /* IRIX6 */ 71# include <sys/hashing.h> 72# endif 73#endif
| |
74#include <netinet/tcp.h>
| 84#include <netinet/tcp.h>
|
75#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
| 85#if defined(IRIX) && (IRIX < 60516) /* IRIX < 6 */
|
76extern struct ifqueue ipintrq; /* ip packet input queue */ 77#else
| 86extern struct ifqueue ipintrq; /* ip packet input queue */ 87#else
|
78# ifndef linux
| 88# if !defined(__hpux) && !defined(linux)
|
79# if __FreeBSD_version >= 300000 80# include <net/if_var.h>
| 89# if __FreeBSD_version >= 300000 90# include <net/if_var.h>
|
| 91# if __FreeBSD_version >= 500042 92# define IF_QFULL _IF_QFULL 93# define IF_DROP _IF_DROP 94# endif /* __FreeBSD_version >= 500042 */
|
81# endif 82# include <netinet/in_var.h> 83# include <netinet/tcp_fsm.h> 84# endif 85#endif 86#include <netinet/udp.h> 87#include <netinet/ip_icmp.h> 88#include "netinet/ip_compat.h" 89#include <netinet/tcpip.h> 90#include "netinet/ip_fil.h" 91#include "netinet/ip_auth.h"
| 95# endif 96# include <netinet/in_var.h> 97# include <netinet/tcp_fsm.h> 98# endif 99#endif 100#include <netinet/udp.h> 101#include <netinet/ip_icmp.h> 102#include "netinet/ip_compat.h" 103#include <netinet/tcpip.h> 104#include "netinet/ip_fil.h" 105#include "netinet/ip_auth.h"
|
92#if !SOLARIS && !defined(linux)
| 106#if !defined(MENTAT) && !defined(linux)
|
93# include <net/netisr.h> 94# ifdef __FreeBSD__ 95# include <machine/cpufunc.h> 96# endif 97#endif 98#if (__FreeBSD_version >= 300000) 99# include <sys/malloc.h>
| 107# include <net/netisr.h> 108# ifdef __FreeBSD__ 109# include <machine/cpufunc.h> 110# endif 111#endif 112#if (__FreeBSD_version >= 300000) 113# include <sys/malloc.h>
|
100# if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
| 114# if defined(_KERNEL) && !defined(IPFILTER_LKM)
|
101# include <sys/libkern.h> 102# include <sys/systm.h> 103# endif 104#endif
| 115# include <sys/libkern.h> 116# include <sys/systm.h> 117# endif 118#endif
|
| 119/* END OF INCLUDES */
|
105 106#if !defined(lint)
| 120 121#if !defined(lint)
|
107/* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.12 2001/07/18 14:57:08 darrenr Exp $"; */ 108static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 139327 2004-12-26 09:09:29Z darrenr $";
| 122static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_auth.c 145522 2005-04-25 18:43:14Z darrenr $"; 123static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp";
|
109#endif 110 111
| 124#endif 125 126
|
112#ifdef USE_MUTEX 113extern KRWLOCK_T ipf_auth, ipf_mutex; 114extern kmutex_t ipf_authmx; 115# if SOLARIS
| 127#if SOLARIS
|
116extern kcondvar_t ipfauthwait;
| 128extern kcondvar_t ipfauthwait;
|
117# endif
| 129#endif /* SOLARIS */ 130#if defined(linux) && defined(_KERNEL) 131wait_queue_head_t fr_authnext_linux;
|
118#endif
| 132#endif
|
119#ifdef linux 120static struct wait_queue *ipfauthwait = NULL; 121#endif
| |
122 123int fr_authsize = FR_NUMAUTH; 124int fr_authused = 0; 125int fr_defaultauthage = 600; 126int fr_auth_lock = 0;
| 133 134int fr_authsize = FR_NUMAUTH; 135int fr_authused = 0; 136int fr_defaultauthage = 600; 137int fr_auth_lock = 0;
|
| 138int fr_auth_init = 0;
|
127fr_authstat_t fr_authstats;
| 139fr_authstat_t fr_authstats;
|
128static frauth_t fr_auth[FR_NUMAUTH]; 129mb_t *fr_authpkts[FR_NUMAUTH]; 130static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0; 131static frauthent_t *fae_list = NULL;
| 140static frauth_t *fr_auth = NULL; 141mb_t **fr_authpkts = NULL; 142int fr_authstart = 0, fr_authend = 0, fr_authnext = 0; 143frauthent_t *fae_list = NULL;
|
132frentry_t *ipauth = NULL, 133 *fr_authlist = NULL; 134 135
| 144frentry_t *ipauth = NULL, 145 *fr_authlist = NULL; 146 147
|
| 148int fr_authinit() 149{ 150 KMALLOCS(fr_auth, frauth_t *, fr_authsize * sizeof(*fr_auth)); 151 if (fr_auth != NULL) 152 bzero((char *)fr_auth, fr_authsize * sizeof(*fr_auth)); 153 else 154 return -1; 155 156 KMALLOCS(fr_authpkts, mb_t **, fr_authsize * sizeof(*fr_authpkts)); 157 if (fr_authpkts != NULL) 158 bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); 159 else 160 return -2; 161 162 MUTEX_INIT(&ipf_authmx, "ipf auth log mutex"); 163 RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock"); 164#if SOLARIS && defined(_KERNEL) 165 cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); 166#endif 167#if defined(linux) && defined(_KERNEL) 168 init_waitqueue_head(&fr_authnext_linux); 169#endif 170 171 fr_auth_init = 1; 172 173 return 0; 174} 175 176
|
136/* 137 * Check if a packet has authorization. If the packet is found to match an 138 * authorization result and that would result in a feedback loop (i.e. it 139 * will end up returning FR_AUTH) then return FR_BLOCK instead. 140 */
| 177/* 178 * Check if a packet has authorization. If the packet is found to match an 179 * authorization result and that would result in a feedback loop (i.e. it 180 * will end up returning FR_AUTH) then return FR_BLOCK instead. 181 */
|
141u_32_t fr_checkauth(ip, fin) 142ip_t *ip;
| 182frentry_t *fr_checkauth(fin, passp)
|
143fr_info_t *fin;
| 183fr_info_t *fin;
|
| 184u_32_t *passp;
|
144{
| 185{
|
145 u_short id = ip->ip_id;
| |
146 frentry_t *fr; 147 frauth_t *fra; 148 u_32_t pass;
| 186 frentry_t *fr; 187 frauth_t *fra; 188 u_32_t pass;
|
| 189 u_short id; 190 ip_t *ip;
|
149 int i; 150 151 if (fr_auth_lock || !fr_authused)
| 191 int i; 192 193 if (fr_auth_lock || !fr_authused)
|
152 return 0;
| 194 return NULL;
|
153
| 195
|
| 196 ip = fin->fin_ip; 197 id = ip->ip_id; 198
|
154 READ_ENTER(&ipf_auth); 155 for (i = fr_authstart; i != fr_authend; ) { 156 /* 157 * index becomes -2 only after an SIOCAUTHW. Check this in 158 * case the same packet gets sent again and it hasn't yet been 159 * auth'd. 160 */ 161 fra = fr_auth + i; 162 if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) && 163 !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) { 164 /* 165 * Avoid feedback loop. 166 */
| 199 READ_ENTER(&ipf_auth); 200 for (i = fr_authstart; i != fr_authend; ) { 201 /* 202 * index becomes -2 only after an SIOCAUTHW. Check this in 203 * case the same packet gets sent again and it hasn't yet been 204 * auth'd. 205 */ 206 fra = fr_auth + i; 207 if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) && 208 !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) { 209 /* 210 * Avoid feedback loop. 211 */
|
167 if (!(pass = fra->fra_pass) || (pass & FR_AUTH))
| 212 if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass)))
|
168 pass = FR_BLOCK; 169 /* 170 * Create a dummy rule for the stateful checking to 171 * use and return. Zero out any values we don't 172 * trust from userland! 173 */ 174 if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) &&
| 213 pass = FR_BLOCK; 214 /* 215 * Create a dummy rule for the stateful checking to 216 * use and return. Zero out any values we don't 217 * trust from userland! 218 */ 219 if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) &&
|
175 (fin->fin_fi.fi_fl & FI_FRAG))) {
| 220 (fin->fin_flx & FI_FRAG))) {
|
176 KMALLOC(fr, frentry_t *); 177 if (fr) { 178 bcopy((char *)fra->fra_info.fin_fr,
| 221 KMALLOC(fr, frentry_t *); 222 if (fr) { 223 bcopy((char *)fra->fra_info.fin_fr,
|
179 fr, sizeof(*fr));
| 224 (char *)fr, sizeof(*fr));
|
180 fr->fr_grp = NULL; 181 fr->fr_ifa = fin->fin_ifp; 182 fr->fr_func = NULL; 183 fr->fr_ref = 1; 184 fr->fr_flags = pass;
| 225 fr->fr_grp = NULL; 226 fr->fr_ifa = fin->fin_ifp; 227 fr->fr_func = NULL; 228 fr->fr_ref = 1; 229 fr->fr_flags = pass;
|
185#if BSD >= 199306 186 fr->fr_oifa = NULL; 187#endif
| 230 fr->fr_ifas[1] = NULL; 231 fr->fr_ifas[2] = NULL; 232 fr->fr_ifas[3] = NULL;
|
188 } 189 } else 190 fr = fra->fra_info.fin_fr; 191 fin->fin_fr = fr; 192 RWLOCK_EXIT(&ipf_auth); 193 WRITE_ENTER(&ipf_auth);
| 233 } 234 } else 235 fr = fra->fra_info.fin_fr; 236 fin->fin_fr = fr; 237 RWLOCK_EXIT(&ipf_auth); 238 WRITE_ENTER(&ipf_auth);
|
194 if (fr && fr != fra->fra_info.fin_fr) {
| 239 if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) {
|
195 fr->fr_next = fr_authlist; 196 fr_authlist = fr; 197 } 198 fr_authstats.fas_hits++; 199 fra->fra_index = -1; 200 fr_authused--; 201 if (i == fr_authstart) { 202 while (fra->fra_index == -1) { 203 i++; 204 fra++;
| 240 fr->fr_next = fr_authlist; 241 fr_authlist = fr; 242 } 243 fr_authstats.fas_hits++; 244 fra->fra_index = -1; 245 fr_authused--; 246 if (i == fr_authstart) { 247 while (fra->fra_index == -1) { 248 i++; 249 fra++;
|
205 if (i == FR_NUMAUTH) {
| 250 if (i == fr_authsize) {
|
206 i = 0; 207 fra = fr_auth; 208 } 209 fr_authstart = i; 210 if (i == fr_authend) 211 break; 212 } 213 if (fr_authstart == fr_authend) { 214 fr_authnext = 0; 215 fr_authstart = fr_authend = 0; 216 } 217 } 218 RWLOCK_EXIT(&ipf_auth);
| 251 i = 0; 252 fra = fr_auth; 253 } 254 fr_authstart = i; 255 if (i == fr_authend) 256 break; 257 } 258 if (fr_authstart == fr_authend) { 259 fr_authnext = 0; 260 fr_authstart = fr_authend = 0; 261 } 262 } 263 RWLOCK_EXIT(&ipf_auth);
|
219 return pass;
| 264 if (passp != NULL) 265 *passp = pass; 266 ATOMIC_INC64(fr_authstats.fas_hits); 267 return fr;
|
220 } 221 i++;
| 268 } 269 i++;
|
222 if (i == FR_NUMAUTH)
| 270 if (i == fr_authsize)
|
223 i = 0; 224 } 225 fr_authstats.fas_miss++; 226 RWLOCK_EXIT(&ipf_auth);
| 271 i = 0; 272 } 273 fr_authstats.fas_miss++; 274 RWLOCK_EXIT(&ipf_auth);
|
227 return 0;
| 275 ATOMIC_INC64(fr_authstats.fas_miss); 276 return NULL;
|
228} 229 230 231/* 232 * Check if we have room in the auth array to hold details for another packet. 233 * If we do, store it and wake up any user programs which are waiting to 234 * hear about these events. 235 */
| 277} 278 279 280/* 281 * Check if we have room in the auth array to hold details for another packet. 282 * If we do, store it and wake up any user programs which are waiting to 283 * hear about these events. 284 */
|
236int fr_newauth(m, fin, ip)
| 285int fr_newauth(m, fin)
|
237mb_t *m; 238fr_info_t *fin;
| 286mb_t *m; 287fr_info_t *fin;
|
239ip_t *ip;
| |
240{
| 288{
|
241#if defined(_KERNEL) && SOLARIS 242 qif_t *qif = fin->fin_qif;
| 289#if defined(_KERNEL) && defined(MENTAT) 290 qpktinfo_t *qpi = fin->fin_qpi;
|
243#endif 244 frauth_t *fra;
| 291#endif 292 frauth_t *fra;
|
| 293#if !defined(sparc) && !defined(m68k) 294 ip_t *ip; 295#endif
|
245 int i; 246 247 if (fr_auth_lock) 248 return 0; 249 250 WRITE_ENTER(&ipf_auth); 251 if (fr_authstart > fr_authend) { 252 fr_authstats.fas_nospace++; 253 RWLOCK_EXIT(&ipf_auth); 254 return 0; 255 } else {
| 296 int i; 297 298 if (fr_auth_lock) 299 return 0; 300 301 WRITE_ENTER(&ipf_auth); 302 if (fr_authstart > fr_authend) { 303 fr_authstats.fas_nospace++; 304 RWLOCK_EXIT(&ipf_auth); 305 return 0; 306 } else {
|
256 if (fr_authused == FR_NUMAUTH) {
| 307 if (fr_authused == fr_authsize) {
|
257 fr_authstats.fas_nospace++; 258 RWLOCK_EXIT(&ipf_auth); 259 return 0; 260 } 261 } 262 263 fr_authstats.fas_added++; 264 fr_authused++; 265 i = fr_authend++;
| 308 fr_authstats.fas_nospace++; 309 RWLOCK_EXIT(&ipf_auth); 310 return 0; 311 } 312 } 313 314 fr_authstats.fas_added++; 315 fr_authused++; 316 i = fr_authend++;
|
266 if (fr_authend == FR_NUMAUTH)
| 317 if (fr_authend == fr_authsize)
|
267 fr_authend = 0; 268 RWLOCK_EXIT(&ipf_auth);
| 318 fr_authend = 0; 319 RWLOCK_EXIT(&ipf_auth);
|
| 320
|
269 fra = fr_auth + i; 270 fra->fra_index = i; 271 fra->fra_pass = 0; 272 fra->fra_age = fr_defaultauthage; 273 bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
| 321 fra = fr_auth + i; 322 fra->fra_index = i; 323 fra->fra_pass = 0; 324 fra->fra_age = fr_defaultauthage; 325 bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
|
274#if SOLARIS && defined(_KERNEL) 275# if !defined(sparc)
| 326#if !defined(sparc) && !defined(m68k)
|
276 /* 277 * No need to copyback here as we want to undo the changes, not keep 278 * them. 279 */
| 327 /* 328 * No need to copyback here as we want to undo the changes, not keep 329 * them. 330 */
|
280 if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
| 331 ip = fin->fin_ip; 332# if defined(MENTAT) && defined(_KERNEL) 333 if ((ip == (ip_t *)m->b_rptr) && (fin->fin_v == 4)) 334# endif
|
281 { 282 register u_short bo; 283 284 bo = ip->ip_len; 285 ip->ip_len = htons(bo); 286 bo = ip->ip_off; 287 ip->ip_off = htons(bo); 288 }
| 335 { 336 register u_short bo; 337 338 bo = ip->ip_len; 339 ip->ip_len = htons(bo); 340 bo = ip->ip_off; 341 ip->ip_off = htons(bo); 342 }
|
289# endif 290 m->b_rptr -= qif->qf_off;
| 343#endif 344#if SOLARIS && defined(_KERNEL) 345 m->b_rptr -= qpi->qpi_off;
|
291 fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
| 346 fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
|
292 fra->fra_q = qif->qf_q;
| 347 fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
|
293 cv_signal(&ipfauthwait); 294#else 295# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
| 348 cv_signal(&ipfauthwait); 349#else 350# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
|
296 if (fin->fin_out == 0) {
| 351 if (!fin->fin_out) {
|
297 ip->ip_len = htons(ip->ip_len); 298 ip->ip_off = htons(ip->ip_off); 299 } 300# endif 301 fr_authpkts[i] = m;
| 352 ip->ip_len = htons(ip->ip_len); 353 ip->ip_off = htons(ip->ip_off); 354 } 355# endif 356 fr_authpkts[i] = m;
|
302 WAKEUP(&fr_authnext);
| 357 WAKEUP(&fr_authnext,0);
|
303#endif 304 return 1; 305} 306 307
| 358#endif 359 return 1; 360} 361 362
|
308int fr_auth_ioctl(data, mode, cmd)
| 363int fr_auth_ioctl(data, cmd, mode)
|
309caddr_t data;
| 364caddr_t data;
|
| 365ioctlcmd_t cmd;
|
310int mode;
| 366int mode;
|
311#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003) 312u_long cmd; 313#else 314int cmd; 315#endif
| |
316{ 317 mb_t *m;
| 367{ 368 mb_t *m;
|
318#if defined(_KERNEL) && !SOLARIS 319# if !defined(__FreeBSD_version) || (__FreeBSD_version < 501104)
| 369#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ 370 (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
|
320 struct ifqueue *ifq;
| 371 struct ifqueue *ifq;
|
321# endif
| 372# ifdef USE_SPL
|
322 int s;
| 373 int s;
|
| 374# endif /* USE_SPL */
|
323#endif 324 frauth_t auth, *au = &auth, *fra;
| 375#endif 376 frauth_t auth, *au = &auth, *fra;
|
325 int i, error = 0;
| 377 int i, error = 0, len; 378 char *t;
|
326 327 switch (cmd) 328 { 329 case SIOCSTLCK : 330 if (!(mode & FWRITE)) { 331 error = EPERM; 332 break; 333 }
| 379 380 switch (cmd) 381 { 382 case SIOCSTLCK : 383 if (!(mode & FWRITE)) { 384 error = EPERM; 385 break; 386 }
|
334 error = fr_lock(data, &fr_auth_lock);
| 387 fr_lock(data, &fr_auth_lock);
|
335 break;
| 388 break;
|
336 case SIOCINIFR : 337 case SIOCRMIFR : 338 case SIOCADIFR : 339 error = EINVAL; 340 break; 341 case SIOCINAFR : 342 error = EINVAL; 343 break; 344 case SIOCRMAFR : 345 case SIOCADAFR : 346 /* These commands go via request to fr_preauthcmd */ 347 error = EINVAL; 348 break;
| 389
|
349 case SIOCATHST: 350 fr_authstats.fas_faelist = fae_list;
| 390 case SIOCATHST: 391 fr_authstats.fas_faelist = fae_list;
|
351 error = IWCOPYPTR((char *)&fr_authstats, data, 352 sizeof(fr_authstats));
| 392 error = fr_outobj(data, &fr_authstats, IPFOBJ_AUTHSTAT);
|
353 break;
| 393 break;
|
| 394 395 case SIOCIPFFL: 396 SPL_NET(s); 397 WRITE_ENTER(&ipf_auth); 398 i = fr_authflush(); 399 RWLOCK_EXIT(&ipf_auth); 400 SPL_X(s); 401 error = copyoutptr((char *)&i, data, sizeof(i)); 402 break; 403
|
354 case SIOCAUTHW:
| 404 case SIOCAUTHW:
|
355 if (!(mode & FWRITE)) { 356 error = EPERM; 357 break; 358 }
| |
359fr_authioctlloop:
| 405fr_authioctlloop:
|
| 406 error = fr_inobj(data, au, IPFOBJ_FRAUTH);
|
360 READ_ENTER(&ipf_auth); 361 if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
| 407 READ_ENTER(&ipf_auth); 408 if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
|
362 error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data, 363 sizeof(frauth_t));
| 409 error = fr_outobj(data, &fr_auth[fr_authnext], 410 IPFOBJ_FRAUTH); 411 if (auth.fra_len != 0 && auth.fra_buf != NULL) { 412 /* 413 * Copy packet contents out to user space if 414 * requested. Bail on an error. 415 */ 416 m = fr_authpkts[fr_authnext]; 417 len = MSGDSIZE(m); 418 if (len > auth.fra_len) 419 len = auth.fra_len; 420 auth.fra_len = len; 421 for (t = auth.fra_buf; m && (len > 0); ) { 422 i = MIN(M_LEN(m), len); 423 error = copyoutptr(MTOD(m, char *), 424 t, i); 425 len -= i; 426 t += i; 427 if (error != 0) 428 break; 429 } 430 }
|
364 RWLOCK_EXIT(&ipf_auth);
| 431 RWLOCK_EXIT(&ipf_auth);
|
365 if (error)
| 432 if (error != 0)
|
366 break;
| 433 break;
|
367 WRITE_ENTER(&ipf_auth);
| |
368 SPL_NET(s);
| 434 SPL_NET(s);
|
| 435 WRITE_ENTER(&ipf_auth);
|
369 fr_authnext++;
| 436 fr_authnext++;
|
370 if (fr_authnext == FR_NUMAUTH)
| 437 if (fr_authnext == fr_authsize)
|
371 fr_authnext = 0;
| 438 fr_authnext = 0;
|
372 SPL_X(s);
| |
373 RWLOCK_EXIT(&ipf_auth);
| 439 RWLOCK_EXIT(&ipf_auth);
|
| 440 SPL_X(s);
|
374 return 0; 375 } 376 RWLOCK_EXIT(&ipf_auth);
| 441 return 0; 442 } 443 RWLOCK_EXIT(&ipf_auth);
|
| 444 /* 445 * We exit ipf_global here because a program that enters in 446 * here will have a lock on it and goto sleep having this lock. 447 * If someone were to do an 'ipf -D' the system would then 448 * deadlock. The catch with releasing it here is that the 449 * caller of this function expects it to be held when we 450 * return so we have to reacquire it in here. 451 */ 452 RWLOCK_EXIT(&ipf_global); 453 454 MUTEX_ENTER(&ipf_authmx);
|
377#ifdef _KERNEL 378# if SOLARIS
| 455#ifdef _KERNEL 456# if SOLARIS
|
379 mutex_enter(&ipf_authmx); 380 if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) { 381 mutex_exit(&ipf_authmx); 382 return EINTR;
| 457 error = 0; 458 if (!cv_wait_sig(&ipfauthwait, &ipf_authmx.ipf_lk)) 459 error = EINTR; 460# else /* SOLARIS */ 461# ifdef __hpux 462 { 463 lock_t *l; 464 465 l = get_sleep_lock(&fr_authnext); 466 error = sleep(&fr_authnext, PZERO+1); 467 spinunlock(l);
|
383 }
| 468 }
|
384 mutex_exit(&ipf_authmx); 385# else
| 469# else 470# ifdef __osf__ 471 error = mpsleep(&fr_authnext, PSUSP|PCATCH, "fr_authnext", 0, 472 &ipf_authmx, MS_LOCK_SIMPLE); 473# else
|
386 error = SLEEP(&fr_authnext, "fr_authnext");
| 474 error = SLEEP(&fr_authnext, "fr_authnext");
|
387# endif
| 475# endif /* __osf__ */ 476# endif /* __hpux */ 477# endif /* SOLARIS */
|
388#endif
| 478#endif
|
389 if (!error)
| 479 MUTEX_EXIT(&ipf_authmx); 480 READ_ENTER(&ipf_global); 481 if (error == 0) { 482 READ_ENTER(&ipf_auth);
|
390 goto fr_authioctlloop;
| 483 goto fr_authioctlloop;
|
| 484 }
|
391 break;
| 485 break;
|
| 486
|
392 case SIOCAUTHR:
| 487 case SIOCAUTHR:
|
393 if (!(mode & FWRITE)) { 394 error = EPERM; 395 break; 396 } 397 error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth)); 398 if (error)
| 488 error = fr_inobj(data, &auth, IPFOBJ_FRAUTH); 489 if (error != 0)
|
399 return error;
| 490 return error;
|
400 WRITE_ENTER(&ipf_auth);
| |
401 SPL_NET(s);
| 491 SPL_NET(s);
|
| 492 WRITE_ENTER(&ipf_auth);
|
402 i = au->fra_index; 403 fra = fr_auth + i;
| 493 i = au->fra_index; 494 fra = fr_auth + i;
|
404 if ((i < 0) || (i > FR_NUMAUTH) ||
| 495 if ((i < 0) || (i >= fr_authsize) ||
|
405 (fra->fra_info.fin_id != au->fra_info.fin_id)) {
| 496 (fra->fra_info.fin_id != au->fra_info.fin_id)) {
|
406 SPL_X(s);
| |
407 RWLOCK_EXIT(&ipf_auth);
| 497 RWLOCK_EXIT(&ipf_auth);
|
408 return EINVAL;
| 498 SPL_X(s); 499 return ESRCH;
|
409 } 410 m = fr_authpkts[i]; 411 fra->fra_index = -2; 412 fra->fra_pass = au->fra_pass; 413 fr_authpkts[i] = NULL; 414 RWLOCK_EXIT(&ipf_auth); 415#ifdef _KERNEL
| 500 } 501 m = fr_authpkts[i]; 502 fra->fra_index = -2; 503 fra->fra_pass = au->fra_pass; 504 fr_authpkts[i] = NULL; 505 RWLOCK_EXIT(&ipf_auth); 506#ifdef _KERNEL
|
416 if (m && au->fra_info.fin_out) { 417# if SOLARIS 418 error = (fr_qout(fra->fra_q, m) == 0) ? EINVAL : 0; 419# else /* SOLARIS */ 420 struct route ro; 421 422 bzero((char *)&ro, sizeof(ro)); 423# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \ 424 defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \ 425 (__FreeBSD_version >= 470102) 426 error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL, 427 NULL);
| 507 if ((m != NULL) && (au->fra_info.fin_out != 0)) { 508# ifdef MENTAT 509 error = !putq(fra->fra_q, m); 510# else /* MENTAT */ 511# ifdef linux
|
428# else
| 512# else
|
429 error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL); 430# endif 431 if (ro.ro_rt) { 432 RTFREE(ro.ro_rt); 433 } 434# endif /* SOLARIS */ 435 if (error)
| 513# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \ 514 (defined(__sgi) && (IRIX >= 60500) || \ 515 (defined(__FreeBSD__) && (__FreeBSD_version >= 470102))) 516 error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, 517 NULL); 518# else 519 error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); 520# endif 521# endif /* Linux */ 522# endif /* MENTAT */ 523 if (error != 0)
|
436 fr_authstats.fas_sendfail++; 437 else 438 fr_authstats.fas_sendok++; 439 } else if (m) {
| 524 fr_authstats.fas_sendfail++; 525 else 526 fr_authstats.fas_sendok++; 527 } else if (m) {
|
440# if SOLARIS 441 error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0; 442# else /* SOLARIS */ 443 if (! netisr_queue(NETISR_IP, m))
| 528# ifdef MENTAT 529 error = !putq(fra->fra_q, m); 530# else /* MENTAT */ 531# ifdef linux 532# else 533# if __FreeBSD_version >= 501000 534 netisr_dispatch(NETISR_IP, m); 535# else 536# if IRIX >= 60516 537 ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd; 538# else 539 ifq = &ipintrq; 540# endif 541 if (IF_QFULL(ifq)) { 542 IF_DROP(ifq); 543 FREE_MB_T(m);
|
444 error = ENOBUFS;
| 544 error = ENOBUFS;
|
445# endif /* SOLARIS */ 446 if (error)
| 545 } else { 546 IF_ENQUEUE(ifq, m); 547# if IRIX < 60500 548 schednetisr(NETISR_IP); 549# endif 550 } 551# endif 552# endif /* Linux */ 553# endif /* MENTAT */ 554 if (error != 0)
|
447 fr_authstats.fas_quefail++; 448 else 449 fr_authstats.fas_queok++; 450 } else 451 error = EINVAL;
| 555 fr_authstats.fas_quefail++; 556 else 557 fr_authstats.fas_queok++; 558 } else 559 error = EINVAL;
|
452# if SOLARIS 453 if (error)
| 560# ifdef MENTAT 561 if (error != 0)
|
454 error = EINVAL;
| 562 error = EINVAL;
|
455# else
| 563# else /* MENTAT */
|
456 /* 457 * If we experience an error which will result in the packet 458 * not being processed, make sure we advance to the next one.
| 564 /* 565 * If we experience an error which will result in the packet 566 * not being processed, make sure we advance to the next one.
|
459 */
| 567 */
|
460 if (error == ENOBUFS) { 461 fr_authused--; 462 fra->fra_index = -1; 463 fra->fra_pass = 0; 464 if (i == fr_authstart) { 465 while (fra->fra_index == -1) { 466 i++;
| 568 if (error == ENOBUFS) { 569 fr_authused--; 570 fra->fra_index = -1; 571 fra->fra_pass = 0; 572 if (i == fr_authstart) { 573 while (fra->fra_index == -1) { 574 i++;
|
467 if (i == FR_NUMAUTH)
| 575 if (i == fr_authsize)
|
468 i = 0; 469 fr_authstart = i; 470 if (i == fr_authend) 471 break; 472 } 473 if (fr_authstart == fr_authend) { 474 fr_authnext = 0; 475 fr_authstart = fr_authend = 0; 476 } 477 } 478 }
| 576 i = 0; 577 fr_authstart = i; 578 if (i == fr_authend) 579 break; 580 } 581 if (fr_authstart == fr_authend) { 582 fr_authnext = 0; 583 fr_authstart = fr_authend = 0; 584 } 585 } 586 }
|
479# endif
| 587# endif /* MENTAT */
|
480#endif /* _KERNEL */ 481 SPL_X(s); 482 break;
| 588#endif /* _KERNEL */ 589 SPL_X(s); 590 break;
|
| 591
|
483 default : 484 error = EINVAL; 485 break; 486 } 487 return error; 488} 489 490 491/* 492 * Free all network buffer memory used to keep saved packets. 493 */ 494void fr_authunload() 495{ 496 register int i; 497 register frauthent_t *fae, **faep; 498 frentry_t *fr, **frp; 499 mb_t *m; 500
| 592 default : 593 error = EINVAL; 594 break; 595 } 596 return error; 597} 598 599 600/* 601 * Free all network buffer memory used to keep saved packets. 602 */ 603void fr_authunload() 604{ 605 register int i; 606 register frauthent_t *fae, **faep; 607 frentry_t *fr, **frp; 608 mb_t *m; 609
|
501 WRITE_ENTER(&ipf_auth); 502 for (i = 0; i < FR_NUMAUTH; i++) { 503 if ((m = fr_authpkts[i])) { 504 FREE_MB_T(m); 505 fr_authpkts[i] = NULL; 506 fr_auth[i].fra_index = -1;
| 610 if (fr_auth != NULL) { 611 KFREES(fr_auth, fr_authsize * sizeof(*fr_auth)); 612 fr_auth = NULL; 613 } 614 615 if (fr_authpkts != NULL) { 616 for (i = 0; i < fr_authsize; i++) { 617 m = fr_authpkts[i]; 618 if (m != NULL) { 619 FREE_MB_T(m); 620 fr_authpkts[i] = NULL; 621 }
|
507 }
| 622 }
|
| 623 KFREES(fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); 624 fr_authpkts = NULL;
|
508 } 509
| 625 } 626
|
510 511 for (faep = &fae_list; (fae = *faep); ) {
| 627 faep = &fae_list; 628 while ((fae = *faep) != NULL) {
|
512 *faep = fae->fae_next; 513 KFREE(fae); 514 } 515 ipauth = NULL;
| 629 *faep = fae->fae_next; 630 KFREE(fae); 631 } 632 ipauth = NULL;
|
516 RWLOCK_EXIT(&ipf_auth);
| |
517
| 633
|
518 if (fr_authlist) { 519 /* 520 * We *MuST* reget ipf_auth because otherwise we won't get the 521 * locks in the right order and risk deadlock. 522 * We need ipf_mutex here to prevent a rule from using it 523 * inside fr_check(). 524 */ 525 WRITE_ENTER(&ipf_mutex); 526 WRITE_ENTER(&ipf_auth); 527 for (frp = &fr_authlist; (fr = *frp); ) {
| 634 if (fr_authlist != NULL) { 635 for (frp = &fr_authlist; ((fr = *frp) != NULL); ) {
|
528 if (fr->fr_ref == 1) { 529 *frp = fr->fr_next; 530 KFREE(fr); 531 } else 532 frp = &fr->fr_next; 533 }
| 636 if (fr->fr_ref == 1) { 637 *frp = fr->fr_next; 638 KFREE(fr); 639 } else 640 frp = &fr->fr_next; 641 }
|
534 RWLOCK_EXIT(&ipf_auth); 535 RWLOCK_EXIT(&ipf_mutex);
| |
536 }
| 642 }
|
| 643 644 if (fr_auth_init == 1) { 645# if SOLARIS && defined(_KERNEL) 646 cv_destroy(&ipfauthwait); 647# endif 648 MUTEX_DESTROY(&ipf_authmx); 649 RW_DESTROY(&ipf_auth); 650 651 fr_auth_init = 0; 652 }
|
537} 538 539 540/* 541 * Slowly expire held auth records. Timeouts are set 542 * in expectation of this being called twice per second. 543 */ 544void fr_authexpire() 545{ 546 register int i; 547 register frauth_t *fra; 548 register frauthent_t *fae, **faep; 549 register frentry_t *fr, **frp; 550 mb_t *m;
| 653} 654 655 656/* 657 * Slowly expire held auth records. Timeouts are set 658 * in expectation of this being called twice per second. 659 */ 660void fr_authexpire() 661{ 662 register int i; 663 register frauth_t *fra; 664 register frauthent_t *fae, **faep; 665 register frentry_t *fr, **frp; 666 mb_t *m;
|
551#if !SOLARIS && defined(_KERNEL)
| 667# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
|
552 int s;
| 668 int s;
|
553#endif
| 669# endif
|
554 555 if (fr_auth_lock) 556 return; 557 558 SPL_NET(s); 559 WRITE_ENTER(&ipf_auth);
| 670 671 if (fr_auth_lock) 672 return; 673 674 SPL_NET(s); 675 WRITE_ENTER(&ipf_auth);
|
560 for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) { 561 if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
| 676 for (i = 0, fra = fr_auth; i < fr_authsize; i++, fra++) { 677 fra->fra_age--; 678 if ((fra->fra_age == 0) && (m = fr_authpkts[i])) {
|
562 FREE_MB_T(m); 563 fr_authpkts[i] = NULL; 564 fr_auth[i].fra_index = -1; 565 fr_authstats.fas_expire++; 566 fr_authused--; 567 } 568 } 569
| 679 FREE_MB_T(m); 680 fr_authpkts[i] = NULL; 681 fr_auth[i].fra_index = -1; 682 fr_authstats.fas_expire++; 683 fr_authused--; 684 } 685 } 686
|
570 for (faep = &fae_list; (fae = *faep); ) { 571 if (!--fae->fae_age) {
| 687 for (faep = &fae_list; ((fae = *faep) != NULL); ) { 688 fae->fae_age--; 689 if (fae->fae_age == 0) {
|
572 *faep = fae->fae_next; 573 KFREE(fae); 574 fr_authstats.fas_expire++; 575 } else 576 faep = &fae->fae_next; 577 } 578 if (fae_list != NULL) 579 ipauth = &fae_list->fae_fr; 580 else 581 ipauth = NULL; 582
| 690 *faep = fae->fae_next; 691 KFREE(fae); 692 fr_authstats.fas_expire++; 693 } else 694 faep = &fae->fae_next; 695 } 696 if (fae_list != NULL) 697 ipauth = &fae_list->fae_fr; 698 else 699 ipauth = NULL; 700
|
583 for (frp = &fr_authlist; (fr = *frp); ) {
| 701 for (frp = &fr_authlist; ((fr = *frp) != NULL); ) {
|
584 if (fr->fr_ref == 1) { 585 *frp = fr->fr_next; 586 KFREE(fr); 587 } else 588 frp = &fr->fr_next; 589 } 590 RWLOCK_EXIT(&ipf_auth); 591 SPL_X(s); 592} 593 594int fr_preauthcmd(cmd, fr, frptr)
| 702 if (fr->fr_ref == 1) { 703 *frp = fr->fr_next; 704 KFREE(fr); 705 } else 706 frp = &fr->fr_next; 707 } 708 RWLOCK_EXIT(&ipf_auth); 709 SPL_X(s); 710} 711 712int fr_preauthcmd(cmd, fr, frptr)
|
595#if defined(__NetBSD__) || defined(__OpenBSD__) || \ 596 (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) 597u_long cmd; 598#else 599int cmd; 600#endif
| 713ioctlcmd_t cmd;
|
601frentry_t *fr, **frptr; 602{ 603 frauthent_t *fae, **faep; 604 int error = 0;
| 714frentry_t *fr, **frptr; 715{ 716 frauthent_t *fae, **faep; 717 int error = 0;
|
605#if defined(KERNEL) && !SOLARIS
| 718# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
|
606 int s; 607#endif 608
| 719 int s; 720#endif 721
|
609 if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) { 610 /* Should not happen */ 611 printf("fr_preauthcmd called with bad cmd 0x%lx", (u_long)cmd);
| 722 if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR))
|
612 return EIO;
| 723 return EIO;
|
613 }
| |
614
| 724
|
615 for (faep = &fae_list; (fae = *faep); )
| 725 for (faep = &fae_list; ((fae = *faep) != NULL); ) {
|
616 if (&fae->fae_fr == fr) 617 break; 618 else 619 faep = &fae->fae_next;
| 726 if (&fae->fae_fr == fr) 727 break; 728 else 729 faep = &fae->fae_next;
|
620 if (cmd == SIOCRMAFR) { 621 if (!fr || !frptr)
| 730 } 731 732 if (cmd == (ioctlcmd_t)SIOCRMAFR) { 733 if (fr == NULL || frptr == NULL)
|
622 error = EINVAL;
| 734 error = EINVAL;
|
623 else if (!fae)
| 735 else if (fae == NULL)
|
624 error = ESRCH; 625 else {
| 736 error = ESRCH; 737 else {
|
626 WRITE_ENTER(&ipf_auth);
| |
627 SPL_NET(s);
| 738 SPL_NET(s);
|
| 739 WRITE_ENTER(&ipf_auth);
|
628 *faep = fae->fae_next;
| 740 *faep = fae->fae_next;
|
629 *frptr = fr->fr_next; 630 SPL_X(s);
| 741 if (ipauth == &fae->fae_fr) 742 ipauth = fae_list ? &fae_list->fae_fr : NULL;
|
631 RWLOCK_EXIT(&ipf_auth);
| 743 RWLOCK_EXIT(&ipf_auth);
|
| 744 SPL_X(s); 745
|
632 KFREE(fae); 633 }
| 746 KFREE(fae); 747 }
|
634 } else if (fr && frptr) {
| 748 } else if (fr != NULL && frptr != NULL) {
|
635 KMALLOC(fae, frauthent_t *); 636 if (fae != NULL) { 637 bcopy((char *)fr, (char *)&fae->fae_fr, 638 sizeof(*fr));
| 749 KMALLOC(fae, frauthent_t *); 750 if (fae != NULL) { 751 bcopy((char *)fr, (char *)&fae->fae_fr, 752 sizeof(*fr));
|
639 WRITE_ENTER(&ipf_auth);
| |
640 SPL_NET(s);
| 753 SPL_NET(s);
|
| 754 WRITE_ENTER(&ipf_auth);
|
641 fae->fae_age = fr_defaultauthage; 642 fae->fae_fr.fr_hits = 0; 643 fae->fae_fr.fr_next = *frptr; 644 *frptr = &fae->fae_fr; 645 fae->fae_next = *faep; 646 *faep = fae; 647 ipauth = &fae_list->fae_fr;
| 755 fae->fae_age = fr_defaultauthage; 756 fae->fae_fr.fr_hits = 0; 757 fae->fae_fr.fr_next = *frptr; 758 *frptr = &fae->fae_fr; 759 fae->fae_next = *faep; 760 *faep = fae; 761 ipauth = &fae_list->fae_fr;
|
648 SPL_X(s);
| |
649 RWLOCK_EXIT(&ipf_auth);
| 762 RWLOCK_EXIT(&ipf_auth);
|
| 763 SPL_X(s);
|
650 } else 651 error = ENOMEM; 652 } else 653 error = EINVAL; 654 return error; 655}
| 764 } else 765 error = ENOMEM; 766 } else 767 error = EINVAL; 768 return error; 769}
|
| 770 771 772/* 773 * Flush held packets. 774 * Must already be properly SPL'ed and Locked on &ipf_auth. 775 * 776 */ 777int fr_authflush() 778{ 779 register int i, num_flushed; 780 mb_t *m; 781 782 if (fr_auth_lock) 783 return -1; 784 785 num_flushed = 0; 786 787 for (i = 0 ; i < fr_authsize; i++) { 788 m = fr_authpkts[i]; 789 if (m != NULL) { 790 FREE_MB_T(m); 791 fr_authpkts[i] = NULL; 792 fr_auth[i].fra_index = -1; 793 /* perhaps add & use a flush counter inst.*/ 794 fr_authstats.fas_expire++; 795 fr_authused--; 796 num_flushed++; 797 } 798 } 799 800 fr_authstart = 0; 801 fr_authend = 0; 802 fr_authnext = 0; 803 804 return num_flushed; 805}
|
| |