]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/ipfilter/netinet/mlfk_ipl.c
Update to bmake-20171028
[FreeBSD/FreeBSD.git] / sys / contrib / ipfilter / netinet / mlfk_ipl.c
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 #if __FreeBSD_version >= 500000
26 # include <sys/selinfo.h>
27 # include <sys/jail.h>
28 #endif
29 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) && defined(_KERNEL)
30 #include <net/vnet.h>
31 #else
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
36 #define VNET(arg)       arg
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 #if __FreeBSD_version >= 502116
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 #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 *));
75 # else
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 */
79 #else
80 static  int     ipfopen __P((dev_t, int, int, struct proc *));
81 static  int     ipfclose __P((dev_t, int, int, struct proc *));
82 #endif
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));
86 #else
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 */
90
91
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, "");
137
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);
143
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 */
148 #endif
149         .d_open =       ipfopen,
150         .d_close =      ipfclose,
151         .d_read =       ipfread,
152         .d_write =      ipfwrite,
153         .d_ioctl =      ipfioctl,
154         .d_poll =       ipfpoll,
155         .d_name =       "ipf",
156 #if __FreeBSD_version < 600000
157         .d_maj =        CDEV_MAJOR,
158 #endif
159 };
160 #else
161 static int ipfpoll(dev_t dev, int events, struct proc *td);
162
163 static struct cdevsw ipf_cdevsw = {
164         /* open */      ipfopen,
165         /* close */     ipfclose,
166         /* read */      ipfread,
167         /* write */     ipfwrite,
168         /* ioctl */     ipfioctl,
169         /* poll */      ipfpoll,
170         /* mmap */      nommap,
171         /* strategy */  nostrategy,
172         /* name */      "ipf",
173         /* maj */       CDEV_MAJOR,
174         /* dump */      nodump,
175         /* psize */     nopsize,
176         /* flags */     0,
177 # if (__FreeBSD_version < 500043)
178         /* bmaj */      -1,
179 # endif
180 # if (__FreeBSD_version >= 430000)
181         /* kqfilter */  NULL
182 # endif
183 };
184 #endif
185
186 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
187                                 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
188
189 static int
190 ipfilter_modevent(module_t mod, int type, void *unused)
191 {
192         int error = 0;
193
194         switch (type)
195         {
196         case MOD_LOAD :
197                 error = ipf_modload();
198                 break;
199
200         case MOD_UNLOAD :
201                 error = ipf_modunload();
202                 break;
203         default:
204                 error = EINVAL;
205                 break;
206         }
207         return error;
208 }
209
210
211 static void
212 vnet_ipf_init(void)
213 {
214         char *defpass;
215         int error;
216
217         if (ipf_create_all(&V_ipfmain) == NULL)
218                 return;
219
220         error = ipfattach(&V_ipfmain);
221         if (error) {
222                 ipf_destroy_all(&V_ipfmain);
223                 return;
224         }
225
226         if (FR_ISPASS(V_ipfmain.ipf_pass))
227                 defpass = "pass";
228         else if (FR_ISBLOCK(V_ipfmain.ipf_pass))
229                 defpass = "block";
230         else
231                 defpass = "no-match -> block";
232
233         if (IS_DEFAULT_VNET(curvnet))
234             printf("%s initialized.  Default = %s all, Logging = %s%s\n",
235                 ipfilter_version, defpass,
236 #ifdef IPFILTER_LOG
237                 "enabled",
238 #else
239                 "disabled",
240 #endif
241 #ifdef IPFILTER_COMPILED
242                 " (COMPILED)"
243 #else
244                 ""
245 #endif
246                 );
247 }
248 VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
249     vnet_ipf_init, NULL);
250
251 static int
252 ipf_modload()
253 {
254         char *c, *str;
255         int i, j, error;
256
257         if (ipf_load_all() != 0)
258                 return EIO;
259
260         if (ipf_fbsd_sysctl_create() != 0) {
261                 return EIO;
262         }
263
264         for (i = 0; i < IPL_LOGSIZE; i++)
265                 ipf_devs[i] = NULL;
266         for (i = 0; (str = ipf_devfiles[i]); i++) {
267                 c = NULL;
268                 for(j = strlen(str); j > 0; j--)
269                         if (str[j] == '/') {
270                                 c = str + j + 1;
271                                 break;
272                         }
273                 if (!c)
274                         c = str;
275                 ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c);
276         }
277
278         error = ipf_pfil_hook();
279         if (error != 0)
280                 return error;
281         ipf_event_reg();
282
283         return 0;
284 }
285
286 static void
287 vnet_ipf_uninit(void)
288 {
289
290         if (V_ipfmain.ipf_refcnt)
291                 return;
292
293         if (V_ipfmain.ipf_running >= 0) {
294
295                 if (ipfdetach(&V_ipfmain) != 0)
296                         return;
297
298                 V_ipfmain.ipf_running = -2;
299
300                 ipf_destroy_all(&V_ipfmain);
301         }
302 }
303 VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
304     vnet_ipf_uninit, NULL);
305
306 static int
307 ipf_modunload()
308 {
309         int error, i;
310
311         ipf_event_dereg();
312
313         ipf_fbsd_sysctl_destroy();
314
315         error = ipf_pfil_unhook();
316         if (error != 0)
317                 return error;
318
319         for (i = 0; ipf_devfiles[i]; i++) {
320                 if (ipf_devs[i] != NULL)
321                         destroy_dev(ipf_devs[i]);
322         }
323
324         ipf_unload_all();
325
326         printf("%s unloaded\n", ipfilter_version);
327
328         return error;
329 }
330
331
332 static moduledata_t ipfiltermod = {
333         "ipfilter",
334         ipfilter_modevent,
335         0
336 };
337
338
339 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
340 #ifdef  MODULE_VERSION
341 MODULE_VERSION(ipfilter, 1);
342 #endif
343
344
345 #ifdef SYSCTL_IPF
346 int
347 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
348 {
349         int error = 0;
350
351         if (arg1)
352                 error = SYSCTL_OUT(req, arg1, sizeof(int));
353         else
354                 error = SYSCTL_OUT(req, &arg2, sizeof(int));
355
356         if (error || !req->newptr)
357                 return (error);
358
359         if (!arg1)
360                 error = EPERM;
361         else {
362                 if ((oidp->oid_kind & CTLFLAG_OFF) && (V_ipfmain.ipf_running > 0))
363                         error = EBUSY;
364                 else
365                         error = SYSCTL_IN(req, arg1, sizeof(int));
366         }
367         return (error);
368 }
369
370 /*
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.
375  */
376 static int
377 sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS )
378 {
379
380         if (arg1) {
381                 ipf_nat_softc_t *nat_softc;
382
383                 nat_softc = V_ipfmain.ipf_nat_soft;
384 #ifdef VIMAGE
385                 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
386 #endif
387                 arg1 = (void *)((uintptr_t)nat_softc + (uintptr_t)arg1);
388         }
389
390         return (sysctl_ipf_int(oidp, arg1, arg2, req));
391 }
392
393 static int
394 sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS )
395 {
396
397         if (arg1) {
398                 ipf_state_softc_t *state_softc;
399
400                 state_softc = V_ipfmain.ipf_state_soft;
401 #ifdef VIMAGE
402                 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
403 #endif
404                 arg1 = (void *)((uintptr_t)state_softc + (uintptr_t)arg1);
405         }
406
407         return (sysctl_ipf_int(oidp, arg1, arg2, req));
408 }
409
410 static int
411 sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS )
412 {
413
414         if (arg1) {
415                 ipf_auth_softc_t *auth_softc;
416
417                 auth_softc = V_ipfmain.ipf_auth_soft;
418 #ifdef VIMAGE
419                 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
420 #endif
421                 arg1 = (void *)((uintptr_t)auth_softc + (uintptr_t)arg1);
422         }
423
424         return (sysctl_ipf_int(oidp, arg1, arg2, req));
425 }
426
427 static int
428 sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS )
429 {
430
431         if (arg1) {
432                 ipf_frag_softc_t *frag_softc;
433
434                 frag_softc = V_ipfmain.ipf_frag_soft;
435 #ifdef VIMAGE
436                 arg1 = (void *)((uintptr_t)arg1 - curvnet->vnet_data_base);
437 #endif
438                 arg1 = (void *)((uintptr_t)frag_softc + (uintptr_t)arg1);
439         }
440
441         return (sysctl_ipf_int(oidp, arg1, arg2, req));
442 }
443 #endif
444
445
446 static int
447 #if __FreeBSD_version >= 500043
448 ipfpoll(struct cdev *dev, int events, struct thread *td)
449 #else
450 ipfpoll(dev_t dev, int events, struct proc *td)
451 #endif
452 {
453         int unit = GET_MINOR(dev);
454         int revents;
455
456         if (unit < 0 || unit > IPL_LOGMAX)
457                 return 0;
458
459         revents = 0;
460
461         CURVNET_SET(TD_TO_VNET(td));
462         switch (unit)
463         {
464         case IPL_LOGIPF :
465         case IPL_LOGNAT :
466         case IPL_LOGSTATE :
467 #ifdef IPFILTER_LOG
468                 if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit))
469                         revents |= events & (POLLIN | POLLRDNORM);
470 #endif
471                 break;
472         case IPL_LOGAUTH :
473                 if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain))
474                         revents |= events & (POLLIN | POLLRDNORM);
475                 break;
476         case IPL_LOGSYNC :
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);
481                 break;
482         case IPL_LOGSCAN :
483         case IPL_LOGLOOKUP :
484         default :
485                 break;
486         }
487
488         if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
489                 selrecord(td, &V_ipfmain.ipf_selwait[unit]);
490         CURVNET_RESTORE();
491
492         return revents;
493 }
494
495
496 /*
497  * routines below for saving IP headers to buffer
498  */
499 static int ipfopen(dev, flags
500 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
501 , devtype, p)
502         int devtype;
503 # if (__FreeBSD_version >= 500024)
504         struct thread *p;
505 # else
506         struct proc *p;
507 # endif /* __FreeBSD_version >= 500024 */
508 #else
509 )
510 #endif
511 #if (__FreeBSD_version >= 502116)
512         struct cdev *dev;
513 #else
514         dev_t dev;
515 #endif
516         int flags;
517 {
518         int unit = GET_MINOR(dev);
519         int error;
520
521         if (IPL_LOGMAX < unit)
522                 error = ENXIO;
523         else {
524                 switch (unit)
525                 {
526                 case IPL_LOGIPF :
527                 case IPL_LOGNAT :
528                 case IPL_LOGSTATE :
529                 case IPL_LOGAUTH :
530                 case IPL_LOGLOOKUP :
531                 case IPL_LOGSYNC :
532 #ifdef IPFILTER_SCAN
533                 case IPL_LOGSCAN :
534 #endif
535                         error = 0;
536                         break;
537                 default :
538                         error = ENXIO;
539                         break;
540                 }
541         }
542         return error;
543 }
544
545
546 static int ipfclose(dev, flags
547 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
548 , devtype, p)
549         int devtype;
550 # if (__FreeBSD_version >= 500024)
551         struct thread *p;
552 # else
553         struct proc *p;
554 # endif /* __FreeBSD_version >= 500024 */
555 #else
556 )
557 #endif
558 #if (__FreeBSD_version >= 502116)
559         struct cdev *dev;
560 #else
561         dev_t dev;
562 #endif
563         int flags;
564 {
565         int     unit = GET_MINOR(dev);
566
567         if (IPL_LOGMAX < unit)
568                 unit = ENXIO;
569         else
570                 unit = 0;
571         return unit;
572 }
573
574 /*
575  * ipfread/ipflog
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
578  * the filter lists.
579  */
580 #if (BSD >= 199306)
581 static int ipfread(dev, uio, ioflag)
582         int ioflag;
583 #else
584 static int ipfread(dev, uio)
585 #endif
586 #if (__FreeBSD_version >= 502116)
587         struct cdev *dev;
588 #else
589         dev_t dev;
590 #endif
591         struct uio *uio;
592 {
593         int error;
594         int     unit = GET_MINOR(dev);
595
596         if (unit < 0)
597                 return ENXIO;
598
599         CURVNET_SET(TD_TO_VNET(curthread));
600         if (V_ipfmain.ipf_running < 1) {
601                 CURVNET_RESTORE();
602                 return EIO;
603         }
604
605         if (unit == IPL_LOGSYNC) {
606                 error = ipf_sync_read(&V_ipfmain, uio);
607                 CURVNET_RESTORE();
608                 return error;
609         }
610
611 #ifdef IPFILTER_LOG
612         error = ipf_log_read(&V_ipfmain, unit, uio);
613 #else
614         error = ENXIO;
615 #endif
616         CURVNET_RESTORE();
617         return error;
618 }
619
620
621 /*
622  * ipfwrite
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
625  * the filter lists.
626  */
627 #if (BSD >= 199306)
628 static int ipfwrite(dev, uio, ioflag)
629         int ioflag;
630 #else
631 static int ipfwrite(dev, uio)
632 #endif
633 #if (__FreeBSD_version >= 502116)
634         struct cdev *dev;
635 #else
636         dev_t dev;
637 #endif
638         struct uio *uio;
639 {
640         int error;
641
642         CURVNET_SET(TD_TO_VNET(curthread));
643         if (V_ipfmain.ipf_running < 1) {
644                 CURVNET_RESTORE();
645                 return EIO;
646         }
647
648         if (GET_MINOR(dev) == IPL_LOGSYNC) {
649                 error = ipf_sync_write(&V_ipfmain, uio);
650                 CURVNET_RESTORE();
651                 return error;
652         }
653         return ENXIO;
654 }
655
656 static int
657 ipf_fbsd_sysctl_create(void)
658 {
659
660         sysctl_ctx_init(&ipf_clist);
661
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, "");
686         return 0;
687 }
688
689 static int
690 ipf_fbsd_sysctl_destroy(void)
691 {
692         if (sysctl_ctx_free(&ipf_clist)) {
693                 printf("sysctl_ctx_free failed");
694                 return(ENOTEMPTY);
695         }
696         return 0;
697 }
698