3 * Copyright (C) 2012 by Darren Reed.
5 * See the IPFILTER.LICENCE file for details on licencing.
7 #if defined(KERNEL) || defined(_KERNEL)
13 #include <sys/param.h>
14 #include <sys/errno.h>
15 #include <sys/types.h>
18 #if defined(__FreeBSD__) && defined(_KERNEL)
19 # include <sys/fcntl.h>
20 # include <sys/filio.h>
22 # include <sys/ioctl.h>
32 #include <sys/socket.h>
34 #if defined(__FreeBSD__)
35 # include <sys/cdefs.h>
36 # include <sys/proc.h>
39 # include <sys/systm.h>
41 # include <sys/mbuf.h>
46 #include <netinet/in.h>
48 #include "netinet/ip_compat.h"
49 #include "netinet/ip_fil.h"
50 #include "netinet/ip_lookup.h"
51 #include "netinet/ip_pool.h"
52 #include "netinet/ip_htable.h"
53 #include "netinet/ip_dstlist.h"
57 static const char rcsid[] = "@(#)$Id$";
61 * In this file, ip_pool.c, ip_htable.c and ip_dstlist.c, you will find the
62 * range for unit is [-1,IPL_LOGMAX]. The -1 is considered to be a valid number
63 * and represents a "wildcard" or "all" units (IPL_LOGALL). The reason for not
64 * starting the numbering at 0 is because the numbers [0,IPL_LOGMAX] correspond
65 * to the minor device number for their respective device. Thus where there is
66 * array indexing on the unit, +1 is used to map [-1.IPL_LOGMAX] to
67 * [0.POOL_LOOKUP_MAX].
69 static int ipf_lookup_addnode(ipf_main_softc_t *, caddr_t, int);
70 static int ipf_lookup_delnode(ipf_main_softc_t *, caddr_t, int);
71 static int ipf_lookup_addtable(ipf_main_softc_t *, caddr_t);
72 static int ipf_lookup_deltable(ipf_main_softc_t *, caddr_t);
73 static int ipf_lookup_stats(ipf_main_softc_t *, caddr_t);
74 static int ipf_lookup_flush(ipf_main_softc_t *, caddr_t);
75 static int ipf_lookup_iterate(ipf_main_softc_t *, void *, int, void *);
76 static int ipf_lookup_deltok(ipf_main_softc_t *, void *, int, void *);
78 #define MAX_BACKENDS 3
79 static ipf_lookup_t *backends[MAX_BACKENDS] = {
86 typedef struct ipf_lookup_softc_s {
87 void *ipf_back[MAX_BACKENDS];
91 /* ------------------------------------------------------------------------ */
92 /* Function: ipf_lookup_init */
93 /* Returns: int - 0 = success, else error */
94 /* Parameters: softc(I) - pointer to soft context main structure */
96 /* Initialise all of the subcomponents of the lookup infrstructure. */
97 /* ------------------------------------------------------------------------ */
99 ipf_lookup_soft_create(softc)
100 ipf_main_softc_t *softc;
102 ipf_lookup_softc_t *softl;
106 KMALLOC(softl, ipf_lookup_softc_t *);
110 bzero((char *)softl, sizeof(*softl));
112 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
113 softl->ipf_back[i] = (*(*l)->ipfl_create)(softc);
114 if (softl->ipf_back[i] == NULL) {
115 ipf_lookup_soft_destroy(softc, softl);
124 /* ------------------------------------------------------------------------ */
125 /* Function: ipf_lookup_soft_init */
126 /* Returns: int - 0 = success, else error */
127 /* Parameters: softc(I) - pointer to soft context main structure */
128 /* arg(I) - pointer to local context to use */
130 /* Initialise all of the subcomponents of the lookup infrstructure. */
131 /* ------------------------------------------------------------------------ */
133 ipf_lookup_soft_init(softc, arg)
134 ipf_main_softc_t *softc;
137 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
141 for (i = 0; i < MAX_BACKENDS; i++) {
142 err = (*backends[i]->ipfl_init)(softc, softl->ipf_back[i]);
151 /* ------------------------------------------------------------------------ */
152 /* Function: ipf_lookup_soft_fini */
153 /* Returns: int - 0 = success, else error */
154 /* Parameters: softc(I) - pointer to soft context main structure */
155 /* arg(I) - pointer to local context to use */
157 /* Call the fini function in each backend to cleanup all allocated data. */
158 /* ------------------------------------------------------------------------ */
160 ipf_lookup_soft_fini(softc, arg)
161 ipf_main_softc_t *softc;
164 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
167 for (i = 0; i < MAX_BACKENDS; i++) {
168 if (softl->ipf_back[i] != NULL)
169 (*backends[i]->ipfl_fini)(softc,
177 /* ------------------------------------------------------------------------ */
178 /* Function: ipf_lookup_expire */
180 /* Parameters: softc(I) - pointer to soft context main structure */
182 /* Step through each of the backends and call their expire functions, */
183 /* allowing them to delete any lifetime limited data. */
184 /* ------------------------------------------------------------------------ */
186 ipf_lookup_expire(softc)
187 ipf_main_softc_t *softc;
189 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
192 WRITE_ENTER(&softc->ipf_poolrw);
193 for (i = 0; i < MAX_BACKENDS; i++)
194 (*backends[i]->ipfl_expire)(softc, softl->ipf_back[i]);
195 RWLOCK_EXIT(&softc->ipf_poolrw);
199 /* ------------------------------------------------------------------------ */
200 /* Function: ipf_lookup_softc_destroy */
201 /* Returns: int - 0 = success, else error */
202 /* Parameters: softc(I) - pointer to soft context main structure */
203 /* arg(I) - pointer to local context to use */
205 /* Free up all pool related memory that has been allocated whilst IPFilter */
206 /* has been running. Also, do any other deinitialisation required such */
207 /* ipf_lookup_init() can be called again, safely. */
208 /* ------------------------------------------------------------------------ */
210 ipf_lookup_soft_destroy(softc, arg)
211 ipf_main_softc_t *softc;
214 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
217 for (i = 0; i < MAX_BACKENDS; i++) {
218 if (softl->ipf_back[i] != NULL)
219 (*backends[i]->ipfl_destroy)(softc,
227 /* ------------------------------------------------------------------------ */
228 /* Function: ipf_lookup_ioctl */
229 /* Returns: int - 0 = success, else error */
230 /* Parameters: softc(I) - pointer to soft context main structure */
231 /* arg(I) - pointer to local context to use */
232 /* data(IO) - pointer to ioctl data to be copied to/from user */
234 /* cmd(I) - ioctl command number */
235 /* mode(I) - file mode bits used with open */
236 /* uid(I) - uid of process doing ioctl */
237 /* ctx(I) - pointer that represents context for uid */
239 /* Handle ioctl commands sent to the ioctl device. For the most part, this */
240 /* involves just calling another function to handle the specifics of each */
242 /* ------------------------------------------------------------------------ */
244 ipf_lookup_ioctl(softc, data, cmd, mode, uid, ctx)
245 ipf_main_softc_t *softc;
254 mode = mode; /* LINT */
260 case SIOCLOOKUPADDNODE :
261 case SIOCLOOKUPADDNODEW :
262 WRITE_ENTER(&softc->ipf_poolrw);
263 err = ipf_lookup_addnode(softc, data, uid);
264 RWLOCK_EXIT(&softc->ipf_poolrw);
267 case SIOCLOOKUPDELNODE :
268 case SIOCLOOKUPDELNODEW :
269 WRITE_ENTER(&softc->ipf_poolrw);
270 err = ipf_lookup_delnode(softc, data, uid);
271 RWLOCK_EXIT(&softc->ipf_poolrw);
274 case SIOCLOOKUPADDTABLE :
275 WRITE_ENTER(&softc->ipf_poolrw);
276 err = ipf_lookup_addtable(softc, data);
277 RWLOCK_EXIT(&softc->ipf_poolrw);
280 case SIOCLOOKUPDELTABLE :
281 WRITE_ENTER(&softc->ipf_poolrw);
282 err = ipf_lookup_deltable(softc, data);
283 RWLOCK_EXIT(&softc->ipf_poolrw);
286 case SIOCLOOKUPSTAT :
287 case SIOCLOOKUPSTATW :
288 WRITE_ENTER(&softc->ipf_poolrw);
289 err = ipf_lookup_stats(softc, data);
290 RWLOCK_EXIT(&softc->ipf_poolrw);
293 case SIOCLOOKUPFLUSH :
294 WRITE_ENTER(&softc->ipf_poolrw);
295 err = ipf_lookup_flush(softc, data);
296 RWLOCK_EXIT(&softc->ipf_poolrw);
299 case SIOCLOOKUPITER :
300 err = ipf_lookup_iterate(softc, data, uid, ctx);
304 err = ipf_lookup_deltok(softc, data, uid, ctx);
317 /* ------------------------------------------------------------------------ */
318 /* Function: ipf_lookup_addnode */
319 /* Returns: int - 0 = success, else error */
320 /* Parameters: softc(I) - pointer to soft context main structure */
321 /* data(I) - pointer to data from ioctl call */
323 /* Add a new data node to a lookup structure. First, check to see if the */
324 /* parent structure refered to by name exists and if it does, then go on to */
325 /* add a node to it. */
326 /* ------------------------------------------------------------------------ */
328 ipf_lookup_addnode(softc, data, uid)
329 ipf_main_softc_t *softc;
333 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
339 err = BCOPYIN(data, &op, sizeof(op));
345 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
346 (op.iplo_unit != IPLT_ALL)) {
351 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
353 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
354 if (op.iplo_type == (*l)->ipfl_type) {
355 err = (*(*l)->ipfl_node_add)(softc,
362 if (i == MAX_BACKENDS) {
371 /* ------------------------------------------------------------------------ */
372 /* Function: ipf_lookup_delnode */
373 /* Returns: int - 0 = success, else error */
374 /* Parameters: softc(I) - pointer to soft context main structure */
375 /* data(I) - pointer to data from ioctl call */
377 /* Delete a node from a lookup table by first looking for the table it is */
378 /* in and then deleting the entry that gets found. */
379 /* ------------------------------------------------------------------------ */
381 ipf_lookup_delnode(softc, data, uid)
382 ipf_main_softc_t *softc;
386 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
392 err = BCOPYIN(data, &op, sizeof(op));
398 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
399 (op.iplo_unit != IPLT_ALL)) {
404 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
406 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
407 if (op.iplo_type == (*l)->ipfl_type) {
408 err = (*(*l)->ipfl_node_del)(softc, softl->ipf_back[i],
414 if (i == MAX_BACKENDS) {
422 /* ------------------------------------------------------------------------ */
423 /* Function: ipf_lookup_addtable */
424 /* Returns: int - 0 = success, else error */
425 /* Parameters: softc(I) - pointer to soft context main structure */
426 /* data(I) - pointer to data from ioctl call */
428 /* Create a new lookup table, if one doesn't already exist using the name */
430 /* ------------------------------------------------------------------------ */
432 ipf_lookup_addtable(softc, data)
433 ipf_main_softc_t *softc;
436 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
441 err = BCOPYIN(data, &op, sizeof(op));
447 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
448 (op.iplo_unit != IPLT_ALL)) {
453 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
455 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
456 if (op.iplo_type == (*l)->ipfl_type) {
457 err = (*(*l)->ipfl_table_add)(softc,
464 if (i == MAX_BACKENDS) {
470 * For anonymous pools, copy back the operation struct because in the
471 * case of success it will contain the new table's name.
473 if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) {
474 err = BCOPYOUT(&op, data, sizeof(op));
485 /* ------------------------------------------------------------------------ */
486 /* Function: ipf_lookup_deltable */
487 /* Returns: int - 0 = success, else error */
488 /* Parameters: softc(I) - pointer to soft context main structure */
489 /* data(I) - pointer to data from ioctl call */
491 /* Decodes ioctl request to remove a particular hash table or pool and */
492 /* calls the relevant function to do the cleanup. */
493 /* ------------------------------------------------------------------------ */
495 ipf_lookup_deltable(softc, data)
496 ipf_main_softc_t *softc;
499 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
504 err = BCOPYIN(data, &op, sizeof(op));
510 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
511 (op.iplo_unit != IPLT_ALL)) {
516 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
518 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
519 if (op.iplo_type == (*l)->ipfl_type) {
520 err = (*(*l)->ipfl_table_del)(softc,
527 if (i == MAX_BACKENDS) {
535 /* ------------------------------------------------------------------------ */
536 /* Function: ipf_lookup_stats */
537 /* Returns: int - 0 = success, else error */
538 /* Parameters: softc(I) - pointer to soft context main structure */
539 /* data(I) - pointer to data from ioctl call */
541 /* Copy statistical information from inside the kernel back to user space. */
542 /* ------------------------------------------------------------------------ */
544 ipf_lookup_stats(softc, data)
545 ipf_main_softc_t *softc;
548 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
554 err = BCOPYIN(data, &op, sizeof(op));
560 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
561 (op.iplo_unit != IPLT_ALL)) {
566 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
567 if (op.iplo_type == (*l)->ipfl_type) {
568 err = (*(*l)->ipfl_stats_get)(softc,
575 if (i == MAX_BACKENDS) {
584 /* ------------------------------------------------------------------------ */
585 /* Function: ipf_lookup_flush */
586 /* Returns: int - 0 = success, else error */
587 /* Parameters: softc(I) - pointer to soft context main structure */
588 /* data(I) - pointer to data from ioctl call */
590 /* A flush is called when we want to flush all the nodes from a particular */
591 /* entry in the hash table/pool or want to remove all groups from those. */
592 /* ------------------------------------------------------------------------ */
594 ipf_lookup_flush(softc, data)
595 ipf_main_softc_t *softc;
598 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
599 int err, unit, num, type, i;
600 iplookupflush_t flush;
603 err = BCOPYIN(data, &flush, sizeof(flush));
609 unit = flush.iplf_unit;
610 if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) {
615 flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
617 type = flush.iplf_type;
622 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
623 if (type == (*l)->ipfl_type || type == IPLT_ALL) {
625 num += (*(*l)->ipfl_flush)(softc,
632 flush.iplf_count = num;
633 err = BCOPYOUT(&flush, data, sizeof(flush));
643 /* ------------------------------------------------------------------------ */
644 /* Function: ipf_lookup_delref */
646 /* Parameters: softc(I) - pointer to soft context main structure */
647 /* type(I) - table type to operate on */
648 /* ptr(I) - pointer to object to remove reference for */
650 /* This function organises calling the correct deref function for a given */
651 /* type of object being passed into it. */
652 /* ------------------------------------------------------------------------ */
654 ipf_lookup_deref(softc, type, ptr)
655 ipf_main_softc_t *softc;
659 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
665 for (i = 0; i < MAX_BACKENDS; i++) {
666 if (type == backends[i]->ipfl_type) {
667 WRITE_ENTER(&softc->ipf_poolrw);
668 (*backends[i]->ipfl_table_deref)(softc,
671 RWLOCK_EXIT(&softc->ipf_poolrw);
678 /* ------------------------------------------------------------------------ */
679 /* Function: ipf_lookup_iterate */
680 /* Returns: int - 0 = success, else error */
681 /* Parameters: softc(I) - pointer to soft context main structure */
682 /* data(I) - pointer to data from ioctl call */
683 /* uid(I) - uid of caller */
684 /* ctx(I) - pointer to give the uid context */
686 /* Decodes ioctl request to step through either hash tables or pools. */
687 /* ------------------------------------------------------------------------ */
689 ipf_lookup_iterate(softc, data, uid, ctx)
690 ipf_main_softc_t *softc;
695 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
696 ipflookupiter_t iter;
701 err = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_LOOKUPITER);
705 if (iter.ili_unit < IPL_LOGALL && iter.ili_unit > IPL_LOGMAX) {
710 if (iter.ili_ival != IPFGENITER_LOOKUP) {
716 token = ipf_token_find(softc, iter.ili_key, uid, ctx);
723 for (i = 0; i < MAX_BACKENDS; i++) {
724 if (iter.ili_type == backends[i]->ipfl_type) {
725 err = (*backends[i]->ipfl_iter_next)(softc,
733 if (i == MAX_BACKENDS) {
738 WRITE_ENTER(&softc->ipf_tokens);
739 ipf_token_deref(softc, token);
740 RWLOCK_EXIT(&softc->ipf_tokens);
746 /* ------------------------------------------------------------------------ */
747 /* Function: ipf_lookup_iterderef */
749 /* Parameters: softc(I) - pointer to soft context main structure */
750 /* type(I) - backend type to iterate through */
751 /* data(I) - pointer to data from ioctl call */
753 /* Decodes ioctl request to remove a particular hash table or pool and */
754 /* calls the relevant function to do the cleanup. */
755 /* Because each of the backend types has a different data structure, */
756 /* iteration is limited to one type at a time (i.e. it is not permitted to */
757 /* go on from pool types to hash types as part of the "get next".) */
758 /* ------------------------------------------------------------------------ */
760 ipf_lookup_iterderef(softc, type, data)
761 ipf_main_softc_t *softc;
765 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
766 struct iplookupiterkey *lkey;
767 iplookupiterkey_t key;
771 lkey = &key.ilik_unstr;
773 if (lkey->ilik_ival != IPFGENITER_LOOKUP)
776 WRITE_ENTER(&softc->ipf_poolrw);
778 for (i = 0; i < MAX_BACKENDS; i++) {
779 if (lkey->ilik_type == backends[i]->ipfl_type) {
780 (*backends[i]->ipfl_iter_deref)(softc,
788 RWLOCK_EXIT(&softc->ipf_poolrw);
792 /* ------------------------------------------------------------------------ */
793 /* Function: ipf_lookup_deltok */
794 /* Returns: int - 0 = success, else error */
795 /* Parameters: softc(I) - pointer to soft context main structure */
796 /* data(I) - pointer to data from ioctl call */
797 /* uid(I) - uid of caller */
798 /* ctx(I) - pointer to give the uid context */
800 /* Deletes the token identified by the combination of (type,uid,ctx) */
801 /* "key" is a combination of the table type, iterator type and the unit for */
802 /* which the token was being used. */
803 /* ------------------------------------------------------------------------ */
805 ipf_lookup_deltok(softc, data, uid, ctx)
806 ipf_main_softc_t *softc;
815 error = BCOPYIN(data, &key, sizeof(key));
817 error = ipf_token_del(softc, key, uid, ctx);
823 /* ------------------------------------------------------------------------ */
824 /* Function: ipf_lookup_res_num */
825 /* Returns: void * - NULL = failure, else success. */
826 /* Parameters: softc(I) - pointer to soft context main structure */
827 /* unit(I) - device for which this is for */
828 /* type(I) - type of lookup these parameters are for. */
829 /* number(I) - table number to use when searching */
830 /* funcptr(IO) - pointer to pointer for storing IP address */
831 /* searching function. */
833 /* Search for the "table" number passed in amongst those configured for */
834 /* that particular type. If the type is recognised then the function to */
835 /* call to do the IP address search will be change, regardless of whether */
836 /* or not the "table" number exists. */
837 /* ------------------------------------------------------------------------ */
839 ipf_lookup_res_num(softc, unit, type, number, funcptr)
840 ipf_main_softc_t *softc;
844 lookupfunc_t *funcptr;
846 char name[FR_GROUPLEN];
848 #if defined(SNPRINTF) && defined(_KERNEL)
849 SNPRINTF(name, sizeof(name), "%u", number);
851 (void) sprintf(name, "%u", number);
854 return ipf_lookup_res_name(softc, unit, type, name, funcptr);
858 /* ------------------------------------------------------------------------ */
859 /* Function: ipf_lookup_res_name */
860 /* Returns: void * - NULL = failure, else success. */
861 /* Parameters: softc(I) - pointer to soft context main structure */
862 /* unit(I) - device for which this is for */
863 /* type(I) - type of lookup these parameters are for. */
864 /* name(I) - table name to use when searching */
865 /* funcptr(IO) - pointer to pointer for storing IP address */
866 /* searching function. */
868 /* Search for the "table" number passed in amongst those configured for */
869 /* that particular type. If the type is recognised then the function to */
870 /* call to do the IP address search will be changed, regardless of whether */
871 /* or not the "table" number exists. */
872 /* ------------------------------------------------------------------------ */
874 ipf_lookup_res_name(softc, unit, type, name, funcptr)
875 ipf_main_softc_t *softc;
879 lookupfunc_t *funcptr;
881 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
886 READ_ENTER(&softc->ipf_poolrw);
888 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
889 if (type == (*l)->ipfl_type) {
890 ptr = (*(*l)->ipfl_select_add_ref)(softl->ipf_back[i],
892 if (ptr != NULL && funcptr != NULL) {
893 *funcptr = (*l)->ipfl_addr_find;
899 if (i == MAX_BACKENDS) {
905 RWLOCK_EXIT(&softc->ipf_poolrw);
911 /* ------------------------------------------------------------------------ */
912 /* Function: ipf_lookup_find_htable */
913 /* Returns: void * - NULL = failure, else success. */
914 /* Parameters: softc(I) - pointer to soft context main structure */
915 /* unit(I) - device for which this is for */
916 /* name(I) - table name to use when searching */
918 /* To support the group-map feature, where a hash table maps address */
919 /* networks to rule group numbers, we need to expose a function that uses */
920 /* only the hash table backend. */
921 /* ------------------------------------------------------------------------ */
923 ipf_lookup_find_htable(softc, unit, name)
924 ipf_main_softc_t *softc;
928 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
933 READ_ENTER(&softc->ipf_poolrw);
935 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
936 if (IPLT_HASH == (*l)->ipfl_type) {
937 tab = ipf_htable_find(softl->ipf_back[i], unit, name);
941 RWLOCK_EXIT(&softc->ipf_poolrw);
947 /* ------------------------------------------------------------------------ */
948 /* Function: ipf_lookup_sync */
950 /* Parameters: softc(I) - pointer to soft context main structure */
952 /* This function is the interface that the machine dependent sync functions */
953 /* call when a network interface name change occurs. It then calls the sync */
954 /* functions of the lookup implementations - if they have one. */
955 /* ------------------------------------------------------------------------ */
958 ipf_lookup_sync(softc, ifp)
959 ipf_main_softc_t *softc;
962 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
966 READ_ENTER(&softc->ipf_poolrw);
968 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
969 if ((*l)->ipfl_sync != NULL)
970 (*(*l)->ipfl_sync)(softc, softl->ipf_back[i]);
972 RWLOCK_EXIT(&softc->ipf_poolrw);
978 ipf_lookup_dump(softc, arg)
979 ipf_main_softc_t *softc;
982 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
986 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
987 if (IPLT_POOL == (*l)->ipfl_type) {
988 ipf_pool_dump(softc, softl->ipf_back[i]);
992 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
993 if (IPLT_HASH == (*l)->ipfl_type) {
994 ipf_htable_dump(softc, softl->ipf_back[i]);