]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/netkey/keydb.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / sys / netkey / keydb.c
1 /*      $KAME: keydb.c,v 1.82 2003/09/07 07:47:33 itojun Exp $  */
2
3 /*-
4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include "opt_inet.h"
36 #include "opt_inet6.h"
37
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/errno.h>
45 #include <sys/queue.h>
46
47 #include <net/if.h>
48 #include <net/route.h>
49
50 #include <netinet/in.h>
51
52 #include <net/pfkeyv2.h>
53 #include <netkey/keydb.h>
54 #include <netkey/key.h>
55 #include <netinet6/ipsec.h>
56
57 #include <net/net_osdep.h>
58
59 MALLOC_DEFINE(M_SECA, "key mgmt", "security associations, key management");
60
61 /*
62  * secpolicy management
63  */
64 struct secpolicy *
65 keydb_newsecpolicy()
66 {
67         struct secpolicy *p;
68
69         p = (struct secpolicy *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
70         if (!p)
71                 return p;
72         bzero(p, sizeof(*p));
73         TAILQ_INSERT_TAIL(&sptailq, p, tailq);
74
75         return p;
76 }
77
78 u_int32_t
79 keydb_newspid(void)
80 {
81         u_int32_t newid = 0;
82         static u_int32_t lastalloc = IPSEC_MANUAL_POLICYID_MAX;
83         struct secpolicy *sp;
84
85         newid = lastalloc + 1;
86         /* XXX possible infinite loop */
87 again:
88         TAILQ_FOREACH(sp, &sptailq, tailq) {
89                 if (sp->id == newid)
90                         break;
91         }
92         if (sp != NULL) {
93                 if (newid + 1 < newid)  /* wraparound */
94                         newid = IPSEC_MANUAL_POLICYID_MAX + 1;
95                 else
96                         newid++;
97                 goto again;
98         }
99         lastalloc = newid;
100
101         return newid;
102 }
103
104 void
105 keydb_delsecpolicy(p)
106         struct secpolicy *p;
107 {
108
109         TAILQ_REMOVE(&sptailq, p, tailq);
110         if (p->spidx)
111                 free(p->spidx, M_SECA);
112         free(p, M_SECA);
113 }
114
115 int
116 keydb_setsecpolicyindex(p, idx)
117         struct secpolicy *p;
118         struct secpolicyindex *idx;
119 {
120
121         if (!p->spidx)
122                 p->spidx = (struct secpolicyindex *)malloc(sizeof(*p->spidx),
123                     M_SECA, M_NOWAIT);
124         if (!p->spidx)
125                 return ENOMEM;
126         memcpy(p->spidx, idx, sizeof(*p->spidx));
127         return 0;
128 }
129
130 /*
131  * secashead management
132  */
133 struct secashead *
134 keydb_newsecashead()
135 {
136         struct secashead *p;
137         int i;
138
139         p = (struct secashead *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
140         if (!p)
141                 return p;
142         bzero(p, sizeof(*p));
143         for (i = 0; i < sizeof(p->savtree)/sizeof(p->savtree[0]); i++)
144                 LIST_INIT(&p->savtree[i]);
145         return p;
146 }
147
148 void
149 keydb_delsecashead(p)
150         struct secashead *p;
151 {
152
153         free(p, M_SECA);
154 }
155
156 /*
157  * secasvar management (reference counted)
158  */
159 struct secasvar *
160 keydb_newsecasvar()
161 {
162         struct secasvar *p, *q;
163         static u_int32_t said = 0;
164
165         p = (struct secasvar *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
166         if (!p)
167                 return p;
168
169 again:
170         said++;
171         if (said == 0)
172                 said++;
173         TAILQ_FOREACH(q, &satailq, tailq) {
174                 if (q->id == said)
175                         goto again;
176                 if (TAILQ_NEXT(q, tailq)) {
177                         if (q->id < said && said < TAILQ_NEXT(q, tailq)->id)
178                                 break;
179                         if (q->id + 1 < TAILQ_NEXT(q, tailq)->id) {
180                                 said = q->id + 1;
181                                 break;
182                         }
183                 }
184         }
185
186         bzero(p, sizeof(*p));
187         p->id = said;
188         if (q)
189                 TAILQ_INSERT_AFTER(&satailq, q, p, tailq);
190         else
191                 TAILQ_INSERT_TAIL(&satailq, p, tailq);
192         return p;
193 }
194
195 void
196 keydb_delsecasvar(p)
197         struct secasvar *p;
198 {
199
200         TAILQ_REMOVE(&satailq, p, tailq);
201
202         free(p, M_SECA);
203 }
204
205 /*
206  * secreplay management
207  */
208 struct secreplay *
209 keydb_newsecreplay(wsize)
210         size_t wsize;
211 {
212         struct secreplay *p;
213
214         p = (struct secreplay *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
215         if (!p)
216                 return p;
217
218         bzero(p, sizeof(*p));
219         if (wsize != 0) {
220                 p->bitmap = malloc(wsize, M_SECA, M_NOWAIT);
221                 if (!p->bitmap) {
222                         free(p, M_SECA);
223                         return NULL;
224                 }
225                 bzero(p->bitmap, wsize);
226         }
227         p->wsize = wsize;
228         return p;
229 }
230
231 void
232 keydb_delsecreplay(p)
233         struct secreplay *p;
234 {
235
236         if (p->bitmap)
237                 free(p->bitmap, M_SECA);
238         free(p, M_SECA);
239 }
240
241 /*
242  * secreg management
243  */
244 struct secreg *
245 keydb_newsecreg()
246 {
247         struct secreg *p;
248
249         p = (struct secreg *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
250         if (p)
251                 bzero(p, sizeof(*p));
252         return p;
253 }
254
255 void
256 keydb_delsecreg(p)
257         struct secreg *p;
258 {
259
260         free(p, M_SECA);
261 }