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/bsd/kern/uipc_domain.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 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */
   26 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
   27 /*
   28  * Copyright (c) 1982, 1986, 1993
   29  *      The Regents of the University of California.  All rights reserved.
   30  *
   31  * Redistribution and use in source and binary forms, with or without
   32  * modification, are permitted provided that the following conditions
   33  * are met:
   34  * 1. Redistributions of source code must retain the above copyright
   35  *    notice, this list of conditions and the following disclaimer.
   36  * 2. Redistributions in binary form must reproduce the above copyright
   37  *    notice, this list of conditions and the following disclaimer in the
   38  *    documentation and/or other materials provided with the distribution.
   39  * 3. All advertising materials mentioning features or use of this software
   40  *    must display the following acknowledgement:
   41  *      This product includes software developed by the University of
   42  *      California, Berkeley and its contributors.
   43  * 4. Neither the name of the University nor the names of its contributors
   44  *    may be used to endorse or promote products derived from this software
   45  *    without specific prior written permission.
   46  *
   47  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   48  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   50  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   51  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   55  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   56  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   57  * SUCH DAMAGE.
   58  *
   59  *      @(#)uipc_domain.c       8.3 (Berkeley) 2/14/95
   60  */
   61 
   62 #include <sys/param.h>
   63 #include <sys/socket.h>
   64 #include <sys/protosw.h>
   65 #include <sys/domain.h>
   66 #include <sys/mbuf.h>
   67 #include <sys/time.h>
   68 #include <sys/kernel.h>
   69 #include <sys/systm.h>
   70 #include <sys/proc.h>
   71 #include <sys/sysctl.h>
   72 #include <sys/syslog.h>
   73 #include <sys/queue.h>
   74 
   75 void    pffasttimo __P((void *));
   76 void    pfslowtimo __P((void *));
   77 
   78 /*
   79  * Add/delete 'domain': Link structure into system list,
   80  *  invoke the domain init, and then the proto inits.
   81  * To delete, just remove from the list (dom_refs must be zero)
   82  */
   83 
   84 
   85 void init_domain(register struct domain *dp)
   86 {
   87         struct protosw  *pr;
   88         
   89         if (dp->dom_init)
   90                 (*dp->dom_init)();
   91 
   92         /* and then init the currently installed protos in this domain */
   93 
   94         for (pr = dp->dom_protosw; pr; pr = pr->pr_next) {
   95                 if (pr->pr_usrreqs == 0)
   96                         panic("domaininit: %ssw[%d] has no usrreqs!",
   97                               dp->dom_name, 
   98                               (int)(pr - dp->dom_protosw));
   99 
  100                 if (pr->pr_init)
  101                         (*pr->pr_init)();
  102         }
  103 
  104         /* Recompute for new protocol */
  105         if (max_linkhdr < 16)           /* XXX - Sheesh; everything's ether? */
  106                 max_linkhdr = 16;
  107         if (dp->dom_protohdrlen > max_protohdr)
  108                 max_protohdr = dp->dom_protohdrlen;
  109         max_hdr = max_linkhdr + max_protohdr;
  110         max_datalen = MHLEN - max_hdr;
  111 }
  112 
  113 void    concat_domain(struct domain *dp) 
  114 {
  115         dp->dom_next = domains; 
  116         domains = dp; 
  117 }
  118 
  119 void
  120 net_add_domain(register struct domain *dp)
  121 {       register struct protosw *pr;
  122         register int s;
  123         extern int splhigh(void);
  124         extern int splx(int);
  125 
  126         kprintf("Adding domain %s (family %d)\n", dp->dom_name,
  127                 dp->dom_family);
  128         /* First, link in the domain */
  129         s = splhigh();
  130 
  131         concat_domain(dp);
  132 
  133         init_domain(dp);
  134 
  135         splx(s);
  136 }
  137 
  138 int
  139 net_del_domain(register struct domain *dp)
  140 {       register struct domain *dp1, *dp2;
  141         register int s, retval = 0;
  142         extern int splhigh(void);
  143         extern int splx(int);
  144  
  145         if (dp->dom_refs)
  146                 return(EBUSY);
  147 
  148         s = splhigh();
  149 
  150         for (dp2 = NULL, dp1 = domains; dp1; dp2 = dp1, dp1 = dp1->dom_next)
  151         {       if (dp == dp1)
  152                         break;
  153         }
  154         if (dp1)
  155         {       if (dp2)
  156                         dp2->dom_next = dp1->dom_next;
  157                 else
  158                         domains = dp1->dom_next;
  159         } else
  160                 retval = EPFNOSUPPORT;
  161         splx(s);
  162 
  163         return(retval);
  164 }
  165 
  166 /*
  167  * net_add_proto - link a protosw into a domain's protosw chain
  168  */
  169 int
  170 net_add_proto(register struct protosw *pp,
  171               register struct domain *dp)
  172 {       register struct protosw *pp1, *pp2;
  173         register int s;
  174         extern int splhigh(void);
  175         extern int splx(int);
  176 
  177         s = splhigh();
  178         for (pp2 = NULL, pp1 = dp->dom_protosw; pp1; pp1 = pp1->pr_next)
  179         {       if (pp1->pr_type == pp->pr_type &&
  180                     pp1->pr_protocol == pp->pr_protocol) {
  181                         splx(s);
  182                         return(EEXIST);
  183                 }
  184                 pp2 = pp1;
  185         }
  186         if (pp2 == NULL)
  187                 dp->dom_protosw = pp;
  188         else
  189                 pp2->pr_next = pp;
  190         pp->pr_next = NULL;
  191         TAILQ_INIT(&pp->pr_sfilter);
  192         if (pp->pr_init)
  193                 (*pp->pr_init)();
  194 
  195         /* Make sure pr_init isn't called again!! */
  196         pp->pr_init = 0;
  197         splx(s);
  198         return(0);
  199 }
  200 
  201 /*
  202  * net_del_proto - remove a protosw from a domain's protosw chain.
  203  * Search the protosw chain for the element with matching data.
  204  * Then unlink and return.
  205  */
  206 int
  207 net_del_proto(register int type,
  208               register int protocol,
  209               register struct domain *dp)
  210 {       register struct protosw *pp1, *pp2;
  211         int s;
  212         extern int splhigh(void);
  213         extern int splx(int);
  214 
  215         s = splhigh();
  216         for (pp2 = NULL, pp1 = dp->dom_protosw; pp1; pp1 = pp1->pr_next)
  217         {       if (pp1->pr_type == type &&
  218                     pp1->pr_protocol == protocol)
  219                         break;
  220                 pp2 = pp1;
  221         }
  222         if (pp1 == NULL) {
  223                         splx(s);
  224                         return(ENXIO);
  225                 }
  226         if (pp2)
  227                 pp2->pr_next = pp1->pr_next;
  228         else
  229                 dp->dom_protosw = pp1->pr_next;
  230         splx(s);
  231         return(0);
  232 }
  233 
  234 
  235 void
  236 domaininit()
  237 {       register struct domain *dp;
  238         register struct protosw *pr;
  239         extern struct domain localdomain, routedomain, ndrvdomain, inetdomain;
  240         extern struct domain systemdomain;
  241 #if NS
  242         extern struct domain nsdomain;
  243 #endif
  244 #if ISO
  245         extern struct domain isodomain;
  246 #endif
  247 #if CCITT
  248         extern struct domain ccittdomain;
  249 #endif
  250 
  251 #if NETAT
  252         extern struct domain atalkdomain;
  253 #endif
  254 #if INET6
  255         extern struct domain inet6domain;
  256 #endif
  257 #if IPSEC
  258         extern struct domain keydomain;
  259 #endif
  260 
  261         /*
  262          * Add all the static domains to the domains list
  263          */
  264 
  265         thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
  266         concat_domain(&localdomain);
  267         concat_domain(&routedomain);
  268         concat_domain(&inetdomain);
  269 #if NETAT
  270         concat_domain(&atalkdomain);
  271 #endif
  272 #if INET6
  273         concat_domain(&inet6domain);
  274 #endif
  275 #if IPSEC
  276         concat_domain(&keydomain);
  277 #endif
  278 
  279 #if NS
  280         concat_domain(&nsdomain);
  281 #endif
  282 #if ISO
  283         concat_domain(&isodomain);
  284 #endif
  285 #if CCITT
  286         concat_domain(&ccittdomain);
  287 #endif
  288         concat_domain(&ndrvdomain);
  289 
  290         concat_domain(&systemdomain);
  291 
  292         /*
  293          * Now ask them all to init (XXX including the routing domain,
  294          * see above)
  295          */
  296         for (dp = domains; dp; dp = dp->dom_next)
  297                 init_domain(dp);
  298 
  299         timeout(pffasttimo, NULL, 1);
  300         timeout(pfslowtimo, NULL, 1);
  301         thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
  302 }
  303 
  304 struct protosw *
  305 pffindtype(family, type)
  306         int family, type;
  307 {
  308         register struct domain *dp;
  309         register struct protosw *pr;
  310 
  311         for (dp = domains; dp; dp = dp->dom_next)
  312                 if (dp->dom_family == family)
  313                         goto found;
  314         return (0);
  315 found:
  316         for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
  317                 if (pr->pr_type && pr->pr_type == type)
  318                         return (pr);
  319         return (0);
  320 }
  321 
  322 struct domain *
  323 pffinddomain(int pf)
  324 {       struct domain *dp;
  325 
  326         dp = domains;
  327         while (dp)
  328         {       if (dp->dom_family == pf)
  329                         return(dp);
  330                 dp = dp->dom_next;
  331         }
  332         return(NULL);
  333 }
  334 
  335 struct protosw *
  336 pffindproto(family, protocol, type)
  337         int family, protocol, type;
  338 {
  339         register struct domain *dp;
  340         register struct protosw *pr;
  341         struct protosw *maybe = 0;
  342 
  343         if (family == 0)
  344                 return (0);
  345         for (dp = domains; dp; dp = dp->dom_next)
  346                 if (dp->dom_family == family)
  347                         goto found;
  348         return (0);
  349 found:
  350         for (pr = dp->dom_protosw; pr; pr = pr->pr_next) {
  351                 if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
  352                         return (pr);
  353 
  354                 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
  355                     pr->pr_protocol == 0 && maybe == (struct protosw *)0)
  356                         maybe = pr;
  357         }
  358         return (maybe);
  359 }
  360 
  361 int
  362 net_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
  363         int *name;
  364         u_int namelen;
  365         void *oldp;
  366         size_t *oldlenp;
  367         void *newp;
  368         size_t newlen;
  369         struct proc *p;
  370 {
  371         register struct domain *dp;
  372         register struct protosw *pr;
  373         int family, protocol;
  374 
  375         /*
  376          * All sysctl names at this level are nonterminal;
  377          * next two components are protocol family and protocol number,
  378          * then at least one addition component.
  379          */
  380         if (namelen < 3)
  381                 return (EISDIR);                /* overloaded */
  382         family = name[0];
  383         protocol = name[1];
  384 
  385         if (family == 0)
  386                 return (0);
  387         for (dp = domains; dp; dp = dp->dom_next)
  388                 if (dp->dom_family == family)
  389                         goto found;
  390         return (ENOPROTOOPT);
  391 found:
  392         for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
  393                 if (pr->pr_protocol == protocol && pr->pr_sysctl)
  394                         return ((*pr->pr_sysctl)(name + 2, namelen - 2,
  395                             oldp, oldlenp, newp, newlen));
  396         return (ENOPROTOOPT);
  397 }
  398 
  399 void
  400 pfctlinput(cmd, sa)
  401         int cmd;
  402         struct sockaddr *sa;
  403 {
  404         pfctlinput2(cmd, sa, (void*)0);
  405 }
  406 
  407 void
  408 pfctlinput2(cmd, sa, ctlparam)
  409         int cmd;
  410         struct sockaddr *sa;
  411         void *ctlparam;
  412 {
  413         struct domain *dp;
  414         struct protosw *pr;
  415 
  416         if (!sa)
  417                 return;
  418         for (dp = domains; dp; dp = dp->dom_next)
  419                 for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
  420                         if (pr->pr_ctlinput)
  421                                 (*pr->pr_ctlinput)(cmd, sa, ctlparam);
  422 }
  423 
  424 void
  425 pfslowtimo(arg)
  426         void *arg;
  427 {
  428         register struct domain *dp;
  429         register struct protosw *pr;
  430         boolean_t       funnel_state;
  431 
  432         funnel_state = thread_funnel_set(network_flock, TRUE);
  433 
  434         for (dp = domains; dp; dp = dp->dom_next)
  435                 for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
  436                         if (pr->pr_slowtimo)
  437                                 (*pr->pr_slowtimo)();
  438         timeout(pfslowtimo, NULL, hz/2);
  439         
  440         (void) thread_funnel_set(network_flock, FALSE);
  441 }
  442 
  443 void
  444 pffasttimo(arg)
  445         void *arg;
  446 {
  447         register struct domain *dp;
  448         register struct protosw *pr;
  449         boolean_t       funnel_state;
  450 
  451         funnel_state = thread_funnel_set(network_flock, TRUE);
  452 
  453         for (dp = domains; dp; dp = dp->dom_next)
  454                 for (pr = dp->dom_protosw; pr; pr = pr->pr_next)
  455                         if (pr->pr_fasttimo)
  456                                 (*pr->pr_fasttimo)();
  457         timeout(pffasttimo, NULL, hz/5);
  458 
  459         (void) thread_funnel_set(network_flock, FALSE);
  460 }

Cache object: 2105083babed6824615b4a9ff4d490f5


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