]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/bsd_tcpip/v2_0/src/sys/kern/uipc_domain.c
Initial revision
[karo-tx-redboot.git] / packages / net / bsd_tcpip / v2_0 / src / sys / kern / uipc_domain.c
1 //==========================================================================
2 //
3 //      src/sys/kern/uipc_domain.c
4 //
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
7 //
8 // -------------------------------------------
9 //
10 // Portions of this software may have been derived from OpenBSD, 
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
13 //
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
16 //
17 // -------------------------------------------
18 //
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
21
22 /*
23  * Copyright (c) 1982, 1986, 1993
24  *      The Regents of the University of California.  All rights reserved.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions
28  * are met:
29  * 1. Redistributions of source code must retain the above copyright
30  *    notice, this list of conditions and the following disclaimer.
31  * 2. Redistributions in binary form must reproduce the above copyright
32  *    notice, this list of conditions and the following disclaimer in the
33  *    documentation and/or other materials provided with the distribution.
34  * 3. All advertising materials mentioning features or use of this software
35  *    must display the following acknowledgement:
36  *      This product includes software developed by the University of
37  *      California, Berkeley and its contributors.
38  * 4. Neither the name of the University nor the names of its contributors
39  *    may be used to endorse or promote products derived from this software
40  *    without specific prior written permission.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  *
54  *      @(#)uipc_domain.c       8.2 (Berkeley) 10/18/93
55  * $FreeBSD: src/sys/kern/uipc_domain.c,v 1.22.2.1 2001/07/03 11:01:37 ume Exp $
56  */
57
58 #include <sys/param.h>
59 #include <sys/socket.h>
60 #include <sys/protosw.h>
61 #include <sys/domain.h>
62 #include <sys/mbuf.h>
63 #include <sys/socketvar.h>
64
65 /*
66  * System initialization
67  *
68  * Note: domain initialization wants to take place on a per domain basis
69  * as a result of traversing a linker set.  Most likely, each domain
70  * want to call a registration function rather than being handled here
71  * in domaininit().  Probably this will look like:
72  *
73  * SYSINIT(unique, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, domain_add, xxx)
74  *
75  * Where 'xxx' is replaced by the address of a parameter struct to be
76  * passed to the doamin_add() function.
77  */
78
79 static void domaininit __P((void *));
80 SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL)
81
82 static void     pffasttimo __P((void *));
83 static void     pfslowtimo __P((void *));
84
85 struct domain *domains;
86
87 /*
88  * Add a new protocol domain to the list of supported domains
89  * Note: you cant unload it again because  a socket may be using it.
90  * XXX can't fail at this time.
91  */
92 static void
93 net_init_domain(struct domain *dp)
94 {
95         register struct protosw *pr;
96         int     s;
97
98         s = splnet();
99         log(LOG_INIT, "New domain %s at %p\n", dp->dom_name, dp->dom_init);
100         if (dp->dom_init)
101                 (*dp->dom_init)();
102         for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){
103                 if (pr->pr_usrreqs == 0)
104                         panic("domaininit: %ssw[%d] has no usrreqs!",
105                               dp->dom_name, 
106                               (int)(pr - dp->dom_protosw));
107                 if (pr->pr_init)
108                         (*pr->pr_init)();
109         }
110         /*
111          * update global informatio about maximums
112          */
113         max_hdr = max_linkhdr + max_protohdr;
114         max_datalen = MHLEN - max_hdr;
115         splx(s);
116 }
117
118 /*
119  * Add a new protocol domain to the list of supported domains
120  * Note: you cant unload it again because  a socket may be using it.
121  * XXX can't fail at this time.
122  */
123 void
124 net_add_domain(void *data)
125 {
126         int     s;
127         struct domain *dp;
128
129         dp = (struct domain *)data;
130         s = splnet();
131         dp->dom_next = domains;
132         domains = dp;
133         splx(s);
134         net_init_domain(dp);
135 }
136
137 /* ARGSUSED*/
138 static void
139 domaininit(void *dummy)
140 {
141         /*
142          * Before we do any setup, make sure to initialize the
143          * zone allocator we get struct sockets from.  The obvious
144          * maximum number of sockets is `maxfiles', but it is possible
145          * to have a socket without an open file (e.g., a connection waiting
146          * to be accept(2)ed).  Rather than think up and define a
147          * better value, we just use nmbclusters, since that's what people
148          * are told to increase first when the network runs out of memory.
149          * Perhaps we should have two pools, one of unlimited size
150          * for use during socreate(), and one ZONE_INTERRUPT pool for
151          * use in sonewconn().
152          */
153         socket_zone = zinit("socket", sizeof(struct socket), maxsockets,
154                             ZONE_INTERRUPT, 0);
155
156         if (max_linkhdr < 16)           /* XXX */
157                 max_linkhdr = 16;
158
159         timeout(pffasttimo, (void *)0, 1);
160         timeout(pfslowtimo, (void *)0, 1);
161 }
162
163
164 struct protosw *
165 pffindtype(family, type)
166         int family;
167         int type;
168 {
169         register struct domain *dp;
170         register struct protosw *pr;
171
172         for (dp = domains; dp; dp = dp->dom_next)
173                 if (dp->dom_family == family)
174                         goto found;
175         return (0);
176 found:
177         for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
178                 if (pr->pr_type && pr->pr_type == type)
179                         return (pr);
180         return (0);
181 }
182
183 struct protosw *
184 pffindproto(family, protocol, type)
185         int family;
186         int protocol;
187         int type;
188 {
189         register struct domain *dp;
190         register struct protosw *pr;
191         struct protosw *maybe = 0;
192
193         if (family == 0)
194                 return (0);
195         for (dp = domains; dp; dp = dp->dom_next)
196                 if (dp->dom_family == family)
197                         goto found;
198         return (0);
199 found:
200         for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
201                 if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
202                         return (pr);
203
204                 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
205                     pr->pr_protocol == 0 && maybe == (struct protosw *)0)
206                         maybe = pr;
207         }
208         return (maybe);
209 }
210
211 void
212 pfctlinput(cmd, sa)
213         int cmd;
214         struct sockaddr *sa;
215 {
216         register struct domain *dp;
217         register struct protosw *pr;
218
219         for (dp = domains; dp; dp = dp->dom_next)
220                 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
221                         if (pr->pr_ctlinput)
222                                 (*pr->pr_ctlinput)(cmd, sa, (void *)0);
223 }
224
225 void
226 pfctlinput2(cmd, sa, ctlparam)
227         int cmd;
228         struct sockaddr *sa;
229         void *ctlparam;
230 {
231         struct domain *dp;
232         struct protosw *pr;
233
234         if (!sa)
235                 return;
236         for (dp = domains; dp; dp = dp->dom_next) {
237                 /*
238                  * the check must be made by xx_ctlinput() anyways, to
239                  * make sure we use data item pointed to by ctlparam in
240                  * correct way.  the following check is made just for safety.
241                  */
242                 if (dp->dom_family != sa->sa_family)
243                         continue;
244
245                 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
246                         if (pr->pr_ctlinput)
247                                 (*pr->pr_ctlinput)(cmd, sa, ctlparam);
248         }
249 }
250
251 static void
252 pfslowtimo(arg)
253         void *arg;
254 {
255         register struct domain *dp;
256         register struct protosw *pr;
257
258         for (dp = domains; dp; dp = dp->dom_next)
259                 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
260                         if (pr->pr_slowtimo)
261                                 (*pr->pr_slowtimo)();
262         timeout(pfslowtimo, (void *)0, hz/2);
263 }
264
265 static void
266 pffasttimo(arg)
267         void *arg;
268 {
269         register struct domain *dp;
270         register struct protosw *pr;
271
272         for (dp = domains; dp; dp = dp->dom_next)
273                 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
274                         if (pr->pr_fasttimo)
275                                 (*pr->pr_fasttimo)();
276         timeout(pffasttimo, (void *)0, hz/5);
277 }