]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/uipc_domain.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */
23 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
25 * Copyright (c) 1982, 1986, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * @(#)uipc_domain.c 8.3 (Berkeley) 2/14/95
59 #include <sys/param.h>
60 #include <sys/socket.h>
61 #include <sys/protosw.h>
62 #include <sys/domain.h>
65 #include <sys/kernel.h>
66 #include <sys/systm.h>
68 #include <sys/sysctl.h>
69 #include <sys/syslog.h>
70 #include <sys/queue.h>
72 void pffasttimo
__P((void *));
73 void pfslowtimo
__P((void *));
76 * Add/delete 'domain': Link structure into system list,
77 * invoke the domain init, and then the proto inits.
78 * To delete, just remove from the list (dom_refs must be zero)
82 void init_domain(register struct domain
*dp
)
89 /* and then init the currently installed protos in this domain */
91 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
92 if (pr
->pr_usrreqs
== 0)
93 panic("domaininit: %ssw[%d] has no usrreqs!",
95 (int)(pr
- dp
->dom_protosw
));
101 /* Recompute for new protocol */
102 if (max_linkhdr
< 16) /* XXX - Sheesh; everything's ether? */
104 if (dp
->dom_protohdrlen
> max_protohdr
)
105 max_protohdr
= dp
->dom_protohdrlen
;
106 max_hdr
= max_linkhdr
+ max_protohdr
;
107 max_datalen
= MHLEN
- max_hdr
;
110 void concat_domain(struct domain
*dp
)
112 dp
->dom_next
= domains
;
117 net_add_domain(register struct domain
*dp
)
118 { register struct protosw
*pr
;
120 extern int splhigh(void);
121 extern int splx(int);
123 kprintf("Adding domain %s (family %d)\n", dp
->dom_name
,
125 /* First, link in the domain */
136 net_del_domain(register struct domain
*dp
)
137 { register struct domain
*dp1
, *dp2
;
138 register int s
, retval
= 0;
139 extern int splhigh(void);
140 extern int splx(int);
147 for (dp2
= NULL
, dp1
= domains
; dp1
; dp2
= dp1
, dp1
= dp1
->dom_next
)
153 dp2
->dom_next
= dp1
->dom_next
;
155 domains
= dp1
->dom_next
;
157 retval
= EPFNOSUPPORT
;
164 * net_add_proto - link a protosw into a domain's protosw chain
167 net_add_proto(register struct protosw
*pp
,
168 register struct domain
*dp
)
169 { register struct protosw
*pp1
, *pp2
;
171 extern int splhigh(void);
172 extern int splx(int);
175 for (pp2
= NULL
, pp1
= dp
->dom_protosw
; pp1
; pp1
= pp1
->pr_next
)
176 { if (pp1
->pr_type
== pp
->pr_type
&&
177 pp1
->pr_protocol
== pp
->pr_protocol
) {
184 dp
->dom_protosw
= pp
;
188 TAILQ_INIT(&pp
->pr_sfilter
);
192 /* Make sure pr_init isn't called again!! */
199 * net_del_proto - remove a protosw from a domain's protosw chain.
200 * Search the protosw chain for the element with matching data.
201 * Then unlink and return.
204 net_del_proto(register int type
,
205 register int protocol
,
206 register struct domain
*dp
)
207 { register struct protosw
*pp1
, *pp2
;
209 extern int splhigh(void);
210 extern int splx(int);
213 for (pp2
= NULL
, pp1
= dp
->dom_protosw
; pp1
; pp1
= pp1
->pr_next
)
214 { if (pp1
->pr_type
== type
&&
215 pp1
->pr_protocol
== protocol
)
224 pp2
->pr_next
= pp1
->pr_next
;
226 dp
->dom_protosw
= pp1
->pr_next
;
234 { register struct domain
*dp
;
235 register struct protosw
*pr
;
236 extern struct domain localdomain
, routedomain
, ndrvdomain
, inetdomain
;
237 extern struct domain systemdomain
;
239 extern struct domain nsdomain
;
242 extern struct domain isodomain
;
245 extern struct domain ccittdomain
;
249 extern struct domain atalkdomain
;
252 extern struct domain inet6domain
;
255 extern struct domain keydomain
;
259 * Add all the static domains to the domains list
262 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
263 concat_domain(&localdomain
);
264 concat_domain(&routedomain
);
265 concat_domain(&inetdomain
);
267 concat_domain(&atalkdomain
);
270 concat_domain(&inet6domain
);
273 concat_domain(&keydomain
);
277 concat_domain(&nsdomain
);
280 concat_domain(&isodomain
);
283 concat_domain(&ccittdomain
);
285 concat_domain(&ndrvdomain
);
287 concat_domain(&systemdomain
);
290 * Now ask them all to init (XXX including the routing domain,
293 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
296 timeout(pffasttimo
, NULL
, 1);
297 timeout(pfslowtimo
, NULL
, 1);
298 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
302 pffindtype(family
, type
)
305 register struct domain
*dp
;
306 register struct protosw
*pr
;
308 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
309 if (dp
->dom_family
== family
)
313 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
314 if (pr
->pr_type
&& pr
->pr_type
== type
)
325 { if (dp
->dom_family
== pf
)
333 pffindproto(family
, protocol
, type
)
334 int family
, protocol
, type
;
336 register struct domain
*dp
;
337 register struct protosw
*pr
;
338 struct protosw
*maybe
= 0;
342 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
343 if (dp
->dom_family
== family
)
347 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
348 if ((pr
->pr_protocol
== protocol
) && (pr
->pr_type
== type
))
351 if (type
== SOCK_RAW
&& pr
->pr_type
== SOCK_RAW
&&
352 pr
->pr_protocol
== 0 && maybe
== (struct protosw
*)0)
359 net_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
368 register struct domain
*dp
;
369 register struct protosw
*pr
;
370 int family
, protocol
;
373 * All sysctl names at this level are nonterminal;
374 * next two components are protocol family and protocol number,
375 * then at least one addition component.
378 return (EISDIR
); /* overloaded */
384 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
385 if (dp
->dom_family
== family
)
387 return (ENOPROTOOPT
);
389 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
390 if (pr
->pr_protocol
== protocol
&& pr
->pr_sysctl
)
391 return ((*pr
->pr_sysctl
)(name
+ 2, namelen
- 2,
392 oldp
, oldlenp
, newp
, newlen
));
393 return (ENOPROTOOPT
);
401 register struct domain
*dp
;
402 register struct protosw
*pr
;
404 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
405 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
407 (*pr
->pr_ctlinput
)(cmd
, sa
, (caddr_t
)0);
414 register struct domain
*dp
;
415 register struct protosw
*pr
;
416 boolean_t funnel_state
;
418 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
420 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
421 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
423 (*pr
->pr_slowtimo
)();
424 timeout(pfslowtimo
, NULL
, hz
/2);
426 (void) thread_funnel_set(network_flock
, FALSE
);
433 register struct domain
*dp
;
434 register struct protosw
*pr
;
435 boolean_t funnel_state
;
437 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
439 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
440 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
442 (*pr
->pr_fasttimo
)();
443 timeout(pffasttimo
, NULL
, hz
/5);
445 (void) thread_funnel_set(network_flock
, FALSE
);