]>
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 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
25 /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */
26 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
28 * Copyright (c) 1982, 1986, 1993
29 * The Regents of the University of California. All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
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.
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
59 * @(#)uipc_domain.c 8.3 (Berkeley) 2/14/95
62 #include <sys/param.h>
63 #include <sys/socket.h>
64 #include <sys/protosw.h>
65 #include <sys/domain.h>
68 #include <sys/kernel.h>
69 #include <sys/systm.h>
71 #include <sys/sysctl.h>
72 #include <sys/syslog.h>
73 #include <sys/queue.h>
75 void pffasttimo
__P((void *));
76 void pfslowtimo
__P((void *));
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)
85 void init_domain(register struct domain
*dp
)
92 /* and then init the currently installed protos in this domain */
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!",
98 (int)(pr
- dp
->dom_protosw
));
104 /* Recompute for new protocol */
105 if (max_linkhdr
< 16) /* XXX - Sheesh; everything's ether? */
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
;
113 void concat_domain(struct domain
*dp
)
115 dp
->dom_next
= domains
;
120 net_add_domain(register struct domain
*dp
)
121 { register struct protosw
*pr
;
123 extern int splhigh(void);
124 extern int splx(int);
126 kprintf("Adding domain %s (family %d)\n", dp
->dom_name
,
128 /* First, link in the domain */
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);
150 for (dp2
= NULL
, dp1
= domains
; dp1
; dp2
= dp1
, dp1
= dp1
->dom_next
)
156 dp2
->dom_next
= dp1
->dom_next
;
158 domains
= dp1
->dom_next
;
160 retval
= EPFNOSUPPORT
;
167 * net_add_proto - link a protosw into a domain's protosw chain
170 net_add_proto(register struct protosw
*pp
,
171 register struct domain
*dp
)
172 { register struct protosw
*pp1
, *pp2
;
174 extern int splhigh(void);
175 extern int splx(int);
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
) {
187 dp
->dom_protosw
= pp
;
191 TAILQ_INIT(&pp
->pr_sfilter
);
195 /* Make sure pr_init isn't called again!! */
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.
207 net_del_proto(register int type
,
208 register int protocol
,
209 register struct domain
*dp
)
210 { register struct protosw
*pp1
, *pp2
;
212 extern int splhigh(void);
213 extern int splx(int);
216 for (pp2
= NULL
, pp1
= dp
->dom_protosw
; pp1
; pp1
= pp1
->pr_next
)
217 { if (pp1
->pr_type
== type
&&
218 pp1
->pr_protocol
== protocol
)
227 pp2
->pr_next
= pp1
->pr_next
;
229 dp
->dom_protosw
= pp1
->pr_next
;
237 { register struct domain
*dp
;
238 register struct protosw
*pr
;
239 extern struct domain localdomain
, routedomain
, ndrvdomain
, inetdomain
;
240 extern struct domain systemdomain
;
242 extern struct domain nsdomain
;
245 extern struct domain isodomain
;
248 extern struct domain ccittdomain
;
252 extern struct domain atalkdomain
;
255 extern struct domain inet6domain
;
258 extern struct domain keydomain
;
262 * Add all the static domains to the domains list
265 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
266 concat_domain(&localdomain
);
267 concat_domain(&routedomain
);
268 concat_domain(&inetdomain
);
270 concat_domain(&atalkdomain
);
273 concat_domain(&inet6domain
);
276 concat_domain(&keydomain
);
280 concat_domain(&nsdomain
);
283 concat_domain(&isodomain
);
286 concat_domain(&ccittdomain
);
288 concat_domain(&ndrvdomain
);
290 concat_domain(&systemdomain
);
293 * Now ask them all to init (XXX including the routing domain,
296 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
299 timeout(pffasttimo
, NULL
, 1);
300 timeout(pfslowtimo
, NULL
, 1);
301 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
305 pffindtype(family
, type
)
308 register struct domain
*dp
;
309 register struct protosw
*pr
;
311 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
312 if (dp
->dom_family
== family
)
316 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
317 if (pr
->pr_type
&& pr
->pr_type
== type
)
328 { if (dp
->dom_family
== pf
)
336 pffindproto(family
, protocol
, type
)
337 int family
, protocol
, type
;
339 register struct domain
*dp
;
340 register struct protosw
*pr
;
341 struct protosw
*maybe
= 0;
345 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
346 if (dp
->dom_family
== family
)
350 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
351 if ((pr
->pr_protocol
== protocol
) && (pr
->pr_type
== type
))
354 if (type
== SOCK_RAW
&& pr
->pr_type
== SOCK_RAW
&&
355 pr
->pr_protocol
== 0 && maybe
== (struct protosw
*)0)
362 net_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
371 register struct domain
*dp
;
372 register struct protosw
*pr
;
373 int family
, protocol
;
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.
381 return (EISDIR
); /* overloaded */
387 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
388 if (dp
->dom_family
== family
)
390 return (ENOPROTOOPT
);
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
);
404 pfctlinput2(cmd
, sa
, (void*)0);
408 pfctlinput2(cmd
, sa
, ctlparam
)
418 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
419 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
421 (*pr
->pr_ctlinput
)(cmd
, sa
, ctlparam
);
428 register struct domain
*dp
;
429 register struct protosw
*pr
;
430 boolean_t funnel_state
;
432 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
434 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
435 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
437 (*pr
->pr_slowtimo
)();
438 timeout(pfslowtimo
, NULL
, hz
/2);
440 (void) thread_funnel_set(network_flock
, FALSE
);
447 register struct domain
*dp
;
448 register struct protosw
*pr
;
449 boolean_t funnel_state
;
451 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
453 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
454 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
456 (*pr
->pr_fasttimo
)();
457 timeout(pffasttimo
, NULL
, hz
/5);
459 (void) thread_funnel_set(network_flock
, FALSE
);