3 * Copyright (C) 2012 by Darren Reed.
5 * See the IPFILTER.LICENCE file for details on licencing.
7 #if defined(KERNEL) || defined(_KERNEL)
14 # define _PROTO_NET_H_
16 #include <sys/param.h>
17 #include <sys/errno.h>
18 #include <sys/types.h>
21 #if __FreeBSD_version >= 220000 && defined(_KERNEL)
22 # include <sys/fcntl.h>
23 # include <sys/filio.h>
25 # include <sys/ioctl.h>
38 #include <sys/socket.h>
40 #if defined(__FreeBSD__)
41 # include <sys/cdefs.h>
42 # include <sys/proc.h>
45 # include <sys/systm.h>
46 # if !defined(__SVR4) && !defined(__svr4__)
47 # include <sys/mbuf.h>
52 #include <netinet/in.h>
54 #include "netinet/ip_compat.h"
55 #include "netinet/ip_fil.h"
56 #include "netinet/ip_lookup.h"
57 #include "netinet/ip_pool.h"
58 #include "netinet/ip_htable.h"
59 #include "netinet/ip_dstlist.h"
63 static const char rcsid[] = "@(#)$Id$";
67 * In this file, ip_pool.c, ip_htable.c and ip_dstlist.c, you will find the
68 * range for unit is [-1,IPL_LOGMAX]. The -1 is considered to be a valid number
69 * and represents a "wildcard" or "all" units (IPL_LOGALL). The reason for not
70 * starting the numbering at 0 is because the numbers [0,IPL_LOGMAX] correspond
71 * to the minor device number for their respective device. Thus where there is
72 * array indexing on the unit, +1 is used to map [-1.IPL_LOGMAX] to
73 * [0.POOL_LOOKUP_MAX].
75 static int ipf_lookup_addnode __P((ipf_main_softc_t *, caddr_t, int));
76 static int ipf_lookup_delnode __P((ipf_main_softc_t *, caddr_t, int));
77 static int ipf_lookup_addtable __P((ipf_main_softc_t *, caddr_t));
78 static int ipf_lookup_deltable __P((ipf_main_softc_t *, caddr_t));
79 static int ipf_lookup_stats __P((ipf_main_softc_t *, caddr_t));
80 static int ipf_lookup_flush __P((ipf_main_softc_t *, caddr_t));
81 static int ipf_lookup_iterate __P((ipf_main_softc_t *, void *, int, void *));
82 static int ipf_lookup_deltok __P((ipf_main_softc_t *, void *, int, void *));
84 #define MAX_BACKENDS 3
85 static ipf_lookup_t *backends[MAX_BACKENDS] = {
92 typedef struct ipf_lookup_softc_s {
93 void *ipf_back[MAX_BACKENDS];
97 /* ------------------------------------------------------------------------ */
98 /* Function: ipf_lookup_init */
99 /* Returns: int - 0 = success, else error */
100 /* Parameters: softc(I) - pointer to soft context main structure */
102 /* Initialise all of the subcomponents of the lookup infrstructure. */
103 /* ------------------------------------------------------------------------ */
105 ipf_lookup_soft_create(softc)
106 ipf_main_softc_t *softc;
108 ipf_lookup_softc_t *softl;
112 KMALLOC(softl, ipf_lookup_softc_t *);
116 bzero((char *)softl, sizeof(*softl));
118 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
119 softl->ipf_back[i] = (*(*l)->ipfl_create)(softc);
120 if (softl->ipf_back[i] == NULL) {
121 ipf_lookup_soft_destroy(softc, softl);
130 /* ------------------------------------------------------------------------ */
131 /* Function: ipf_lookup_soft_init */
132 /* Returns: int - 0 = success, else error */
133 /* Parameters: softc(I) - pointer to soft context main structure */
134 /* arg(I) - pointer to local context to use */
136 /* Initialise all of the subcomponents of the lookup infrstructure. */
137 /* ------------------------------------------------------------------------ */
139 ipf_lookup_soft_init(softc, arg)
140 ipf_main_softc_t *softc;
143 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
147 for (i = 0; i < MAX_BACKENDS; i++) {
148 err = (*backends[i]->ipfl_init)(softc, softl->ipf_back[i]);
157 /* ------------------------------------------------------------------------ */
158 /* Function: ipf_lookup_soft_fini */
159 /* Returns: int - 0 = success, else error */
160 /* Parameters: softc(I) - pointer to soft context main structure */
161 /* arg(I) - pointer to local context to use */
163 /* Call the fini function in each backend to cleanup all allocated data. */
164 /* ------------------------------------------------------------------------ */
166 ipf_lookup_soft_fini(softc, arg)
167 ipf_main_softc_t *softc;
170 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
173 for (i = 0; i < MAX_BACKENDS; i++) {
174 if (softl->ipf_back[i] != NULL)
175 (*backends[i]->ipfl_fini)(softc,
183 /* ------------------------------------------------------------------------ */
184 /* Function: ipf_lookup_expire */
186 /* Parameters: softc(I) - pointer to soft context main structure */
188 /* Step through each of the backends and call their expire functions, */
189 /* allowing them to delete any lifetime limited data. */
190 /* ------------------------------------------------------------------------ */
192 ipf_lookup_expire(softc)
193 ipf_main_softc_t *softc;
195 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
198 WRITE_ENTER(&softc->ipf_poolrw);
199 for (i = 0; i < MAX_BACKENDS; i++)
200 (*backends[i]->ipfl_expire)(softc, softl->ipf_back[i]);
201 RWLOCK_EXIT(&softc->ipf_poolrw);
205 /* ------------------------------------------------------------------------ */
206 /* Function: ipf_lookup_softc_destroy */
207 /* Returns: int - 0 = success, else error */
208 /* Parameters: softc(I) - pointer to soft context main structure */
209 /* arg(I) - pointer to local context to use */
211 /* Free up all pool related memory that has been allocated whilst IPFilter */
212 /* has been running. Also, do any other deinitialisation required such */
213 /* ipf_lookup_init() can be called again, safely. */
214 /* ------------------------------------------------------------------------ */
216 ipf_lookup_soft_destroy(softc, arg)
217 ipf_main_softc_t *softc;
220 ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg;
223 for (i = 0; i < MAX_BACKENDS; i++) {
224 if (softl->ipf_back[i] != NULL)
225 (*backends[i]->ipfl_destroy)(softc,
233 /* ------------------------------------------------------------------------ */
234 /* Function: ipf_lookup_ioctl */
235 /* Returns: int - 0 = success, else error */
236 /* Parameters: softc(I) - pointer to soft context main structure */
237 /* arg(I) - pointer to local context to use */
238 /* data(IO) - pointer to ioctl data to be copied to/from user */
240 /* cmd(I) - ioctl command number */
241 /* mode(I) - file mode bits used with open */
242 /* uid(I) - uid of process doing ioctl */
243 /* ctx(I) - pointer that represents context for uid */
245 /* Handle ioctl commands sent to the ioctl device. For the most part, this */
246 /* involves just calling another function to handle the specifics of each */
248 /* ------------------------------------------------------------------------ */
250 ipf_lookup_ioctl(softc, data, cmd, mode, uid, ctx)
251 ipf_main_softc_t *softc;
260 mode = mode; /* LINT */
266 case SIOCLOOKUPADDNODE :
267 case SIOCLOOKUPADDNODEW :
268 WRITE_ENTER(&softc->ipf_poolrw);
269 err = ipf_lookup_addnode(softc, data, uid);
270 RWLOCK_EXIT(&softc->ipf_poolrw);
273 case SIOCLOOKUPDELNODE :
274 case SIOCLOOKUPDELNODEW :
275 WRITE_ENTER(&softc->ipf_poolrw);
276 err = ipf_lookup_delnode(softc, data, uid);
277 RWLOCK_EXIT(&softc->ipf_poolrw);
280 case SIOCLOOKUPADDTABLE :
281 WRITE_ENTER(&softc->ipf_poolrw);
282 err = ipf_lookup_addtable(softc, data);
283 RWLOCK_EXIT(&softc->ipf_poolrw);
286 case SIOCLOOKUPDELTABLE :
287 WRITE_ENTER(&softc->ipf_poolrw);
288 err = ipf_lookup_deltable(softc, data);
289 RWLOCK_EXIT(&softc->ipf_poolrw);
292 case SIOCLOOKUPSTAT :
293 case SIOCLOOKUPSTATW :
294 WRITE_ENTER(&softc->ipf_poolrw);
295 err = ipf_lookup_stats(softc, data);
296 RWLOCK_EXIT(&softc->ipf_poolrw);
299 case SIOCLOOKUPFLUSH :
300 WRITE_ENTER(&softc->ipf_poolrw);
301 err = ipf_lookup_flush(softc, data);
302 RWLOCK_EXIT(&softc->ipf_poolrw);
305 case SIOCLOOKUPITER :
306 err = ipf_lookup_iterate(softc, data, uid, ctx);
310 err = ipf_lookup_deltok(softc, data, uid, ctx);
323 /* ------------------------------------------------------------------------ */
324 /* Function: ipf_lookup_addnode */
325 /* Returns: int - 0 = success, else error */
326 /* Parameters: softc(I) - pointer to soft context main structure */
327 /* data(I) - pointer to data from ioctl call */
329 /* Add a new data node to a lookup structure. First, check to see if the */
330 /* parent structure refered to by name exists and if it does, then go on to */
331 /* add a node to it. */
332 /* ------------------------------------------------------------------------ */
334 ipf_lookup_addnode(softc, data, uid)
335 ipf_main_softc_t *softc;
339 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
345 err = BCOPYIN(data, &op, sizeof(op));
351 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
352 (op.iplo_unit != IPLT_ALL)) {
357 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
359 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
360 if (op.iplo_type == (*l)->ipfl_type) {
361 err = (*(*l)->ipfl_node_add)(softc,
368 if (i == MAX_BACKENDS) {
377 /* ------------------------------------------------------------------------ */
378 /* Function: ipf_lookup_delnode */
379 /* Returns: int - 0 = success, else error */
380 /* Parameters: softc(I) - pointer to soft context main structure */
381 /* data(I) - pointer to data from ioctl call */
383 /* Delete a node from a lookup table by first looking for the table it is */
384 /* in and then deleting the entry that gets found. */
385 /* ------------------------------------------------------------------------ */
387 ipf_lookup_delnode(softc, data, uid)
388 ipf_main_softc_t *softc;
392 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
398 err = BCOPYIN(data, &op, sizeof(op));
404 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
405 (op.iplo_unit != IPLT_ALL)) {
410 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
412 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
413 if (op.iplo_type == (*l)->ipfl_type) {
414 err = (*(*l)->ipfl_node_del)(softc, softl->ipf_back[i],
420 if (i == MAX_BACKENDS) {
428 /* ------------------------------------------------------------------------ */
429 /* Function: ipf_lookup_addtable */
430 /* Returns: int - 0 = success, else error */
431 /* Parameters: softc(I) - pointer to soft context main structure */
432 /* data(I) - pointer to data from ioctl call */
434 /* Create a new lookup table, if one doesn't already exist using the name */
436 /* ------------------------------------------------------------------------ */
438 ipf_lookup_addtable(softc, data)
439 ipf_main_softc_t *softc;
442 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
447 err = BCOPYIN(data, &op, sizeof(op));
453 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
454 (op.iplo_unit != IPLT_ALL)) {
459 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
461 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
462 if (op.iplo_type == (*l)->ipfl_type) {
463 err = (*(*l)->ipfl_table_add)(softc,
470 if (i == MAX_BACKENDS) {
476 * For anonymous pools, copy back the operation struct because in the
477 * case of success it will contain the new table's name.
479 if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) {
480 err = BCOPYOUT(&op, data, sizeof(op));
491 /* ------------------------------------------------------------------------ */
492 /* Function: ipf_lookup_deltable */
493 /* Returns: int - 0 = success, else error */
494 /* Parameters: softc(I) - pointer to soft context main structure */
495 /* data(I) - pointer to data from ioctl call */
497 /* Decodes ioctl request to remove a particular hash table or pool and */
498 /* calls the relevant function to do the cleanup. */
499 /* ------------------------------------------------------------------------ */
501 ipf_lookup_deltable(softc, data)
502 ipf_main_softc_t *softc;
505 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
510 err = BCOPYIN(data, &op, sizeof(op));
516 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
517 (op.iplo_unit != IPLT_ALL)) {
522 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
524 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
525 if (op.iplo_type == (*l)->ipfl_type) {
526 err = (*(*l)->ipfl_table_del)(softc,
533 if (i == MAX_BACKENDS) {
541 /* ------------------------------------------------------------------------ */
542 /* Function: ipf_lookup_stats */
543 /* Returns: int - 0 = success, else error */
544 /* Parameters: softc(I) - pointer to soft context main structure */
545 /* data(I) - pointer to data from ioctl call */
547 /* Copy statistical information from inside the kernel back to user space. */
548 /* ------------------------------------------------------------------------ */
550 ipf_lookup_stats(softc, data)
551 ipf_main_softc_t *softc;
554 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
560 err = BCOPYIN(data, &op, sizeof(op));
566 if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) &&
567 (op.iplo_unit != IPLT_ALL)) {
572 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
573 if (op.iplo_type == (*l)->ipfl_type) {
574 err = (*(*l)->ipfl_stats_get)(softc,
581 if (i == MAX_BACKENDS) {
590 /* ------------------------------------------------------------------------ */
591 /* Function: ipf_lookup_flush */
592 /* Returns: int - 0 = success, else error */
593 /* Parameters: softc(I) - pointer to soft context main structure */
594 /* data(I) - pointer to data from ioctl call */
596 /* A flush is called when we want to flush all the nodes from a particular */
597 /* entry in the hash table/pool or want to remove all groups from those. */
598 /* ------------------------------------------------------------------------ */
600 ipf_lookup_flush(softc, data)
601 ipf_main_softc_t *softc;
604 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
605 int err, unit, num, type, i;
606 iplookupflush_t flush;
609 err = BCOPYIN(data, &flush, sizeof(flush));
615 unit = flush.iplf_unit;
616 if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) {
621 flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0';
623 type = flush.iplf_type;
628 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
629 if (type == (*l)->ipfl_type || type == IPLT_ALL) {
631 num += (*(*l)->ipfl_flush)(softc,
638 flush.iplf_count = num;
639 err = BCOPYOUT(&flush, data, sizeof(flush));
649 /* ------------------------------------------------------------------------ */
650 /* Function: ipf_lookup_delref */
652 /* Parameters: softc(I) - pointer to soft context main structure */
653 /* type(I) - table type to operate on */
654 /* ptr(I) - pointer to object to remove reference for */
656 /* This function organises calling the correct deref function for a given */
657 /* type of object being passed into it. */
658 /* ------------------------------------------------------------------------ */
660 ipf_lookup_deref(softc, type, ptr)
661 ipf_main_softc_t *softc;
665 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
671 for (i = 0; i < MAX_BACKENDS; i++) {
672 if (type == backends[i]->ipfl_type) {
673 WRITE_ENTER(&softc->ipf_poolrw);
674 (*backends[i]->ipfl_table_deref)(softc,
677 RWLOCK_EXIT(&softc->ipf_poolrw);
684 /* ------------------------------------------------------------------------ */
685 /* Function: ipf_lookup_iterate */
686 /* Returns: int - 0 = success, else error */
687 /* Parameters: softc(I) - pointer to soft context main structure */
688 /* data(I) - pointer to data from ioctl call */
689 /* uid(I) - uid of caller */
690 /* ctx(I) - pointer to give the uid context */
692 /* Decodes ioctl request to step through either hash tables or pools. */
693 /* ------------------------------------------------------------------------ */
695 ipf_lookup_iterate(softc, data, uid, ctx)
696 ipf_main_softc_t *softc;
701 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
702 ipflookupiter_t iter;
707 err = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_LOOKUPITER);
711 if (iter.ili_unit < IPL_LOGALL && iter.ili_unit > IPL_LOGMAX) {
716 if (iter.ili_ival != IPFGENITER_LOOKUP) {
722 token = ipf_token_find(softc, iter.ili_key, uid, ctx);
729 for (i = 0; i < MAX_BACKENDS; i++) {
730 if (iter.ili_type == backends[i]->ipfl_type) {
731 err = (*backends[i]->ipfl_iter_next)(softc,
739 if (i == MAX_BACKENDS) {
744 WRITE_ENTER(&softc->ipf_tokens);
745 ipf_token_deref(softc, token);
746 RWLOCK_EXIT(&softc->ipf_tokens);
752 /* ------------------------------------------------------------------------ */
753 /* Function: ipf_lookup_iterderef */
755 /* Parameters: softc(I) - pointer to soft context main structure */
756 /* type(I) - backend type to iterate through */
757 /* data(I) - pointer to data from ioctl call */
759 /* Decodes ioctl request to remove a particular hash table or pool and */
760 /* calls the relevant function to do the cleanup. */
761 /* Because each of the backend types has a different data structure, */
762 /* iteration is limited to one type at a time (i.e. it is not permitted to */
763 /* go on from pool types to hash types as part of the "get next".) */
764 /* ------------------------------------------------------------------------ */
766 ipf_lookup_iterderef(softc, type, data)
767 ipf_main_softc_t *softc;
771 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
772 struct iplookupiterkey *lkey;
773 iplookupiterkey_t key;
777 lkey = &key.ilik_unstr;
779 if (lkey->ilik_ival != IPFGENITER_LOOKUP)
782 WRITE_ENTER(&softc->ipf_poolrw);
784 for (i = 0; i < MAX_BACKENDS; i++) {
785 if (lkey->ilik_type == backends[i]->ipfl_type) {
786 (*backends[i]->ipfl_iter_deref)(softc,
794 RWLOCK_EXIT(&softc->ipf_poolrw);
798 /* ------------------------------------------------------------------------ */
799 /* Function: ipf_lookup_deltok */
800 /* Returns: int - 0 = success, else error */
801 /* Parameters: softc(I) - pointer to soft context main structure */
802 /* data(I) - pointer to data from ioctl call */
803 /* uid(I) - uid of caller */
804 /* ctx(I) - pointer to give the uid context */
806 /* Deletes the token identified by the combination of (type,uid,ctx) */
807 /* "key" is a combination of the table type, iterator type and the unit for */
808 /* which the token was being used. */
809 /* ------------------------------------------------------------------------ */
811 ipf_lookup_deltok(softc, data, uid, ctx)
812 ipf_main_softc_t *softc;
821 error = BCOPYIN(data, &key, sizeof(key));
823 error = ipf_token_del(softc, key, uid, ctx);
829 /* ------------------------------------------------------------------------ */
830 /* Function: ipf_lookup_res_num */
831 /* Returns: void * - NULL = failure, else success. */
832 /* Parameters: softc(I) - pointer to soft context main structure */
833 /* unit(I) - device for which this is for */
834 /* type(I) - type of lookup these parameters are for. */
835 /* number(I) - table number to use when searching */
836 /* funcptr(IO) - pointer to pointer for storing IP address */
837 /* searching function. */
839 /* Search for the "table" number passed in amongst those configured for */
840 /* that particular type. If the type is recognised then the function to */
841 /* call to do the IP address search will be change, regardless of whether */
842 /* or not the "table" number exists. */
843 /* ------------------------------------------------------------------------ */
845 ipf_lookup_res_num(softc, unit, type, number, funcptr)
846 ipf_main_softc_t *softc;
850 lookupfunc_t *funcptr;
852 char name[FR_GROUPLEN];
854 #if defined(SNPRINTF) && defined(_KERNEL)
855 SNPRINTF(name, sizeof(name), "%u", number);
857 (void) sprintf(name, "%u", number);
860 return ipf_lookup_res_name(softc, unit, type, name, funcptr);
864 /* ------------------------------------------------------------------------ */
865 /* Function: ipf_lookup_res_name */
866 /* Returns: void * - NULL = failure, else success. */
867 /* Parameters: softc(I) - pointer to soft context main structure */
868 /* unit(I) - device for which this is for */
869 /* type(I) - type of lookup these parameters are for. */
870 /* name(I) - table name to use when searching */
871 /* funcptr(IO) - pointer to pointer for storing IP address */
872 /* searching function. */
874 /* Search for the "table" number passed in amongst those configured for */
875 /* that particular type. If the type is recognised then the function to */
876 /* call to do the IP address search will be changed, regardless of whether */
877 /* or not the "table" number exists. */
878 /* ------------------------------------------------------------------------ */
880 ipf_lookup_res_name(softc, unit, type, name, funcptr)
881 ipf_main_softc_t *softc;
885 lookupfunc_t *funcptr;
887 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
892 READ_ENTER(&softc->ipf_poolrw);
894 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) {
895 if (type == (*l)->ipfl_type) {
896 ptr = (*(*l)->ipfl_select_add_ref)(softl->ipf_back[i],
898 if (ptr != NULL && funcptr != NULL) {
899 *funcptr = (*l)->ipfl_addr_find;
905 if (i == MAX_BACKENDS) {
911 RWLOCK_EXIT(&softc->ipf_poolrw);
917 /* ------------------------------------------------------------------------ */
918 /* Function: ipf_lookup_find_htable */
919 /* Returns: void * - NULL = failure, else success. */
920 /* Parameters: softc(I) - pointer to soft context main structure */
921 /* unit(I) - device for which this is for */
922 /* name(I) - table name to use when searching */
924 /* To support the group-map feature, where a hash table maps address */
925 /* networks to rule group numbers, we need to expose a function that uses */
926 /* only the hash table backend. */
927 /* ------------------------------------------------------------------------ */
929 ipf_lookup_find_htable(softc, unit, name)
930 ipf_main_softc_t *softc;
934 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
939 READ_ENTER(&softc->ipf_poolrw);
941 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
942 if (IPLT_HASH == (*l)->ipfl_type) {
943 tab = ipf_htable_find(softl->ipf_back[i], unit, name);
947 RWLOCK_EXIT(&softc->ipf_poolrw);
953 /* ------------------------------------------------------------------------ */
954 /* Function: ipf_lookup_sync */
956 /* Parameters: softc(I) - pointer to soft context main structure */
958 /* This function is the interface that the machine dependent sync functions */
959 /* call when a network interface name change occurs. It then calls the sync */
960 /* functions of the lookup implementations - if they have one. */
961 /* ------------------------------------------------------------------------ */
964 ipf_lookup_sync(softc, ifp)
965 ipf_main_softc_t *softc;
968 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
972 READ_ENTER(&softc->ipf_poolrw);
974 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
975 if ((*l)->ipfl_sync != NULL)
976 (*(*l)->ipfl_sync)(softc, softl->ipf_back[i]);
978 RWLOCK_EXIT(&softc->ipf_poolrw);
984 ipf_lookup_dump(softc, arg)
985 ipf_main_softc_t *softc;
988 ipf_lookup_softc_t *softl = softc->ipf_lookup_soft;
992 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
993 if (IPLT_POOL == (*l)->ipfl_type) {
994 ipf_pool_dump(softc, softl->ipf_back[i]);
998 for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++)
999 if (IPLT_HASH == (*l)->ipfl_type) {
1000 ipf_htable_dump(softc, softl->ipf_back[i]);