Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 1 | /* |
| 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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 27 | # include <stdio.h> |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 28 | # include <string.h> |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 29 | # include <stdlib.h> |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 30 | # define _KERNEL |
| 31 | # ifdef __OpenBSD__ |
| 32 | struct file; |
| 33 | # endif |
| 34 | # include <sys/uio.h> |
| 35 | # undef _KERNEL |
| 36 | #endif |
| 37 | #include <sys/socket.h> |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 38 | #include <net/if.h> |
| 39 | #if defined(__FreeBSD__) |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 40 | # include <sys/cdefs.h> |
| 41 | # include <sys/proc.h> |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 42 | #endif |
| 43 | #if defined(_KERNEL) |
| 44 | # include <sys/systm.h> |
| 45 | # if !defined(__SVR4) && !defined(__svr4__) |
| 46 | # include <sys/mbuf.h> |
| 47 | # endif |
Darren Reed | abb8af6 | 2009-07-23 11:57:09 +0000 | [diff] [blame] | 48 | #else |
| 49 | # include "ipf.h" |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 50 | #endif |
| 51 | #include <netinet/in.h> |
| 52 | |
| 53 | #include "netinet/ip_compat.h" |
| 54 | #include "netinet/ip_fil.h" |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 55 | #include "netinet/ip_lookup.h" |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 56 | #include "netinet/ip_pool.h" |
| 57 | #include "netinet/ip_htable.h" |
Darren Reed | fdc6eed | 2009-01-03 06:02:37 +0000 | [diff] [blame] | 58 | #include "netinet/ip_dstlist.h" |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 59 | /* END OF INCLUDES */ |
| 60 | |
| 61 | #if !defined(lint) |
| 62 | static const char rcsid[] = "@(#)$Id$"; |
| 63 | #endif |
| 64 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 65 | /* |
| 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 Reed | 278d16e | 2009-12-27 07:34:34 +0000 | [diff] [blame] | 74 | static int ipf_lookup_addnode __P((ipf_main_softc_t *, caddr_t, int)); |
| 75 | static int ipf_lookup_delnode __P((ipf_main_softc_t *, caddr_t, int)); |
| 76 | static int ipf_lookup_addtable __P((ipf_main_softc_t *, caddr_t)); |
| 77 | static int ipf_lookup_deltable __P((ipf_main_softc_t *, caddr_t)); |
| 78 | static int ipf_lookup_stats __P((ipf_main_softc_t *, caddr_t)); |
| 79 | static int ipf_lookup_flush __P((ipf_main_softc_t *, caddr_t)); |
| 80 | static int ipf_lookup_iterate __P((ipf_main_softc_t *, void *, int, void *)); |
| 81 | static int ipf_lookup_deltok __P((ipf_main_softc_t *, void *, int, void *)); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 82 | |
Darren Reed | f96e37f | 2009-12-19 12:33:30 +0000 | [diff] [blame] | 83 | #define MAX_BACKENDS 3 |
| 84 | static ipf_lookup_t *backends[MAX_BACKENDS] = { |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 85 | &ipf_pool_backend, |
| 86 | &ipf_htable_backend, |
| 87 | &ipf_dstlist_backend |
| 88 | }; |
| 89 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 90 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 91 | typedef struct ipf_lookup_softc_s { |
| 92 | void *ipf_back[MAX_BACKENDS]; |
| 93 | } ipf_lookup_softc_t; |
| 94 | |
Darren Reed | f96e37f | 2009-12-19 12:33:30 +0000 | [diff] [blame] | 95 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 96 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 97 | /* Function: ipf_lookup_init */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 98 | /* Returns: int - 0 = success, else error */ |
| 99 | /* Parameters: softc(I) - pointer to soft context main structure */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 100 | /* */ |
| 101 | /* Initialise all of the subcomponents of the lookup infrstructure. */ |
| 102 | /* ------------------------------------------------------------------------ */ |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 103 | void * |
| 104 | ipf_lookup_soft_create(softc) |
| 105 | ipf_main_softc_t *softc; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 106 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 107 | ipf_lookup_softc_t *softl; |
| 108 | ipf_lookup_t **l; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 109 | int i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 110 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 111 | 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 Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 129 | /* ------------------------------------------------------------------------ */ |
| 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 Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 137 | int |
| 138 | ipf_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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 145 | |
| 146 | for (i = 0; i < MAX_BACKENDS; i++) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 147 | 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 Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 156 | /* ------------------------------------------------------------------------ */ |
| 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 Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 164 | int |
| 165 | ipf_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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 176 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 177 | |
| 178 | return 0; |
| 179 | } |
| 180 | |
| 181 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 182 | /* ------------------------------------------------------------------------ */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 183 | /* 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 | /* ------------------------------------------------------------------------ */ |
| 190 | void |
| 191 | ipf_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 Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 205 | /* Function: ipf_lookup_softc_destroy */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 206 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 207 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 208 | /* arg(I) - pointer to local context to use */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 209 | /* */ |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 212 | /* ipf_lookup_init() can be called again, safely. */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 213 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 214 | void |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 215 | ipf_lookup_soft_destroy(softc, arg) |
| 216 | ipf_main_softc_t *softc; |
| 217 | void *arg; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 218 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 219 | ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 220 | int i; |
| 221 | |
| 222 | for (i = 0; i < MAX_BACKENDS; i++) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 223 | if (softl->ipf_back[i] != NULL) |
| 224 | (*backends[i]->ipfl_destroy)(softc, |
| 225 | softl->ipf_back[i]); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 226 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 227 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 228 | KFREE(softl); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 229 | } |
| 230 | |
| 231 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 232 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 233 | /* Function: ipf_lookup_ioctl */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 234 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 235 | /* 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 Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 238 | /* space. */ |
| 239 | /* cmd(I) - ioctl command number */ |
| 240 | /* mode(I) - file mode bits used with open */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 241 | /* uid(I) - uid of process doing ioctl */ |
| 242 | /* ctx(I) - pointer that represents context for uid */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 243 | /* */ |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 248 | int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 249 | ipf_lookup_ioctl(softc, data, cmd, mode, uid, ctx) |
| 250 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 251 | caddr_t data; |
| 252 | ioctlcmd_t cmd; |
| 253 | int mode, uid; |
| 254 | void *ctx; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 255 | { |
| 256 | int err; |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 257 | SPL_INT(s); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 258 | |
| 259 | mode = mode; /* LINT */ |
| 260 | |
| 261 | SPL_NET(s); |
| 262 | |
| 263 | switch (cmd) |
| 264 | { |
| 265 | case SIOCLOOKUPADDNODE : |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 266 | case SIOCLOOKUPADDNODEW : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 267 | WRITE_ENTER(&softc->ipf_poolrw); |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 268 | err = ipf_lookup_addnode(softc, data, uid); |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 269 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 270 | break; |
| 271 | |
| 272 | case SIOCLOOKUPDELNODE : |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 273 | case SIOCLOOKUPDELNODEW : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 274 | WRITE_ENTER(&softc->ipf_poolrw); |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 275 | err = ipf_lookup_delnode(softc, data, uid); |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 276 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 277 | break; |
| 278 | |
| 279 | case SIOCLOOKUPADDTABLE : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 280 | WRITE_ENTER(&softc->ipf_poolrw); |
| 281 | err = ipf_lookup_addtable(softc, data); |
| 282 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 283 | break; |
| 284 | |
| 285 | case SIOCLOOKUPDELTABLE : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 286 | WRITE_ENTER(&softc->ipf_poolrw); |
| 287 | err = ipf_lookup_deltable(softc, data); |
| 288 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 289 | break; |
| 290 | |
| 291 | case SIOCLOOKUPSTAT : |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 292 | case SIOCLOOKUPSTATW : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 293 | WRITE_ENTER(&softc->ipf_poolrw); |
| 294 | err = ipf_lookup_stats(softc, data); |
| 295 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 296 | break; |
| 297 | |
| 298 | case SIOCLOOKUPFLUSH : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 299 | WRITE_ENTER(&softc->ipf_poolrw); |
| 300 | err = ipf_lookup_flush(softc, data); |
| 301 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 302 | break; |
| 303 | |
| 304 | case SIOCLOOKUPITER : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 305 | err = ipf_lookup_iterate(softc, data, uid, ctx); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 306 | break; |
| 307 | |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 308 | case SIOCIPFDELTOK : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 309 | err = ipf_lookup_deltok(softc, data, uid, ctx); |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 310 | break; |
| 311 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 312 | default : |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 313 | softc->ipf_interror = 50001; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 314 | err = EINVAL; |
| 315 | break; |
| 316 | } |
| 317 | SPL_X(s); |
| 318 | return err; |
| 319 | } |
| 320 | |
| 321 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 322 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 323 | /* Function: ipf_lookup_addnode */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 324 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 325 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 326 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 327 | /* */ |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 332 | static int |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 333 | ipf_lookup_addnode(softc, data, uid) |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 334 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 335 | caddr_t data; |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 336 | int uid; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 337 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 338 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 339 | iplookupop_t op; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 340 | ipf_lookup_t **l; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 341 | int err; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 342 | int i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 343 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 344 | err = BCOPYIN(data, &op, sizeof(op)); |
| 345 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 346 | softc->ipf_interror = 50002; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 347 | return EFAULT; |
| 348 | } |
| 349 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 350 | if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && |
| 351 | (op.iplo_unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 352 | softc->ipf_interror = 50003; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 353 | return EINVAL; |
| 354 | } |
| 355 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 356 | op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; |
| 357 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 358 | 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 Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 362 | &op, uid); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 363 | break; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 364 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 365 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 366 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 367 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 368 | softc->ipf_interror = 50012; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 369 | err = EINVAL; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 370 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 371 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 372 | return err; |
| 373 | } |
| 374 | |
| 375 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 376 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 377 | /* Function: ipf_lookup_delnode */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 378 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 379 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 380 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 381 | /* */ |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 385 | static int |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 386 | ipf_lookup_delnode(softc, data, uid) |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 387 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 388 | caddr_t data; |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 389 | int uid; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 390 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 391 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 392 | iplookupop_t op; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 393 | ipf_lookup_t **l; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 394 | int err; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 395 | int i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 396 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 397 | err = BCOPYIN(data, &op, sizeof(op)); |
| 398 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 399 | softc->ipf_interror = 50042; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 400 | return EFAULT; |
| 401 | } |
| 402 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 403 | if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && |
| 404 | (op.iplo_unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 405 | softc->ipf_interror = 50013; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 406 | return EINVAL; |
| 407 | } |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 408 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 409 | op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; |
| 410 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 411 | for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { |
| 412 | if (op.iplo_type == (*l)->ipfl_type) { |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 413 | err = (*(*l)->ipfl_node_del)(softc, softl->ipf_back[i], |
| 414 | &op, uid); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 415 | break; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 416 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 417 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 418 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 419 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 420 | softc->ipf_interror = 50021; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 421 | err = EINVAL; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 422 | } |
| 423 | return err; |
| 424 | } |
| 425 | |
| 426 | |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 427 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 428 | /* Function: ipf_lookup_addtable */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 429 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 430 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 431 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 432 | /* */ |
| 433 | /* Create a new lookup table, if one doesn't already exist using the name */ |
| 434 | /* for this one. */ |
| 435 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 436 | static int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 437 | ipf_lookup_addtable(softc, data) |
| 438 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 439 | caddr_t data; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 440 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 441 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 442 | iplookupop_t op; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 443 | ipf_lookup_t **l; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 444 | int err, i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 445 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 446 | err = BCOPYIN(data, &op, sizeof(op)); |
| 447 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 448 | softc->ipf_interror = 50022; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 449 | return EFAULT; |
| 450 | } |
| 451 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 452 | if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && |
| 453 | (op.iplo_unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 454 | softc->ipf_interror = 50023; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 455 | return EINVAL; |
| 456 | } |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 457 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 458 | op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; |
| 459 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 460 | for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { |
| 461 | if (op.iplo_type == (*l)->ipfl_type) { |
Darren Reed | 408afbd | 2009-02-09 01:49:27 +0000 | [diff] [blame] | 462 | err = (*(*l)->ipfl_table_add)(softc, |
| 463 | softl->ipf_back[i], |
| 464 | &op); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 465 | break; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 466 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 467 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 468 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 469 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 470 | softc->ipf_interror = 50026; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 471 | err = EINVAL; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 472 | } |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 473 | |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 478 | if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) { |
| 479 | err = BCOPYOUT(&op, data, sizeof(op)); |
| 480 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 481 | softc->ipf_interror = 50027; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 482 | err = EFAULT; |
| 483 | } |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 484 | } |
| 485 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 486 | return err; |
| 487 | } |
| 488 | |
| 489 | |
| 490 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 491 | /* Function: ipf_lookup_deltable */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 492 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 493 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 494 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 495 | /* */ |
| 496 | /* Decodes ioctl request to remove a particular hash table or pool and */ |
| 497 | /* calls the relevant function to do the cleanup. */ |
| 498 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 499 | static int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 500 | ipf_lookup_deltable(softc, data) |
| 501 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 502 | caddr_t data; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 503 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 504 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 505 | iplookupop_t op; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 506 | ipf_lookup_t **l; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 507 | int err, i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 508 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 509 | err = BCOPYIN(data, &op, sizeof(op)); |
| 510 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 511 | softc->ipf_interror = 50028; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 512 | return EFAULT; |
| 513 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 514 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 515 | if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && |
| 516 | (op.iplo_unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 517 | softc->ipf_interror = 50029; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 518 | return EINVAL; |
| 519 | } |
| 520 | |
| 521 | op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 522 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 523 | 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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 528 | break; |
| 529 | } |
| 530 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 531 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 532 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 533 | softc->ipf_interror = 50030; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 534 | err = EINVAL; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 535 | } |
| 536 | return err; |
| 537 | } |
| 538 | |
| 539 | |
| 540 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 541 | /* Function: ipf_lookup_stats */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 542 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 543 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 544 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 545 | /* */ |
| 546 | /* Copy statistical information from inside the kernel back to user space. */ |
| 547 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 548 | static int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 549 | ipf_lookup_stats(softc, data) |
| 550 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 551 | caddr_t data; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 552 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 553 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 554 | iplookupop_t op; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 555 | ipf_lookup_t **l; |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 556 | int err; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 557 | int i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 558 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 559 | err = BCOPYIN(data, &op, sizeof(op)); |
| 560 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 561 | softc->ipf_interror = 50031; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 562 | return EFAULT; |
| 563 | } |
| 564 | |
Darren Reed | de94985 | 2009-03-03 10:07:12 +0000 | [diff] [blame] | 565 | if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && |
| 566 | (op.iplo_unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 567 | softc->ipf_interror = 50032; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 568 | return EINVAL; |
| 569 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 570 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 571 | 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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 576 | break; |
| 577 | } |
| 578 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 579 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 580 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 581 | softc->ipf_interror = 50033; |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 582 | err = EINVAL; |
Darren Reed | d4718fc | 2006-06-15 17:00:40 +0000 | [diff] [blame] | 583 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 584 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 585 | return err; |
| 586 | } |
| 587 | |
| 588 | |
| 589 | /* ------------------------------------------------------------------------ */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 590 | /* Function: ipf_lookup_flush */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 591 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 592 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 593 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 594 | /* */ |
| 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 598 | static int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 599 | ipf_lookup_flush(softc, data) |
| 600 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 601 | caddr_t data; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 602 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 603 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 604 | int err, unit, num, type, i; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 605 | iplookupflush_t flush; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 606 | ipf_lookup_t **l; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 607 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 608 | err = BCOPYIN(data, &flush, sizeof(flush)); |
| 609 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 610 | softc->ipf_interror = 50034; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 611 | return EFAULT; |
| 612 | } |
| 613 | |
| 614 | unit = flush.iplf_unit; |
| 615 | if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 616 | softc->ipf_interror = 50035; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 617 | return EINVAL; |
| 618 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 619 | |
| 620 | flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; |
| 621 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 622 | type = flush.iplf_type; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 623 | softc->ipf_interror = 50036; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 624 | err = EINVAL; |
| 625 | num = 0; |
| 626 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 627 | for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { |
| 628 | if (type == (*l)->ipfl_type || type == IPLT_ALL) { |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 629 | err = 0; |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 630 | num += (*(*l)->ipfl_flush)(softc, |
| 631 | softl->ipf_back[i], |
| 632 | &flush); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 633 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 634 | } |
| 635 | |
| 636 | if (err == 0) { |
| 637 | flush.iplf_count = num; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 638 | err = BCOPYOUT(&flush, data, sizeof(flush)); |
| 639 | if (err != 0) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 640 | softc->ipf_interror = 50037; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 641 | err = EFAULT; |
| 642 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 643 | } |
| 644 | return err; |
| 645 | } |
| 646 | |
| 647 | |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 648 | /* ------------------------------------------------------------------------ */ |
| 649 | /* Function: ipf_lookup_delref */ |
| 650 | /* Returns: void */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 651 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 652 | /* type(I) - table type to operate on */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 653 | /* 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 | /* ------------------------------------------------------------------------ */ |
| 658 | void |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 659 | ipf_lookup_deref(softc, type, ptr) |
| 660 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 661 | int type; |
| 662 | void *ptr; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 663 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 664 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 665 | int i; |
| 666 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 667 | if (ptr == NULL) |
| 668 | return; |
| 669 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 670 | for (i = 0; i < MAX_BACKENDS; i++) { |
| 671 | if (type == backends[i]->ipfl_type) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 672 | 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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 677 | break; |
| 678 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 679 | } |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 680 | } |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 681 | |
| 682 | |
| 683 | /* ------------------------------------------------------------------------ */ |
| 684 | /* Function: ipf_lookup_iterate */ |
| 685 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 686 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 687 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 688 | /* uid(I) - uid of caller */ |
| 689 | /* ctx(I) - pointer to give the uid context */ |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 690 | /* */ |
| 691 | /* Decodes ioctl request to step through either hash tables or pools. */ |
| 692 | /* ------------------------------------------------------------------------ */ |
Darren Reed | 97a145a | 2007-10-11 09:08:29 +0000 | [diff] [blame] | 693 | static int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 694 | ipf_lookup_iterate(softc, data, uid, ctx) |
| 695 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 696 | void *data; |
| 697 | int uid; |
| 698 | void *ctx; |
| 699 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 700 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 701 | ipflookupiter_t iter; |
| 702 | ipftoken_t *token; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 703 | int err, i; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 704 | SPL_INT(s); |
| 705 | |
Darren Reed | 21fd8be | 2010-02-07 00:10:05 +0000 | [diff] [blame] | 706 | err = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_LOOKUPITER); |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 707 | if (err != 0) |
| 708 | return err; |
| 709 | |
Darren Reed | fc5c4b1 | 2009-03-14 14:42:06 +0000 | [diff] [blame] | 710 | if (iter.ili_unit < IPL_LOGALL && iter.ili_unit > IPL_LOGMAX) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 711 | softc->ipf_interror = 50038; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 712 | return EINVAL; |
| 713 | } |
| 714 | |
| 715 | if (iter.ili_ival != IPFGENITER_LOOKUP) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 716 | softc->ipf_interror = 50039; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 717 | return EINVAL; |
| 718 | } |
| 719 | |
| 720 | SPL_SCHED(s); |
Darren Reed | 7e3c354 | 2009-05-13 19:18:56 +0000 | [diff] [blame] | 721 | token = ipf_token_find(softc, iter.ili_key, uid, ctx); |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 722 | if (token == NULL) { |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 723 | SPL_X(s); |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 724 | softc->ipf_interror = 50040; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 725 | return ESRCH; |
| 726 | } |
| 727 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 728 | for (i = 0; i < MAX_BACKENDS; i++) { |
| 729 | if (iter.ili_type == backends[i]->ipfl_type) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 730 | err = (*backends[i]->ipfl_iter_next)(softc, |
| 731 | softl->ipf_back[i], |
| 732 | token, &iter); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 733 | break; |
| 734 | } |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 735 | } |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 736 | SPL_X(s); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 737 | |
| 738 | if (i == MAX_BACKENDS) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 739 | softc->ipf_interror = 50041; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 740 | err = EINVAL; |
| 741 | } |
Darren Reed | 7e3c354 | 2009-05-13 19:18:56 +0000 | [diff] [blame] | 742 | |
| 743 | WRITE_ENTER(&softc->ipf_tokens); |
| 744 | ipf_token_deref(softc, token); |
| 745 | RWLOCK_EXIT(&softc->ipf_tokens); |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 746 | |
| 747 | return err; |
| 748 | } |
| 749 | |
| 750 | |
| 751 | /* ------------------------------------------------------------------------ */ |
| 752 | /* Function: ipf_lookup_iterderef */ |
Darren Reed | bb421c4 | 2010-01-31 13:07:29 +0000 | [diff] [blame] | 753 | /* Returns: void */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 754 | /* 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 757 | /* */ |
| 758 | /* Decodes ioctl request to remove a particular hash table or pool and */ |
| 759 | /* calls the relevant function to do the cleanup. */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 760 | /* 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 Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 763 | /* ------------------------------------------------------------------------ */ |
| 764 | void |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 765 | ipf_lookup_iterderef(softc, type, data) |
| 766 | ipf_main_softc_t *softc; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 767 | u_32_t type; |
| 768 | void *data; |
| 769 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 770 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 771 | struct iplookupiterkey *lkey; |
| 772 | iplookupiterkey_t key; |
| 773 | int i; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 774 | |
| 775 | key.ilik_key = type; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 776 | lkey = &key.ilik_unstr; |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 777 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 778 | if (lkey->ilik_ival != IPFGENITER_LOOKUP) |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 779 | return; |
| 780 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 781 | WRITE_ENTER(&softc->ipf_poolrw); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 782 | |
| 783 | for (i = 0; i < MAX_BACKENDS; i++) { |
| 784 | if (type == backends[i]->ipfl_type) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 785 | (*backends[i]->ipfl_iter_deref)(softc, |
| 786 | softl->ipf_back[i], |
| 787 | lkey->ilik_otype, |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 788 | lkey->ilik_unit, |
| 789 | data); |
| 790 | break; |
| 791 | } |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 792 | } |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 793 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | c4af1f3 | 2007-08-20 10:15:33 +0000 | [diff] [blame] | 794 | } |
| 795 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 796 | |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 797 | /* ------------------------------------------------------------------------ */ |
Darren Reed | 97a145a | 2007-10-11 09:08:29 +0000 | [diff] [blame] | 798 | /* Function: ipf_lookup_deltok */ |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 799 | /* Returns: int - 0 = success, else error */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 800 | /* Parameters: softc(I) - pointer to soft context main structure */ |
| 801 | /* data(I) - pointer to data from ioctl call */ |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 802 | /* 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 Reed | 97a145a | 2007-10-11 09:08:29 +0000 | [diff] [blame] | 809 | int |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 810 | ipf_lookup_deltok(softc, data, uid, ctx) |
| 811 | ipf_main_softc_t *softc; |
Darren Reed | 97a145a | 2007-10-11 09:08:29 +0000 | [diff] [blame] | 812 | void *data; |
| 813 | int uid; |
| 814 | void *ctx; |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 815 | { |
| 816 | int error, key; |
| 817 | SPL_INT(s); |
| 818 | |
| 819 | SPL_SCHED(s); |
Martti Kuparinen | b4c6ea2 | 2007-10-25 09:26:49 +0000 | [diff] [blame] | 820 | error = BCOPYIN(data, &key, sizeof(key)); |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 821 | if (error == 0) |
Darren Reed | 7e3c354 | 2009-05-13 19:18:56 +0000 | [diff] [blame] | 822 | error = ipf_token_del(softc, key, uid, ctx); |
Darren Reed | 4c3f162 | 2007-10-10 09:24:25 +0000 | [diff] [blame] | 823 | SPL_X(s); |
| 824 | return error; |
| 825 | } |
| 826 | |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 827 | |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 828 | /* ------------------------------------------------------------------------ */ |
| 829 | /* Function: ipf_lookup_res_num */ |
| 830 | /* Returns: void * - NULL = failure, else success. */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 831 | /* Parameters: softc(I) - pointer to soft context main structure */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 832 | /* unit(I) - device for which this is for */ |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 833 | /* type(I) - type of lookup these parameters are for. */ |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 834 | /* 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 | /* ------------------------------------------------------------------------ */ |
| 843 | void * |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 844 | ipf_lookup_res_num(softc, unit, type, number, funcptr) |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 845 | ipf_main_softc_t *softc; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 846 | int unit; |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 847 | u_int type; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 848 | u_int number; |
| 849 | lookupfunc_t *funcptr; |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 850 | { |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 851 | 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 Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 859 | return ipf_lookup_res_name(softc, unit, type, name, funcptr); |
Darren Reed | da0443e | 2006-06-15 16:17:17 +0000 | [diff] [blame] | 860 | } |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 861 | |
| 862 | |
| 863 | /* ------------------------------------------------------------------------ */ |
| 864 | /* Function: ipf_lookup_res_name */ |
| 865 | /* Returns: void * - NULL = failure, else success. */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 866 | /* Parameters: softc(I) - pointer to soft context main structure */ |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 867 | /* unit(I) - device for which this is for */ |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 868 | /* type(I) - type of lookup these parameters are for. */ |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 869 | /* 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 | /* ------------------------------------------------------------------------ */ |
| 878 | void * |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 879 | ipf_lookup_res_name(softc, unit, type, name, funcptr) |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 880 | ipf_main_softc_t *softc; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 881 | int unit; |
Darren Reed | a6872a7 | 2009-05-01 18:01:35 +0000 | [diff] [blame] | 882 | u_int type; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 883 | char *name; |
| 884 | lookupfunc_t *funcptr; |
| 885 | { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 886 | ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; |
| 887 | ipf_lookup_t **l; |
Darren Reed | 7e99d16 | 2008-03-07 21:23:11 +0000 | [diff] [blame] | 888 | void *ptr = NULL; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 889 | int i; |
| 890 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 891 | READ_ENTER(&softc->ipf_poolrw); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 892 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 893 | 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 Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 897 | if (ptr != NULL && funcptr != NULL) { |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 898 | *funcptr = (*l)->ipfl_addr_find; |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 899 | } |
| 900 | break; |
| 901 | } |
| 902 | } |
| 903 | |
| 904 | if (i == MAX_BACKENDS) { |
| 905 | ptr = NULL; |
| 906 | if (funcptr != NULL) |
| 907 | *funcptr = NULL; |
| 908 | } |
| 909 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 910 | RWLOCK_EXIT(&softc->ipf_poolrw); |
Darren Reed | ae72cf0 | 2008-03-07 09:09:49 +0000 | [diff] [blame] | 911 | |
| 912 | return ptr; |
| 913 | } |
David Stes | 6c06677 | 2008-04-19 21:33:53 +0000 | [diff] [blame] | 914 | |
| 915 | |
Darren Reed | 8038b7d | 2008-12-31 10:55:21 +0000 | [diff] [blame] | 916 | /* ------------------------------------------------------------------------ */ |
| 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 Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 927 | void * |
| 928 | ipf_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 Stes | 6c06677 | 2008-04-19 21:33:53 +0000 | [diff] [blame] | 937 | |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 938 | 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 Reed | bb421c4 | 2010-01-31 13:07:29 +0000 | [diff] [blame] | 952 | /* ------------------------------------------------------------------------ */ |
| 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*/ |
| 962 | void |
| 963 | ipf_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 Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 981 | #ifndef _KERNEL |
Darren Reed | 1b44c34 | 2008-08-10 05:51:57 +0000 | [diff] [blame] | 982 | void |
| 983 | ipf_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 |