File: | net/pfkeyv2_convert.c |
Warning: | line 757, column 2 3rd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: pfkeyv2_convert.c,v 1.78 2021/12/20 15:59:09 mvs Exp $ */ | |||
2 | /* | |||
3 | * The author of this code is Angelos D. Keromytis (angelos@keromytis.org) | |||
4 | * | |||
5 | * Part of this code is based on code written by Craig Metz (cmetz@inner.net) | |||
6 | * for NRL. Those licenses follow this one. | |||
7 | * | |||
8 | * Copyright (c) 2001 Angelos D. Keromytis. | |||
9 | * | |||
10 | * Permission to use, copy, and modify this software with or without fee | |||
11 | * is hereby granted, provided that this entire notice is included in | |||
12 | * all copies of any software which is or includes a copy or | |||
13 | * modification of this software. | |||
14 | * You may use this code under the GNU public license if you so wish. Please | |||
15 | * contribute changes back to the authors under this freer than GPL license | |||
16 | * so that we may further the use of strong encryption without limitations to | |||
17 | * all. | |||
18 | * | |||
19 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR | |||
20 | * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY | |||
21 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE | |||
22 | * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR | |||
23 | * PURPOSE. | |||
24 | */ | |||
25 | ||||
26 | /* | |||
27 | * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 | |||
28 | * | |||
29 | * NRL grants permission for redistribution and use in source and binary | |||
30 | * forms, with or without modification, of the software and documentation | |||
31 | * created at NRL provided that the following conditions are met: | |||
32 | * | |||
33 | * 1. Redistributions of source code must retain the above copyright | |||
34 | * notice, this list of conditions and the following disclaimer. | |||
35 | * 2. Redistributions in binary form must reproduce the above copyright | |||
36 | * notice, this list of conditions and the following disclaimer in the | |||
37 | * documentation and/or other materials provided with the distribution. | |||
38 | * 3. All advertising materials mentioning features or use of this software | |||
39 | * must display the following acknowledgements: | |||
40 | * This product includes software developed by the University of | |||
41 | * California, Berkeley and its contributors. | |||
42 | * This product includes software developed at the Information | |||
43 | * Technology Division, US Naval Research Laboratory. | |||
44 | * 4. Neither the name of the NRL nor the names of its contributors | |||
45 | * may be used to endorse or promote products derived from this software | |||
46 | * without specific prior written permission. | |||
47 | * | |||
48 | * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS | |||
49 | * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |||
50 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |||
51 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR | |||
52 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
53 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
54 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
55 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
56 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
57 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
58 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
59 | * | |||
60 | * The views and conclusions contained in the software and documentation | |||
61 | * are those of the authors and should not be interpreted as representing | |||
62 | * official policies, either expressed or implied, of the US Naval | |||
63 | * Research Laboratory (NRL). | |||
64 | */ | |||
65 | ||||
66 | /* | |||
67 | * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved. | |||
68 | * | |||
69 | * Redistribution and use in source and binary forms, with or without | |||
70 | * modification, are permitted provided that the following conditions | |||
71 | * are met: | |||
72 | * 1. Redistributions of source code must retain the above copyright | |||
73 | * notice, this list of conditions and the following disclaimer. | |||
74 | * 2. Redistributions in binary form must reproduce the above copyright | |||
75 | * notice, this list of conditions and the following disclaimer in the | |||
76 | * documentation and/or other materials provided with the distribution. | |||
77 | * 3. Neither the name of the author nor the names of any contributors | |||
78 | * may be used to endorse or promote products derived from this software | |||
79 | * without specific prior written permission. | |||
80 | * | |||
81 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
82 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
83 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
84 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
85 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
86 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
87 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
88 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
89 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
90 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
91 | * SUCH DAMAGE. | |||
92 | */ | |||
93 | ||||
94 | #include "pf.h" | |||
95 | ||||
96 | #include <sys/param.h> | |||
97 | #include <sys/systm.h> | |||
98 | #include <sys/mbuf.h> | |||
99 | #include <sys/kernel.h> | |||
100 | #include <sys/socket.h> | |||
101 | #include <sys/timeout.h> | |||
102 | #include <net/route.h> | |||
103 | #include <net/if.h> | |||
104 | ||||
105 | #include <netinet/in.h> | |||
106 | #include <netinet/ip_ipsp.h> | |||
107 | #include <net/pfkeyv2.h> | |||
108 | #include <crypto/cryptodev.h> | |||
109 | #include <crypto/xform.h> | |||
110 | ||||
111 | #if NPF1 > 0 | |||
112 | #include <net/pfvar.h> | |||
113 | #endif | |||
114 | ||||
115 | /* | |||
116 | * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts | |||
117 | * of the TDB will be initialized by other import routines, and tdb_init(). | |||
118 | */ | |||
119 | void | |||
120 | import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii) | |||
121 | { | |||
122 | if (!sadb_sa) | |||
123 | return; | |||
124 | ||||
125 | mtx_enter(&tdb->tdb_mtx); | |||
126 | if (ii) { | |||
127 | ii->ii_encalg = sadb_sa->sadb_sa_encrypt; | |||
128 | ii->ii_authalg = sadb_sa->sadb_sa_auth; | |||
129 | ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */ | |||
130 | ||||
131 | tdb->tdb_spi = sadb_sa->sadb_sa_spi; | |||
132 | tdb->tdb_wnd = sadb_sa->sadb_sa_replay; | |||
133 | ||||
134 | if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS0x001) | |||
135 | tdb->tdb_flags |= TDBF_PFS0x00800; | |||
136 | ||||
137 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL0x004) | |||
138 | tdb->tdb_flags |= TDBF_TUNNELING0x01000; | |||
139 | ||||
140 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP0x200) | |||
141 | tdb->tdb_flags |= TDBF_UDPENCAP0x20000; | |||
142 | ||||
143 | if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN0x400) | |||
144 | tdb->tdb_flags |= TDBF_ESN0x100000; | |||
145 | } | |||
146 | ||||
147 | if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE1) | |||
148 | tdb->tdb_flags |= TDBF_INVALID0x00010; | |||
149 | mtx_leave(&tdb->tdb_mtx); | |||
150 | } | |||
151 | ||||
152 | /* | |||
153 | * Export some of the information on a TDB. | |||
154 | */ | |||
155 | void | |||
156 | export_sa(void **p, struct tdb *tdb) | |||
157 | { | |||
158 | struct sadb_sa *sadb_sa = (struct sadb_sa *) *p; | |||
159 | ||||
160 | sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t); | |||
161 | ||||
162 | sadb_sa->sadb_sa_spi = tdb->tdb_spi; | |||
163 | sadb_sa->sadb_sa_replay = tdb->tdb_wnd; | |||
164 | ||||
165 | if (tdb->tdb_flags & TDBF_INVALID0x00010) | |||
166 | sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL0; | |||
167 | else | |||
168 | sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE1; | |||
169 | ||||
170 | if (tdb->tdb_sproto == IPPROTO_IPCOMP108 && | |||
171 | tdb->tdb_compalgxform != NULL((void *)0)) { | |||
172 | switch (tdb->tdb_compalgxform->type) { | |||
173 | case CRYPTO_DEFLATE_COMP8: | |||
174 | sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE2; | |||
175 | break; | |||
176 | } | |||
177 | } | |||
178 | ||||
179 | if (tdb->tdb_authalgxform) { | |||
180 | switch (tdb->tdb_authalgxform->type) { | |||
181 | case CRYPTO_MD5_HMAC4: | |||
182 | sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC2; | |||
183 | break; | |||
184 | ||||
185 | case CRYPTO_SHA1_HMAC5: | |||
186 | sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC3; | |||
187 | break; | |||
188 | ||||
189 | case CRYPTO_RIPEMD160_HMAC6: | |||
190 | sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC8; | |||
191 | break; | |||
192 | ||||
193 | case CRYPTO_SHA2_256_HMAC11: | |||
194 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_2565; | |||
195 | break; | |||
196 | ||||
197 | case CRYPTO_SHA2_384_HMAC12: | |||
198 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_3846; | |||
199 | break; | |||
200 | ||||
201 | case CRYPTO_SHA2_512_HMAC13: | |||
202 | sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_5127; | |||
203 | break; | |||
204 | ||||
205 | case CRYPTO_AES_128_GMAC17: | |||
206 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC9; | |||
207 | break; | |||
208 | ||||
209 | case CRYPTO_AES_192_GMAC18: | |||
210 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC10; | |||
211 | break; | |||
212 | ||||
213 | case CRYPTO_AES_256_GMAC19: | |||
214 | sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC11; | |||
215 | break; | |||
216 | ||||
217 | case CRYPTO_CHACHA20_POLY1305_MAC22: | |||
218 | sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY130512; | |||
219 | break; | |||
220 | } | |||
221 | } | |||
222 | ||||
223 | if (tdb->tdb_encalgxform) { | |||
224 | switch (tdb->tdb_encalgxform->type) { | |||
225 | case CRYPTO_NULL9: | |||
226 | sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL11; | |||
227 | break; | |||
228 | ||||
229 | case CRYPTO_3DES_CBC1: | |||
230 | sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC3; | |||
231 | break; | |||
232 | ||||
233 | case CRYPTO_AES_CBC7: | |||
234 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES12; | |||
235 | break; | |||
236 | ||||
237 | case CRYPTO_AES_CTR14: | |||
238 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR13; | |||
239 | break; | |||
240 | ||||
241 | case CRYPTO_AES_GCM_1616: | |||
242 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM1620; | |||
243 | break; | |||
244 | ||||
245 | case CRYPTO_AES_GMAC20: | |||
246 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC21; | |||
247 | break; | |||
248 | ||||
249 | case CRYPTO_CAST_CBC3: | |||
250 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST6; | |||
251 | break; | |||
252 | ||||
253 | case CRYPTO_BLF_CBC2: | |||
254 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF7; | |||
255 | break; | |||
256 | ||||
257 | case CRYPTO_CHACHA20_POLY130521: | |||
258 | sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY130522; | |||
259 | break; | |||
260 | } | |||
261 | } | |||
262 | ||||
263 | if (tdb->tdb_flags & TDBF_PFS0x00800) | |||
264 | sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS0x001; | |||
265 | ||||
266 | if (tdb->tdb_flags & TDBF_TUNNELING0x01000) | |||
267 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL0x004; | |||
268 | ||||
269 | if (tdb->tdb_flags & TDBF_UDPENCAP0x20000) | |||
270 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP0x200; | |||
271 | ||||
272 | if (tdb->tdb_flags & TDBF_ESN0x100000) | |||
273 | sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN0x400; | |||
274 | ||||
275 | *p += sizeof(struct sadb_sa); | |||
276 | } | |||
277 | ||||
278 | /* | |||
279 | * Initialize expirations and counters based on lifetime payload. | |||
280 | */ | |||
281 | void | |||
282 | import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) | |||
283 | { | |||
284 | if (!sadb_lifetime) | |||
285 | return; | |||
286 | ||||
287 | mtx_enter(&tdb->tdb_mtx); | |||
288 | switch (type) { | |||
289 | case PFKEYV2_LIFETIME_HARD0: | |||
290 | if ((tdb->tdb_exp_allocations = | |||
291 | sadb_lifetime->sadb_lifetime_allocations) != 0) | |||
292 | tdb->tdb_flags |= TDBF_ALLOCATIONS0x00008; | |||
293 | else | |||
294 | tdb->tdb_flags &= ~TDBF_ALLOCATIONS0x00008; | |||
295 | ||||
296 | if ((tdb->tdb_exp_bytes = | |||
297 | sadb_lifetime->sadb_lifetime_bytes) != 0) | |||
298 | tdb->tdb_flags |= TDBF_BYTES0x00004; | |||
299 | else | |||
300 | tdb->tdb_flags &= ~TDBF_BYTES0x00004; | |||
301 | ||||
302 | if ((tdb->tdb_exp_timeout = | |||
303 | sadb_lifetime->sadb_lifetime_addtime) != 0) { | |||
304 | tdb->tdb_flags |= TDBF_TIMER0x00002; | |||
305 | if (timeout_add_sec(&tdb->tdb_timer_tmo, | |||
306 | tdb->tdb_exp_timeout)) | |||
307 | tdb_ref(tdb); | |||
308 | } else | |||
309 | tdb->tdb_flags &= ~TDBF_TIMER0x00002; | |||
310 | ||||
311 | if ((tdb->tdb_exp_first_use = | |||
312 | sadb_lifetime->sadb_lifetime_usetime) != 0) | |||
313 | tdb->tdb_flags |= TDBF_FIRSTUSE0x00020; | |||
314 | else | |||
315 | tdb->tdb_flags &= ~TDBF_FIRSTUSE0x00020; | |||
316 | break; | |||
317 | ||||
318 | case PFKEYV2_LIFETIME_SOFT1: | |||
319 | if ((tdb->tdb_soft_allocations = | |||
320 | sadb_lifetime->sadb_lifetime_allocations) != 0) | |||
321 | tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS0x00200; | |||
322 | else | |||
323 | tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS0x00200; | |||
324 | ||||
325 | if ((tdb->tdb_soft_bytes = | |||
326 | sadb_lifetime->sadb_lifetime_bytes) != 0) | |||
327 | tdb->tdb_flags |= TDBF_SOFT_BYTES0x00100; | |||
328 | else | |||
329 | tdb->tdb_flags &= ~TDBF_SOFT_BYTES0x00100; | |||
330 | ||||
331 | if ((tdb->tdb_soft_timeout = | |||
332 | sadb_lifetime->sadb_lifetime_addtime) != 0) { | |||
333 | tdb->tdb_flags |= TDBF_SOFT_TIMER0x00080; | |||
334 | if (timeout_add_sec(&tdb->tdb_stimer_tmo, | |||
335 | tdb->tdb_soft_timeout)) | |||
336 | tdb_ref(tdb); | |||
337 | } else | |||
338 | tdb->tdb_flags &= ~TDBF_SOFT_TIMER0x00080; | |||
339 | ||||
340 | if ((tdb->tdb_soft_first_use = | |||
341 | sadb_lifetime->sadb_lifetime_usetime) != 0) | |||
342 | tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE0x00400; | |||
343 | else | |||
344 | tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE0x00400; | |||
345 | break; | |||
346 | ||||
347 | case PFKEYV2_LIFETIME_CURRENT2: /* Nothing fancy here. */ | |||
348 | tdb->tdb_cur_allocations = | |||
349 | sadb_lifetime->sadb_lifetime_allocations; | |||
350 | tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes; | |||
351 | tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; | |||
352 | tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; | |||
353 | } | |||
354 | mtx_leave(&tdb->tdb_mtx); | |||
355 | } | |||
356 | ||||
357 | /* | |||
358 | * Export TDB expiration information. | |||
359 | */ | |||
360 | void | |||
361 | export_lifetime(void **p, struct tdb *tdb, int type) | |||
362 | { | |||
363 | struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p; | |||
364 | ||||
365 | sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / | |||
366 | sizeof(uint64_t); | |||
367 | ||||
368 | switch (type) { | |||
369 | case PFKEYV2_LIFETIME_HARD0: | |||
370 | if (tdb->tdb_flags & TDBF_ALLOCATIONS0x00008) | |||
371 | sadb_lifetime->sadb_lifetime_allocations = | |||
372 | tdb->tdb_exp_allocations; | |||
373 | ||||
374 | if (tdb->tdb_flags & TDBF_BYTES0x00004) | |||
375 | sadb_lifetime->sadb_lifetime_bytes = | |||
376 | tdb->tdb_exp_bytes; | |||
377 | ||||
378 | if (tdb->tdb_flags & TDBF_TIMER0x00002) | |||
379 | sadb_lifetime->sadb_lifetime_addtime = | |||
380 | tdb->tdb_exp_timeout; | |||
381 | ||||
382 | if (tdb->tdb_flags & TDBF_FIRSTUSE0x00020) | |||
383 | sadb_lifetime->sadb_lifetime_usetime = | |||
384 | tdb->tdb_exp_first_use; | |||
385 | break; | |||
386 | ||||
387 | case PFKEYV2_LIFETIME_SOFT1: | |||
388 | if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS0x00200) | |||
389 | sadb_lifetime->sadb_lifetime_allocations = | |||
390 | tdb->tdb_soft_allocations; | |||
391 | ||||
392 | if (tdb->tdb_flags & TDBF_SOFT_BYTES0x00100) | |||
393 | sadb_lifetime->sadb_lifetime_bytes = | |||
394 | tdb->tdb_soft_bytes; | |||
395 | ||||
396 | if (tdb->tdb_flags & TDBF_SOFT_TIMER0x00080) | |||
397 | sadb_lifetime->sadb_lifetime_addtime = | |||
398 | tdb->tdb_soft_timeout; | |||
399 | ||||
400 | if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE0x00400) | |||
401 | sadb_lifetime->sadb_lifetime_usetime = | |||
402 | tdb->tdb_soft_first_use; | |||
403 | break; | |||
404 | ||||
405 | case PFKEYV2_LIFETIME_CURRENT2: | |||
406 | sadb_lifetime->sadb_lifetime_allocations = | |||
407 | tdb->tdb_cur_allocations; | |||
408 | sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes; | |||
409 | sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established; | |||
410 | sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use; | |||
411 | break; | |||
412 | ||||
413 | case PFKEYV2_LIFETIME_LASTUSE3: | |||
414 | sadb_lifetime->sadb_lifetime_allocations = 0; | |||
415 | sadb_lifetime->sadb_lifetime_bytes = 0; | |||
416 | sadb_lifetime->sadb_lifetime_addtime = 0; | |||
417 | sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used; | |||
418 | break; | |||
419 | } | |||
420 | ||||
421 | *p += sizeof(struct sadb_lifetime); | |||
422 | } | |||
423 | ||||
424 | /* | |||
425 | * Import flow information to two struct sockaddr_encap's. Either | |||
426 | * all or none of the address arguments are NULL. | |||
427 | */ | |||
428 | int | |||
429 | import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask, | |||
430 | struct sadb_address *ssrc, struct sadb_address *ssrcmask, | |||
431 | struct sadb_address *ddst, struct sadb_address *ddstmask, | |||
432 | struct sadb_protocol *sab, struct sadb_protocol *ftype) | |||
433 | { | |||
434 | u_int8_t transproto = 0; | |||
435 | union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1); | |||
436 | union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1); | |||
437 | union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1); | |||
438 | union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1); | |||
439 | ||||
440 | if (ssrc == NULL((void *)0)) | |||
441 | return 0; /* There wasn't any information to begin with. */ | |||
442 | ||||
443 | bzero(flow, sizeof(*flow))__builtin_bzero((flow), (sizeof(*flow))); | |||
444 | bzero(flowmask, sizeof(*flowmask))__builtin_bzero((flowmask), (sizeof(*flowmask))); | |||
445 | ||||
446 | if (sab != NULL((void *)0)) | |||
447 | transproto = sab->sadb_protocol_proto; | |||
448 | ||||
449 | /* | |||
450 | * Check that all the address families match. We know they are | |||
451 | * valid and supported because pfkeyv2_parsemessage() checked that. | |||
452 | */ | |||
453 | if ((src->sa.sa_family != dst->sa.sa_family) || | |||
454 | (src->sa.sa_family != srcmask->sa.sa_family) || | |||
455 | (src->sa.sa_family != dstmask->sa.sa_family)) | |||
456 | return EINVAL22; | |||
457 | ||||
458 | /* | |||
459 | * We set these as an indication that tdb_filter/tdb_filtermask are | |||
460 | * in fact initialized. | |||
461 | */ | |||
462 | flow->sen_family = flowmask->sen_family = PF_KEY30; | |||
463 | flow->sen_len = flowmask->sen_len = SENT_LENsizeof(struct sockaddr_encap); | |||
464 | ||||
465 | switch (src->sa.sa_family) { | |||
466 | case AF_INET2: | |||
467 | /* netmask handling */ | |||
468 | rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); | |||
469 | rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); | |||
470 | ||||
471 | flow->sen_type = SENT_IP40x0001; | |||
472 | flow->sen_directionSen.Sip4.Direction = ftype->sadb_protocol_direction; | |||
473 | flow->sen_ip_srcSen.Sip4.Src = src->sin.sin_addr; | |||
474 | flow->sen_ip_dstSen.Sip4.Dst = dst->sin.sin_addr; | |||
475 | flow->sen_protoSen.Sip4.Proto = transproto; | |||
476 | flow->sen_sportSen.Sip4.Sport = src->sin.sin_port; | |||
477 | flow->sen_dportSen.Sip4.Dport = dst->sin.sin_port; | |||
478 | ||||
479 | flowmask->sen_type = SENT_IP40x0001; | |||
480 | flowmask->sen_directionSen.Sip4.Direction = 0xff; | |||
481 | flowmask->sen_ip_srcSen.Sip4.Src = srcmask->sin.sin_addr; | |||
482 | flowmask->sen_ip_dstSen.Sip4.Dst = dstmask->sin.sin_addr; | |||
483 | flowmask->sen_sportSen.Sip4.Sport = srcmask->sin.sin_port; | |||
484 | flowmask->sen_dportSen.Sip4.Dport = dstmask->sin.sin_port; | |||
485 | if (transproto) | |||
486 | flowmask->sen_protoSen.Sip4.Proto = 0xff; | |||
487 | break; | |||
488 | ||||
489 | #ifdef INET61 | |||
490 | case AF_INET624: | |||
491 | in6_embedscope(&src->sin6.sin6_addr, &src->sin6, | |||
492 | NULL((void *)0)); | |||
493 | in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6, | |||
494 | NULL((void *)0)); | |||
495 | ||||
496 | /* netmask handling */ | |||
497 | rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa); | |||
498 | rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa); | |||
499 | ||||
500 | flow->sen_type = SENT_IP60x0002; | |||
501 | flow->sen_ip6_directionSen.Sip6.Direction = ftype->sadb_protocol_direction; | |||
502 | flow->sen_ip6_srcSen.Sip6.Src = src->sin6.sin6_addr; | |||
503 | flow->sen_ip6_dstSen.Sip6.Dst = dst->sin6.sin6_addr; | |||
504 | flow->sen_ip6_protoSen.Sip6.Proto = transproto; | |||
505 | flow->sen_ip6_sportSen.Sip6.Sport = src->sin6.sin6_port; | |||
506 | flow->sen_ip6_dportSen.Sip6.Dport = dst->sin6.sin6_port; | |||
507 | ||||
508 | flowmask->sen_type = SENT_IP60x0002; | |||
509 | flowmask->sen_ip6_directionSen.Sip6.Direction = 0xff; | |||
510 | flowmask->sen_ip6_srcSen.Sip6.Src = srcmask->sin6.sin6_addr; | |||
511 | flowmask->sen_ip6_dstSen.Sip6.Dst = dstmask->sin6.sin6_addr; | |||
512 | flowmask->sen_ip6_sportSen.Sip6.Sport = srcmask->sin6.sin6_port; | |||
513 | flowmask->sen_ip6_dportSen.Sip6.Dport = dstmask->sin6.sin6_port; | |||
514 | if (transproto) | |||
515 | flowmask->sen_ip6_protoSen.Sip6.Proto = 0xff; | |||
516 | break; | |||
517 | #endif /* INET6 */ | |||
518 | } | |||
519 | ||||
520 | return 0; | |||
521 | } | |||
522 | ||||
523 | /* | |||
524 | * Helper to export addresses from an struct sockaddr_encap. | |||
525 | */ | |||
526 | static void | |||
527 | export_encap(void **p, struct sockaddr_encap *encap, int type) | |||
528 | { | |||
529 | struct sadb_address *saddr = (struct sadb_address *)*p; | |||
530 | union sockaddr_union *sunion; | |||
531 | ||||
532 | *p += sizeof(struct sadb_address); | |||
533 | sunion = (union sockaddr_union *)*p; | |||
534 | ||||
535 | switch (encap->sen_type) { | |||
536 | case SENT_IP40x0001: | |||
537 | saddr->sadb_address_len = (sizeof(struct sadb_address) + | |||
538 | PADUP(sizeof(struct sockaddr_in))(((sizeof(struct sockaddr_in)) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
539 | sunion->sa.sa_len = sizeof(struct sockaddr_in); | |||
540 | sunion->sa.sa_family = AF_INET2; | |||
541 | if (type == SADB_X_EXT_SRC_FLOW21 || | |||
542 | type == SADB_X_EXT_SRC_MASK17) { | |||
543 | sunion->sin.sin_addr = encap->sen_ip_srcSen.Sip4.Src; | |||
544 | sunion->sin.sin_port = encap->sen_sportSen.Sip4.Sport; | |||
545 | } else { | |||
546 | sunion->sin.sin_addr = encap->sen_ip_dstSen.Sip4.Dst; | |||
547 | sunion->sin.sin_port = encap->sen_dportSen.Sip4.Dport; | |||
548 | } | |||
549 | *p += PADUP(sizeof(struct sockaddr_in))(((sizeof(struct sockaddr_in)) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1)); | |||
550 | break; | |||
551 | case SENT_IP60x0002: | |||
552 | saddr->sadb_address_len = (sizeof(struct sadb_address) | |||
553 | + PADUP(sizeof(struct sockaddr_in6))(((sizeof(struct sockaddr_in6)) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
554 | sunion->sa.sa_len = sizeof(struct sockaddr_in6); | |||
555 | sunion->sa.sa_family = AF_INET624; | |||
556 | if (type == SADB_X_EXT_SRC_FLOW21 || | |||
557 | type == SADB_X_EXT_SRC_MASK17) { | |||
558 | sunion->sin6.sin6_addr = encap->sen_ip6_srcSen.Sip6.Src; | |||
559 | sunion->sin6.sin6_port = encap->sen_ip6_sportSen.Sip6.Sport; | |||
560 | } else { | |||
561 | sunion->sin6.sin6_addr = encap->sen_ip6_dstSen.Sip6.Dst; | |||
562 | sunion->sin6.sin6_port = encap->sen_ip6_dportSen.Sip6.Dport; | |||
563 | } | |||
564 | *p += PADUP(sizeof(struct sockaddr_in6))(((sizeof(struct sockaddr_in6)) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)); | |||
565 | break; | |||
566 | } | |||
567 | } | |||
568 | ||||
569 | /* | |||
570 | * Export flow information from two struct sockaddr_encap's. | |||
571 | */ | |||
572 | void | |||
573 | export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow, | |||
574 | struct sockaddr_encap *flowmask, void **headers) | |||
575 | { | |||
576 | struct sadb_protocol *sab; | |||
577 | ||||
578 | headers[SADB_X_EXT_FLOW_TYPE20] = *p; | |||
579 | sab = (struct sadb_protocol *)*p; | |||
580 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
581 | sizeof(uint64_t); | |||
582 | ||||
583 | switch (ftype) { | |||
584 | case IPSP_IPSEC_USE0: | |||
585 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE1; | |||
586 | break; | |||
587 | case IPSP_IPSEC_ACQUIRE1: | |||
588 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE2; | |||
589 | break; | |||
590 | case IPSP_IPSEC_REQUIRE2: | |||
591 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE3; | |||
592 | break; | |||
593 | case IPSP_DENY4: | |||
594 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY5; | |||
595 | break; | |||
596 | case IPSP_PERMIT3: | |||
597 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS4; | |||
598 | break; | |||
599 | case IPSP_IPSEC_DONTACQ5: | |||
600 | sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ6; | |||
601 | break; | |||
602 | default: | |||
603 | sab->sadb_protocol_proto = 0; | |||
604 | break; | |||
605 | } | |||
606 | ||||
607 | switch (flow->sen_type) { | |||
608 | case SENT_IP40x0001: | |||
609 | sab->sadb_protocol_direction = flow->sen_directionSen.Sip4.Direction; | |||
610 | break; | |||
611 | #ifdef INET61 | |||
612 | case SENT_IP60x0002: | |||
613 | sab->sadb_protocol_direction = flow->sen_ip6_directionSen.Sip6.Direction; | |||
614 | break; | |||
615 | #endif /* INET6 */ | |||
616 | } | |||
617 | *p += sizeof(struct sadb_protocol); | |||
618 | ||||
619 | headers[SADB_X_EXT_PROTOCOL19] = *p; | |||
620 | sab = (struct sadb_protocol *)*p; | |||
621 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
622 | sizeof(uint64_t); | |||
623 | switch (flow->sen_type) { | |||
624 | case SENT_IP40x0001: | |||
625 | sab->sadb_protocol_proto = flow->sen_protoSen.Sip4.Proto; | |||
626 | break; | |||
627 | #ifdef INET61 | |||
628 | case SENT_IP60x0002: | |||
629 | sab->sadb_protocol_proto = flow->sen_ip6_protoSen.Sip6.Proto; | |||
630 | break; | |||
631 | #endif /* INET6 */ | |||
632 | } | |||
633 | *p += sizeof(struct sadb_protocol); | |||
634 | ||||
635 | headers[SADB_X_EXT_SRC_FLOW21] = *p; | |||
636 | export_encap(p, flow, SADB_X_EXT_SRC_FLOW21); | |||
637 | ||||
638 | headers[SADB_X_EXT_SRC_MASK17] = *p; | |||
639 | export_encap(p, flowmask, SADB_X_EXT_SRC_MASK17); | |||
640 | ||||
641 | headers[SADB_X_EXT_DST_FLOW22] = *p; | |||
642 | export_encap(p, flow, SADB_X_EXT_DST_FLOW22); | |||
643 | ||||
644 | headers[SADB_X_EXT_DST_MASK18] = *p; | |||
645 | export_encap(p, flowmask, SADB_X_EXT_DST_MASK18); | |||
646 | } | |||
647 | ||||
648 | /* | |||
649 | * Copy an SADB_ADDRESS payload to a struct sockaddr. | |||
650 | */ | |||
651 | void | |||
652 | import_address(struct sockaddr *sa, struct sadb_address *sadb_address) | |||
653 | { | |||
654 | int salen; | |||
655 | struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address + | |||
656 | sizeof(struct sadb_address)); | |||
657 | ||||
658 | if (!sadb_address) | |||
659 | return; | |||
660 | ||||
661 | if (ssa->sa_len) | |||
662 | salen = ssa->sa_len; | |||
663 | else | |||
664 | switch (ssa->sa_family) { | |||
665 | case AF_INET2: | |||
666 | salen = sizeof(struct sockaddr_in); | |||
667 | break; | |||
668 | ||||
669 | #ifdef INET61 | |||
670 | case AF_INET624: | |||
671 | salen = sizeof(struct sockaddr_in6); | |||
672 | break; | |||
673 | #endif /* INET6 */ | |||
674 | ||||
675 | default: | |||
676 | return; | |||
677 | } | |||
678 | ||||
679 | bcopy(ssa, sa, salen); | |||
680 | sa->sa_len = salen; | |||
681 | } | |||
682 | ||||
683 | /* | |||
684 | * Export a struct sockaddr as an SADB_ADDRESS payload. | |||
685 | */ | |||
686 | void | |||
687 | export_address(void **p, struct sockaddr *sa) | |||
688 | { | |||
689 | struct sadb_address *sadb_address = (struct sadb_address *) *p; | |||
690 | ||||
691 | sadb_address->sadb_address_len = (sizeof(struct sadb_address) + | |||
692 | PADUP(sa->sa_len)(((sa->sa_len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1))) / sizeof(uint64_t); | |||
693 | ||||
694 | *p += sizeof(struct sadb_address); | |||
695 | bcopy(sa, *p, sa->sa_len); | |||
696 | ((struct sockaddr *) *p)->sa_family = sa->sa_family; | |||
697 | *p += PADUP(sa->sa_len)(((sa->sa_len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1)); | |||
698 | } | |||
699 | ||||
700 | /* | |||
701 | * Import an identity payload into the TDB. | |||
702 | */ | |||
703 | static void | |||
704 | import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident, | |||
705 | size_t *id_sz) | |||
706 | { | |||
707 | size_t id_len; | |||
708 | ||||
709 | if (!sadb_ident) { | |||
710 | *id = NULL((void *)0); | |||
711 | return; | |||
712 | } | |||
713 | ||||
714 | id_len = EXTLEN(sadb_ident)(((struct sadb_ext *)(sadb_ident))->sadb_ext_len * sizeof( uint64_t)) - sizeof(struct sadb_ident); | |||
715 | *id_sz = sizeof(struct ipsec_id) + id_len; | |||
716 | *id = malloc(*id_sz, M_CREDENTIALS110, M_WAITOK0x0001); | |||
717 | (*id)->len = id_len; | |||
718 | ||||
719 | switch (sadb_ident->sadb_ident_type) { | |||
720 | case SADB_IDENTTYPE_PREFIX1: | |||
721 | (*id)->type = IPSP_IDENTITY_PREFIX1; | |||
722 | break; | |||
723 | case SADB_IDENTTYPE_FQDN2: | |||
724 | (*id)->type = IPSP_IDENTITY_FQDN2; | |||
725 | break; | |||
726 | case SADB_IDENTTYPE_USERFQDN3: | |||
727 | (*id)->type = IPSP_IDENTITY_USERFQDN3; | |||
728 | break; | |||
729 | case SADB_IDENTTYPE_ASN1_DN4: | |||
730 | (*id)->type = IPSP_IDENTITY_ASN1_DN4; | |||
731 | break; | |||
732 | default: | |||
733 | free(*id, M_CREDENTIALS110, *id_sz); | |||
734 | *id = NULL((void *)0); | |||
735 | return; | |||
736 | } | |||
737 | bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1, | |||
738 | (*id)->len); | |||
739 | } | |||
740 | ||||
741 | void | |||
742 | import_identities(struct ipsec_ids **ids, int swapped, | |||
743 | struct sadb_ident *srcid, struct sadb_ident *dstid) | |||
744 | { | |||
745 | struct ipsec_ids *tmp; | |||
746 | size_t id_local_sz, id_remote_sz; | |||
| ||||
747 | ||||
748 | *ids = NULL((void *)0); | |||
749 | tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS110, M_WAITOK0x0001); | |||
750 | import_identity(&tmp->id_local, swapped ? dstid: srcid, &id_local_sz); | |||
751 | import_identity(&tmp->id_remote, swapped
| |||
752 | if (tmp->id_local
| |||
753 | *ids = ipsp_ids_insert(tmp); | |||
754 | if (*ids == tmp) | |||
755 | return; | |||
756 | } | |||
757 | free(tmp->id_local, M_CREDENTIALS110, id_local_sz); | |||
| ||||
758 | free(tmp->id_remote, M_CREDENTIALS110, id_remote_sz); | |||
759 | free(tmp, M_CREDENTIALS110, sizeof(*tmp)); | |||
760 | } | |||
761 | ||||
762 | static void | |||
763 | export_identity(void **p, struct ipsec_id *id) | |||
764 | { | |||
765 | struct sadb_ident *sadb_ident = (struct sadb_ident *) *p; | |||
766 | ||||
767 | sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) + | |||
768 | PADUP(id->len)(((id->len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1))) / sizeof(uint64_t); | |||
769 | ||||
770 | switch (id->type) { | |||
771 | case IPSP_IDENTITY_PREFIX1: | |||
772 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX1; | |||
773 | break; | |||
774 | case IPSP_IDENTITY_FQDN2: | |||
775 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN2; | |||
776 | break; | |||
777 | case IPSP_IDENTITY_USERFQDN3: | |||
778 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN3; | |||
779 | break; | |||
780 | case IPSP_IDENTITY_ASN1_DN4: | |||
781 | sadb_ident->sadb_ident_type = SADB_IDENTTYPE_ASN1_DN4; | |||
782 | break; | |||
783 | } | |||
784 | *p += sizeof(struct sadb_ident); | |||
785 | bcopy(id + 1, *p, id->len); | |||
786 | *p += PADUP(id->len)(((id->len) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t ) - 1)); | |||
787 | } | |||
788 | ||||
789 | void | |||
790 | export_identities(void **p, struct ipsec_ids *ids, int swapped, | |||
791 | void **headers) | |||
792 | { | |||
793 | headers[SADB_EXT_IDENTITY_SRC10] = *p; | |||
794 | export_identity(p, swapped ? ids->id_remote : ids->id_local); | |||
795 | headers[SADB_EXT_IDENTITY_DST11] = *p; | |||
796 | export_identity(p, swapped ? ids->id_local : ids->id_remote); | |||
797 | } | |||
798 | ||||
799 | /* ... */ | |||
800 | void | |||
801 | import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type) | |||
802 | { | |||
803 | if (!sadb_key) | |||
804 | return; | |||
805 | ||||
806 | if (type == PFKEYV2_ENCRYPTION_KEY0) { /* Encryption key */ | |||
807 | ii->ii_enckeylen = sadb_key->sadb_key_bits / 8; | |||
808 | ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key); | |||
809 | } else { | |||
810 | ii->ii_authkeylen = sadb_key->sadb_key_bits / 8; | |||
811 | ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key); | |||
812 | } | |||
813 | } | |||
814 | ||||
815 | void | |||
816 | export_key(void **p, struct tdb *tdb, int type) | |||
817 | { | |||
818 | struct sadb_key *sadb_key = (struct sadb_key *) *p; | |||
819 | ||||
820 | if (type == PFKEYV2_ENCRYPTION_KEY0) { | |||
821 | sadb_key->sadb_key_len = (sizeof(struct sadb_key) + | |||
822 | PADUP(tdb->tdb_emxkeylen)(((tdb->tdb_emxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1))) / | |||
823 | sizeof(uint64_t); | |||
824 | sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8; | |||
825 | *p += sizeof(struct sadb_key); | |||
826 | bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen); | |||
827 | *p += PADUP(tdb->tdb_emxkeylen)(((tdb->tdb_emxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1)); | |||
828 | } else { | |||
829 | sadb_key->sadb_key_len = (sizeof(struct sadb_key) + | |||
830 | PADUP(tdb->tdb_amxkeylen)(((tdb->tdb_amxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1))) / | |||
831 | sizeof(uint64_t); | |||
832 | sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8; | |||
833 | *p += sizeof(struct sadb_key); | |||
834 | bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen); | |||
835 | *p += PADUP(tdb->tdb_amxkeylen)(((tdb->tdb_amxkeylen) + sizeof(uint64_t) - 1) & ~(sizeof (uint64_t) - 1)); | |||
836 | } | |||
837 | } | |||
838 | ||||
839 | /* Import/Export remote port for UDP Encapsulation */ | |||
840 | void | |||
841 | import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap) | |||
842 | { | |||
843 | if (sadb_udpencap) | |||
844 | tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port; | |||
845 | } | |||
846 | ||||
847 | void | |||
848 | export_udpencap(void **p, struct tdb *tdb) | |||
849 | { | |||
850 | struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p; | |||
851 | ||||
852 | sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port; | |||
853 | sadb_udpencap->sadb_x_udpencap_reserved = 0; | |||
854 | sadb_udpencap->sadb_x_udpencap_len = | |||
855 | sizeof(struct sadb_x_udpencap) / sizeof(uint64_t); | |||
856 | *p += sizeof(struct sadb_x_udpencap); | |||
857 | } | |||
858 | ||||
859 | /* Export PF replay for SA */ | |||
860 | void | |||
861 | export_replay(void **p, struct tdb *tdb) | |||
862 | { | |||
863 | struct sadb_x_replay *sreplay = (struct sadb_x_replay *)*p; | |||
864 | ||||
865 | sreplay->sadb_x_replay_count = tdb->tdb_rpl; | |||
866 | sreplay->sadb_x_replay_len = | |||
867 | sizeof(struct sadb_x_replay) / sizeof(uint64_t); | |||
868 | *p += sizeof(struct sadb_x_replay); | |||
869 | } | |||
870 | ||||
871 | /* Export mtu for SA */ | |||
872 | void | |||
873 | export_mtu(void **p, struct tdb *tdb) | |||
874 | { | |||
875 | struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)*p; | |||
876 | ||||
877 | smtu->sadb_x_mtu_mtu = tdb->tdb_mtu; | |||
878 | smtu->sadb_x_mtu_len = | |||
879 | sizeof(struct sadb_x_mtu) / sizeof(uint64_t); | |||
880 | *p += sizeof(struct sadb_x_mtu); | |||
881 | } | |||
882 | ||||
883 | /* Import rdomain switch for SA */ | |||
884 | void | |||
885 | import_rdomain(struct tdb *tdb, struct sadb_x_rdomain *srdomain) | |||
886 | { | |||
887 | if (srdomain) | |||
888 | tdb->tdb_rdomain_post = srdomain->sadb_x_rdomain_dom2; | |||
889 | } | |||
890 | ||||
891 | /* Export rdomain switch for SA */ | |||
892 | void | |||
893 | export_rdomain(void **p, struct tdb *tdb) | |||
894 | { | |||
895 | struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)*p; | |||
896 | ||||
897 | srdomain->sadb_x_rdomain_dom1 = tdb->tdb_rdomain; | |||
898 | srdomain->sadb_x_rdomain_dom2 = tdb->tdb_rdomain_post; | |||
899 | srdomain->sadb_x_rdomain_len = | |||
900 | sizeof(struct sadb_x_rdomain) / sizeof(uint64_t); | |||
901 | *p += sizeof(struct sadb_x_rdomain); | |||
902 | } | |||
903 | ||||
904 | #if NPF1 > 0 | |||
905 | /* Import PF tag information for SA */ | |||
906 | void | |||
907 | import_tag(struct tdb *tdb, struct sadb_x_tag *stag) | |||
908 | { | |||
909 | char *s; | |||
910 | ||||
911 | if (stag) { | |||
912 | s = (char *)(stag + 1); | |||
913 | tdb->tdb_tag = pf_tagname2tag(s, 1); | |||
914 | } | |||
915 | } | |||
916 | ||||
917 | /* Export PF tag information for SA */ | |||
918 | void | |||
919 | export_tag(void **p, struct tdb *tdb) | |||
920 | { | |||
921 | struct sadb_x_tag *stag = (struct sadb_x_tag *)*p; | |||
922 | char *s = (char *)(stag + 1); | |||
923 | ||||
924 | pf_tag2tagname(tdb->tdb_tag, s); | |||
925 | ||||
926 | stag->sadb_x_tag_taglen = strlen(s) + 1; | |||
927 | stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) + | |||
928 | PADUP(stag->sadb_x_tag_taglen)(((stag->sadb_x_tag_taglen) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1))) / sizeof(uint64_t); | |||
929 | *p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen)(((stag->sadb_x_tag_taglen) + sizeof(uint64_t) - 1) & ~ (sizeof(uint64_t) - 1)); | |||
930 | } | |||
931 | ||||
932 | /* Import enc(4) tap device information for SA */ | |||
933 | void | |||
934 | import_tap(struct tdb *tdb, struct sadb_x_tap *stap) | |||
935 | { | |||
936 | if (stap) | |||
937 | tdb->tdb_tap = stap->sadb_x_tap_unit; | |||
938 | } | |||
939 | ||||
940 | /* Export enc(4) tap device information for SA */ | |||
941 | void | |||
942 | export_tap(void **p, struct tdb *tdb) | |||
943 | { | |||
944 | struct sadb_x_tap *stag = (struct sadb_x_tap *)*p; | |||
945 | ||||
946 | stag->sadb_x_tap_unit = tdb->tdb_tap; | |||
947 | stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t); | |||
948 | *p += sizeof(struct sadb_x_tap); | |||
949 | } | |||
950 | #endif | |||
951 | ||||
952 | void | |||
953 | export_satype(void **p, struct tdb *tdb) | |||
954 | { | |||
955 | struct sadb_protocol *sab = *p; | |||
956 | ||||
957 | sab->sadb_protocol_len = sizeof(struct sadb_protocol) / | |||
958 | sizeof(uint64_t); | |||
959 | sab->sadb_protocol_proto = tdb->tdb_satype; | |||
960 | *p += sizeof(struct sadb_protocol); | |||
961 | } | |||
962 | ||||
963 | void | |||
964 | export_counter(void **p, struct tdb *tdb) | |||
965 | { | |||
966 | uint64_t counters[tdb_ncounters]; | |||
967 | struct sadb_x_counter *scnt = (struct sadb_x_counter *)*p; | |||
968 | ||||
969 | counters_read(tdb->tdb_counters, counters, tdb_ncounters); | |||
970 | ||||
971 | scnt->sadb_x_counter_len = sizeof(struct sadb_x_counter) / | |||
972 | sizeof(uint64_t); | |||
973 | scnt->sadb_x_counter_pad = 0; | |||
974 | scnt->sadb_x_counter_ipackets = counters[tdb_ipackets]; | |||
975 | scnt->sadb_x_counter_opackets = counters[tdb_opackets]; | |||
976 | scnt->sadb_x_counter_ibytes = counters[tdb_ibytes]; | |||
977 | scnt->sadb_x_counter_obytes = counters[tdb_obytes]; | |||
978 | scnt->sadb_x_counter_idrops = counters[tdb_idrops]; | |||
979 | scnt->sadb_x_counter_odrops = counters[tdb_odrops]; | |||
980 | scnt->sadb_x_counter_idecompbytes = counters[tdb_idecompbytes]; | |||
981 | scnt->sadb_x_counter_ouncompbytes = counters[tdb_ouncompbytes]; | |||
982 | *p += sizeof(struct sadb_x_counter); | |||
983 | } |