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