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