Register keyword removal
[dragonfly.git] / sys / kern / uipc_domain.c
CommitLineData
984263bc
MD
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: src/sys/kern/uipc_domain.c,v 1.22.2.1 2001/07/03 11:01:37 ume Exp $
1fd87d54 35 * $DragonFly: src/sys/kern/uipc_domain.c,v 1.3 2003/07/26 19:42:11 rob Exp $
984263bc
MD
36 */
37
38#include <sys/param.h>
39#include <sys/socket.h>
40#include <sys/protosw.h>
41#include <sys/domain.h>
42#include <sys/mbuf.h>
43#include <sys/kernel.h>
44#include <sys/socketvar.h>
45#include <sys/systm.h>
46#include <vm/vm_zone.h>
47
48/*
49 * System initialization
50 *
51 * Note: domain initialization wants to take place on a per domain basis
52 * as a result of traversing a linker set. Most likely, each domain
53 * want to call a registration function rather than being handled here
54 * in domaininit(). Probably this will look like:
55 *
56 * SYSINIT(unique, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, domain_add, xxx)
57 *
58 * Where 'xxx' is replaced by the address of a parameter struct to be
59 * passed to the doamin_add() function.
60 */
61
62static void domaininit __P((void *));
63SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL)
64
65static void pffasttimo __P((void *));
66static void pfslowtimo __P((void *));
67
68struct domain *domains;
69
70/*
71 * Add a new protocol domain to the list of supported domains
72 * Note: you cant unload it again because a socket may be using it.
73 * XXX can't fail at this time.
74 */
75static void
76net_init_domain(struct domain *dp)
77{
1fd87d54 78 struct protosw *pr;
984263bc
MD
79 int s;
80
81 s = splnet();
82 if (dp->dom_init)
83 (*dp->dom_init)();
84 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){
85 if (pr->pr_usrreqs == 0)
86 panic("domaininit: %ssw[%d] has no usrreqs!",
87 dp->dom_name,
88 (int)(pr - dp->dom_protosw));
89 if (pr->pr_init)
90 (*pr->pr_init)();
91 }
92 /*
93 * update global informatio about maximums
94 */
95 max_hdr = max_linkhdr + max_protohdr;
96 max_datalen = MHLEN - max_hdr;
97 splx(s);
98}
99
100/*
101 * Add a new protocol domain to the list of supported domains
102 * Note: you cant unload it again because a socket may be using it.
103 * XXX can't fail at this time.
104 */
105void
106net_add_domain(void *data)
107{
108 int s;
109 struct domain *dp;
110
111 dp = (struct domain *)data;
112 s = splnet();
113 dp->dom_next = domains;
114 domains = dp;
115 splx(s);
116 net_init_domain(dp);
117}
118
119/* ARGSUSED*/
120static void
121domaininit(void *dummy)
122{
123 /*
124 * Before we do any setup, make sure to initialize the
125 * zone allocator we get struct sockets from. The obvious
126 * maximum number of sockets is `maxfiles', but it is possible
127 * to have a socket without an open file (e.g., a connection waiting
128 * to be accept(2)ed). Rather than think up and define a
129 * better value, we just use nmbclusters, since that's what people
130 * are told to increase first when the network runs out of memory.
131 * Perhaps we should have two pools, one of unlimited size
132 * for use during socreate(), and one ZONE_INTERRUPT pool for
133 * use in sonewconn().
134 */
135 socket_zone = zinit("socket", sizeof(struct socket), maxsockets,
136 ZONE_INTERRUPT, 0);
137
138 if (max_linkhdr < 16) /* XXX */
139 max_linkhdr = 16;
140
141 timeout(pffasttimo, (void *)0, 1);
142 timeout(pfslowtimo, (void *)0, 1);
143}
144
145
146struct protosw *
147pffindtype(family, type)
148 int family;
149 int type;
150{
1fd87d54
RG
151 struct domain *dp;
152 struct protosw *pr;
984263bc
MD
153
154 for (dp = domains; dp; dp = dp->dom_next)
155 if (dp->dom_family == family)
156 goto found;
157 return (0);
158found:
159 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
160 if (pr->pr_type && pr->pr_type == type)
161 return (pr);
162 return (0);
163}
164
165struct protosw *
166pffindproto(family, protocol, type)
167 int family;
168 int protocol;
169 int type;
170{
1fd87d54
RG
171 struct domain *dp;
172 struct protosw *pr;
984263bc
MD
173 struct protosw *maybe = 0;
174
175 if (family == 0)
176 return (0);
177 for (dp = domains; dp; dp = dp->dom_next)
178 if (dp->dom_family == family)
179 goto found;
180 return (0);
181found:
182 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
183 if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
184 return (pr);
185
186 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
187 pr->pr_protocol == 0 && maybe == (struct protosw *)0)
188 maybe = pr;
189 }
190 return (maybe);
191}
192
193void
194pfctlinput(cmd, sa)
195 int cmd;
196 struct sockaddr *sa;
197{
1fd87d54
RG
198 struct domain *dp;
199 struct protosw *pr;
984263bc
MD
200
201 for (dp = domains; dp; dp = dp->dom_next)
202 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
203 if (pr->pr_ctlinput)
204 (*pr->pr_ctlinput)(cmd, sa, (void *)0);
205}
206
207void
208pfctlinput2(cmd, sa, ctlparam)
209 int cmd;
210 struct sockaddr *sa;
211 void *ctlparam;
212{
213 struct domain *dp;
214 struct protosw *pr;
215
216 if (!sa)
217 return;
218 for (dp = domains; dp; dp = dp->dom_next) {
219 /*
220 * the check must be made by xx_ctlinput() anyways, to
221 * make sure we use data item pointed to by ctlparam in
222 * correct way. the following check is made just for safety.
223 */
224 if (dp->dom_family != sa->sa_family)
225 continue;
226
227 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
228 if (pr->pr_ctlinput)
229 (*pr->pr_ctlinput)(cmd, sa, ctlparam);
230 }
231}
232
233static void
234pfslowtimo(arg)
235 void *arg;
236{
1fd87d54
RG
237 struct domain *dp;
238 struct protosw *pr;
984263bc
MD
239
240 for (dp = domains; dp; dp = dp->dom_next)
241 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
242 if (pr->pr_slowtimo)
243 (*pr->pr_slowtimo)();
244 timeout(pfslowtimo, (void *)0, hz/2);
245}
246
247static void
248pffasttimo(arg)
249 void *arg;
250{
1fd87d54
RG
251 struct domain *dp;
252 struct protosw *pr;
984263bc
MD
253
254 for (dp = domains; dp; dp = dp->dom_next)
255 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
256 if (pr->pr_fasttimo)
257 (*pr->pr_fasttimo)();
258 timeout(pffasttimo, (void *)0, hz/5);
259}