1 /* $FreeBSD$ */
2
3 /*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * $FreeBSD$
7 * See the IPFILTER.LICENCE file for details on licencing.
8 */
9
10 #if defined(KERNEL) || defined(_KERNEL)
11 # undef KERNEL
12 # undef _KERNEL
13 # define KERNEL 1
14 # define _KERNEL 1
15 #endif
16
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/kernel.h>
20 #include <sys/module.h>
21 #include <sys/conf.h>
22 #include <sys/socket.h>
23 #include <sys/sysctl.h>
24 #include <sys/select.h>
25 #ifdef __FreeBSD_version
26 # include <sys/selinfo.h>
27 # include <sys/jail.h>
28 # ifdef _KERNEL
29 # include <net/vnet.h>
30 # else
31 # define CURVNET_SET(arg)
32 # define CURVNET_RESTORE()
33 # define VNET_DEFINE(_t, _v) _t _v
34 # define VNET_DECLARE(_t, _v) extern _t _v
35 # define VNET(arg) arg
36 # endif
37 #endif
38 #include <net/if.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41
42
43 #include "netinet/ipl.h"
44 #include "netinet/ip_compat.h"
45 #include "netinet/ip_fil.h"
46 #include "netinet/ip_state.h"
47 #include "netinet/ip_nat.h"
48 #include "netinet/ip_auth.h"
49 #include "netinet/ip_frag.h"
50 #include "netinet/ip_sync.h"
51
52 VNET_DECLARE(ipf_main_softc_t, ipfmain);
53 #define V_ipfmain VNET(ipfmain)
54
55 #ifdef __FreeBSD_version
56 static struct cdev *ipf_devs[IPL_LOGSIZE];
57 #else
58 static dev_t ipf_devs[IPL_LOGSIZE];
59 #endif
60
61 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
62 static int sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS );
63 static int sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS );
64 static int sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS );
65 static int sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS );
66 static int ipf_modload(void);
67 static int ipf_modunload(void);
68 static int ipf_fbsd_sysctl_create(void);
69 static int ipf_fbsd_sysctl_destroy(void);
70
71 #ifdef __FreeBSD_version
72 static int ipfopen __P((struct cdev*, int, int, struct thread *));
73 static int ipfclose __P((struct cdev*, int, int, struct thread *));
74 static int ipfread __P((struct cdev*, struct uio *, int));
75 static int ipfwrite __P((struct cdev*, struct uio *, int));
76 #else
77 static int ipfopen __P((dev_t, int, int, struct proc *));
78 static int ipfclose __P((dev_t, int, int, struct proc *));
79 static int ipfread __P((dev_t, struct uio *, int));
80 static int ipfwrite __P((dev_t, struct uio *, int));
81 #endif
82
83
84 SYSCTL_DECL(_net_inet);
85 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
86 SYSCTL_OID(parent, nbr, name, \
87 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \
88 ptr, val, sysctl_ipf_int, "I", descr)
89 #define SYSCTL_DYN_IPF_NAT(parent, nbr, name, access,ptr, val, descr) \
90 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
91 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE |access, \
92 ptr, val, sysctl_ipf_int_nat, "I", descr)
93 #define SYSCTL_DYN_IPF_STATE(parent, nbr, name, access,ptr, val, descr) \
94 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
95 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \
96 ptr, val, sysctl_ipf_int_state, "I", descr)
97 #define SYSCTL_DYN_IPF_FRAG(parent, nbr, name, access,ptr, val, descr) \
98 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
99 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \
100 ptr, val, sysctl_ipf_int_frag, "I", descr)
101 #define SYSCTL_DYN_IPF_AUTH(parent, nbr, name, access,ptr, val, descr) \
102 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
103 CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_MPSAFE | access, \
104 ptr, val, sysctl_ipf_int_auth, "I", descr)
105 static struct sysctl_ctx_list ipf_clist;
106 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */
107 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF)
108 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
109 "IPF");
110 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_flags), 0, "IPF flags");
111 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_pass), 0, "default pass/block");
112 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_active), 0, "IPF is active");
113 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
114 &VNET_NAME(ipfmain.ipf_tcpidletimeout), 0, "TCP idle timeout in seconds");
115 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
116 &VNET_NAME(ipfmain.ipf_tcphalfclosed), 0, "timeout for half closed TCP sessions");
117 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
118 &VNET_NAME(ipfmain.ipf_tcpclosewait), 0, "timeout for TCP sessions in closewait status");
119 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
120 &VNET_NAME(ipfmain.ipf_tcplastack), 0, "timeout for TCP sessions in last ack status");
121 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
122 &VNET_NAME(ipfmain.ipf_tcptimeout), 0, "");
123 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
124 &VNET_NAME(ipfmain.ipf_tcpclosed), 0, "");
125 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
126 &VNET_NAME(ipfmain.ipf_udptimeout), 0, "UDP timeout");
127 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
128 &VNET_NAME(ipfmain.ipf_udpacktimeout), 0, "");
129 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
130 &VNET_NAME(ipfmain.ipf_icmptimeout), 0, "ICMP timeout");
131 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
132 &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running");
133 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, "");
134 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, "");
135
136 #define CDEV_MAJOR 79
137 #include <sys/poll.h>
138 #ifdef __FreeBSD_version
139 # include <sys/select.h>
140 static int ipfpoll(struct cdev *dev, int events, struct thread *td);
141
142 static struct cdevsw ipf_cdevsw = {
143 .d_version = D_VERSION,
144 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */
145 .d_open = ipfopen,
146 .d_close = ipfclose,
147 .d_read = ipfread,
148 .d_write = ipfwrite,
149 .d_ioctl = ipfioctl,
150 .d_poll = ipfpoll,
151 .d_name = "ipf",
152 };
153 #else
154 static int ipfpoll(dev_t dev, int events, struct proc *td);
155
156 static struct cdevsw ipf_cdevsw = {
157 /* open */ ipfopen,
158 /* close */ ipfclose,
159 /* read */ ipfread,
160 /* write */ ipfwrite,
161 /* ioctl */ ipfioctl,
162 /* poll */ ipfpoll,
163 /* mmap */ nommap,
164 /* strategy */ nostrategy,
165 /* name */ "ipf",
166 /* maj */ CDEV_MAJOR,
167 /* dump */ nodump,
168 /* psize */ nopsize,
169 /* flags */ 0,
170 };
171 #endif
172
173 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
174 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
175
176 static int
ipfilter_modevent(module_t mod,int type,void * unused)177 ipfilter_modevent(module_t mod, int type, void *unused)
178 {
179 int error = 0;
180
181 switch (type)
182 {
183 case MOD_LOAD :
184 error = ipf_modload();
185 break;
186
187 case MOD_UNLOAD :
188 error = ipf_modunload();
189 break;
190 default:
191 error = EINVAL;
192 break;
193 }
194 return error;
195 }
196
197
198 static void
vnet_ipf_init(void)199 vnet_ipf_init(void)
200 {
201 char *defpass;
202 int error;
203
204 if (ipf_create_all(&V_ipfmain) == NULL)
205 return;
206
207 error = ipfattach(&V_ipfmain);
208 if (error) {
209 ipf_destroy_all(&V_ipfmain);
210 return;
211 }
212
213 if (FR_ISPASS(V_ipfmain.ipf_pass))
214 defpass = "pass";
215 else if (FR_ISBLOCK(V_ipfmain.ipf_pass))
216 defpass = "block";
217 else
218 defpass = "no-match -> block";
219
220 if (IS_DEFAULT_VNET(curvnet)) {
221 printf("%s initialized. Default = %s all, Logging = %s%s\n",
222 ipfilter_version, defpass,
223 #ifdef IPFILTER_LOG
224 "enabled",
225 #else
226 "disabled",
227 #endif
228 #ifdef IPFILTER_COMPILED
229 " (COMPILED)"
230 #else
231 ""
232 #endif
233 );
234 } else {
235 (void)ipf_pfil_hook();
236 ipf_event_reg();
237 }
238 }
239 VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
240 vnet_ipf_init, NULL);
241
242 static int
ipf_modload()243 ipf_modload()
244 {
245 char *c, *str;
246 int i, j, error;
247
248 if (ipf_load_all() != 0)
249 return EIO;
250
251 if (ipf_fbsd_sysctl_create() != 0) {
252 return EIO;
253 }
254
255 for (i = 0; i < IPL_LOGSIZE; i++)
256 ipf_devs[i] = NULL;
257 for (i = 0; (str = ipf_devfiles[i]); i++) {
258 c = NULL;
259 for(j = strlen(str); j > 0; j--)
260 if (str[j] == '/') {
261 c = str + j + 1;
262 break;
263 }
264 if (!c)
265 c = str;
266 ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c);
267 }
268
269 error = ipf_pfil_hook();
270 if (error != 0)
271 return error;
272 ipf_event_reg();
273
274 return 0;
275 }
276
277 static void
vnet_ipf_uninit(void)278 vnet_ipf_uninit(void)
279 {
280
281 if (V_ipfmain.ipf_refcnt)
282 return;
283
284 if (V_ipfmain.ipf_running >= 0) {
285
286 if (ipfdetach(&V_ipfmain) != 0)
287 return;
288
289 V_ipfmain.ipf_running = -2;
290
291 ipf_destroy_all(&V_ipfmain);
292 if (!IS_DEFAULT_VNET(curvnet)) {
293 ipf_event_dereg();
294 (void)ipf_pfil_unhook();
295 }
296 }
297 }
298 VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
299 vnet_ipf_uninit, NULL);
300
301 static int
ipf_modunload()302 ipf_modunload()
303 {
304 int error, i;
305
306 ipf_event_dereg();
307
308 ipf_fbsd_sysctl_destroy();
309
310 error = ipf_pfil_unhook();
311 if (error != 0)
312 return error;
313
314 for (i = 0; ipf_devfiles[i]; i++) {
315 if (ipf_devs[i] != NULL)
316 destroy_dev(ipf_devs[i]);
317 }
318
319 ipf_unload_all();
320
321 printf("%s unloaded\n", ipfilter_version);
322
323 return (0);
324 }
325
326
327 static moduledata_t ipfiltermod = {
328 "ipfilter",
329 ipfilter_modevent,
330 0
331 };
332
333
334 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
335 #ifdef MODULE_VERSION
336 MODULE_VERSION(ipfilter, 1);
337 #endif
338
339
340 #ifdef SYSCTL_IPF
341 int
sysctl_ipf_int(SYSCTL_HANDLER_ARGS)342 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
343 {
344 int error = 0;
345
346 WRITE_ENTER(&V_ipfmain.ipf_mutex);
347 if (arg1)
348 error = SYSCTL_OUT(req, arg1, sizeof(int));
349 else
350 error = SYSCTL_OUT(req, &arg2, sizeof(int));
351
352 if (error || !req->newptr)
353 goto sysctl_error;
354
355 if (!arg1)
356 error = EPERM;
357 else {
358 if ((oidp->oid_kind & CTLFLAG_OFF) && (V_ipfmain.ipf_running > 0))
359 error = EBUSY;
360 else
361 error = SYSCTL_IN(req, arg1, sizeof(int));
362 }
363
364 sysctl_error:
365 RWLOCK_EXIT(&V_ipfmain.ipf_mutex);
366 return (error);
367 }
368
369 /*
370 * arg2 holds the offset of the relevant member in the virtualized
371 * ipfmain structure.
372 */
373 static int
sysctl_ipf_int_nat(SYSCTL_HANDLER_ARGS)374 sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS )
375 {
376 ipf_nat_softc_t *nat_softc;
377
378 nat_softc = V_ipfmain.ipf_nat_soft;
379 arg1 = (void *)((uintptr_t)nat_softc + arg2);
380
381 return (sysctl_ipf_int(oidp, arg1, 0, req));
382 }
383
384 static int
sysctl_ipf_int_state(SYSCTL_HANDLER_ARGS)385 sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS )
386 {
387 ipf_state_softc_t *state_softc;
388
389 state_softc = V_ipfmain.ipf_state_soft;
390 arg1 = (void *)((uintptr_t)state_softc + arg2);
391
392 return (sysctl_ipf_int(oidp, arg1, 0, req));
393 }
394
395 static int
sysctl_ipf_int_auth(SYSCTL_HANDLER_ARGS)396 sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS )
397 {
398 ipf_auth_softc_t *auth_softc;
399
400 auth_softc = V_ipfmain.ipf_auth_soft;
401 arg1 = (void *)((uintptr_t)auth_softc + arg2);
402
403 return (sysctl_ipf_int(oidp, arg1, 0, req));
404 }
405
406 static int
sysctl_ipf_int_frag(SYSCTL_HANDLER_ARGS)407 sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS )
408 {
409 ipf_frag_softc_t *frag_softc;
410
411 frag_softc = V_ipfmain.ipf_frag_soft;
412 arg1 = (void *)((uintptr_t)frag_softc + arg2);
413
414 return (sysctl_ipf_int(oidp, arg1, 0, req));
415 }
416 #endif
417
418
419 static int
420 #ifdef __FreeBSD_version
ipfpoll(struct cdev * dev,int events,struct thread * td)421 ipfpoll(struct cdev *dev, int events, struct thread *td)
422 #else
423 ipfpoll(dev_t dev, int events, struct proc *td)
424 #endif
425 {
426 int unit = GET_MINOR(dev);
427 int revents;
428
429 if (unit < 0 || unit > IPL_LOGMAX)
430 return 0;
431
432 revents = 0;
433
434 CURVNET_SET(TD_TO_VNET(td));
435 switch (unit)
436 {
437 case IPL_LOGIPF :
438 case IPL_LOGNAT :
439 case IPL_LOGSTATE :
440 #ifdef IPFILTER_LOG
441 if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit))
442 revents |= events & (POLLIN | POLLRDNORM);
443 #endif
444 break;
445 case IPL_LOGAUTH :
446 if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain))
447 revents |= events & (POLLIN | POLLRDNORM);
448 break;
449 case IPL_LOGSYNC :
450 if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain))
451 revents |= events & (POLLIN | POLLRDNORM);
452 if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain))
453 revents |= events & (POLLOUT | POLLWRNORM);
454 break;
455 case IPL_LOGSCAN :
456 case IPL_LOGLOOKUP :
457 default :
458 break;
459 }
460
461 if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
462 selrecord(td, &V_ipfmain.ipf_selwait[unit]);
463 CURVNET_RESTORE();
464
465 return revents;
466 }
467
468
469 /*
470 * routines below for saving IP headers to buffer
471 */
ipfopen(dev,flags,devtype,p)472 static int ipfopen(dev, flags
473 #ifdef __FreeBSD_version
474 , devtype, p)
475 int devtype;
476 struct thread *p;
477 struct cdev *dev;
478 #else
479 )
480 dev_t dev;
481 #endif
482 int flags;
483 {
484 int unit = GET_MINOR(dev);
485 int error;
486
487 if (IPL_LOGMAX < unit)
488 error = ENXIO;
489 else {
490 switch (unit)
491 {
492 case IPL_LOGIPF :
493 case IPL_LOGNAT :
494 case IPL_LOGSTATE :
495 case IPL_LOGAUTH :
496 case IPL_LOGLOOKUP :
497 case IPL_LOGSYNC :
498 #ifdef IPFILTER_SCAN
499 case IPL_LOGSCAN :
500 #endif
501 error = 0;
502 break;
503 default :
504 error = ENXIO;
505 break;
506 }
507 }
508 return error;
509 }
510
511
ipfclose(dev,flags,devtype,p)512 static int ipfclose(dev, flags
513 #ifdef __FreeBSD_version
514 , devtype, p)
515 int devtype;
516 struct thread *p;
517 struct cdev *dev;
518 #else
519 )
520 dev_t dev;
521 #endif
522 int flags;
523 {
524 int unit = GET_MINOR(dev);
525
526 if (IPL_LOGMAX < unit)
527 unit = ENXIO;
528 else
529 unit = 0;
530 return unit;
531 }
532
533 /*
534 * ipfread/ipflog
535 * both of these must operate with at least splnet() lest they be
536 * called during packet processing and cause an inconsistancy to appear in
537 * the filter lists.
538 */
539 #if (BSD >= 199306)
ipfread(dev,uio,ioflag)540 static int ipfread(dev, uio, ioflag)
541 int ioflag;
542 #else
543 static int ipfread(dev, uio)
544 #endif
545 #ifdef __FreeBSD_version
546 struct cdev *dev;
547 #else
548 dev_t dev;
549 #endif
550 struct uio *uio;
551 {
552 int error;
553 int unit = GET_MINOR(dev);
554
555 if (unit < 0)
556 return ENXIO;
557
558 CURVNET_SET(TD_TO_VNET(curthread));
559 if (V_ipfmain.ipf_running < 1) {
560 CURVNET_RESTORE();
561 return EIO;
562 }
563
564 if (unit == IPL_LOGSYNC) {
565 error = ipf_sync_read(&V_ipfmain, uio);
566 CURVNET_RESTORE();
567 return error;
568 }
569
570 #ifdef IPFILTER_LOG
571 error = ipf_log_read(&V_ipfmain, unit, uio);
572 #else
573 error = ENXIO;
574 #endif
575 CURVNET_RESTORE();
576 return error;
577 }
578
579
580 /*
581 * ipfwrite
582 * both of these must operate with at least splnet() lest they be
583 * called during packet processing and cause an inconsistancy to appear in
584 * the filter lists.
585 */
586 #if (BSD >= 199306)
ipfwrite(dev,uio,ioflag)587 static int ipfwrite(dev, uio, ioflag)
588 int ioflag;
589 #else
590 static int ipfwrite(dev, uio)
591 #endif
592 #ifdef __FreeBSD_version
593 struct cdev *dev;
594 #else
595 dev_t dev;
596 #endif
597 struct uio *uio;
598 {
599 int error;
600
601 CURVNET_SET(TD_TO_VNET(curthread));
602 if (V_ipfmain.ipf_running < 1) {
603 CURVNET_RESTORE();
604 return EIO;
605 }
606
607 if (GET_MINOR(dev) == IPL_LOGSYNC) {
608 error = ipf_sync_write(&V_ipfmain, uio);
609 CURVNET_RESTORE();
610 return error;
611 }
612 return ENXIO;
613 }
614
615 static int
ipf_fbsd_sysctl_create(void)616 ipf_fbsd_sysctl_create(void)
617 {
618
619 sysctl_ctx_init(&ipf_clist);
620
621 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "fr_defnatage", CTLFLAG_RWO,
622 NULL, offsetof(ipf_nat_softc_t, ipf_nat_defage), "");
623 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statesize", CTLFLAG_RWO,
624 NULL, offsetof(ipf_state_softc_t, ipf_state_size), "");
625 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statemax", CTLFLAG_RWO,
626 NULL, offsetof(ipf_state_softc_t, ipf_state_max), "");
627 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_max", CTLFLAG_RWO,
628 NULL, offsetof(ipf_nat_softc_t, ipf_nat_table_max), "");
629 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_sz", CTLFLAG_RWO,
630 NULL, offsetof(ipf_nat_softc_t, ipf_nat_table_sz), "");
631 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_natrules_sz", CTLFLAG_RWO,
632 NULL, offsetof(ipf_nat_softc_t, ipf_nat_maprules_sz), "");
633 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_rdrrules_sz", CTLFLAG_RWO,
634 NULL, offsetof(ipf_nat_softc_t, ipf_nat_rdrrules_sz), "");
635 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_hostmap_sz", CTLFLAG_RWO,
636 NULL, offsetof(ipf_nat_softc_t, ipf_nat_hostmap_sz), "");
637 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authsize", CTLFLAG_RWO,
638 NULL, offsetof(ipf_auth_softc_t, ipf_auth_size), "");
639 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authused", CTLFLAG_RD,
640 NULL, offsetof(ipf_auth_softc_t, ipf_auth_used), "");
641 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_defaultauthage", CTLFLAG_RW,
642 NULL, offsetof(ipf_auth_softc_t, ipf_auth_defaultage), "");
643 SYSCTL_DYN_IPF_FRAG(_net_inet_ipf, OID_AUTO, "fr_ipfrttl", CTLFLAG_RW,
644 NULL, offsetof(ipf_frag_softc_t, ipfr_ttl), "");
645 return 0;
646 }
647
648 static int
ipf_fbsd_sysctl_destroy(void)649 ipf_fbsd_sysctl_destroy(void)
650 {
651 if (sysctl_ctx_free(&ipf_clist)) {
652 printf("sysctl_ctx_free failed");
653 return(ENOTEMPTY);
654 }
655 return 0;
656 }
657
658