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/ip_auth.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  * See the IPFILTER.LICENCE file for details on licencing.
    7  */
    8 #if defined(KERNEL) || defined(_KERNEL)
    9 # undef KERNEL
   10 # undef _KERNEL
   11 # define        KERNEL  1
   12 # define        _KERNEL 1
   13 #endif
   14 #include <sys/errno.h>
   15 #include <sys/types.h>
   16 #include <sys/param.h>
   17 #include <sys/time.h>
   18 #include <sys/file.h>
   19 #if !defined(_KERNEL)
   20 # include <stdio.h>
   21 # include <stdlib.h>
   22 # ifdef _STDC_C99
   23 #  include <stdbool.h>
   24 # endif
   25 # include <string.h>
   26 # define _KERNEL
   27 # include <sys/uio.h>
   28 # undef _KERNEL
   29 #endif
   30 #if defined(_KERNEL) && defined(__FreeBSD__)
   31 # include <sys/filio.h>
   32 # include <sys/fcntl.h>
   33 #else
   34 # include <sys/ioctl.h>
   35 #endif
   36 # include <sys/protosw.h>
   37 #include <sys/socket.h>
   38 #if defined(_KERNEL)
   39 # include <sys/systm.h>
   40 # if !defined(__SVR4)
   41 #  include <sys/mbuf.h>
   42 # endif
   43 #endif
   44 #if defined(__SVR4)
   45 # include <sys/filio.h>
   46 # include <sys/byteorder.h>
   47 # ifdef _KERNEL
   48 #  include <sys/dditypes.h>
   49 # endif
   50 # include <sys/stream.h>
   51 # include <sys/kmem.h>
   52 #endif
   53 #if defined(__FreeBSD__)
   54 # include <sys/queue.h>
   55 #endif
   56 #if defined(__NetBSD__)
   57 # include <machine/cpu.h>
   58 #endif
   59 #if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)
   60 # include <sys/proc.h>
   61 #endif
   62 #if defined(__NetBSD_Version__) &&  (__NetBSD_Version__ >= 400000) && \
   63      !defined(_KERNEL)
   64 # include <stdbool.h>
   65 #endif
   66 #include <net/if.h>
   67 #ifdef sun
   68 # include <net/af.h>
   69 #endif
   70 #include <netinet/in.h>
   71 #include <netinet/in_systm.h>
   72 #include <netinet/ip.h>
   73 # include <netinet/ip_var.h>
   74 #if !defined(_KERNEL)
   75 # define        KERNEL
   76 # define        _KERNEL
   77 # define        NOT_KERNEL
   78 #endif
   79 #ifdef  NOT_KERNEL
   80 # undef _KERNEL
   81 # undef KERNEL
   82 #endif
   83 #include <netinet/tcp.h>
   84 #if defined(__FreeBSD__)
   85 # include <net/if_var.h>
   86 # define IF_QFULL _IF_QFULL
   87 # define IF_DROP _IF_DROP
   88 #endif
   89 #include <netinet/in_var.h>
   90 #include <netinet/tcp_fsm.h>
   91 #include <netinet/udp.h>
   92 #include <netinet/ip_icmp.h>
   93 #include "netinet/ip_compat.h"
   94 #include <netinet/tcpip.h>
   95 #include "netinet/ip_fil.h"
   96 #include "netinet/ip_auth.h"
   97 #if !SOLARIS
   98 # include <net/netisr.h>
   99 # ifdef __FreeBSD__
  100 #  include <machine/cpufunc.h>
  101 # endif
  102 #endif
  103 #if defined(__FreeBSD__)
  104 # include <sys/malloc.h>
  105 # if defined(_KERNEL) && !defined(IPFILTER_LKM)
  106 #  include <sys/libkern.h>
  107 #  include <sys/systm.h>
  108 # endif
  109 #endif
  110 /* END OF INCLUDES */
  111 
  112 #if !defined(lint)
  113 static const char rcsid[] = "@(#)$FreeBSD$";
  114 /* static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.24 2007/09/09 11:32:04 darrenr Exp $"; */
  115 #endif
  116 
  117 
  118 static void ipf_auth_deref(frauthent_t **);
  119 static void ipf_auth_deref_unlocked(ipf_auth_softc_t *, frauthent_t **);
  120 static int ipf_auth_geniter(ipf_main_softc_t *, ipftoken_t *,
  121                                  ipfgeniter_t *, ipfobj_t *);
  122 static int ipf_auth_reply(ipf_main_softc_t *, ipf_auth_softc_t *, char *);
  123 static int ipf_auth_wait(ipf_main_softc_t *, ipf_auth_softc_t *, char *);
  124 static int ipf_auth_flush(void *);
  125 
  126 
  127 /* ------------------------------------------------------------------------ */
  128 /* Function:    ipf_auth_main_load                                          */
  129 /* Returns:     int - 0 == success, else error                              */
  130 /* Parameters:  None                                                        */
  131 /*                                                                          */
  132 /* A null-op function that exists as a placeholder so that the flow in      */
  133 /* other functions is obvious.                                              */
  134 /* ------------------------------------------------------------------------ */
  135 int
  136 ipf_auth_main_load(void)
  137 {
  138         return (0);
  139 }
  140 
  141 
  142 /* ------------------------------------------------------------------------ */
  143 /* Function:    ipf_auth_main_unload                                        */
  144 /* Returns:     int - 0 == success, else error                              */
  145 /* Parameters:  None                                                        */
  146 /*                                                                          */
  147 /* A null-op function that exists as a placeholder so that the flow in      */
  148 /* other functions is obvious.                                              */
  149 /* ------------------------------------------------------------------------ */
  150 int
  151 ipf_auth_main_unload(void)
  152 {
  153         return (0);
  154 }
  155 
  156 
  157 /* ------------------------------------------------------------------------ */
  158 /* Function:    ipf_auth_soft_create                                        */
  159 /* Returns:     int - NULL = failure, else success                          */
  160 /* Parameters:  softc(I) - pointer to soft context data                     */
  161 /*                                                                          */
  162 /* Create a structre to store all of the run-time data for packet auth in   */
  163 /* and initialise some fields to their defaults.                            */
  164 /* ------------------------------------------------------------------------ */
  165 void *
  166 ipf_auth_soft_create(ipf_main_softc_t *softc)
  167 {
  168         ipf_auth_softc_t *softa;
  169 
  170         KMALLOC(softa, ipf_auth_softc_t *);
  171         if (softa == NULL)
  172                 return (NULL);
  173 
  174         bzero((char *)softa, sizeof(*softa));
  175 
  176         softa->ipf_auth_size = FR_NUMAUTH;
  177         softa->ipf_auth_defaultage = 600;
  178 
  179         RWLOCK_INIT(&softa->ipf_authlk, "ipf IP User-Auth rwlock");
  180         MUTEX_INIT(&softa->ipf_auth_mx, "ipf auth log mutex");
  181 #if SOLARIS && defined(_KERNEL)
  182         cv_init(&softa->ipf_auth_wait, "ipf auth condvar", CV_DRIVER, NULL);
  183 #endif
  184 
  185         return (softa);
  186 }
  187 
  188 /* ------------------------------------------------------------------------ */
  189 /* Function:    ipf_auth_soft_init                                          */
  190 /* Returns:     int - 0 == success, else error                              */
  191 /* Parameters:  softc(I) - pointer to soft context data                     */
  192 /*              arg(I)   - opaque pointer to auth context data              */
  193 /*                                                                          */
  194 /* Allocate memory and initialise data structures used in handling auth     */
  195 /* rules.                                                                   */
  196 /* ------------------------------------------------------------------------ */
  197 int
  198 ipf_auth_soft_init(ipf_main_softc_t *softc, void *arg)
  199 {
  200         ipf_auth_softc_t *softa = arg;
  201 
  202         KMALLOCS(softa->ipf_auth, frauth_t *,
  203                  softa->ipf_auth_size * sizeof(*softa->ipf_auth));
  204         if (softa->ipf_auth == NULL)
  205                 return (-1);
  206         bzero((char *)softa->ipf_auth,
  207               softa->ipf_auth_size * sizeof(*softa->ipf_auth));
  208 
  209         KMALLOCS(softa->ipf_auth_pkts, mb_t **,
  210                  softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts));
  211         if (softa->ipf_auth_pkts == NULL)
  212                 return (-2);
  213         bzero((char *)softa->ipf_auth_pkts,
  214               softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts));
  215 
  216 
  217         return (0);
  218 }
  219 
  220 
  221 /* ------------------------------------------------------------------------ */
  222 /* Function:    ipf_auth_soft_fini                                          */
  223 /* Returns:     int - 0 == success, else error                              */
  224 /* Parameters:  softc(I) - pointer to soft context data                     */
  225 /*              arg(I)   - opaque pointer to auth context data              */
  226 /*                                                                          */
  227 /* Free all network buffer memory used to keep saved packets that have been */
  228 /* connectedd to the soft soft context structure *but* do not free that: it */
  229 /* is free'd by _destroy().                                                 */
  230 /* ------------------------------------------------------------------------ */
  231 int
  232 ipf_auth_soft_fini(ipf_main_softc_t *softc, void *arg)
  233 {
  234         ipf_auth_softc_t *softa = arg;
  235         frauthent_t *fae, **faep;
  236         frentry_t *fr, **frp;
  237         mb_t *m;
  238         int i;
  239 
  240         if (softa->ipf_auth != NULL) {
  241                 KFREES(softa->ipf_auth,
  242                        softa->ipf_auth_size * sizeof(*softa->ipf_auth));
  243                 softa->ipf_auth = NULL;
  244         }
  245 
  246         if (softa->ipf_auth_pkts != NULL) {
  247                 for (i = 0; i < softa->ipf_auth_size; i++) {
  248                         m = softa->ipf_auth_pkts[i];
  249                         if (m != NULL) {
  250                                 FREE_MB_T(m);
  251                                 softa->ipf_auth_pkts[i] = NULL;
  252                         }
  253                 }
  254                 KFREES(softa->ipf_auth_pkts,
  255                        softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts));
  256                 softa->ipf_auth_pkts = NULL;
  257         }
  258 
  259         faep = &softa->ipf_auth_entries;
  260         while ((fae = *faep) != NULL) {
  261                 *faep = fae->fae_next;
  262                 KFREE(fae);
  263         }
  264         softa->ipf_auth_ip = NULL;
  265 
  266         if (softa->ipf_auth_rules != NULL) {
  267                 for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) {
  268                         if (fr->fr_ref == 1) {
  269                                 *frp = fr->fr_next;
  270                                 MUTEX_DESTROY(&fr->fr_lock);
  271                                 KFREE(fr);
  272                         } else
  273                                 frp = &fr->fr_next;
  274                 }
  275         }
  276 
  277         return (0);
  278 }
  279 
  280 
  281 /* ------------------------------------------------------------------------ */
  282 /* Function:    ipf_auth_soft_destroy                                       */
  283 /* Returns:     void                                                        */
  284 /* Parameters:  softc(I) - pointer to soft context data                     */
  285 /*              arg(I)   - opaque pointer to auth context data              */
  286 /*                                                                          */
  287 /* Undo what was done in _create() - i.e. free the soft context data.       */
  288 /* ------------------------------------------------------------------------ */
  289 void
  290 ipf_auth_soft_destroy(ipf_main_softc_t *softc, void *arg)
  291 {
  292         ipf_auth_softc_t *softa = arg;
  293 
  294 #if SOLARIS && defined(_KERNEL)
  295         cv_destroy(&softa->ipf_auth_wait);
  296 #endif
  297         MUTEX_DESTROY(&softa->ipf_auth_mx);
  298         RW_DESTROY(&softa->ipf_authlk);
  299 
  300         KFREE(softa);
  301 }
  302 
  303 
  304 /* ------------------------------------------------------------------------ */
  305 /* Function:    ipf_auth_setlock                                            */
  306 /* Returns:     void                                                        */
  307 /* Paramters:   arg(I) - pointer to soft context data                       */
  308 /*              tmp(I) - value to assign to auth lock                       */
  309 /*                                                                          */
  310 /* ------------------------------------------------------------------------ */
  311 void
  312 ipf_auth_setlock(void *arg, int tmp)
  313 {
  314         ipf_auth_softc_t *softa = arg;
  315 
  316         softa->ipf_auth_lock = tmp;
  317 }
  318 
  319 
  320 /* ------------------------------------------------------------------------ */
  321 /* Function:    ipf_auth_check                                              */
  322 /* Returns:     frentry_t* - pointer to ipf rule if match found, else NULL  */
  323 /* Parameters:  fin(I)   - pointer to ipftoken structure                    */
  324 /*              passp(I) - pointer to ipfgeniter structure                  */
  325 /*                                                                          */
  326 /* Check if a packet has authorization.  If the packet is found to match an */
  327 /* authorization result and that would result in a feedback loop (i.e. it   */
  328 /* will end up returning FR_AUTH) then return FR_BLOCK instead.             */
  329 /* ------------------------------------------------------------------------ */
  330 frentry_t *
  331 ipf_auth_check(fr_info_t *fin, u_32_t *passp)
  332 {
  333         ipf_main_softc_t *softc = fin->fin_main_soft;
  334         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  335         frentry_t *fr;
  336         frauth_t *fra;
  337         u_32_t pass;
  338         u_short id;
  339         ip_t *ip;
  340         int i;
  341 
  342         if (softa->ipf_auth_lock || !softa->ipf_auth_used)
  343                 return (NULL);
  344 
  345         ip = fin->fin_ip;
  346         id = ip->ip_id;
  347 
  348         READ_ENTER(&softa->ipf_authlk);
  349         for (i = softa->ipf_auth_start; i != softa->ipf_auth_end; ) {
  350                 /*
  351                  * index becomes -2 only after an SIOCAUTHW.  Check this in
  352                  * case the same packet gets sent again and it hasn't yet been
  353                  * auth'd.
  354                  */
  355                 fra = softa->ipf_auth + i;
  356                 if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) &&
  357                     !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) {
  358                         /*
  359                          * Avoid feedback loop.
  360                          */
  361                         if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) {
  362                                 pass = FR_BLOCK;
  363                                 fin->fin_reason = FRB_AUTHFEEDBACK;
  364                         }
  365                         /*
  366                          * Create a dummy rule for the stateful checking to
  367                          * use and return.  Zero out any values we don't
  368                          * trust from userland!
  369                          */
  370                         if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) &&
  371                              (fin->fin_flx & FI_FRAG))) {
  372                                 KMALLOC(fr, frentry_t *);
  373                                 if (fr) {
  374                                         bcopy((char *)fra->fra_info.fin_fr,
  375                                               (char *)fr, sizeof(*fr));
  376                                         fr->fr_grp = NULL;
  377                                         fr->fr_ifa = fin->fin_ifp;
  378                                         fr->fr_func = NULL;
  379                                         fr->fr_ref = 1;
  380                                         fr->fr_flags = pass;
  381                                         fr->fr_ifas[1] = NULL;
  382                                         fr->fr_ifas[2] = NULL;
  383                                         fr->fr_ifas[3] = NULL;
  384                                         MUTEX_INIT(&fr->fr_lock,
  385                                                    "ipf auth rule");
  386                                 }
  387                         } else
  388                                 fr = fra->fra_info.fin_fr;
  389                         fin->fin_fr = fr;
  390                         fin->fin_flx |= fra->fra_flx;
  391                         RWLOCK_EXIT(&softa->ipf_authlk);
  392 
  393                         WRITE_ENTER(&softa->ipf_authlk);
  394                         /*
  395                          * ipf_auth_rules is populated with the rules malloc'd
  396                          * above and only those.
  397                          */
  398                         if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) {
  399                                 fr->fr_next = softa->ipf_auth_rules;
  400                                 softa->ipf_auth_rules = fr;
  401                         }
  402                         softa->ipf_auth_stats.fas_hits++;
  403                         fra->fra_index = -1;
  404                         softa->ipf_auth_used--;
  405                         softa->ipf_auth_replies--;
  406                         if (i == softa->ipf_auth_start) {
  407                                 while (fra->fra_index == -1) {
  408                                         i++;
  409                                         fra++;
  410                                         if (i == softa->ipf_auth_size) {
  411                                                 i = 0;
  412                                                 fra = softa->ipf_auth;
  413                                         }
  414                                         softa->ipf_auth_start = i;
  415                                         if (i == softa->ipf_auth_end)
  416                                                 break;
  417                                 }
  418                                 if (softa->ipf_auth_start ==
  419                                     softa->ipf_auth_end) {
  420                                         softa->ipf_auth_next = 0;
  421                                         softa->ipf_auth_start = 0;
  422                                         softa->ipf_auth_end = 0;
  423                                 }
  424                         }
  425                         RWLOCK_EXIT(&softa->ipf_authlk);
  426                         if (passp != NULL)
  427                                 *passp = pass;
  428                         softa->ipf_auth_stats.fas_hits++;
  429                         return (fr);
  430                 }
  431                 i++;
  432                 if (i == softa->ipf_auth_size)
  433                         i = 0;
  434         }
  435         RWLOCK_EXIT(&softa->ipf_authlk);
  436         softa->ipf_auth_stats.fas_miss++;
  437         return (NULL);
  438 }
  439 
  440 
  441 /* ------------------------------------------------------------------------ */
  442 /* Function:    ipf_auth_new                                                */
  443 /* Returns:     int - 1 == success, 0 = did not put packet on auth queue    */
  444 /* Parameters:  m(I)   - pointer to mb_t with packet in it                  */
  445 /*              fin(I) - pointer to packet information                      */
  446 /*                                                                          */
  447 /* Check if we have room in the auth array to hold details for another      */
  448 /* packet. If we do, store it and wake up any user programs which are       */
  449 /* waiting to hear about these events.                                      */
  450 /* ------------------------------------------------------------------------ */
  451 int
  452 ipf_auth_new(mb_t *m, fr_info_t *fin)
  453 {
  454         ipf_main_softc_t *softc = fin->fin_main_soft;
  455         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  456 #if defined(_KERNEL) && SOLARIS
  457         qpktinfo_t *qpi = fin->fin_qpi;
  458 #endif
  459         frauth_t *fra;
  460 #if !defined(sparc) && !defined(m68k)
  461         ip_t *ip;
  462 #endif
  463         int i;
  464 
  465         if (softa->ipf_auth_lock)
  466                 return (0);
  467 
  468         WRITE_ENTER(&softa->ipf_authlk);
  469         if (((softa->ipf_auth_end + 1) % softa->ipf_auth_size) ==
  470             softa->ipf_auth_start) {
  471                 softa->ipf_auth_stats.fas_nospace++;
  472                 RWLOCK_EXIT(&softa->ipf_authlk);
  473                 return (0);
  474         }
  475 
  476         softa->ipf_auth_stats.fas_added++;
  477         softa->ipf_auth_used++;
  478         i = softa->ipf_auth_end++;
  479         if (softa->ipf_auth_end == softa->ipf_auth_size)
  480                 softa->ipf_auth_end = 0;
  481 
  482         fra = softa->ipf_auth + i;
  483         fra->fra_index = i;
  484         if (fin->fin_fr != NULL)
  485                 fra->fra_pass = fin->fin_fr->fr_flags;
  486         else
  487                 fra->fra_pass = 0;
  488         fra->fra_age = softa->ipf_auth_defaultage;
  489         bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin));
  490         fra->fra_flx = fra->fra_info.fin_flx & (FI_STATE|FI_NATED);
  491         fra->fra_info.fin_flx &= ~(FI_STATE|FI_NATED);
  492 #if !defined(sparc) && !defined(m68k)
  493         /*
  494          * No need to copyback here as we want to undo the changes, not keep
  495          * them.
  496          */
  497         ip = fin->fin_ip;
  498 # if SOLARIS && defined(_KERNEL)
  499         if ((ip == (ip_t *)m->b_rptr) && (fin->fin_v == 4))
  500 # endif
  501         {
  502                 register u_short bo;
  503 
  504                 bo = ip->ip_len;
  505                 ip->ip_len = htons(bo);
  506                 bo = ip->ip_off;
  507                 ip->ip_off = htons(bo);
  508         }
  509 #endif
  510 #if SOLARIS && defined(_KERNEL)
  511         COPYIFNAME(fin->fin_v, fin->fin_ifp, fra->fra_info.fin_ifname);
  512         m->b_rptr -= qpi->qpi_off;
  513         fra->fra_q = qpi->qpi_q;        /* The queue can disappear! */
  514         fra->fra_m = *fin->fin_mp;
  515         fra->fra_info.fin_mp = &fra->fra_m;
  516         softa->ipf_auth_pkts[i] = *(mblk_t **)fin->fin_mp;
  517         RWLOCK_EXIT(&softa->ipf_authlk);
  518         cv_signal(&softa->ipf_auth_wait);
  519         pollwakeup(&softc->ipf_poll_head[IPL_LOGAUTH], POLLIN|POLLRDNORM);
  520 #else
  521         softa->ipf_auth_pkts[i] = m;
  522         RWLOCK_EXIT(&softa->ipf_authlk);
  523         WAKEUP(&softa->ipf_auth_next, 0);
  524 #endif
  525         return (1);
  526 }
  527 
  528 
  529 /* ------------------------------------------------------------------------ */
  530 /* Function:    ipf_auth_ioctl                                              */
  531 /* Returns:     int - 0 == success, else error                              */
  532 /* Parameters:  data(IO) - pointer to ioctl data                            */
  533 /*              cmd(I)   - ioctl command                                    */
  534 /*              mode(I)  - mode flags associated with open descriptor       */
  535 /*              uid(I)   - uid associatd with application making the call   */
  536 /*              ctx(I)   - pointer for context                              */
  537 /*                                                                          */
  538 /* This function handles all of the ioctls recognised by the auth component */
  539 /* in IPFilter - ie ioctls called on an open fd for /dev/ipf_auth           */
  540 /* ------------------------------------------------------------------------ */
  541 int
  542 ipf_auth_ioctl(ipf_main_softc_t *softc, caddr_t data, ioctlcmd_t cmd,
  543         int mode, int uid, void *ctx)
  544 {
  545         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  546         int error = 0, i;
  547         SPL_INT(s);
  548 
  549         switch (cmd)
  550         {
  551         case SIOCGENITER :
  552             {
  553                 ipftoken_t *token;
  554                 ipfgeniter_t iter;
  555                 ipfobj_t obj;
  556 
  557                 error = ipf_inobj(softc, data, &obj, &iter, IPFOBJ_GENITER);
  558                 if (error != 0)
  559                         break;
  560 
  561                 SPL_SCHED(s);
  562                 token = ipf_token_find(softc, IPFGENITER_AUTH, uid, ctx);
  563                 if (token != NULL)
  564                         error = ipf_auth_geniter(softc, token, &iter, &obj);
  565                 else {
  566                         WRITE_ENTER(&softc->ipf_tokens);
  567                         ipf_token_deref(softc, token);
  568                         RWLOCK_EXIT(&softc->ipf_tokens);
  569                         IPFERROR(10001);
  570                         error = ESRCH;
  571                 }
  572                 SPL_X(s);
  573 
  574                 break;
  575             }
  576 
  577         case SIOCADAFR :
  578         case SIOCRMAFR :
  579                 if (!(mode & FWRITE)) {
  580                         IPFERROR(10002);
  581                         error = EPERM;
  582                 } else
  583                         error = frrequest(softc, IPL_LOGAUTH, cmd, data,
  584                                           softc->ipf_active, 1);
  585                 break;
  586 
  587         case SIOCSTLCK :
  588                 if (!(mode & FWRITE)) {
  589                         IPFERROR(10003);
  590                         error = EPERM;
  591                 } else {
  592                         error = ipf_lock(data, &softa->ipf_auth_lock);
  593                 }
  594                 break;
  595 
  596         case SIOCATHST:
  597                 softa->ipf_auth_stats.fas_faelist = softa->ipf_auth_entries;
  598                 error = ipf_outobj(softc, data, &softa->ipf_auth_stats,
  599                                    IPFOBJ_AUTHSTAT);
  600                 break;
  601 
  602         case SIOCIPFFL:
  603                 SPL_NET(s);
  604                 WRITE_ENTER(&softa->ipf_authlk);
  605                 i = ipf_auth_flush(softa);
  606                 RWLOCK_EXIT(&softa->ipf_authlk);
  607                 SPL_X(s);
  608                 error = BCOPYOUT(&i, data, sizeof(i));
  609                 if (error != 0) {
  610                         IPFERROR(10004);
  611                         error = EFAULT;
  612                 }
  613                 break;
  614 
  615         case SIOCAUTHW:
  616                 error = ipf_auth_wait(softc, softa, data);
  617                 break;
  618 
  619         case SIOCAUTHR:
  620                 error = ipf_auth_reply(softc, softa, data);
  621                 break;
  622 
  623         default :
  624                 IPFERROR(10005);
  625                 error = EINVAL;
  626                 break;
  627         }
  628         return (error);
  629 }
  630 
  631 
  632 /* ------------------------------------------------------------------------ */
  633 /* Function:    ipf_auth_expire                                             */
  634 /* Returns:     None                                                        */
  635 /* Parameters:  None                                                        */
  636 /*                                                                          */
  637 /* Slowly expire held auth records.  Timeouts are set in expectation of     */
  638 /* this being called twice per second.                                      */
  639 /* ------------------------------------------------------------------------ */
  640 void
  641 ipf_auth_expire(ipf_main_softc_t *softc)
  642 {
  643         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  644         frauthent_t *fae, **faep;
  645         frentry_t *fr, **frp;
  646         frauth_t *fra;
  647         mb_t *m;
  648         int i;
  649         SPL_INT(s);
  650 
  651         if (softa->ipf_auth_lock)
  652                 return;
  653         SPL_NET(s);
  654         WRITE_ENTER(&softa->ipf_authlk);
  655         for (i = 0, fra = softa->ipf_auth; i < softa->ipf_auth_size;
  656              i++, fra++) {
  657                 fra->fra_age--;
  658                 if ((fra->fra_age == 0) &&
  659                     (softa->ipf_auth[i].fra_index != -1)) {
  660                         if ((m = softa->ipf_auth_pkts[i]) != NULL) {
  661                                 FREE_MB_T(m);
  662                                 softa->ipf_auth_pkts[i] = NULL;
  663                         } else if (softa->ipf_auth[i].fra_index == -2) {
  664                                 softa->ipf_auth_replies--;
  665                         }
  666                         softa->ipf_auth[i].fra_index = -1;
  667                         softa->ipf_auth_stats.fas_expire++;
  668                         softa->ipf_auth_used--;
  669                 }
  670         }
  671 
  672         /*
  673          * Expire pre-auth rules
  674          */
  675         for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) {
  676                 fae->fae_age--;
  677                 if (fae->fae_age == 0) {
  678                         ipf_auth_deref(&fae);
  679                         softa->ipf_auth_stats.fas_expire++;
  680                 } else
  681                         faep = &fae->fae_next;
  682         }
  683         if (softa->ipf_auth_entries != NULL)
  684                 softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr;
  685         else
  686                 softa->ipf_auth_ip = NULL;
  687 
  688         for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) {
  689                 if (fr->fr_ref == 1) {
  690                         *frp = fr->fr_next;
  691                         MUTEX_DESTROY(&fr->fr_lock);
  692                         KFREE(fr);
  693                 } else
  694                         frp = &fr->fr_next;
  695         }
  696         RWLOCK_EXIT(&softa->ipf_authlk);
  697         SPL_X(s);
  698 }
  699 
  700 
  701 /* ------------------------------------------------------------------------ */
  702 /* Function:    ipf_auth_precmd                                             */
  703 /* Returns:     int - 0 == success, else error                              */
  704 /* Parameters:  cmd(I)  - ioctl command for rule                            */
  705 /*              fr(I)   - pointer to ipf rule                               */
  706 /*              fptr(I) - pointer to caller's 'fr'                          */
  707 /*                                                                          */
  708 /* ------------------------------------------------------------------------ */
  709 int
  710 ipf_auth_precmd(ipf_main_softc_t *softc, ioctlcmd_t cmd, frentry_t *fr,
  711         frentry_t **frptr)
  712 {
  713         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  714         frauthent_t *fae, **faep;
  715         int error = 0;
  716         SPL_INT(s);
  717 
  718         if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) {
  719                 IPFERROR(10006);
  720                 return (EIO);
  721         }
  722 
  723         for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) {
  724                 if (&fae->fae_fr == fr)
  725                         break;
  726                 else
  727                         faep = &fae->fae_next;
  728         }
  729 
  730         if (cmd == (ioctlcmd_t)SIOCRMAFR) {
  731                 if (fr == NULL || frptr == NULL) {
  732                         IPFERROR(10007);
  733                         error = EINVAL;
  734 
  735                 } else if (fae == NULL) {
  736                         IPFERROR(10008);
  737                         error = ESRCH;
  738 
  739                 } else {
  740                         SPL_NET(s);
  741                         WRITE_ENTER(&softa->ipf_authlk);
  742                         *faep = fae->fae_next;
  743                         if (softa->ipf_auth_ip == &fae->fae_fr)
  744                                 softa->ipf_auth_ip = softa->ipf_auth_entries ?
  745                                     &softa->ipf_auth_entries->fae_fr : NULL;
  746                         RWLOCK_EXIT(&softa->ipf_authlk);
  747                         SPL_X(s);
  748 
  749                         KFREE(fae);
  750                 }
  751         } else if (fr != NULL && frptr != NULL) {
  752                 KMALLOC(fae, frauthent_t *);
  753                 if (fae != NULL) {
  754                         bcopy((char *)fr, (char *)&fae->fae_fr,
  755                               sizeof(*fr));
  756                         SPL_NET(s);
  757                         WRITE_ENTER(&softa->ipf_authlk);
  758                         fae->fae_age = softa->ipf_auth_defaultage;
  759                         fae->fae_fr.fr_hits = 0;
  760                         fae->fae_fr.fr_next = *frptr;
  761                         fae->fae_ref = 1;
  762                         *frptr = &fae->fae_fr;
  763                         fae->fae_next = *faep;
  764                         *faep = fae;
  765                         softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr;
  766                         RWLOCK_EXIT(&softa->ipf_authlk);
  767                         SPL_X(s);
  768                 } else {
  769                         IPFERROR(10009);
  770                         error = ENOMEM;
  771                 }
  772         } else {
  773                 IPFERROR(10010);
  774                 error = EINVAL;
  775         }
  776         return (error);
  777 }
  778 
  779 
  780 /* ------------------------------------------------------------------------ */
  781 /* Function:    ipf_auth_flush                                              */
  782 /* Returns:     int - number of auth entries flushed                        */
  783 /* Parameters:  None                                                        */
  784 /* Locks:       WRITE(ipf_authlk)                                           */
  785 /*                                                                          */
  786 /* This function flushs the ipf_auth_pkts array of any packet data with     */
  787 /* references still there.                                                  */
  788 /* It is expected that the caller has already acquired the correct locks or */
  789 /* set the priority level correctly for this to block out other code paths  */
  790 /* into these data structures.                                              */
  791 /* ------------------------------------------------------------------------ */
  792 static int
  793 ipf_auth_flush(void *arg)
  794 {
  795         ipf_auth_softc_t *softa = arg;
  796         int i, num_flushed;
  797         mb_t *m;
  798 
  799         if (softa->ipf_auth_lock)
  800                 return (-1);
  801 
  802         num_flushed = 0;
  803 
  804         for (i = 0 ; i < softa->ipf_auth_size; i++) {
  805                 if (softa->ipf_auth[i].fra_index != -1) {
  806                         m = softa->ipf_auth_pkts[i];
  807                         if (m != NULL) {
  808                                 FREE_MB_T(m);
  809                                 softa->ipf_auth_pkts[i] = NULL;
  810                         }
  811 
  812                         softa->ipf_auth[i].fra_index = -1;
  813                         /* perhaps add & use a flush counter inst.*/
  814                         softa->ipf_auth_stats.fas_expire++;
  815                         num_flushed++;
  816                 }
  817         }
  818 
  819         softa->ipf_auth_start = 0;
  820         softa->ipf_auth_end = 0;
  821         softa->ipf_auth_next = 0;
  822         softa->ipf_auth_used = 0;
  823         softa->ipf_auth_replies = 0;
  824 
  825         return (num_flushed);
  826 }
  827 
  828 
  829 /* ------------------------------------------------------------------------ */
  830 /* Function:    ipf_auth_waiting                                            */
  831 /* Returns:     int - number of packets in the auth queue                   */
  832 /* Parameters:  None                                                        */
  833 /*                                                                          */
  834 /* Simple truth check to see if there are any packets waiting in the auth   */
  835 /* queue.                                                                   */
  836 /* ------------------------------------------------------------------------ */
  837 int
  838 ipf_auth_waiting(ipf_main_softc_t *softc)
  839 {
  840         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  841 
  842         return (softa->ipf_auth_used != 0);
  843 }
  844 
  845 
  846 /* ------------------------------------------------------------------------ */
  847 /* Function:    ipf_auth_geniter                                            */
  848 /* Returns:     int - 0 == success, else error                              */
  849 /* Parameters:  token(I) - pointer to ipftoken structure                    */
  850 /*              itp(I)   - pointer to ipfgeniter structure                  */
  851 /*              objp(I)  - pointer to ipf object destription                */
  852 /*                                                                          */
  853 /* Iterate through the list of entries in the auth queue list.              */
  854 /* objp is used here to get the location of where to do the copy out to.    */
  855 /* Stomping over various fields with new information will not harm anything */
  856 /* ------------------------------------------------------------------------ */
  857 static int
  858 ipf_auth_geniter(ipf_main_softc_t *softc, ipftoken_t *token,
  859         ipfgeniter_t *itp, ipfobj_t *objp)
  860 {
  861         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
  862         frauthent_t *fae, *next, zero;
  863         int error;
  864 
  865         if (itp->igi_data == NULL) {
  866                 IPFERROR(10011);
  867                 return (EFAULT);
  868         }
  869 
  870         if (itp->igi_type != IPFGENITER_AUTH) {
  871                 IPFERROR(10012);
  872                 return (EINVAL);
  873         }
  874 
  875         objp->ipfo_type = IPFOBJ_FRAUTH;
  876         objp->ipfo_ptr = itp->igi_data;
  877         objp->ipfo_size = sizeof(frauth_t);
  878 
  879         READ_ENTER(&softa->ipf_authlk);
  880 
  881         fae = token->ipt_data;
  882         if (fae == NULL) {
  883                 next = softa->ipf_auth_entries;
  884         } else {
  885                 next = fae->fae_next;
  886         }
  887 
  888         /*
  889          * If we found an auth entry to use, bump its reference count
  890          * so that it can be used for is_next when we come back.
  891          */
  892         if (next != NULL) {
  893                 ATOMIC_INC(next->fae_ref);
  894                 token->ipt_data = next;
  895         } else {
  896                 bzero(&zero, sizeof(zero));
  897                 next = &zero;
  898                 token->ipt_data = NULL;
  899         }
  900 
  901         RWLOCK_EXIT(&softa->ipf_authlk);
  902 
  903         error = ipf_outobjk(softc, objp, next);
  904         if (fae != NULL)
  905                 ipf_auth_deref_unlocked(softa, &fae);
  906 
  907         if (next->fae_next == NULL)
  908                 ipf_token_mark_complete(token);
  909         return (error);
  910 }
  911 
  912 
  913 /* ------------------------------------------------------------------------ */
  914 /* Function:    ipf_auth_deref_unlocked                                     */
  915 /* Returns:     None                                                        */
  916 /* Parameters:  faep(IO) - pointer to caller's frauthent_t pointer          */
  917 /*                                                                          */
  918 /* Wrapper for ipf_auth_deref for when a write lock on ipf_authlk is not    */
  919 /* held.                                                                    */
  920 /* ------------------------------------------------------------------------ */
  921 static void
  922 ipf_auth_deref_unlocked(ipf_auth_softc_t *softa, frauthent_t **faep)
  923 {
  924         WRITE_ENTER(&softa->ipf_authlk);
  925         ipf_auth_deref(faep);
  926         RWLOCK_EXIT(&softa->ipf_authlk);
  927 }
  928 
  929 
  930 /* ------------------------------------------------------------------------ */
  931 /* Function:    ipf_auth_deref                                              */
  932 /* Returns:     None                                                        */
  933 /* Parameters:  faep(IO) - pointer to caller's frauthent_t pointer          */
  934 /* Locks:       WRITE(ipf_authlk)                                           */
  935 /*                                                                          */
  936 /* This function unconditionally sets the pointer in the caller to NULL,    */
  937 /* to make it clear that it should no longer use that pointer, and drops    */
  938 /* the reference count on the structure by 1.  If it reaches 0, free it up. */
  939 /* ------------------------------------------------------------------------ */
  940 static void
  941 ipf_auth_deref(frauthent_t **faep)
  942 {
  943         frauthent_t *fae;
  944 
  945         fae = *faep;
  946         *faep = NULL;
  947 
  948         fae->fae_ref--;
  949         if (fae->fae_ref == 0) {
  950                 KFREE(fae);
  951         }
  952 }
  953 
  954 
  955 /* ------------------------------------------------------------------------ */
  956 /* Function:    ipf_auth_wait_pkt                                           */
  957 /* Returns:     int - 0 == success, else error                              */
  958 /* Parameters:  data(I) - pointer to data from ioctl call                   */
  959 /*                                                                          */
  960 /* This function is called when an application is waiting for a packet to   */
  961 /* match an "auth" rule by issuing an SIOCAUTHW ioctl.  If there is already */
  962 /* a packet waiting on the queue then we will return that _one_ immediately.*/
  963 /* If there are no packets present in the queue (ipf_auth_pkts) then we go  */
  964 /* to sleep.                                                                */
  965 /* ------------------------------------------------------------------------ */
  966 static int
  967 ipf_auth_wait(ipf_main_softc_t *softc, ipf_auth_softc_t *softa, char *data)
  968 {
  969         frauth_t auth, *au = &auth;
  970         int error, len, i;
  971         mb_t *m;
  972         char *t;
  973         SPL_INT(s);
  974 
  975 ipf_auth_ioctlloop:
  976         error = ipf_inobj(softc, data, NULL, au, IPFOBJ_FRAUTH);
  977         if (error != 0)
  978                 return (error);
  979 
  980         /*
  981          * XXX Locks are held below over calls to copyout...a better
  982          * solution needs to be found so this isn't necessary.  The situation
  983          * we are trying to guard against here is an error in the copyout
  984          * steps should not cause the packet to "disappear" from the queue.
  985          */
  986         SPL_NET(s);
  987         READ_ENTER(&softa->ipf_authlk);
  988 
  989         /*
  990          * If ipf_auth_next is not equal to ipf_auth_end it will be because
  991          * there is a packet waiting to be delt with in the ipf_auth_pkts
  992          * array.  We copy as much of that out to user space as requested.
  993          */
  994         if (softa->ipf_auth_used > 0) {
  995                 while (softa->ipf_auth_pkts[softa->ipf_auth_next] == NULL) {
  996                         softa->ipf_auth_next++;
  997                         if (softa->ipf_auth_next == softa->ipf_auth_size)
  998                                 softa->ipf_auth_next = 0;
  999                 }
 1000 
 1001                 error = ipf_outobj(softc, data,
 1002                                    &softa->ipf_auth[softa->ipf_auth_next],
 1003                                    IPFOBJ_FRAUTH);
 1004                 if (error != 0) {
 1005                         RWLOCK_EXIT(&softa->ipf_authlk);
 1006                         SPL_X(s);
 1007                         return (error);
 1008                 }
 1009 
 1010                 if (auth.fra_len != 0 && auth.fra_buf != NULL) {
 1011                         /*
 1012                          * Copy packet contents out to user space if
 1013                          * requested.  Bail on an error.
 1014                          */
 1015                         m = softa->ipf_auth_pkts[softa->ipf_auth_next];
 1016                         len = MSGDSIZE(m);
 1017                         if (len > auth.fra_len)
 1018                                 len = auth.fra_len;
 1019                         auth.fra_len = len;
 1020 
 1021                         for (t = auth.fra_buf; m && (len > 0); ) {
 1022                                 i = MIN(M_LEN(m), len);
 1023                                 error = copyoutptr(softc, MTOD(m, char *),
 1024                                                    &t, i);
 1025                                 len -= i;
 1026                                 t += i;
 1027                                 if (error != 0) {
 1028                                         RWLOCK_EXIT(&softa->ipf_authlk);
 1029                                         SPL_X(s);
 1030                                         return (error);
 1031                                 }
 1032                                 m = m->m_next;
 1033                         }
 1034                 }
 1035                 RWLOCK_EXIT(&softa->ipf_authlk);
 1036 
 1037                 SPL_NET(s);
 1038                 WRITE_ENTER(&softa->ipf_authlk);
 1039                 softa->ipf_auth_next++;
 1040                 if (softa->ipf_auth_next == softa->ipf_auth_size)
 1041                         softa->ipf_auth_next = 0;
 1042                 RWLOCK_EXIT(&softa->ipf_authlk);
 1043                 SPL_X(s);
 1044 
 1045                 return (0);
 1046         }
 1047         RWLOCK_EXIT(&softa->ipf_authlk);
 1048         SPL_X(s);
 1049 
 1050         MUTEX_ENTER(&softa->ipf_auth_mx);
 1051 #ifdef  _KERNEL
 1052 # if    SOLARIS
 1053         error = 0;
 1054         if (!cv_wait_sig(&softa->ipf_auth_wait, &softa->ipf_auth_mx.ipf_lk)) {
 1055                 IPFERROR(10014);
 1056                 error = EINTR;
 1057         }
 1058 # else /* SOLARIS */
 1059         error = SLEEP(&softa->ipf_auth_next, "ipf_auth_next");
 1060 # endif /* SOLARIS */
 1061 #endif
 1062         MUTEX_EXIT(&softa->ipf_auth_mx);
 1063         if (error == 0)
 1064                 goto ipf_auth_ioctlloop;
 1065         return (error);
 1066 }
 1067 
 1068 
 1069 /* ------------------------------------------------------------------------ */
 1070 /* Function:    ipf_auth_reply                                              */
 1071 /* Returns:     int - 0 == success, else error                              */
 1072 /* Parameters:  data(I) - pointer to data from ioctl call                   */
 1073 /*                                                                          */
 1074 /* This function is called by an application when it wants to return a      */
 1075 /* decision on a packet using the SIOCAUTHR ioctl.  This is after it has    */
 1076 /* received information using an SIOCAUTHW.  The decision returned in the   */
 1077 /* form of flags, the same as those used in each rule.                      */
 1078 /* ------------------------------------------------------------------------ */
 1079 static int
 1080 ipf_auth_reply(ipf_main_softc_t *softc, ipf_auth_softc_t *softa, char *data)
 1081 {
 1082         frauth_t auth, *au = &auth, *fra;
 1083         fr_info_t fin;
 1084         int error, i;
 1085         mb_t *m;
 1086         SPL_INT(s);
 1087 
 1088         error = ipf_inobj(softc, data, NULL, &auth, IPFOBJ_FRAUTH);
 1089         if (error != 0)
 1090                 return (error);
 1091 
 1092         SPL_NET(s);
 1093         WRITE_ENTER(&softa->ipf_authlk);
 1094 
 1095         i = au->fra_index;
 1096         fra = softa->ipf_auth + i;
 1097         error = 0;
 1098 
 1099         /*
 1100          * Check the validity of the information being returned with two simple
 1101          * checks.  First, the auth index value should be within the size of
 1102          * the array and second the packet id being returned should also match.
 1103          */
 1104         if ((i < 0) || (i >= softa->ipf_auth_size)) {
 1105                 RWLOCK_EXIT(&softa->ipf_authlk);
 1106                 SPL_X(s);
 1107                 IPFERROR(10015);
 1108                 return (ESRCH);
 1109         }
 1110         if  (fra->fra_info.fin_id != au->fra_info.fin_id) {
 1111                 RWLOCK_EXIT(&softa->ipf_authlk);
 1112                 SPL_X(s);
 1113                 IPFERROR(10019);
 1114                 return (ESRCH);
 1115         }
 1116 
 1117         m = softa->ipf_auth_pkts[i];
 1118         fra->fra_index = -2;
 1119         fra->fra_pass = au->fra_pass;
 1120         softa->ipf_auth_pkts[i] = NULL;
 1121         softa->ipf_auth_replies++;
 1122         bcopy(&fra->fra_info, &fin, sizeof(fin));
 1123 
 1124         RWLOCK_EXIT(&softa->ipf_authlk);
 1125 
 1126         /*
 1127          * Re-insert the packet back into the packet stream flowing through
 1128          * the kernel in a manner that will mean IPFilter sees the packet
 1129          * again.  This is not the same as is done with fastroute,
 1130          * deliberately, as we want to resume the normal packet processing
 1131          * path for it.
 1132          */
 1133 #ifdef  _KERNEL
 1134         if ((m != NULL) && (au->fra_info.fin_out != 0)) {
 1135                 error = ipf_inject(&fin, m);
 1136                 if (error != 0) {
 1137                         IPFERROR(10016);
 1138                         error = ENOBUFS;
 1139                         softa->ipf_auth_stats.fas_sendfail++;
 1140                 } else {
 1141                         softa->ipf_auth_stats.fas_sendok++;
 1142                 }
 1143         } else if (m) {
 1144                 error = ipf_inject(&fin, m);
 1145                 if (error != 0) {
 1146                         IPFERROR(10017);
 1147                         error = ENOBUFS;
 1148                         softa->ipf_auth_stats.fas_quefail++;
 1149                 } else {
 1150                         softa->ipf_auth_stats.fas_queok++;
 1151                 }
 1152         } else {
 1153                 IPFERROR(10018);
 1154                 error = EINVAL;
 1155         }
 1156 
 1157         /*
 1158          * If we experience an error which will result in the packet
 1159          * not being processed, make sure we advance to the next one.
 1160          */
 1161         if (error == ENOBUFS) {
 1162                 WRITE_ENTER(&softa->ipf_authlk);
 1163                 softa->ipf_auth_used--;
 1164                 fra->fra_index = -1;
 1165                 fra->fra_pass = 0;
 1166                 if (i == softa->ipf_auth_start) {
 1167                         while (fra->fra_index == -1) {
 1168                                 i++;
 1169                                 if (i == softa->ipf_auth_size)
 1170                                         i = 0;
 1171                                 softa->ipf_auth_start = i;
 1172                                 if (i == softa->ipf_auth_end)
 1173                                         break;
 1174                         }
 1175                         if (softa->ipf_auth_start == softa->ipf_auth_end) {
 1176                                 softa->ipf_auth_next = 0;
 1177                                 softa->ipf_auth_start = 0;
 1178                                 softa->ipf_auth_end = 0;
 1179                         }
 1180                 }
 1181                 RWLOCK_EXIT(&softa->ipf_authlk);
 1182         }
 1183 #endif /* _KERNEL */
 1184         SPL_X(s);
 1185 
 1186         return (0);
 1187 }
 1188 
 1189 
 1190 u_32_t
 1191 ipf_auth_pre_scanlist(ipf_main_softc_t *softc, fr_info_t *fin, u_32_t pass)
 1192 {
 1193         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
 1194 
 1195         if (softa->ipf_auth_ip != NULL)
 1196                 return (ipf_scanlist(fin, softc->ipf_pass));
 1197 
 1198         return (pass);
 1199 }
 1200 
 1201 
 1202 frentry_t **
 1203 ipf_auth_rulehead(ipf_main_softc_t *softc)
 1204 {
 1205         ipf_auth_softc_t *softa = softc->ipf_auth_soft;
 1206 
 1207         return (&softa->ipf_auth_ip);
 1208 }

Cache object: 21e90facd4e315ed6e80967f514834c1


[ 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.