blob: b19ac4c8ff5d46ba7d0635963cc768a46a8d6e95 [file] [log] [blame] [raw]
Darren Reedda0443e2006-06-15 16:17:17 +00001/*
2 * Copyright (C) 2002-2003 by Darren Reed.
3 *
4 * See the IPFILTER.LICENCE file for details on licencing.
5 */
6#if defined(KERNEL) || defined(_KERNEL)
7# undef KERNEL
8# undef _KERNEL
9# define KERNEL 1
10# define _KERNEL 1
11#endif
12#if defined(__osf__)
13# define _PROTO_NET_H_
14#endif
15#include <sys/param.h>
16#include <sys/errno.h>
17#include <sys/types.h>
18#include <sys/time.h>
19#include <sys/file.h>
20#if __FreeBSD_version >= 220000 && defined(_KERNEL)
21# include <sys/fcntl.h>
22# include <sys/filio.h>
23#else
24# include <sys/ioctl.h>
25#endif
26#if !defined(_KERNEL)
Darren Reedae72cf02008-03-07 09:09:49 +000027# include <stdio.h>
Darren Reedda0443e2006-06-15 16:17:17 +000028# include <string.h>
Darren Reed1b44c342008-08-10 05:51:57 +000029# include <stdlib.h>
Darren Reedda0443e2006-06-15 16:17:17 +000030# define _KERNEL
31# ifdef __OpenBSD__
32struct file;
33# endif
34# include <sys/uio.h>
35# undef _KERNEL
36#endif
37#include <sys/socket.h>
Darren Reedda0443e2006-06-15 16:17:17 +000038#include <net/if.h>
39#if defined(__FreeBSD__)
Darren Reed1b44c342008-08-10 05:51:57 +000040# include <sys/cdefs.h>
41# include <sys/proc.h>
Darren Reedda0443e2006-06-15 16:17:17 +000042#endif
43#if defined(_KERNEL)
44# include <sys/systm.h>
45# if !defined(__SVR4) && !defined(__svr4__)
46# include <sys/mbuf.h>
47# endif
Darren Reedabb8af62009-07-23 11:57:09 +000048#else
49# include "ipf.h"
Darren Reedda0443e2006-06-15 16:17:17 +000050#endif
51#include <netinet/in.h>
52
53#include "netinet/ip_compat.h"
54#include "netinet/ip_fil.h"
Darren Reedae72cf02008-03-07 09:09:49 +000055#include "netinet/ip_lookup.h"
Darren Reedda0443e2006-06-15 16:17:17 +000056#include "netinet/ip_pool.h"
57#include "netinet/ip_htable.h"
Darren Reedfdc6eed2009-01-03 06:02:37 +000058#include "netinet/ip_dstlist.h"
Darren Reedda0443e2006-06-15 16:17:17 +000059/* END OF INCLUDES */
60
61#if !defined(lint)
62static const char rcsid[] = "@(#)$Id$";
63#endif
64
Darren Reedde949852009-03-03 10:07:12 +000065/*
66 * In this file, ip_pool.c, ip_htable.c and ip_dstlist.c, you will find the
67 * range for unit is [-1,IPL_LOGMAX]. The -1 is considered to be a valid number
68 * and represents a "wildcard" or "all" units (IPL_LOGALL). The reason for not
69 * starting the numbering at 0 is because the numbers [0,IPL_LOGMAX] correspond
70 * to the minor device number for their respective device. Thus where there is
71 * array indexing on the unit, +1 is used to map [-1.IPL_LOGMAX] to
72 * [0.POOL_LOOKUP_MAX].
73 */
Darren Reed278d16e2009-12-27 07:34:34 +000074static int ipf_lookup_addnode __P((ipf_main_softc_t *, caddr_t, int));
75static int ipf_lookup_delnode __P((ipf_main_softc_t *, caddr_t, int));
76static int ipf_lookup_addtable __P((ipf_main_softc_t *, caddr_t));
77static int ipf_lookup_deltable __P((ipf_main_softc_t *, caddr_t));
78static int ipf_lookup_stats __P((ipf_main_softc_t *, caddr_t));
79static int ipf_lookup_flush __P((ipf_main_softc_t *, caddr_t));
80static int ipf_lookup_iterate __P((ipf_main_softc_t *, void *, int, void *));
81static int ipf_lookup_deltok __P((ipf_main_softc_t *, void *, int, void *));
Darren Reedda0443e2006-06-15 16:17:17 +000082
Darren Reedf96e37f2009-12-19 12:33:30 +000083#define MAX_BACKENDS 3
84static ipf_lookup_t *backends[MAX_BACKENDS] = {
Darren Reedae72cf02008-03-07 09:09:49 +000085 &ipf_pool_backend,
86 &ipf_htable_backend,
87 &ipf_dstlist_backend
88};
89
Darren Reedda0443e2006-06-15 16:17:17 +000090
Darren Reed1b44c342008-08-10 05:51:57 +000091typedef struct ipf_lookup_softc_s {
92 void *ipf_back[MAX_BACKENDS];
93} ipf_lookup_softc_t;
94
Darren Reedf96e37f2009-12-19 12:33:30 +000095
Darren Reedd4718fc2006-06-15 17:00:40 +000096/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +000097/* Function: ipf_lookup_init */
Darren Reed8038b7d2008-12-31 10:55:21 +000098/* Returns: int - 0 = success, else error */
99/* Parameters: softc(I) - pointer to soft context main structure */
Darren Reedd4718fc2006-06-15 17:00:40 +0000100/* */
101/* Initialise all of the subcomponents of the lookup infrstructure. */
102/* ------------------------------------------------------------------------ */
Darren Reed1b44c342008-08-10 05:51:57 +0000103void *
104ipf_lookup_soft_create(softc)
105 ipf_main_softc_t *softc;
Darren Reedda0443e2006-06-15 16:17:17 +0000106{
Darren Reed1b44c342008-08-10 05:51:57 +0000107 ipf_lookup_softc_t *softl;
108 ipf_lookup_t **l;
Darren Reedae72cf02008-03-07 09:09:49 +0000109 int i;
Darren Reedda0443e2006-06-15 16:17:17 +0000110
Darren Reed1b44c342008-08-10 05:51:57 +0000111 KMALLOC(softl, ipf_lookup_softc_t *);
112 if (softl == NULL)
113 return NULL;
114
115 bzero((char *)softl, sizeof(*softl));
116
117 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
118 softl->ipf_back[i] = (*(*l)->ipfl_create)(softc);
119 if (softl->ipf_back[i] == NULL) {
120 ipf_lookup_soft_destroy(softc, softl);
121 return NULL;
122 }
123 }
124
125 return softl;
126}
127
128
Darren Reed8038b7d2008-12-31 10:55:21 +0000129/* ------------------------------------------------------------------------ */
130/* Function: ipf_lookup_soft_init */
131/* Returns: int - 0 = success, else error */
132/* Parameters: softc(I) - pointer to soft context main structure */
133/* arg(I) - pointer to local context to use */
134/* */
135/* Initialise all of the subcomponents of the lookup infrstructure. */
136/* ------------------------------------------------------------------------ */
Darren Reed1b44c342008-08-10 05:51:57 +0000137int
138ipf_lookup_soft_init(softc, arg)
139 ipf_main_softc_t *softc;
140 void *arg;
141{
142 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
143 int err = 0;
144 int i;
Darren Reedae72cf02008-03-07 09:09:49 +0000145
146 for (i = 0; i < MAX_BACKENDS; i++) {
Darren Reed1b44c342008-08-10 05:51:57 +0000147 err = (*backends[i]->ipfl_init)(softc, softl->ipf_back[i]);
148 if (err != 0)
149 break;
150 }
151
152 return err;
153}
154
155
Darren Reed8038b7d2008-12-31 10:55:21 +0000156/* ------------------------------------------------------------------------ */
157/* Function: ipf_lookup_soft_fini */
158/* Returns: int - 0 = success, else error */
159/* Parameters: softc(I) - pointer to soft context main structure */
160/* arg(I) - pointer to local context to use */
161/* */
162/* Call the fini function in each backend to cleanup all allocated data. */
163/* ------------------------------------------------------------------------ */
Darren Reed1b44c342008-08-10 05:51:57 +0000164int
165ipf_lookup_soft_fini(softc, arg)
166 ipf_main_softc_t *softc;
167 void *arg;
168{
169 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
170 int i;
171
172 for (i = 0; i < MAX_BACKENDS; i++) {
173 if (softl->ipf_back[i] != NULL)
174 (*backends[i]->ipfl_fini)(softc,
175 softl->ipf_back[i]);
Darren Reedae72cf02008-03-07 09:09:49 +0000176 }
Darren Reedda0443e2006-06-15 16:17:17 +0000177
178 return 0;
179}
180
181
Darren Reedd4718fc2006-06-15 17:00:40 +0000182/* ------------------------------------------------------------------------ */
Darren Reed8038b7d2008-12-31 10:55:21 +0000183/* Function: ipf_lookup_expire */
184/* Returns: Nil */
185/* Parameters: softc(I) - pointer to soft context main structure */
186/* */
187/* Step through each of the backends and call their expire functions, */
188/* allowing them to delete any lifetime limited data. */
189/* ------------------------------------------------------------------------ */
190void
191ipf_lookup_expire(softc)
192 ipf_main_softc_t *softc;
193{
194 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
195 int i;
196
197 WRITE_ENTER(&softc->ipf_poolrw);
198 for (i = 0; i < MAX_BACKENDS; i++)
199 (*backends[i]->ipfl_expire)(softc, softl->ipf_back[i]);
200 RWLOCK_EXIT(&softc->ipf_poolrw);
201}
202
203
204/* ------------------------------------------------------------------------ */
Darren Reed1b44c342008-08-10 05:51:57 +0000205/* Function: ipf_lookup_softc_destroy */
Darren Reedd4718fc2006-06-15 17:00:40 +0000206/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000207/* Parameters: softc(I) - pointer to soft context main structure */
208/* arg(I) - pointer to local context to use */
Darren Reedd4718fc2006-06-15 17:00:40 +0000209/* */
210/* Free up all pool related memory that has been allocated whilst IPFilter */
211/* has been running. Also, do any other deinitialisation required such */
Darren Reedc4af1f32007-08-20 10:15:33 +0000212/* ipf_lookup_init() can be called again, safely. */
Darren Reedd4718fc2006-06-15 17:00:40 +0000213/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000214void
Darren Reed1b44c342008-08-10 05:51:57 +0000215ipf_lookup_soft_destroy(softc, arg)
216 ipf_main_softc_t *softc;
217 void *arg;
Darren Reedda0443e2006-06-15 16:17:17 +0000218{
Darren Reed1b44c342008-08-10 05:51:57 +0000219 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
Darren Reedae72cf02008-03-07 09:09:49 +0000220 int i;
221
222 for (i = 0; i < MAX_BACKENDS; i++) {
Darren Reed1b44c342008-08-10 05:51:57 +0000223 if (softl->ipf_back[i] != NULL)
224 (*backends[i]->ipfl_destroy)(softc,
225 softl->ipf_back[i]);
Darren Reedae72cf02008-03-07 09:09:49 +0000226 }
Darren Reedda0443e2006-06-15 16:17:17 +0000227
Darren Reed1b44c342008-08-10 05:51:57 +0000228 KFREE(softl);
Darren Reedda0443e2006-06-15 16:17:17 +0000229}
230
231
Darren Reedd4718fc2006-06-15 17:00:40 +0000232/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000233/* Function: ipf_lookup_ioctl */
Darren Reedd4718fc2006-06-15 17:00:40 +0000234/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000235/* Parameters: softc(I) - pointer to soft context main structure */
236/* arg(I) - pointer to local context to use */
237/* data(IO) - pointer to ioctl data to be copied to/from user */
Darren Reedd4718fc2006-06-15 17:00:40 +0000238/* space. */
239/* cmd(I) - ioctl command number */
240/* mode(I) - file mode bits used with open */
Darren Reed8038b7d2008-12-31 10:55:21 +0000241/* uid(I) - uid of process doing ioctl */
242/* ctx(I) - pointer that represents context for uid */
Darren Reedd4718fc2006-06-15 17:00:40 +0000243/* */
244/* Handle ioctl commands sent to the ioctl device. For the most part, this */
245/* involves just calling another function to handle the specifics of each */
246/* command. */
247/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000248int
Darren Reed1b44c342008-08-10 05:51:57 +0000249ipf_lookup_ioctl(softc, data, cmd, mode, uid, ctx)
250 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000251 caddr_t data;
252 ioctlcmd_t cmd;
253 int mode, uid;
254 void *ctx;
Darren Reedda0443e2006-06-15 16:17:17 +0000255{
256 int err;
Darren Reedd4718fc2006-06-15 17:00:40 +0000257 SPL_INT(s);
Darren Reedda0443e2006-06-15 16:17:17 +0000258
259 mode = mode; /* LINT */
260
261 SPL_NET(s);
262
263 switch (cmd)
264 {
265 case SIOCLOOKUPADDNODE :
Darren Reedd4718fc2006-06-15 17:00:40 +0000266 case SIOCLOOKUPADDNODEW :
Darren Reed1b44c342008-08-10 05:51:57 +0000267 WRITE_ENTER(&softc->ipf_poolrw);
Darren Reed408afbd2009-02-09 01:49:27 +0000268 err = ipf_lookup_addnode(softc, data, uid);
Darren Reed1b44c342008-08-10 05:51:57 +0000269 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedda0443e2006-06-15 16:17:17 +0000270 break;
271
272 case SIOCLOOKUPDELNODE :
Darren Reedd4718fc2006-06-15 17:00:40 +0000273 case SIOCLOOKUPDELNODEW :
Darren Reed1b44c342008-08-10 05:51:57 +0000274 WRITE_ENTER(&softc->ipf_poolrw);
Darren Reed408afbd2009-02-09 01:49:27 +0000275 err = ipf_lookup_delnode(softc, data, uid);
Darren Reed1b44c342008-08-10 05:51:57 +0000276 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedda0443e2006-06-15 16:17:17 +0000277 break;
278
279 case SIOCLOOKUPADDTABLE :
Darren Reed1b44c342008-08-10 05:51:57 +0000280 WRITE_ENTER(&softc->ipf_poolrw);
281 err = ipf_lookup_addtable(softc, data);
282 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedda0443e2006-06-15 16:17:17 +0000283 break;
284
285 case SIOCLOOKUPDELTABLE :
Darren Reed1b44c342008-08-10 05:51:57 +0000286 WRITE_ENTER(&softc->ipf_poolrw);
287 err = ipf_lookup_deltable(softc, data);
288 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedda0443e2006-06-15 16:17:17 +0000289 break;
290
291 case SIOCLOOKUPSTAT :
Darren Reedd4718fc2006-06-15 17:00:40 +0000292 case SIOCLOOKUPSTATW :
Darren Reed1b44c342008-08-10 05:51:57 +0000293 WRITE_ENTER(&softc->ipf_poolrw);
294 err = ipf_lookup_stats(softc, data);
295 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedda0443e2006-06-15 16:17:17 +0000296 break;
297
298 case SIOCLOOKUPFLUSH :
Darren Reed1b44c342008-08-10 05:51:57 +0000299 WRITE_ENTER(&softc->ipf_poolrw);
300 err = ipf_lookup_flush(softc, data);
301 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedc4af1f32007-08-20 10:15:33 +0000302 break;
303
304 case SIOCLOOKUPITER :
Darren Reed1b44c342008-08-10 05:51:57 +0000305 err = ipf_lookup_iterate(softc, data, uid, ctx);
Darren Reedda0443e2006-06-15 16:17:17 +0000306 break;
307
Darren Reed4c3f1622007-10-10 09:24:25 +0000308 case SIOCIPFDELTOK :
Darren Reed1b44c342008-08-10 05:51:57 +0000309 err = ipf_lookup_deltok(softc, data, uid, ctx);
Darren Reed4c3f1622007-10-10 09:24:25 +0000310 break;
311
Darren Reedda0443e2006-06-15 16:17:17 +0000312 default :
Darren Reed1b44c342008-08-10 05:51:57 +0000313 softc->ipf_interror = 50001;
Darren Reedda0443e2006-06-15 16:17:17 +0000314 err = EINVAL;
315 break;
316 }
317 SPL_X(s);
318 return err;
319}
320
321
Darren Reedd4718fc2006-06-15 17:00:40 +0000322/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000323/* Function: ipf_lookup_addnode */
Darren Reedd4718fc2006-06-15 17:00:40 +0000324/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000325/* Parameters: softc(I) - pointer to soft context main structure */
326/* data(I) - pointer to data from ioctl call */
Darren Reedd4718fc2006-06-15 17:00:40 +0000327/* */
328/* Add a new data node to a lookup structure. First, check to see if the */
329/* parent structure refered to by name exists and if it does, then go on to */
330/* add a node to it. */
331/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000332static int
Darren Reed408afbd2009-02-09 01:49:27 +0000333ipf_lookup_addnode(softc, data, uid)
Darren Reed1b44c342008-08-10 05:51:57 +0000334 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000335 caddr_t data;
Darren Reed408afbd2009-02-09 01:49:27 +0000336 int uid;
Darren Reedda0443e2006-06-15 16:17:17 +0000337{
Darren Reed1b44c342008-08-10 05:51:57 +0000338 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedda0443e2006-06-15 16:17:17 +0000339 iplookupop_t op;
Darren Reed1b44c342008-08-10 05:51:57 +0000340 ipf_lookup_t **l;
Darren Reedda0443e2006-06-15 16:17:17 +0000341 int err;
Darren Reedae72cf02008-03-07 09:09:49 +0000342 int i;
Darren Reedda0443e2006-06-15 16:17:17 +0000343
Darren Reedc4af1f32007-08-20 10:15:33 +0000344 err = BCOPYIN(data, &op, sizeof(op));
345 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000346 softc->ipf_interror = 50002;
Darren Reedc4af1f32007-08-20 10:15:33 +0000347 return EFAULT;
348 }
349
Darren Reedde949852009-03-03 10:07:12 +0000350 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
351 (op.iplo_unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000352 softc->ipf_interror = 50003;
Darren Reedc4af1f32007-08-20 10:15:33 +0000353 return EINVAL;
354 }
355
Darren Reedda0443e2006-06-15 16:17:17 +0000356 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
357
Darren Reed1b44c342008-08-10 05:51:57 +0000358 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
359 if (op.iplo_type == (*l)->ipfl_type) {
360 err = (*(*l)->ipfl_node_add)(softc,
361 softl->ipf_back[i],
Darren Reed408afbd2009-02-09 01:49:27 +0000362 &op, uid);
Darren Reedae72cf02008-03-07 09:09:49 +0000363 break;
Darren Reedc4af1f32007-08-20 10:15:33 +0000364 }
Darren Reedae72cf02008-03-07 09:09:49 +0000365 }
Darren Reedda0443e2006-06-15 16:17:17 +0000366
Darren Reedae72cf02008-03-07 09:09:49 +0000367 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000368 softc->ipf_interror = 50012;
Darren Reedda0443e2006-06-15 16:17:17 +0000369 err = EINVAL;
Darren Reedda0443e2006-06-15 16:17:17 +0000370 }
Darren Reedae72cf02008-03-07 09:09:49 +0000371
Darren Reedda0443e2006-06-15 16:17:17 +0000372 return err;
373}
374
375
Darren Reedd4718fc2006-06-15 17:00:40 +0000376/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000377/* Function: ipf_lookup_delnode */
Darren Reedd4718fc2006-06-15 17:00:40 +0000378/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000379/* Parameters: softc(I) - pointer to soft context main structure */
380/* data(I) - pointer to data from ioctl call */
Darren Reedd4718fc2006-06-15 17:00:40 +0000381/* */
382/* Delete a node from a lookup table by first looking for the table it is */
383/* in and then deleting the entry that gets found. */
384/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000385static int
Darren Reed408afbd2009-02-09 01:49:27 +0000386ipf_lookup_delnode(softc, data, uid)
Darren Reed1b44c342008-08-10 05:51:57 +0000387 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000388 caddr_t data;
Darren Reed408afbd2009-02-09 01:49:27 +0000389 int uid;
Darren Reedda0443e2006-06-15 16:17:17 +0000390{
Darren Reed1b44c342008-08-10 05:51:57 +0000391 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedda0443e2006-06-15 16:17:17 +0000392 iplookupop_t op;
Darren Reed1b44c342008-08-10 05:51:57 +0000393 ipf_lookup_t **l;
Darren Reedda0443e2006-06-15 16:17:17 +0000394 int err;
Darren Reedae72cf02008-03-07 09:09:49 +0000395 int i;
Darren Reedda0443e2006-06-15 16:17:17 +0000396
Darren Reedc4af1f32007-08-20 10:15:33 +0000397 err = BCOPYIN(data, &op, sizeof(op));
398 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000399 softc->ipf_interror = 50042;
Darren Reedc4af1f32007-08-20 10:15:33 +0000400 return EFAULT;
401 }
402
Darren Reedde949852009-03-03 10:07:12 +0000403 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
404 (op.iplo_unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000405 softc->ipf_interror = 50013;
Darren Reedc4af1f32007-08-20 10:15:33 +0000406 return EINVAL;
407 }
Darren Reedd4718fc2006-06-15 17:00:40 +0000408
Darren Reedda0443e2006-06-15 16:17:17 +0000409 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
410
Darren Reed1b44c342008-08-10 05:51:57 +0000411 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
412 if (op.iplo_type == (*l)->ipfl_type) {
Darren Reed408afbd2009-02-09 01:49:27 +0000413 err = (*(*l)->ipfl_node_del)(softc, softl->ipf_back[i],
414 &op, uid);
Darren Reedae72cf02008-03-07 09:09:49 +0000415 break;
Darren Reedc4af1f32007-08-20 10:15:33 +0000416 }
Darren Reedae72cf02008-03-07 09:09:49 +0000417 }
Darren Reedda0443e2006-06-15 16:17:17 +0000418
Darren Reedae72cf02008-03-07 09:09:49 +0000419 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000420 softc->ipf_interror = 50021;
Darren Reedda0443e2006-06-15 16:17:17 +0000421 err = EINVAL;
Darren Reedda0443e2006-06-15 16:17:17 +0000422 }
423 return err;
424}
425
426
Darren Reedd4718fc2006-06-15 17:00:40 +0000427/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000428/* Function: ipf_lookup_addtable */
Darren Reedd4718fc2006-06-15 17:00:40 +0000429/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000430/* Parameters: softc(I) - pointer to soft context main structure */
431/* data(I) - pointer to data from ioctl call */
Darren Reedd4718fc2006-06-15 17:00:40 +0000432/* */
433/* Create a new lookup table, if one doesn't already exist using the name */
434/* for this one. */
435/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000436static int
Darren Reed1b44c342008-08-10 05:51:57 +0000437ipf_lookup_addtable(softc, data)
438 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000439 caddr_t data;
Darren Reedda0443e2006-06-15 16:17:17 +0000440{
Darren Reed1b44c342008-08-10 05:51:57 +0000441 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedda0443e2006-06-15 16:17:17 +0000442 iplookupop_t op;
Darren Reed1b44c342008-08-10 05:51:57 +0000443 ipf_lookup_t **l;
Darren Reedae72cf02008-03-07 09:09:49 +0000444 int err, i;
Darren Reedda0443e2006-06-15 16:17:17 +0000445
Darren Reedc4af1f32007-08-20 10:15:33 +0000446 err = BCOPYIN(data, &op, sizeof(op));
447 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000448 softc->ipf_interror = 50022;
Darren Reedc4af1f32007-08-20 10:15:33 +0000449 return EFAULT;
450 }
451
Darren Reedde949852009-03-03 10:07:12 +0000452 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
453 (op.iplo_unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000454 softc->ipf_interror = 50023;
Darren Reedc4af1f32007-08-20 10:15:33 +0000455 return EINVAL;
456 }
Darren Reedd4718fc2006-06-15 17:00:40 +0000457
Darren Reedda0443e2006-06-15 16:17:17 +0000458 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
459
Darren Reed1b44c342008-08-10 05:51:57 +0000460 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
461 if (op.iplo_type == (*l)->ipfl_type) {
Darren Reed408afbd2009-02-09 01:49:27 +0000462 err = (*(*l)->ipfl_table_add)(softc,
463 softl->ipf_back[i],
464 &op);
Darren Reedae72cf02008-03-07 09:09:49 +0000465 break;
Darren Reedc4af1f32007-08-20 10:15:33 +0000466 }
Darren Reedae72cf02008-03-07 09:09:49 +0000467 }
Darren Reedda0443e2006-06-15 16:17:17 +0000468
Darren Reedae72cf02008-03-07 09:09:49 +0000469 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000470 softc->ipf_interror = 50026;
Darren Reedda0443e2006-06-15 16:17:17 +0000471 err = EINVAL;
Darren Reedda0443e2006-06-15 16:17:17 +0000472 }
Darren Reedd4718fc2006-06-15 17:00:40 +0000473
474 /*
475 * For anonymous pools, copy back the operation struct because in the
476 * case of success it will contain the new table's name.
477 */
Darren Reedc4af1f32007-08-20 10:15:33 +0000478 if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) {
479 err = BCOPYOUT(&op, data, sizeof(op));
480 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000481 softc->ipf_interror = 50027;
Darren Reedc4af1f32007-08-20 10:15:33 +0000482 err = EFAULT;
483 }
Darren Reedd4718fc2006-06-15 17:00:40 +0000484 }
485
Darren Reedda0443e2006-06-15 16:17:17 +0000486 return err;
487}
488
489
490/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000491/* Function: ipf_lookup_deltable */
Darren Reedda0443e2006-06-15 16:17:17 +0000492/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000493/* Parameters: softc(I) - pointer to soft context main structure */
494/* data(I) - pointer to data from ioctl call */
Darren Reedda0443e2006-06-15 16:17:17 +0000495/* */
496/* Decodes ioctl request to remove a particular hash table or pool and */
497/* calls the relevant function to do the cleanup. */
498/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000499static int
Darren Reed1b44c342008-08-10 05:51:57 +0000500ipf_lookup_deltable(softc, data)
501 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000502 caddr_t data;
Darren Reedda0443e2006-06-15 16:17:17 +0000503{
Darren Reed1b44c342008-08-10 05:51:57 +0000504 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedda0443e2006-06-15 16:17:17 +0000505 iplookupop_t op;
Darren Reed1b44c342008-08-10 05:51:57 +0000506 ipf_lookup_t **l;
Darren Reedae72cf02008-03-07 09:09:49 +0000507 int err, i;
Darren Reedda0443e2006-06-15 16:17:17 +0000508
Darren Reedc4af1f32007-08-20 10:15:33 +0000509 err = BCOPYIN(data, &op, sizeof(op));
510 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000511 softc->ipf_interror = 50028;
Darren Reedc4af1f32007-08-20 10:15:33 +0000512 return EFAULT;
513 }
Darren Reedda0443e2006-06-15 16:17:17 +0000514
Darren Reedde949852009-03-03 10:07:12 +0000515 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
516 (op.iplo_unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000517 softc->ipf_interror = 50029;
Darren Reedc4af1f32007-08-20 10:15:33 +0000518 return EINVAL;
519 }
520
521 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
Darren Reedda0443e2006-06-15 16:17:17 +0000522
Darren Reed1b44c342008-08-10 05:51:57 +0000523 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
524 if (op.iplo_type == (*l)->ipfl_type) {
525 err = (*(*l)->ipfl_table_del)(softc,
526 softl->ipf_back[i],
527 &op);
Darren Reedae72cf02008-03-07 09:09:49 +0000528 break;
529 }
530 }
Darren Reedda0443e2006-06-15 16:17:17 +0000531
Darren Reedae72cf02008-03-07 09:09:49 +0000532 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000533 softc->ipf_interror = 50030;
Darren Reedda0443e2006-06-15 16:17:17 +0000534 err = EINVAL;
Darren Reedda0443e2006-06-15 16:17:17 +0000535 }
536 return err;
537}
538
539
540/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000541/* Function: ipf_lookup_stats */
Darren Reedda0443e2006-06-15 16:17:17 +0000542/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000543/* Parameters: softc(I) - pointer to soft context main structure */
544/* data(I) - pointer to data from ioctl call */
Darren Reedda0443e2006-06-15 16:17:17 +0000545/* */
546/* Copy statistical information from inside the kernel back to user space. */
547/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000548static int
Darren Reed1b44c342008-08-10 05:51:57 +0000549ipf_lookup_stats(softc, data)
550 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000551 caddr_t data;
Darren Reedda0443e2006-06-15 16:17:17 +0000552{
Darren Reed1b44c342008-08-10 05:51:57 +0000553 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedda0443e2006-06-15 16:17:17 +0000554 iplookupop_t op;
Darren Reed1b44c342008-08-10 05:51:57 +0000555 ipf_lookup_t **l;
Darren Reedd4718fc2006-06-15 17:00:40 +0000556 int err;
Darren Reedae72cf02008-03-07 09:09:49 +0000557 int i;
Darren Reedda0443e2006-06-15 16:17:17 +0000558
Darren Reedc4af1f32007-08-20 10:15:33 +0000559 err = BCOPYIN(data, &op, sizeof(op));
560 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000561 softc->ipf_interror = 50031;
Darren Reedc4af1f32007-08-20 10:15:33 +0000562 return EFAULT;
563 }
564
Darren Reedde949852009-03-03 10:07:12 +0000565 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
566 (op.iplo_unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000567 softc->ipf_interror = 50032;
Darren Reedc4af1f32007-08-20 10:15:33 +0000568 return EINVAL;
569 }
Darren Reedda0443e2006-06-15 16:17:17 +0000570
Darren Reed1b44c342008-08-10 05:51:57 +0000571 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
572 if (op.iplo_type == (*l)->ipfl_type) {
573 err = (*(*l)->ipfl_stats_get)(softc,
574 softl->ipf_back[i],
575 &op);
Darren Reedae72cf02008-03-07 09:09:49 +0000576 break;
577 }
578 }
Darren Reedda0443e2006-06-15 16:17:17 +0000579
Darren Reedae72cf02008-03-07 09:09:49 +0000580 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000581 softc->ipf_interror = 50033;
Darren Reedd4718fc2006-06-15 17:00:40 +0000582 err = EINVAL;
Darren Reedd4718fc2006-06-15 17:00:40 +0000583 }
Darren Reedae72cf02008-03-07 09:09:49 +0000584
Darren Reedda0443e2006-06-15 16:17:17 +0000585 return err;
586}
587
588
589/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000590/* Function: ipf_lookup_flush */
Darren Reedda0443e2006-06-15 16:17:17 +0000591/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000592/* Parameters: softc(I) - pointer to soft context main structure */
593/* data(I) - pointer to data from ioctl call */
Darren Reedda0443e2006-06-15 16:17:17 +0000594/* */
595/* A flush is called when we want to flush all the nodes from a particular */
596/* entry in the hash table/pool or want to remove all groups from those. */
597/* ------------------------------------------------------------------------ */
Darren Reedc4af1f32007-08-20 10:15:33 +0000598static int
Darren Reed1b44c342008-08-10 05:51:57 +0000599ipf_lookup_flush(softc, data)
600 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000601 caddr_t data;
Darren Reedda0443e2006-06-15 16:17:17 +0000602{
Darren Reed1b44c342008-08-10 05:51:57 +0000603 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedae72cf02008-03-07 09:09:49 +0000604 int err, unit, num, type, i;
Darren Reedda0443e2006-06-15 16:17:17 +0000605 iplookupflush_t flush;
Darren Reed1b44c342008-08-10 05:51:57 +0000606 ipf_lookup_t **l;
Darren Reedda0443e2006-06-15 16:17:17 +0000607
Darren Reedc4af1f32007-08-20 10:15:33 +0000608 err = BCOPYIN(data, &flush, sizeof(flush));
609 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000610 softc->ipf_interror = 50034;
Darren Reedc4af1f32007-08-20 10:15:33 +0000611 return EFAULT;
612 }
613
614 unit = flush.iplf_unit;
615 if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) {
Darren Reed1b44c342008-08-10 05:51:57 +0000616 softc->ipf_interror = 50035;
Darren Reedc4af1f32007-08-20 10:15:33 +0000617 return EINVAL;
618 }
Darren Reedda0443e2006-06-15 16:17:17 +0000619
620 flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
621
Darren Reedda0443e2006-06-15 16:17:17 +0000622 type = flush.iplf_type;
Darren Reed1b44c342008-08-10 05:51:57 +0000623 softc->ipf_interror = 50036;
Darren Reedda0443e2006-06-15 16:17:17 +0000624 err = EINVAL;
625 num = 0;
626
Darren Reed1b44c342008-08-10 05:51:57 +0000627 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
628 if (type == (*l)->ipfl_type || type == IPLT_ALL) {
Darren Reedae72cf02008-03-07 09:09:49 +0000629 err = 0;
Darren Reed1b44c342008-08-10 05:51:57 +0000630 num += (*(*l)->ipfl_flush)(softc,
631 softl->ipf_back[i],
632 &flush);
Darren Reedae72cf02008-03-07 09:09:49 +0000633 }
Darren Reedda0443e2006-06-15 16:17:17 +0000634 }
635
636 if (err == 0) {
637 flush.iplf_count = num;
Darren Reedc4af1f32007-08-20 10:15:33 +0000638 err = BCOPYOUT(&flush, data, sizeof(flush));
639 if (err != 0) {
Darren Reed1b44c342008-08-10 05:51:57 +0000640 softc->ipf_interror = 50037;
Darren Reedc4af1f32007-08-20 10:15:33 +0000641 err = EFAULT;
642 }
Darren Reedda0443e2006-06-15 16:17:17 +0000643 }
644 return err;
645}
646
647
Darren Reedc4af1f32007-08-20 10:15:33 +0000648/* ------------------------------------------------------------------------ */
649/* Function: ipf_lookup_delref */
650/* Returns: void */
Darren Reed8038b7d2008-12-31 10:55:21 +0000651/* Parameters: softc(I) - pointer to soft context main structure */
652/* type(I) - table type to operate on */
Darren Reedc4af1f32007-08-20 10:15:33 +0000653/* ptr(I) - pointer to object to remove reference for */
654/* */
655/* This function organises calling the correct deref function for a given */
656/* type of object being passed into it. */
657/* ------------------------------------------------------------------------ */
658void
Darren Reed1b44c342008-08-10 05:51:57 +0000659ipf_lookup_deref(softc, type, ptr)
660 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000661 int type;
662 void *ptr;
Darren Reedda0443e2006-06-15 16:17:17 +0000663{
Darren Reed1b44c342008-08-10 05:51:57 +0000664 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedae72cf02008-03-07 09:09:49 +0000665 int i;
666
Darren Reedda0443e2006-06-15 16:17:17 +0000667 if (ptr == NULL)
668 return;
669
Darren Reedae72cf02008-03-07 09:09:49 +0000670 for (i = 0; i < MAX_BACKENDS; i++) {
671 if (type == backends[i]->ipfl_type) {
Darren Reed1b44c342008-08-10 05:51:57 +0000672 WRITE_ENTER(&softc->ipf_poolrw);
673 (*backends[i]->ipfl_table_deref)(softc,
674 softl->ipf_back[i],
675 ptr);
676 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedae72cf02008-03-07 09:09:49 +0000677 break;
678 }
Darren Reedda0443e2006-06-15 16:17:17 +0000679 }
Darren Reedda0443e2006-06-15 16:17:17 +0000680}
Darren Reedc4af1f32007-08-20 10:15:33 +0000681
682
683/* ------------------------------------------------------------------------ */
684/* Function: ipf_lookup_iterate */
685/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000686/* Parameters: softc(I) - pointer to soft context main structure */
687/* data(I) - pointer to data from ioctl call */
Darren Reed4c3f1622007-10-10 09:24:25 +0000688/* uid(I) - uid of caller */
689/* ctx(I) - pointer to give the uid context */
Darren Reedc4af1f32007-08-20 10:15:33 +0000690/* */
691/* Decodes ioctl request to step through either hash tables or pools. */
692/* ------------------------------------------------------------------------ */
Darren Reed97a145a2007-10-11 09:08:29 +0000693static int
Darren Reed1b44c342008-08-10 05:51:57 +0000694ipf_lookup_iterate(softc, data, uid, ctx)
695 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000696 void *data;
697 int uid;
698 void *ctx;
699{
Darren Reed1b44c342008-08-10 05:51:57 +0000700 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedc4af1f32007-08-20 10:15:33 +0000701 ipflookupiter_t iter;
702 ipftoken_t *token;
Darren Reedae72cf02008-03-07 09:09:49 +0000703 int err, i;
Darren Reedc4af1f32007-08-20 10:15:33 +0000704 SPL_INT(s);
705
Darren Reed21fd8be2010-02-07 00:10:05 +0000706 err = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_LOOKUPITER);
Darren Reedc4af1f32007-08-20 10:15:33 +0000707 if (err != 0)
708 return err;
709
Darren Reedfc5c4b12009-03-14 14:42:06 +0000710 if (iter.ili_unit < IPL_LOGALL && iter.ili_unit > IPL_LOGMAX) {
Darren Reed1b44c342008-08-10 05:51:57 +0000711 softc->ipf_interror = 50038;
Darren Reedc4af1f32007-08-20 10:15:33 +0000712 return EINVAL;
713 }
714
715 if (iter.ili_ival != IPFGENITER_LOOKUP) {
Darren Reed1b44c342008-08-10 05:51:57 +0000716 softc->ipf_interror = 50039;
Darren Reedc4af1f32007-08-20 10:15:33 +0000717 return EINVAL;
718 }
719
720 SPL_SCHED(s);
Darren Reed7e3c3542009-05-13 19:18:56 +0000721 token = ipf_token_find(softc, iter.ili_key, uid, ctx);
Darren Reedc4af1f32007-08-20 10:15:33 +0000722 if (token == NULL) {
Darren Reedc4af1f32007-08-20 10:15:33 +0000723 SPL_X(s);
Darren Reed1b44c342008-08-10 05:51:57 +0000724 softc->ipf_interror = 50040;
Darren Reedc4af1f32007-08-20 10:15:33 +0000725 return ESRCH;
726 }
727
Darren Reedae72cf02008-03-07 09:09:49 +0000728 for (i = 0; i < MAX_BACKENDS; i++) {
729 if (iter.ili_type == backends[i]->ipfl_type) {
Darren Reed1b44c342008-08-10 05:51:57 +0000730 err = (*backends[i]->ipfl_iter_next)(softc,
731 softl->ipf_back[i],
732 token, &iter);
Darren Reedae72cf02008-03-07 09:09:49 +0000733 break;
734 }
Darren Reedc4af1f32007-08-20 10:15:33 +0000735 }
Darren Reedc4af1f32007-08-20 10:15:33 +0000736 SPL_X(s);
Darren Reedae72cf02008-03-07 09:09:49 +0000737
738 if (i == MAX_BACKENDS) {
Darren Reed1b44c342008-08-10 05:51:57 +0000739 softc->ipf_interror = 50041;
Darren Reedae72cf02008-03-07 09:09:49 +0000740 err = EINVAL;
741 }
Darren Reed7e3c3542009-05-13 19:18:56 +0000742
743 WRITE_ENTER(&softc->ipf_tokens);
744 ipf_token_deref(softc, token);
745 RWLOCK_EXIT(&softc->ipf_tokens);
Darren Reedc4af1f32007-08-20 10:15:33 +0000746
747 return err;
748}
749
750
751/* ------------------------------------------------------------------------ */
752/* Function: ipf_lookup_iterderef */
Darren Reedbb421c42010-01-31 13:07:29 +0000753/* Returns: void */
Darren Reed8038b7d2008-12-31 10:55:21 +0000754/* Parameters: softc(I) - pointer to soft context main structure */
755/* type(I) - backend type to iterate through */
756/* data(I) - pointer to data from ioctl call */
Darren Reedc4af1f32007-08-20 10:15:33 +0000757/* */
758/* Decodes ioctl request to remove a particular hash table or pool and */
759/* calls the relevant function to do the cleanup. */
Darren Reed8038b7d2008-12-31 10:55:21 +0000760/* Because each of the backend types has a different data structure, */
761/* iteration is limited to one type at a time (i.e. it is not permitted to */
762/* go on from pool types to hash types as part of the "get next".) */
Darren Reedc4af1f32007-08-20 10:15:33 +0000763/* ------------------------------------------------------------------------ */
764void
Darren Reed1b44c342008-08-10 05:51:57 +0000765ipf_lookup_iterderef(softc, type, data)
766 ipf_main_softc_t *softc;
Darren Reedc4af1f32007-08-20 10:15:33 +0000767 u_32_t type;
768 void *data;
769{
Darren Reed1b44c342008-08-10 05:51:57 +0000770 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
Darren Reedae72cf02008-03-07 09:09:49 +0000771 struct iplookupiterkey *lkey;
772 iplookupiterkey_t key;
773 int i;
Darren Reedc4af1f32007-08-20 10:15:33 +0000774
775 key.ilik_key = type;
Darren Reedae72cf02008-03-07 09:09:49 +0000776 lkey = &key.ilik_unstr;
Darren Reedc4af1f32007-08-20 10:15:33 +0000777
Darren Reedae72cf02008-03-07 09:09:49 +0000778 if (lkey->ilik_ival != IPFGENITER_LOOKUP)
Darren Reedc4af1f32007-08-20 10:15:33 +0000779 return;
780
Darren Reed1b44c342008-08-10 05:51:57 +0000781 WRITE_ENTER(&softc->ipf_poolrw);
Darren Reedae72cf02008-03-07 09:09:49 +0000782
783 for (i = 0; i < MAX_BACKENDS; i++) {
784 if (type == backends[i]->ipfl_type) {
Darren Reed1b44c342008-08-10 05:51:57 +0000785 (*backends[i]->ipfl_iter_deref)(softc,
786 softl->ipf_back[i],
787 lkey->ilik_otype,
Darren Reedae72cf02008-03-07 09:09:49 +0000788 lkey->ilik_unit,
789 data);
790 break;
791 }
Darren Reedc4af1f32007-08-20 10:15:33 +0000792 }
Darren Reed1b44c342008-08-10 05:51:57 +0000793 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedc4af1f32007-08-20 10:15:33 +0000794}
795
Darren Reedda0443e2006-06-15 16:17:17 +0000796
Darren Reed4c3f1622007-10-10 09:24:25 +0000797/* ------------------------------------------------------------------------ */
Darren Reed97a145a2007-10-11 09:08:29 +0000798/* Function: ipf_lookup_deltok */
Darren Reed4c3f1622007-10-10 09:24:25 +0000799/* Returns: int - 0 = success, else error */
Darren Reed8038b7d2008-12-31 10:55:21 +0000800/* Parameters: softc(I) - pointer to soft context main structure */
801/* data(I) - pointer to data from ioctl call */
Darren Reed4c3f1622007-10-10 09:24:25 +0000802/* uid(I) - uid of caller */
803/* ctx(I) - pointer to give the uid context */
804/* */
805/* Deletes the token identified by the combination of (type,uid,ctx) */
806/* "key" is a combination of the table type, iterator type and the unit for */
807/* which the token was being used. */
808/* ------------------------------------------------------------------------ */
Darren Reed97a145a2007-10-11 09:08:29 +0000809int
Darren Reed1b44c342008-08-10 05:51:57 +0000810ipf_lookup_deltok(softc, data, uid, ctx)
811 ipf_main_softc_t *softc;
Darren Reed97a145a2007-10-11 09:08:29 +0000812 void *data;
813 int uid;
814 void *ctx;
Darren Reed4c3f1622007-10-10 09:24:25 +0000815{
816 int error, key;
817 SPL_INT(s);
818
819 SPL_SCHED(s);
Martti Kuparinenb4c6ea22007-10-25 09:26:49 +0000820 error = BCOPYIN(data, &key, sizeof(key));
Darren Reed4c3f1622007-10-10 09:24:25 +0000821 if (error == 0)
Darren Reed7e3c3542009-05-13 19:18:56 +0000822 error = ipf_token_del(softc, key, uid, ctx);
Darren Reed4c3f1622007-10-10 09:24:25 +0000823 SPL_X(s);
824 return error;
825}
826
Darren Reedda0443e2006-06-15 16:17:17 +0000827
Darren Reedae72cf02008-03-07 09:09:49 +0000828/* ------------------------------------------------------------------------ */
829/* Function: ipf_lookup_res_num */
830/* Returns: void * - NULL = failure, else success. */
Darren Reed8038b7d2008-12-31 10:55:21 +0000831/* Parameters: softc(I) - pointer to soft context main structure */
Darren Reed8038b7d2008-12-31 10:55:21 +0000832/* unit(I) - device for which this is for */
Darren Reeda6872a72009-05-01 18:01:35 +0000833/* type(I) - type of lookup these parameters are for. */
Darren Reedae72cf02008-03-07 09:09:49 +0000834/* number(I) - table number to use when searching */
835/* funcptr(IO) - pointer to pointer for storing IP address */
836/* searching function. */
837/* */
838/* Search for the "table" number passed in amongst those configured for */
839/* that particular type. If the type is recognised then the function to */
840/* call to do the IP address search will be change, regardless of whether */
841/* or not the "table" number exists. */
842/* ------------------------------------------------------------------------ */
843void *
Darren Reeda6872a72009-05-01 18:01:35 +0000844ipf_lookup_res_num(softc, unit, type, number, funcptr)
Darren Reed1b44c342008-08-10 05:51:57 +0000845 ipf_main_softc_t *softc;
Darren Reedae72cf02008-03-07 09:09:49 +0000846 int unit;
Darren Reeda6872a72009-05-01 18:01:35 +0000847 u_int type;
Darren Reedae72cf02008-03-07 09:09:49 +0000848 u_int number;
849 lookupfunc_t *funcptr;
Darren Reedda0443e2006-06-15 16:17:17 +0000850{
Darren Reedae72cf02008-03-07 09:09:49 +0000851 char name[FR_GROUPLEN];
852
853#if defined(SNPRINTF) && defined(_KERNEL)
854 SNPRINTF(name, sizeof(name), "%u", number);
855#else
856 (void) sprintf(name, "%u", number);
857#endif
858
Darren Reeda6872a72009-05-01 18:01:35 +0000859 return ipf_lookup_res_name(softc, unit, type, name, funcptr);
Darren Reedda0443e2006-06-15 16:17:17 +0000860}
Darren Reedae72cf02008-03-07 09:09:49 +0000861
862
863/* ------------------------------------------------------------------------ */
864/* Function: ipf_lookup_res_name */
865/* Returns: void * - NULL = failure, else success. */
Darren Reed8038b7d2008-12-31 10:55:21 +0000866/* Parameters: softc(I) - pointer to soft context main structure */
Darren Reed8038b7d2008-12-31 10:55:21 +0000867/* unit(I) - device for which this is for */
Darren Reeda6872a72009-05-01 18:01:35 +0000868/* type(I) - type of lookup these parameters are for. */
Darren Reedae72cf02008-03-07 09:09:49 +0000869/* name(I) - table name to use when searching */
870/* funcptr(IO) - pointer to pointer for storing IP address */
871/* searching function. */
872/* */
873/* Search for the "table" number passed in amongst those configured for */
874/* that particular type. If the type is recognised then the function to */
875/* call to do the IP address search will be change, regardless of whether */
876/* or not the "table" number exists. */
877/* ------------------------------------------------------------------------ */
878void *
Darren Reeda6872a72009-05-01 18:01:35 +0000879ipf_lookup_res_name(softc, unit, type, name, funcptr)
Darren Reed1b44c342008-08-10 05:51:57 +0000880 ipf_main_softc_t *softc;
Darren Reedae72cf02008-03-07 09:09:49 +0000881 int unit;
Darren Reeda6872a72009-05-01 18:01:35 +0000882 u_int type;
Darren Reedae72cf02008-03-07 09:09:49 +0000883 char *name;
884 lookupfunc_t *funcptr;
885{
Darren Reed1b44c342008-08-10 05:51:57 +0000886 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
887 ipf_lookup_t **l;
Darren Reed7e99d162008-03-07 21:23:11 +0000888 void *ptr = NULL;
Darren Reedae72cf02008-03-07 09:09:49 +0000889 int i;
890
Darren Reed1b44c342008-08-10 05:51:57 +0000891 READ_ENTER(&softc->ipf_poolrw);
Darren Reedae72cf02008-03-07 09:09:49 +0000892
Darren Reed1b44c342008-08-10 05:51:57 +0000893 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
894 if (type == (*l)->ipfl_type) {
895 ptr = (*(*l)->ipfl_select_add_ref)(softl->ipf_back[i],
896 unit, name);
Darren Reedae72cf02008-03-07 09:09:49 +0000897 if (ptr != NULL && funcptr != NULL) {
Darren Reed1b44c342008-08-10 05:51:57 +0000898 *funcptr = (*l)->ipfl_addr_find;
Darren Reedae72cf02008-03-07 09:09:49 +0000899 }
900 break;
901 }
902 }
903
904 if (i == MAX_BACKENDS) {
905 ptr = NULL;
906 if (funcptr != NULL)
907 *funcptr = NULL;
908 }
909
Darren Reed1b44c342008-08-10 05:51:57 +0000910 RWLOCK_EXIT(&softc->ipf_poolrw);
Darren Reedae72cf02008-03-07 09:09:49 +0000911
912 return ptr;
913}
David Stes6c066772008-04-19 21:33:53 +0000914
915
Darren Reed8038b7d2008-12-31 10:55:21 +0000916/* ------------------------------------------------------------------------ */
917/* Function: ipf_lookup_find_htable */
918/* Returns: void * - NULL = failure, else success. */
919/* Parameters: softc(I) - pointer to soft context main structure */
920/* unit(I) - device for which this is for */
921/* name(I) - table name to use when searching */
922/* */
923/* To support the group-map feature, where a hash table maps address */
924/* networks to rule group numbers, we need to expose a function that uses */
925/* only the hash table backend. */
926/* ------------------------------------------------------------------------ */
Darren Reed1b44c342008-08-10 05:51:57 +0000927void *
928ipf_lookup_find_htable(softc, unit, name)
929 ipf_main_softc_t *softc;
930 int unit;
931 char *name;
932{
933 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
934 ipf_lookup_t **l;
935 void *tab = NULL;
936 int i;
David Stes6c066772008-04-19 21:33:53 +0000937
Darren Reed1b44c342008-08-10 05:51:57 +0000938 READ_ENTER(&softc->ipf_poolrw);
939
940 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
941 if (IPLT_HASH == (*l)->ipfl_type) {
942 tab = ipf_htable_find(softl->ipf_back[i], unit, name);
943 break;
944 }
945
946 RWLOCK_EXIT(&softc->ipf_poolrw);
947
948 return tab;
949}
950
951
Darren Reedbb421c42010-01-31 13:07:29 +0000952/* ------------------------------------------------------------------------ */
953/* Function: ipf_lookup_sync */
954/* Returns: void */
955/* Parameters: softc(I) - pointer to soft context main structure */
956/* */
957/* This function is the interface that the machine dependent sync functions */
958/* call when a network interface name change occurs. It then calls the sync */
959/* functions of the lookup implementations - if they have one. */
960/* ------------------------------------------------------------------------ */
961/*ARGSUSED*/
962void
963ipf_lookup_sync(softc, ifp)
964 ipf_main_softc_t *softc;
965 void *ifp;
966{
967 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
968 ipf_lookup_t **l;
969 int i;
970
971 READ_ENTER(&softc->ipf_poolrw);
972
973 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
974 if ((*l)->ipfl_sync != NULL)
975 (*(*l)->ipfl_sync)(softc, softl->ipf_back[i]);
976
977 RWLOCK_EXIT(&softc->ipf_poolrw);
978}
979
980
Darren Reed1b44c342008-08-10 05:51:57 +0000981#ifndef _KERNEL
Darren Reed1b44c342008-08-10 05:51:57 +0000982void
983ipf_lookup_dump(softc, arg)
984 ipf_main_softc_t *softc;
985 void *arg;
986{
987 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
988 ipf_lookup_t **l;
989 int i;
990
991 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
992 if (IPLT_POOL == (*l)->ipfl_type) {
993 ipf_pool_dump(softc, softl->ipf_back[i]);
994 break;
995 }
996
997 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
998 if (IPLT_HASH == (*l)->ipfl_type) {
999 ipf_htable_dump(softc, softl->ipf_back[i]);
1000 break;
1001 }
1002}
1003#endif