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>
67 #include <sys/proc_internal.h>
68 #include <sys/sysctl.h>
69 #include <sys/syslog.h>
70 #include <sys/queue.h>
72 void pffasttimo(void *);
73 void pfslowtimo(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)
81 lck_grp_t
*domain_proto_mtx_grp
;
82 lck_attr_t
*domain_proto_mtx_attr
;
83 static lck_grp_attr_t
*domain_proto_mtx_grp_attr
;
84 lck_mtx_t
*domain_proto_mtx
;
85 extern int do_reclaim
;
87 void init_domain(register struct domain
*dp
)
91 if ((dp
->dom_mtx
= lck_mtx_alloc_init(domain_proto_mtx_grp
, domain_proto_mtx_attr
)) == NULL
) {
92 printf("init_domain: can't init domain mtx for domain=%s\n", dp
->dom_name
);
93 return; /* we have a problem... */
99 /* and then init the currently installed protos in this domain */
101 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
102 if (pr
->pr_usrreqs
== 0)
103 panic("domaininit: %ssw[%d] has no usrreqs!",
105 (int)(pr
- dp
->dom_protosw
));
111 /* Recompute for new protocol */
112 if (max_linkhdr
< 16) /* XXX - Sheesh; everything's ether? */
114 if (dp
->dom_protohdrlen
> max_protohdr
)
115 max_protohdr
= dp
->dom_protohdrlen
;
116 max_hdr
= max_linkhdr
+ max_protohdr
;
117 max_datalen
= MHLEN
- max_hdr
;
120 void concat_domain(struct domain
*dp
)
122 lck_mtx_assert(domain_proto_mtx
, LCK_MTX_ASSERT_OWNED
);
123 dp
->dom_next
= domains
;
128 net_add_domain(register struct domain
*dp
)
129 { register struct protosw
*pr
;
131 kprintf("Adding domain %s (family %d)\n", dp
->dom_name
,
133 /* First, link in the domain */
135 lck_mtx_lock(domain_proto_mtx
);
139 lck_mtx_unlock(domain_proto_mtx
);
144 net_del_domain(register struct domain
*dp
)
145 { register struct domain
*dp1
, *dp2
;
146 register int retval
= 0;
148 lck_mtx_lock(domain_proto_mtx
);
151 lck_mtx_unlock(domain_proto_mtx
);
155 for (dp2
= NULL
, dp1
= domains
; dp1
; dp2
= dp1
, dp1
= dp1
->dom_next
)
161 dp2
->dom_next
= dp1
->dom_next
;
163 domains
= dp1
->dom_next
;
165 retval
= EPFNOSUPPORT
;
166 lck_mtx_unlock(domain_proto_mtx
);
172 * net_add_proto - link a protosw into a domain's protosw chain
174 * note: protocols must use their own domain lock before calling net_add_proto
177 net_add_proto(register struct protosw
*pp
,
178 register struct domain
*dp
)
179 { register struct protosw
*pp1
, *pp2
;
181 for (pp2
= NULL
, pp1
= dp
->dom_protosw
; pp1
; pp1
= pp1
->pr_next
)
182 { if (pp1
->pr_type
== pp
->pr_type
&&
183 pp1
->pr_protocol
== pp
->pr_protocol
) {
189 dp
->dom_protosw
= pp
;
193 TAILQ_INIT(&pp
->pr_filter_head
);
197 /* Make sure pr_init isn't called again!! */
203 * net_del_proto - remove a protosw from a domain's protosw chain.
204 * Search the protosw chain for the element with matching data.
205 * Then unlink and return.
207 * note: protocols must use their own domain lock before calling net_del_proto
210 net_del_proto(register int type
,
211 register int protocol
,
212 register struct domain
*dp
)
213 { register struct protosw
*pp1
, *pp2
;
215 for (pp2
= NULL
, pp1
= dp
->dom_protosw
; pp1
; pp1
= pp1
->pr_next
)
216 { if (pp1
->pr_type
== type
&&
217 pp1
->pr_protocol
== protocol
)
225 pp2
->pr_next
= pp1
->pr_next
;
227 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 * allocate lock group attribute and group for domain mutexes
261 domain_proto_mtx_grp_attr
= lck_grp_attr_alloc_init();
263 domain_proto_mtx_grp
= lck_grp_alloc_init("domain", domain_proto_mtx_grp_attr
);
266 * allocate the lock attribute for per domain mutexes
268 domain_proto_mtx_attr
= lck_attr_alloc_init();
270 if ((domain_proto_mtx
= lck_mtx_alloc_init(domain_proto_mtx_grp
, domain_proto_mtx_attr
)) == NULL
) {
271 printf("domaininit: can't init domain mtx for domain list\n");
272 return; /* we have a problem... */
275 * Add all the static domains to the domains list
278 lck_mtx_lock(domain_proto_mtx
);
280 concat_domain(&localdomain
);
281 concat_domain(&routedomain
);
282 concat_domain(&inetdomain
);
284 concat_domain(&atalkdomain
);
287 concat_domain(&inet6domain
);
290 concat_domain(&keydomain
);
294 concat_domain(&nsdomain
);
297 concat_domain(&isodomain
);
300 concat_domain(&ccittdomain
);
302 concat_domain(&ndrvdomain
);
304 concat_domain(&systemdomain
);
307 * Now ask them all to init (XXX including the routing domain,
310 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
313 lck_mtx_unlock(domain_proto_mtx
);
314 timeout(pffasttimo
, NULL
, 1);
315 timeout(pfslowtimo
, NULL
, 1);
319 pffindtype(family
, type
)
322 register struct domain
*dp
;
323 register struct protosw
*pr
;
325 lck_mtx_assert(domain_proto_mtx
, LCK_MTX_ASSERT_NOTOWNED
);
326 lck_mtx_lock(domain_proto_mtx
);
327 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
328 if (dp
->dom_family
== family
)
330 lck_mtx_unlock(domain_proto_mtx
);
333 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
334 if (pr
->pr_type
&& pr
->pr_type
== type
) {
335 lck_mtx_unlock(domain_proto_mtx
);
338 lck_mtx_unlock(domain_proto_mtx
);
346 lck_mtx_assert(domain_proto_mtx
, LCK_MTX_ASSERT_NOTOWNED
);
347 lck_mtx_lock(domain_proto_mtx
);
350 { if (dp
->dom_family
== pf
) {
351 lck_mtx_unlock(domain_proto_mtx
);
356 lck_mtx_unlock(domain_proto_mtx
);
361 pffindproto(family
, protocol
, type
)
362 int family
, protocol
, type
;
364 register struct protosw
*pr
;
365 lck_mtx_assert(domain_proto_mtx
, LCK_MTX_ASSERT_NOTOWNED
);
366 lck_mtx_lock(domain_proto_mtx
);
367 pr
= pffindproto_locked(family
, protocol
, type
);
368 lck_mtx_unlock(domain_proto_mtx
);
373 pffindproto_locked(family
, protocol
, type
)
374 int family
, protocol
, type
;
376 register struct domain
*dp
;
377 register struct protosw
*pr
;
378 struct protosw
*maybe
= 0;
382 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
383 if (dp
->dom_family
== family
)
387 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
388 if ((pr
->pr_protocol
== protocol
) && (pr
->pr_type
== type
))
391 if (type
== SOCK_RAW
&& pr
->pr_type
== SOCK_RAW
&&
392 pr
->pr_protocol
== 0 && maybe
== (struct protosw
*)0)
399 net_sysctl(int *name
, u_int namelen
, user_addr_t oldp
, size_t *oldlenp
,
400 user_addr_t newp
, size_t newlen
, struct proc
*p
)
402 register struct domain
*dp
;
403 register struct protosw
*pr
;
404 int family
, protocol
, error
;
407 * All sysctl names at this level are nonterminal;
408 * next two components are protocol family and protocol number,
409 * then at least one addition component.
412 return (EISDIR
); /* overloaded */
418 lck_mtx_lock(domain_proto_mtx
);
419 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
420 if (dp
->dom_family
== family
)
422 lck_mtx_unlock(domain_proto_mtx
);
423 return (ENOPROTOOPT
);
425 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
426 if (pr
->pr_protocol
== protocol
&& pr
->pr_sysctl
) {
427 error
= (*pr
->pr_sysctl
)(name
+ 2, namelen
- 2,
428 oldp
, oldlenp
, newp
, newlen
);
429 lck_mtx_unlock(domain_proto_mtx
);
432 lck_mtx_unlock(domain_proto_mtx
);
433 return (ENOPROTOOPT
);
441 pfctlinput2(cmd
, sa
, (void*)0);
445 pfctlinput2(cmd
, sa
, ctlparam
)
456 lck_mtx_lock(domain_proto_mtx
);
457 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
458 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
460 (*pr
->pr_ctlinput
)(cmd
, sa
, ctlparam
);
461 lck_mtx_unlock(domain_proto_mtx
);
468 register struct domain
*dp
;
469 register struct protosw
*pr
;
471 lck_mtx_lock(domain_proto_mtx
);
472 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
473 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
) {
475 (*pr
->pr_slowtimo
)();
476 if (do_reclaim
&& pr
->pr_drain
)
480 lck_mtx_unlock(domain_proto_mtx
);
481 timeout(pfslowtimo
, NULL
, hz
/2);
489 register struct domain
*dp
;
490 register struct protosw
*pr
;
492 lck_mtx_lock(domain_proto_mtx
);
493 for (dp
= domains
; dp
; dp
= dp
->dom_next
)
494 for (pr
= dp
->dom_protosw
; pr
; pr
= pr
->pr_next
)
496 (*pr
->pr_fasttimo
)();
497 lck_mtx_unlock(domain_proto_mtx
);
498 timeout(pffasttimo
, NULL
, hz
/5);