4 * Copyright (C) 2012 by Darren Reed.
7 * See the IPFILTER.LICENCE file for details on licencing.
10 #if defined(KERNEL) || defined(_KERNEL)
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/kernel.h>
20 #include <sys/module.h>
22 #include <sys/socket.h>
23 #include <sys/sysctl.h>
24 #include <sys/select.h>
25 #if __FreeBSD_version >= 500000
26 # include <sys/selinfo.h>
27 # include <sys/jail.h>
29 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) && defined(_KERNEL)
32 #define CURVNET_SET(arg)
33 #define CURVNET_RESTORE()
34 #define VNET_DEFINE(_t, _v) _t _v
35 #define VNET_DECLARE(_t, _v) extern _t _v
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
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"
52 VNET_DECLARE(ipf_main_softc_t, ipfmain);
53 #define V_ipfmain VNET(ipfmain)
55 #if __FreeBSD_version >= 502116
56 static struct cdev *ipf_devs[IPL_LOGSIZE];
58 static dev_t ipf_devs[IPL_LOGSIZE];
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);
71 #if (__FreeBSD_version >= 500024)
72 # if (__FreeBSD_version >= 502116)
73 static int ipfopen __P((struct cdev*, int, int, struct thread *));
74 static int ipfclose __P((struct cdev*, int, int, struct thread *));
76 static int ipfopen __P((dev_t, int, int, struct thread *));
77 static int ipfclose __P((dev_t, int, int, struct thread *));
78 # endif /* __FreeBSD_version >= 502116 */
80 static int ipfopen __P((dev_t, int, int, struct proc *));
81 static int ipfclose __P((dev_t, int, int, struct proc *));
83 #if (__FreeBSD_version >= 502116)
84 static int ipfread __P((struct cdev*, struct uio *, int));
85 static int ipfwrite __P((struct cdev*, struct uio *, int));
87 static int ipfread __P((dev_t, struct uio *, int));
88 static int ipfwrite __P((dev_t, struct uio *, int));
89 #endif /* __FreeBSD_version >= 502116 */
92 SYSCTL_DECL(_net_inet);
93 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
94 SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_VNET|access, \
95 ptr, val, sysctl_ipf_int, "I", descr)
96 #define SYSCTL_DYN_IPF_NAT(parent, nbr, name, access,ptr, val, descr) \
97 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
98 CTLFLAG_DYN|CTLTYPE_INT|CTLFLAG_VNET|access, ptr, val, sysctl_ipf_int_nat, "I", descr)
99 #define SYSCTL_DYN_IPF_STATE(parent, nbr, name, access,ptr, val, descr) \
100 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
101 CTLFLAG_DYN|CTLTYPE_INT|CTLFLAG_VNET|access, ptr, val, sysctl_ipf_int_state, "I", descr)
102 #define SYSCTL_DYN_IPF_FRAG(parent, nbr, name, access,ptr, val, descr) \
103 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
104 CTLFLAG_DYN|CTLTYPE_INT|CTLFLAG_VNET|access, ptr, val, sysctl_ipf_int_frag, "I", descr)
105 #define SYSCTL_DYN_IPF_AUTH(parent, nbr, name, access,ptr, val, descr) \
106 SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
107 CTLFLAG_DYN|CTLTYPE_INT|CTLFLAG_VNET|access, ptr, val, sysctl_ipf_int_auth, "I", descr)
108 static struct sysctl_ctx_list ipf_clist;
109 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */
110 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF)
111 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
112 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_flags), 0, "IPF flags");
113 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_pass), 0, "default pass/block");
114 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_active), 0, "IPF is active");
115 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
116 &VNET_NAME(ipfmain.ipf_tcpidletimeout), 0, "TCP idle timeout in seconds");
117 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
118 &VNET_NAME(ipfmain.ipf_tcphalfclosed), 0, "timeout for half closed TCP sessions");
119 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
120 &VNET_NAME(ipfmain.ipf_tcpclosewait), 0, "timeout for TCP sessions in closewait status");
121 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
122 &VNET_NAME(ipfmain.ipf_tcplastack), 0, "timeout for TCP sessions in last ack status");
123 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
124 &VNET_NAME(ipfmain.ipf_tcptimeout), 0, "");
125 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
126 &VNET_NAME(ipfmain.ipf_tcpclosed), 0, "");
127 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
128 &VNET_NAME(ipfmain.ipf_udptimeout), 0, "UDP timeout");
129 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
130 &VNET_NAME(ipfmain.ipf_udpacktimeout), 0, "");
131 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
132 &VNET_NAME(ipfmain.ipf_icmptimeout), 0, "ICMP timeout");
133 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
134 &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running");
135 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, "");
136 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, "");
138 #define CDEV_MAJOR 79
139 #include <sys/poll.h>
140 #if __FreeBSD_version >= 500043
141 # include <sys/select.h>
142 static int ipfpoll(struct cdev *dev, int events, struct thread *td);
144 static struct cdevsw ipf_cdevsw = {
145 #if __FreeBSD_version >= 502103
146 .d_version = D_VERSION,
147 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */
156 #if __FreeBSD_version < 600000
161 static int ipfpoll(dev_t dev, int events, struct proc *td);
163 static struct cdevsw ipf_cdevsw = {
165 /* close */ ipfclose,
167 /* write */ ipfwrite,
168 /* ioctl */ ipfioctl,
171 /* strategy */ nostrategy,
173 /* maj */ CDEV_MAJOR,
177 # if (__FreeBSD_version < 500043)
180 # if (__FreeBSD_version >= 430000)
186 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
187 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
190 ipfilter_modevent(module_t mod, int type, void *unused)
197 error = ipf_modload();
201 error = ipf_modunload();
217 if (ipf_create_all(&V_ipfmain) == NULL)
220 error = ipfattach(&V_ipfmain);
222 ipf_destroy_all(&V_ipfmain);
226 if (FR_ISPASS(V_ipfmain.ipf_pass))
228 else if (FR_ISBLOCK(V_ipfmain.ipf_pass))
231 defpass = "no-match -> block";
233 if (IS_DEFAULT_VNET(curvnet))
234 printf("%s initialized. Default = %s all, Logging = %s%s\n",
235 ipfilter_version, defpass,
241 #ifdef IPFILTER_COMPILED
248 VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
249 vnet_ipf_init, NULL);
257 if (ipf_load_all() != 0)
260 if (ipf_fbsd_sysctl_create() != 0) {
264 for (i = 0; i < IPL_LOGSIZE; i++)
266 for (i = 0; (str = ipf_devfiles[i]); i++) {
268 for(j = strlen(str); j > 0; j--)
275 ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c);
278 error = ipf_pfil_hook();
287 vnet_ipf_uninit(void)
290 if (V_ipfmain.ipf_refcnt)
293 if (V_ipfmain.ipf_running >= 0) {
295 if (ipfdetach(&V_ipfmain) != 0)
298 V_ipfmain.ipf_running = -2;
300 ipf_destroy_all(&V_ipfmain);
303 VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
304 vnet_ipf_uninit, NULL);
313 ipf_fbsd_sysctl_destroy();
315 error = ipf_pfil_unhook();
319 for (i = 0; ipf_devfiles[i]; i++) {
320 if (ipf_devs[i] != NULL)
321 destroy_dev(ipf_devs[i]);
326 printf("%s unloaded\n", ipfilter_version);
332 static moduledata_t ipfiltermod = {
339 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
340 #ifdef MODULE_VERSION
341 MODULE_VERSION(ipfilter, 1);
347 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
352 error = SYSCTL_OUT(req, arg1, sizeof(int));
354 error = SYSCTL_OUT(req, &arg2, sizeof(int));
356 if (error || !req->newptr)
362 if ((oidp->oid_kind & CTLFLAG_OFF) && (V_ipfmain.ipf_running > 0))
365 error = SYSCTL_IN(req, arg1, sizeof(int));
371 * In the VIMAGE case kern_sysctl.c already adds the vnet base address given
372 * we set CTLFLAG_VNET to get proper access checks. Have to undo this.
373 * Then we add the given offset to the specific malloced struct hanging off
374 * virtualized ipmain struct.
377 sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS )
381 ipf_nat_softc_t *nat_softc;
383 nat_softc = V_ipfmain.ipf_nat_soft;
385 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
387 arg1 = (void *)((uintptr_t)nat_softc + (uintptr_t)arg1);
390 return (sysctl_ipf_int(oidp, arg1, arg2, req));
394 sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS )
398 ipf_state_softc_t *state_softc;
400 state_softc = V_ipfmain.ipf_state_soft;
402 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
404 arg1 = (void *)((uintptr_t)state_softc + (uintptr_t)arg1);
407 return (sysctl_ipf_int(oidp, arg1, arg2, req));
411 sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS )
415 ipf_auth_softc_t *auth_softc;
417 auth_softc = V_ipfmain.ipf_auth_soft;
419 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
421 arg1 = (void *)((uintptr_t)auth_softc + (uintptr_t)arg1);
424 return (sysctl_ipf_int(oidp, arg1, arg2, req));
428 sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS )
432 ipf_frag_softc_t *frag_softc;
434 frag_softc = V_ipfmain.ipf_frag_soft;
436 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
438 arg1 = (void *)((uintptr_t)frag_softc + (uintptr_t)arg1);
441 return (sysctl_ipf_int(oidp, arg1, arg2, req));
447 #if __FreeBSD_version >= 500043
448 ipfpoll(struct cdev *dev, int events, struct thread *td)
450 ipfpoll(dev_t dev, int events, struct proc *td)
453 int unit = GET_MINOR(dev);
456 if (unit < 0 || unit > IPL_LOGMAX)
461 CURVNET_SET(TD_TO_VNET(td));
468 if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit))
469 revents |= events & (POLLIN | POLLRDNORM);
473 if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain))
474 revents |= events & (POLLIN | POLLRDNORM);
477 if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain))
478 revents |= events & (POLLIN | POLLRDNORM);
479 if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain))
480 revents |= events & (POLLOUT | POLLWRNORM);
488 if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
489 selrecord(td, &V_ipfmain.ipf_selwait[unit]);
497 * routines below for saving IP headers to buffer
499 static int ipfopen(dev, flags
500 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
503 # if (__FreeBSD_version >= 500024)
507 # endif /* __FreeBSD_version >= 500024 */
511 #if (__FreeBSD_version >= 502116)
518 int unit = GET_MINOR(dev);
521 if (IPL_LOGMAX < unit)
546 static int ipfclose(dev, flags
547 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
550 # if (__FreeBSD_version >= 500024)
554 # endif /* __FreeBSD_version >= 500024 */
558 #if (__FreeBSD_version >= 502116)
565 int unit = GET_MINOR(dev);
567 if (IPL_LOGMAX < unit)
576 * both of these must operate with at least splnet() lest they be
577 * called during packet processing and cause an inconsistancy to appear in
581 static int ipfread(dev, uio, ioflag)
584 static int ipfread(dev, uio)
586 #if (__FreeBSD_version >= 502116)
594 int unit = GET_MINOR(dev);
599 CURVNET_SET(TD_TO_VNET(curthread));
600 if (V_ipfmain.ipf_running < 1) {
605 if (unit == IPL_LOGSYNC) {
606 error = ipf_sync_read(&V_ipfmain, uio);
612 error = ipf_log_read(&V_ipfmain, unit, uio);
623 * both of these must operate with at least splnet() lest they be
624 * called during packet processing and cause an inconsistancy to appear in
628 static int ipfwrite(dev, uio, ioflag)
631 static int ipfwrite(dev, uio)
633 #if (__FreeBSD_version >= 502116)
642 CURVNET_SET(TD_TO_VNET(curthread));
643 if (V_ipfmain.ipf_running < 1) {
648 if (GET_MINOR(dev) == IPL_LOGSYNC) {
649 error = ipf_sync_write(&V_ipfmain, uio);
657 ipf_fbsd_sysctl_create(void)
660 sysctl_ctx_init(&ipf_clist);
662 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "fr_defnatage", CTLFLAG_RWO,
663 (void *)offsetof(ipf_nat_softc_t, ipf_nat_defage), 0, "");
664 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statesize", CTLFLAG_RWO,
665 (void *)offsetof(ipf_state_softc_t, ipf_state_size), 0, "");
666 SYSCTL_DYN_IPF_STATE(_net_inet_ipf, OID_AUTO, "fr_statemax", CTLFLAG_RWO,
667 (void *)offsetof(ipf_state_softc_t, ipf_state_max), 0, "");
668 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_max", CTLFLAG_RWO,
669 (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_max), 0, "");
670 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_nattable_sz", CTLFLAG_RWO,
671 (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_sz), 0, "");
672 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_natrules_sz", CTLFLAG_RWO,
673 (void *)offsetof(ipf_nat_softc_t, ipf_nat_maprules_sz), 0, "");
674 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_rdrrules_sz", CTLFLAG_RWO,
675 (void *)offsetof(ipf_nat_softc_t, ipf_nat_rdrrules_sz), 0, "");
676 SYSCTL_DYN_IPF_NAT(_net_inet_ipf, OID_AUTO, "ipf_hostmap_sz", CTLFLAG_RWO,
677 (void *)offsetof(ipf_nat_softc_t, ipf_nat_hostmap_sz), 0, "");
678 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authsize", CTLFLAG_RWO,
679 (void *)offsetof(ipf_auth_softc_t, ipf_auth_size), 0, "");
680 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_authused", CTLFLAG_RD,
681 (void *)offsetof(ipf_auth_softc_t, ipf_auth_used), 0, "");
682 SYSCTL_DYN_IPF_AUTH(_net_inet_ipf, OID_AUTO, "fr_defaultauthage", CTLFLAG_RW,
683 (void *)offsetof(ipf_auth_softc_t, ipf_auth_defaultage), 0, "");
684 SYSCTL_DYN_IPF_FRAG(_net_inet_ipf, OID_AUTO, "fr_ipfrttl", CTLFLAG_RW,
685 (void *)offsetof(ipf_frag_softc_t, ipfr_ttl), 0, "");
690 ipf_fbsd_sysctl_destroy(void)
692 if (sysctl_ctx_free(&ipf_clist)) {
693 printf("sysctl_ctx_free failed");