The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netpfil/ipfilter/netinet/mlfk_ipl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6b591e66e98ccbbeb3b4a3672c1a275c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.