Print this page
First attempt at further IPsec cluster cleanup
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/inet/ip/sadb.c
+++ new/usr/src/uts/common/inet/ip/sadb.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 *
25 25 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
26 26 */
27 27
28 28 #include <sys/types.h>
29 29 #include <sys/stream.h>
30 30 #include <sys/stropts.h>
31 31 #include <sys/strsubr.h>
32 32 #include <sys/errno.h>
33 33 #include <sys/ddi.h>
34 34 #include <sys/debug.h>
35 35 #include <sys/cmn_err.h>
36 36 #include <sys/stream.h>
37 37 #include <sys/strlog.h>
38 38 #include <sys/kmem.h>
39 39 #include <sys/sunddi.h>
40 40 #include <sys/tihdr.h>
41 41 #include <sys/atomic.h>
42 42 #include <sys/socket.h>
43 43 #include <sys/sysmacros.h>
44 44 #include <sys/crypto/common.h>
45 45 #include <sys/crypto/api.h>
46 46 #include <sys/zone.h>
47 47 #include <netinet/in.h>
48 48 #include <net/if.h>
49 49 #include <net/pfkeyv2.h>
50 50 #include <net/pfpolicy.h>
51 51 #include <inet/common.h>
52 52 #include <netinet/ip6.h>
53 53 #include <inet/ip.h>
54 54 #include <inet/ip_ire.h>
55 55 #include <inet/ip6.h>
56 56 #include <inet/ipsec_info.h>
57 57 #include <inet/tcp.h>
58 58 #include <inet/sadb.h>
59 59 #include <inet/ipsec_impl.h>
60 60 #include <inet/ipsecah.h>
61 61 #include <inet/ipsecesp.h>
62 62 #include <sys/random.h>
63 63 #include <sys/dlpi.h>
64 64 #include <sys/strsun.h>
65 65 #include <sys/strsubr.h>
66 66 #include <inet/ip_if.h>
67 67 #include <inet/ipdrop.h>
68 68 #include <inet/ipclassifier.h>
69 69 #include <inet/sctp_ip.h>
70 70 #include <sys/tsol/tnet.h>
71 71
72 72 /*
73 73 * This source file contains Security Association Database (SADB) common
74 74 * routines. They are linked in with the AH module. Since AH has no chance
75 75 * of falling under export control, it was safe to link it in there.
76 76 */
77 77
78 78 static mblk_t *sadb_extended_acquire(ipsec_selector_t *, ipsec_policy_t *,
79 79 ipsec_action_t *, boolean_t, uint32_t, uint32_t, sadb_sens_t *,
80 80 netstack_t *);
81 81 static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *);
82 82 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t,
83 83 netstack_t *);
84 84 static void sadb_destroy(sadb_t *, netstack_t *);
85 85 static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *);
86 86 static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *);
87 87 static sadb_sens_t *sadb_make_sens_ext(ts_label_t *tsl, int *len);
88 88
89 89 static time_t sadb_add_time(time_t, uint64_t);
90 90 static void lifetime_fuzz(ipsa_t *);
91 91 static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t);
92 92 static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *);
93 93 static void init_ipsa_pair(ipsap_t *);
94 94 static void destroy_ipsa_pair(ipsap_t *);
95 95 static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *);
96 96 static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset);
97 97
98 98 /*
99 99 * ipsacq_maxpackets is defined here to make it tunable
100 100 * from /etc/system.
101 101 */
102 102 extern uint64_t ipsacq_maxpackets;
103 103
104 104 #define SET_EXPIRE(sa, delta, exp) { \
105 105 if (((sa)->ipsa_ ## delta) != 0) { \
106 106 (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime, \
107 107 (sa)->ipsa_ ## delta); \
108 108 } \
109 109 }
110 110
111 111 #define UPDATE_EXPIRE(sa, delta, exp) { \
112 112 if (((sa)->ipsa_ ## delta) != 0) { \
113 113 time_t tmp = sadb_add_time((sa)->ipsa_usetime, \
114 114 (sa)->ipsa_ ## delta); \
115 115 if (((sa)->ipsa_ ## exp) == 0) \
116 116 (sa)->ipsa_ ## exp = tmp; \
117 117 else \
118 118 (sa)->ipsa_ ## exp = \
119 119 MIN((sa)->ipsa_ ## exp, tmp); \
120 120 } \
121 121 }
122 122
123 123
124 124 /* wrap the macro so we can pass it as a function pointer */
125 125 void
126 126 sadb_sa_refrele(void *target)
127 127 {
128 128 IPSA_REFRELE(((ipsa_t *)target));
129 129 }
130 130
131 131 /*
132 132 * We presume that sizeof (long) == sizeof (time_t) and that time_t is
133 133 * a signed type.
134 134 */
135 135 #define TIME_MAX LONG_MAX
136 136
137 137 /*
138 138 * PF_KEY gives us lifetimes in uint64_t seconds. We presume that
139 139 * time_t is defined to be a signed type with the same range as
140 140 * "long". On ILP32 systems, we thus run the risk of wrapping around
141 141 * at end of time, as well as "overwrapping" the clock back around
142 142 * into a seemingly valid but incorrect future date earlier than the
143 143 * desired expiration.
144 144 *
145 145 * In order to avoid odd behavior (either negative lifetimes or loss
146 146 * of high order bits) when someone asks for bizarrely long SA
147 147 * lifetimes, we do a saturating add for expire times.
148 148 *
149 149 * We presume that ILP32 systems will be past end of support life when
150 150 * the 32-bit time_t overflows (a dangerous assumption, mind you..).
151 151 *
152 152 * On LP64, 2^64 seconds are about 5.8e11 years, at which point we
153 153 * will hopefully have figured out clever ways to avoid the use of
154 154 * fixed-sized integers in computation.
155 155 */
156 156 static time_t
157 157 sadb_add_time(time_t base, uint64_t delta)
158 158 {
159 159 time_t sum;
160 160
161 161 /*
162 162 * Clip delta to the maximum possible time_t value to
163 163 * prevent "overwrapping" back into a shorter-than-desired
164 164 * future time.
165 165 */
166 166 if (delta > TIME_MAX)
167 167 delta = TIME_MAX;
168 168 /*
169 169 * This sum may still overflow.
170 170 */
171 171 sum = base + delta;
172 172
173 173 /*
174 174 * .. so if the result is less than the base, we overflowed.
175 175 */
176 176 if (sum < base)
177 177 sum = TIME_MAX;
178 178
179 179 return (sum);
180 180 }
181 181
182 182 /*
183 183 * Callers of this function have already created a working security
184 184 * association, and have found the appropriate table & hash chain. All this
185 185 * function does is check duplicates, and insert the SA. The caller needs to
186 186 * hold the hash bucket lock and increment the refcnt before insertion.
187 187 *
188 188 * Return 0 if success, EEXIST if collision.
189 189 */
190 190 #define SA_UNIQUE_MATCH(sa1, sa2) \
191 191 (((sa1)->ipsa_unique_id & (sa1)->ipsa_unique_mask) == \
192 192 ((sa2)->ipsa_unique_id & (sa2)->ipsa_unique_mask))
193 193
194 194 int
195 195 sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket)
196 196 {
197 197 ipsa_t **ptpn = NULL;
198 198 ipsa_t *walker;
199 199 boolean_t unspecsrc;
200 200
201 201 ASSERT(MUTEX_HELD(&bucket->isaf_lock));
202 202
203 203 unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam);
204 204
205 205 walker = bucket->isaf_ipsa;
206 206 ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam);
207 207
208 208 /*
209 209 * Find insertion point (pointed to with **ptpn). Insert at the head
210 210 * of the list unless there's an unspecified source address, then
211 211 * insert it after the last SA with a specified source address.
212 212 *
213 213 * BTW, you'll have to walk the whole chain, matching on {DST, SPI}
214 214 * checking for collisions.
215 215 */
216 216
217 217 while (walker != NULL) {
218 218 if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr,
219 219 ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) {
220 220 if (walker->ipsa_spi == ipsa->ipsa_spi)
221 221 return (EEXIST);
222 222
223 223 mutex_enter(&walker->ipsa_lock);
224 224 if (ipsa->ipsa_state == IPSA_STATE_MATURE &&
225 225 (walker->ipsa_flags & IPSA_F_USED) &&
226 226 SA_UNIQUE_MATCH(walker, ipsa)) {
227 227 walker->ipsa_flags |= IPSA_F_CINVALID;
228 228 }
229 229 mutex_exit(&walker->ipsa_lock);
230 230 }
231 231
232 232 if (ptpn == NULL && unspecsrc) {
233 233 if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr,
234 234 walker->ipsa_addrfam))
235 235 ptpn = walker->ipsa_ptpn;
236 236 else if (walker->ipsa_next == NULL)
237 237 ptpn = &walker->ipsa_next;
238 238 }
239 239
240 240 walker = walker->ipsa_next;
241 241 }
242 242
243 243 if (ptpn == NULL)
244 244 ptpn = &bucket->isaf_ipsa;
245 245 ipsa->ipsa_next = *ptpn;
246 246 ipsa->ipsa_ptpn = ptpn;
247 247 if (ipsa->ipsa_next != NULL)
248 248 ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next;
249 249 *ptpn = ipsa;
250 250 ipsa->ipsa_linklock = &bucket->isaf_lock;
251 251
252 252 return (0);
253 253 }
254 254 #undef SA_UNIQUE_MATCH
255 255
256 256 /*
257 257 * Free a security association. Its reference count is 0, which means
258 258 * I must free it. The SA must be unlocked and must not be linked into
259 259 * any fanout list.
260 260 */
261 261 static void
262 262 sadb_freeassoc(ipsa_t *ipsa)
263 263 {
264 264 ipsec_stack_t *ipss = ipsa->ipsa_netstack->netstack_ipsec;
265 265 mblk_t *asyncmp, *mp;
266 266
267 267 ASSERT(ipss != NULL);
268 268 ASSERT(MUTEX_NOT_HELD(&ipsa->ipsa_lock));
269 269 ASSERT(ipsa->ipsa_refcnt == 0);
270 270 ASSERT(ipsa->ipsa_next == NULL);
271 271 ASSERT(ipsa->ipsa_ptpn == NULL);
272 272
273 273
274 274 asyncmp = sadb_clear_lpkt(ipsa);
275 275 if (asyncmp != NULL) {
276 276 mp = ip_recv_attr_free_mblk(asyncmp);
277 277 ip_drop_packet(mp, B_TRUE, NULL,
278 278 DROPPER(ipss, ipds_sadb_inlarval_timeout),
279 279 &ipss->ipsec_sadb_dropper);
280 280 }
281 281 mutex_enter(&ipsa->ipsa_lock);
282 282
283 283 if (ipsa->ipsa_tsl != NULL) {
284 284 label_rele(ipsa->ipsa_tsl);
285 285 ipsa->ipsa_tsl = NULL;
286 286 }
287 287
288 288 if (ipsa->ipsa_otsl != NULL) {
289 289 label_rele(ipsa->ipsa_otsl);
290 290 ipsa->ipsa_otsl = NULL;
291 291 }
292 292
293 293 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH);
294 294 ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR);
295 295 mutex_exit(&ipsa->ipsa_lock);
296 296
297 297 /* bzero() these fields for paranoia's sake. */
298 298 if (ipsa->ipsa_authkey != NULL) {
299 299 bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
300 300 kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen);
301 301 }
302 302 if (ipsa->ipsa_encrkey != NULL) {
303 303 bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
304 304 kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen);
305 305 }
306 306 if (ipsa->ipsa_nonce_buf != NULL) {
307 307 bzero(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
308 308 kmem_free(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t));
309 309 }
310 310 if (ipsa->ipsa_src_cid != NULL) {
311 311 IPSID_REFRELE(ipsa->ipsa_src_cid);
312 312 }
313 313 if (ipsa->ipsa_dst_cid != NULL) {
314 314 IPSID_REFRELE(ipsa->ipsa_dst_cid);
315 315 }
316 316 if (ipsa->ipsa_emech.cm_param != NULL)
317 317 kmem_free(ipsa->ipsa_emech.cm_param,
318 318 ipsa->ipsa_emech.cm_param_len);
319 319
320 320 mutex_destroy(&ipsa->ipsa_lock);
321 321 kmem_free(ipsa, sizeof (*ipsa));
322 322 }
323 323
324 324 /*
325 325 * Unlink a security association from a hash bucket. Assume the hash bucket
326 326 * lock is held, but the association's lock is not.
327 327 *
328 328 * Note that we do not bump the bucket's generation number here because
329 329 * we might not be making a visible change to the set of visible SA's.
330 330 * All callers MUST bump the bucket's generation number before they unlock
331 331 * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which
332 332 * was present in the bucket at the time it was locked.
333 333 */
334 334 void
335 335 sadb_unlinkassoc(ipsa_t *ipsa)
336 336 {
337 337 ASSERT(ipsa->ipsa_linklock != NULL);
338 338 ASSERT(MUTEX_HELD(ipsa->ipsa_linklock));
339 339
340 340 /* These fields are protected by the link lock. */
341 341 *(ipsa->ipsa_ptpn) = ipsa->ipsa_next;
342 342 if (ipsa->ipsa_next != NULL) {
343 343 ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn;
344 344 ipsa->ipsa_next = NULL;
345 345 }
346 346
347 347 ipsa->ipsa_ptpn = NULL;
348 348
349 349 /* This may destroy the SA. */
350 350 IPSA_REFRELE(ipsa);
351 351 }
352 352
353 353 /*
354 354 * Create a larval security association with the specified SPI. All other
355 355 * fields are zeroed.
356 356 */
357 357 static ipsa_t *
358 358 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam,
359 359 netstack_t *ns)
360 360 {
361 361 ipsa_t *newbie;
362 362
363 363 /*
364 364 * Allocate...
365 365 */
366 366
367 367 newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP);
368 368 if (newbie == NULL) {
369 369 /* Can't make new larval SA. */
370 370 return (NULL);
371 371 }
372 372
373 373 /* Assigned requested SPI, assume caller does SPI allocation magic. */
374 374 newbie->ipsa_spi = spi;
375 375 newbie->ipsa_netstack = ns; /* No netstack_hold */
376 376
377 377 /*
378 378 * Copy addresses...
379 379 */
380 380
381 381 IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam);
382 382 IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam);
383 383
384 384 newbie->ipsa_addrfam = addrfam;
385 385
386 386 /*
387 387 * Set common initialization values, including refcnt.
388 388 */
389 389 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
390 390 newbie->ipsa_state = IPSA_STATE_LARVAL;
391 391 newbie->ipsa_refcnt = 1;
392 392 newbie->ipsa_freefunc = sadb_freeassoc;
393 393
394 394 /*
395 395 * There aren't a lot of other common initialization values, as
396 396 * they are copied in from the PF_KEY message.
397 397 */
398 398
399 399 return (newbie);
400 400 }
401 401
402 402 /*
403 403 * Call me to initialize a security association fanout.
404 404 */
405 405 static int
406 406 sadb_init_fanout(isaf_t **tablep, uint_t size, int kmflag)
407 407 {
408 408 isaf_t *table;
409 409 int i;
410 410
411 411 table = (isaf_t *)kmem_alloc(size * sizeof (*table), kmflag);
412 412 *tablep = table;
413 413
414 414 if (table == NULL)
415 415 return (ENOMEM);
416 416
417 417 for (i = 0; i < size; i++) {
418 418 mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL);
419 419 table[i].isaf_ipsa = NULL;
420 420 table[i].isaf_gen = 0;
421 421 }
422 422
423 423 return (0);
424 424 }
425 425
426 426 /*
427 427 * Call me to initialize an acquire fanout
428 428 */
429 429 static int
430 430 sadb_init_acfanout(iacqf_t **tablep, uint_t size, int kmflag)
431 431 {
432 432 iacqf_t *table;
433 433 int i;
434 434
435 435 table = (iacqf_t *)kmem_alloc(size * sizeof (*table), kmflag);
436 436 *tablep = table;
437 437
438 438 if (table == NULL)
439 439 return (ENOMEM);
440 440
441 441 for (i = 0; i < size; i++) {
442 442 mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL);
443 443 table[i].iacqf_ipsacq = NULL;
444 444 }
445 445
446 446 return (0);
447 447 }
448 448
449 449 /*
450 450 * Attempt to initialize an SADB instance. On failure, return ENOMEM;
451 451 * caller must clean up partial allocations.
452 452 */
453 453 static int
454 454 sadb_init_trial(sadb_t *sp, uint_t size, int kmflag)
455 455 {
456 456 ASSERT(sp->sdb_of == NULL);
457 457 ASSERT(sp->sdb_if == NULL);
458 458 ASSERT(sp->sdb_acq == NULL);
459 459
460 460 sp->sdb_hashsize = size;
461 461 if (sadb_init_fanout(&sp->sdb_of, size, kmflag) != 0)
462 462 return (ENOMEM);
463 463 if (sadb_init_fanout(&sp->sdb_if, size, kmflag) != 0)
464 464 return (ENOMEM);
465 465 if (sadb_init_acfanout(&sp->sdb_acq, size, kmflag) != 0)
466 466 return (ENOMEM);
467 467
468 468 return (0);
469 469 }
470 470
471 471 /*
472 472 * Call me to initialize an SADB instance; fall back to default size on failure.
473 473 */
474 474 static void
475 475 sadb_init(const char *name, sadb_t *sp, uint_t size, uint_t ver,
476 476 netstack_t *ns)
477 477 {
478 478 ASSERT(sp->sdb_of == NULL);
479 479 ASSERT(sp->sdb_if == NULL);
480 480 ASSERT(sp->sdb_acq == NULL);
481 481
482 482 if (size < IPSEC_DEFAULT_HASH_SIZE)
483 483 size = IPSEC_DEFAULT_HASH_SIZE;
484 484
485 485 if (sadb_init_trial(sp, size, KM_NOSLEEP) != 0) {
486 486
487 487 cmn_err(CE_WARN,
488 488 "Unable to allocate %u entry IPv%u %s SADB hash table",
489 489 size, ver, name);
490 490
491 491 sadb_destroy(sp, ns);
492 492 size = IPSEC_DEFAULT_HASH_SIZE;
493 493 cmn_err(CE_WARN, "Falling back to %d entries", size);
494 494 (void) sadb_init_trial(sp, size, KM_SLEEP);
495 495 }
496 496 }
497 497
498 498
499 499 /*
500 500 * Initialize an SADB-pair.
501 501 */
502 502 void
503 503 sadbp_init(const char *name, sadbp_t *sp, int type, int size, netstack_t *ns)
504 504 {
505 505 sadb_init(name, &sp->s_v4, size, 4, ns);
506 506 sadb_init(name, &sp->s_v6, size, 6, ns);
507 507
508 508 sp->s_satype = type;
509 509
510 510 ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP));
511 511 if (type == SADB_SATYPE_AH) {
512 512 ipsec_stack_t *ipss = ns->netstack_ipsec;
513 513
514 514 ip_drop_register(&ipss->ipsec_sadb_dropper, "IPsec SADB");
515 515 sp->s_addflags = AH_ADD_SETTABLE_FLAGS;
516 516 sp->s_updateflags = AH_UPDATE_SETTABLE_FLAGS;
517 517 } else {
518 518 sp->s_addflags = ESP_ADD_SETTABLE_FLAGS;
519 519 sp->s_updateflags = ESP_UPDATE_SETTABLE_FLAGS;
520 520 }
521 521 }
522 522
523 523 /*
524 524 * Deliver a single SADB_DUMP message representing a single SA. This is
525 525 * called many times by sadb_dump().
526 526 *
527 527 * If the return value of this is ENOBUFS (not the same as ENOMEM), then
528 528 * the caller should take that as a hint that dupb() on the "original answer"
529 529 * failed, and that perhaps the caller should try again with a copyb()ed
530 530 * "original answer".
531 531 */
532 532 static int
533 533 sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa,
534 534 sadb_msg_t *samsg)
535 535 {
536 536 mblk_t *answer;
537 537
538 538 answer = dupb(original_answer);
539 539 if (answer == NULL)
540 540 return (ENOBUFS);
541 541 answer->b_cont = sadb_sa2msg(ipsa, samsg);
542 542 if (answer->b_cont == NULL) {
543 543 freeb(answer);
544 544 return (ENOMEM);
545 545 }
546 546
547 547 /* Just do a putnext, and let keysock deal with flow control. */
548 548 putnext(pfkey_q, answer);
549 549 return (0);
550 550 }
551 551
552 552 /*
553 553 * Common function to allocate and prepare a keysock_out_t M_CTL message.
554 554 */
555 555 mblk_t *
556 556 sadb_keysock_out(minor_t serial)
557 557 {
558 558 mblk_t *mp;
559 559 keysock_out_t *kso;
560 560
561 561 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
562 562 if (mp != NULL) {
563 563 mp->b_datap->db_type = M_CTL;
564 564 mp->b_wptr += sizeof (ipsec_info_t);
565 565 kso = (keysock_out_t *)mp->b_rptr;
566 566 kso->ks_out_type = KEYSOCK_OUT;
567 567 kso->ks_out_len = sizeof (*kso);
568 568 kso->ks_out_serial = serial;
569 569 }
|
↓ open down ↓ |
569 lines elided |
↑ open up ↑ |
570 570
571 571 return (mp);
572 572 }
573 573
574 574 /*
575 575 * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
576 576 * to keysock.
577 577 */
578 578 static int
579 579 sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout,
580 - int num_entries, boolean_t do_peers, time_t active_time)
580 + int num_entries, boolean_t do_peers)
581 581 {
582 582 int i, error = 0;
583 583 mblk_t *original_answer;
584 584 ipsa_t *walker;
585 585 sadb_msg_t *samsg;
586 - time_t current;
587 586
588 587 /*
589 588 * For each IPSA hash bucket do:
590 589 * - Hold the mutex
591 590 * - Walk each entry, doing an sadb_dump_deliver() on it.
592 591 */
593 592 ASSERT(mp->b_cont != NULL);
594 593 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
595 594
596 595 original_answer = sadb_keysock_out(serial);
597 596 if (original_answer == NULL)
598 597 return (ENOMEM);
599 598
600 - current = gethrestime_sec();
601 599 for (i = 0; i < num_entries; i++) {
602 600 mutex_enter(&fanout[i].isaf_lock);
603 601 for (walker = fanout[i].isaf_ipsa; walker != NULL;
604 602 walker = walker->ipsa_next) {
605 603 if (!do_peers && walker->ipsa_haspeer)
606 604 continue;
607 - if ((active_time != 0) &&
608 - ((current - walker->ipsa_lastuse) > active_time))
609 - continue;
610 605 error = sadb_dump_deliver(pfkey_q, original_answer,
611 606 walker, samsg);
612 607 if (error == ENOBUFS) {
613 608 mblk_t *new_original_answer;
614 609
615 610 /* Ran out of dupb's. Try a copyb. */
616 611 new_original_answer = copyb(original_answer);
617 612 if (new_original_answer == NULL) {
618 613 error = ENOMEM;
619 614 } else {
620 615 freeb(original_answer);
621 616 original_answer = new_original_answer;
622 617 error = sadb_dump_deliver(pfkey_q,
623 618 original_answer, walker, samsg);
624 619 }
625 620 }
626 621 if (error != 0)
627 622 break; /* out of for loop. */
628 623 }
629 624 mutex_exit(&fanout[i].isaf_lock);
630 625 if (error != 0)
631 626 break; /* out of for loop. */
632 627 }
633 628
634 629 freeb(original_answer);
635 630 return (error);
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
636 631 }
637 632
638 633 /*
639 634 * Dump an entire SADB; outbound first, then inbound.
640 635 */
641 636
642 637 int
643 638 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
644 639 {
645 640 int error;
646 - time_t active_time = 0;
647 - sadb_x_edump_t *edump =
648 - (sadb_x_edump_t *)ksi->ks_in_extv[SADB_X_EXT_EDUMP];
649 641
650 - if (edump != NULL) {
651 - active_time = edump->sadb_x_edump_timeout;
652 - }
653 -
654 642 /* Dump outbound */
655 643 error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
656 - sp->sdb_hashsize, B_TRUE, active_time);
644 + sp->sdb_hashsize, B_TRUE);
657 645 if (error)
658 646 return (error);
659 647
660 648 /* Dump inbound */
661 - return sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
662 - sp->sdb_hashsize, B_FALSE, active_time);
649 + return (sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
650 + sp->sdb_hashsize, B_FALSE));
663 651 }
664 652
665 653 /*
666 654 * Generic sadb table walker.
667 655 *
668 656 * Call "walkfn" for each SA in each bucket in "table"; pass the
669 657 * bucket, the entry and "cookie" to the callback function.
670 658 * Take care to ensure that walkfn can delete the SA without screwing
671 659 * up our traverse.
672 660 *
673 661 * The bucket is locked for the duration of the callback, both so that the
674 662 * callback can just call sadb_unlinkassoc() when it wants to delete something,
675 663 * and so that no new entries are added while we're walking the list.
676 664 */
677 665 static void
678 666 sadb_walker(isaf_t *table, uint_t numentries,
679 667 void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
680 668 void *cookie)
681 669 {
682 670 int i;
683 671 for (i = 0; i < numentries; i++) {
684 672 ipsa_t *entry, *next;
685 673
686 674 mutex_enter(&table[i].isaf_lock);
687 675
688 676 for (entry = table[i].isaf_ipsa; entry != NULL;
689 677 entry = next) {
690 678 next = entry->ipsa_next;
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
691 679 (*walkfn)(&table[i], entry, cookie);
692 680 }
693 681 mutex_exit(&table[i].isaf_lock);
694 682 }
695 683 }
696 684
697 685 /*
698 686 * Call me to free up a security association fanout. Use the forever
699 687 * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
700 688 * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
701 - * when a module is unloaded).
689 + * when a netstack is destroyed or a module is unloaded).
702 690 */
703 691 static void
704 -sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever,
705 - boolean_t inbound)
692 +sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever)
706 693 {
707 694 int i;
708 695 isaf_t *table = *tablep;
709 696 ipsa_t *sa;
710 697
711 698 if (table == NULL)
712 699 return;
713 700
714 701 for (i = 0; i < numentries; i++) {
715 702 mutex_enter(&table[i].isaf_lock);
716 703 while ((sa = table[i].isaf_ipsa) != NULL) {
717 704 sadb_unlinkassoc(sa);
718 705 }
719 706 table[i].isaf_gen++;
720 707 mutex_exit(&table[i].isaf_lock);
721 708 if (forever)
722 709 mutex_destroy(&(table[i].isaf_lock));
723 710 }
724 711
725 712 if (forever) {
726 713 *tablep = NULL;
727 714 kmem_free(table, numentries * sizeof (*table));
728 715 }
729 716 }
730 717
731 718 /*
732 719 * Entry points to sadb_destroyer().
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
733 720 */
734 721 static void
735 722 sadb_flush(sadb_t *sp, netstack_t *ns)
736 723 {
737 724 /*
738 725 * Flush out each bucket, one at a time. Were it not for keysock's
739 726 * enforcement, there would be a subtlety where I could add on the
740 727 * heels of a flush. With keysock's enforcement, however, this
741 728 * makes ESP's job easy.
742 729 */
743 - sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE, B_FALSE);
744 - sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE, B_TRUE);
730 + sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE);
731 + sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE);
745 732
746 733 /* For each acquire, destroy it; leave the bucket mutex alone. */
747 734 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
748 735 }
749 736
750 737 static void
751 738 sadb_destroy(sadb_t *sp, netstack_t *ns)
752 739 {
753 - sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE, B_FALSE);
754 - sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE, B_TRUE);
740 + sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE);
741 + sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE);
755 742
756 743 /* For each acquire, destroy it, including the bucket mutex. */
757 744 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
758 745
759 746 ASSERT(sp->sdb_of == NULL);
760 747 ASSERT(sp->sdb_if == NULL);
761 748 ASSERT(sp->sdb_acq == NULL);
762 749 }
763 750
764 751 void
765 752 sadbp_flush(sadbp_t *spp, netstack_t *ns)
766 753 {
767 754 sadb_flush(&spp->s_v4, ns);
768 755 sadb_flush(&spp->s_v6, ns);
769 756 }
770 757
771 758 void
772 759 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
773 760 {
774 761 sadb_destroy(&spp->s_v4, ns);
775 762 sadb_destroy(&spp->s_v6, ns);
776 763
777 764 if (spp->s_satype == SADB_SATYPE_AH) {
778 765 ipsec_stack_t *ipss = ns->netstack_ipsec;
779 766
780 767 ip_drop_unregister(&ipss->ipsec_sadb_dropper);
781 768 }
782 769 }
783 770
784 771
785 772 /*
786 773 * Check hard vs. soft lifetimes. If there's a reality mismatch (e.g.
787 774 * soft lifetimes > hard lifetimes) return an appropriate diagnostic for
788 775 * EINVAL.
789 776 */
790 777 int
791 778 sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft,
792 779 sadb_lifetime_t *idle)
793 780 {
794 781 if (hard == NULL || soft == NULL)
795 782 return (0);
796 783
797 784 if (hard->sadb_lifetime_allocations != 0 &&
798 785 soft->sadb_lifetime_allocations != 0 &&
799 786 hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations)
800 787 return (SADB_X_DIAGNOSTIC_ALLOC_HSERR);
801 788
802 789 if (hard->sadb_lifetime_bytes != 0 &&
803 790 soft->sadb_lifetime_bytes != 0 &&
804 791 hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes)
805 792 return (SADB_X_DIAGNOSTIC_BYTES_HSERR);
806 793
807 794 if (hard->sadb_lifetime_addtime != 0 &&
808 795 soft->sadb_lifetime_addtime != 0 &&
809 796 hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime)
810 797 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
811 798
812 799 if (hard->sadb_lifetime_usetime != 0 &&
813 800 soft->sadb_lifetime_usetime != 0 &&
814 801 hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime)
815 802 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
816 803
817 804 if (idle != NULL) {
818 805 if (hard->sadb_lifetime_addtime != 0 &&
819 806 idle->sadb_lifetime_addtime != 0 &&
820 807 hard->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
821 808 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
822 809
823 810 if (soft->sadb_lifetime_addtime != 0 &&
824 811 idle->sadb_lifetime_addtime != 0 &&
825 812 soft->sadb_lifetime_addtime < idle->sadb_lifetime_addtime)
826 813 return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR);
827 814
828 815 if (hard->sadb_lifetime_usetime != 0 &&
829 816 idle->sadb_lifetime_usetime != 0 &&
830 817 hard->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
831 818 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
832 819
833 820 if (soft->sadb_lifetime_usetime != 0 &&
834 821 idle->sadb_lifetime_usetime != 0 &&
835 822 soft->sadb_lifetime_usetime < idle->sadb_lifetime_usetime)
836 823 return (SADB_X_DIAGNOSTIC_USETIME_HSERR);
837 824 }
838 825
839 826 return (0);
840 827 }
841 828
842 829 /*
843 830 * Sanity check sensitivity labels.
844 831 *
845 832 * For now, just reject labels on unlabeled systems.
846 833 */
847 834 int
848 835 sadb_labelchk(keysock_in_t *ksi)
849 836 {
850 837 if (!is_system_labeled()) {
851 838 if (ksi->ks_in_extv[SADB_EXT_SENSITIVITY] != NULL)
852 839 return (SADB_X_DIAGNOSTIC_BAD_LABEL);
853 840
854 841 if (ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS] != NULL)
855 842 return (SADB_X_DIAGNOSTIC_BAD_LABEL);
856 843 }
857 844
858 845 return (0);
859 846 }
860 847
861 848 /*
862 849 * Clone a security association for the purposes of inserting a single SA
863 850 * into inbound and outbound tables respectively. This function should only
864 851 * be called from sadb_common_add().
865 852 */
866 853 static ipsa_t *
867 854 sadb_cloneassoc(ipsa_t *ipsa)
868 855 {
869 856 ipsa_t *newbie;
870 857 boolean_t error = B_FALSE;
871 858
872 859 ASSERT(MUTEX_NOT_HELD(&(ipsa->ipsa_lock)));
873 860
874 861 newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP);
875 862 if (newbie == NULL)
876 863 return (NULL);
877 864
878 865 /* Copy over what we can. */
879 866 *newbie = *ipsa;
880 867
881 868 /* bzero and initialize locks, in case *_init() allocates... */
882 869 mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL);
883 870
884 871 if (newbie->ipsa_tsl != NULL)
885 872 label_hold(newbie->ipsa_tsl);
886 873
887 874 if (newbie->ipsa_otsl != NULL)
888 875 label_hold(newbie->ipsa_otsl);
889 876
890 877 /*
891 878 * While somewhat dain-bramaged, the most graceful way to
892 879 * recover from errors is to keep plowing through the
893 880 * allocations, and getting what I can. It's easier to call
894 881 * sadb_freeassoc() on the stillborn clone when all the
895 882 * pointers aren't pointing to the parent's data.
896 883 */
897 884
898 885 if (ipsa->ipsa_authkey != NULL) {
899 886 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
900 887 KM_NOSLEEP);
901 888 if (newbie->ipsa_authkey == NULL) {
902 889 error = B_TRUE;
903 890 } else {
904 891 bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey,
905 892 newbie->ipsa_authkeylen);
906 893
907 894 newbie->ipsa_kcfauthkey.ck_data =
908 895 newbie->ipsa_authkey;
909 896 }
910 897
911 898 if (newbie->ipsa_amech.cm_param != NULL) {
912 899 newbie->ipsa_amech.cm_param =
913 900 (char *)&newbie->ipsa_mac_len;
914 901 }
915 902 }
916 903
917 904 if (ipsa->ipsa_encrkey != NULL) {
918 905 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
919 906 KM_NOSLEEP);
920 907 if (newbie->ipsa_encrkey == NULL) {
921 908 error = B_TRUE;
922 909 } else {
923 910 bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey,
924 911 newbie->ipsa_encrkeylen);
925 912
926 913 newbie->ipsa_kcfencrkey.ck_data =
927 914 newbie->ipsa_encrkey;
928 915 }
929 916 }
930 917
931 918 newbie->ipsa_authtmpl = NULL;
932 919 newbie->ipsa_encrtmpl = NULL;
933 920 newbie->ipsa_haspeer = B_TRUE;
934 921
935 922 if (ipsa->ipsa_src_cid != NULL) {
936 923 newbie->ipsa_src_cid = ipsa->ipsa_src_cid;
937 924 IPSID_REFHOLD(ipsa->ipsa_src_cid);
938 925 }
939 926
940 927 if (ipsa->ipsa_dst_cid != NULL) {
941 928 newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid;
942 929 IPSID_REFHOLD(ipsa->ipsa_dst_cid);
943 930 }
944 931
945 932 if (error) {
946 933 sadb_freeassoc(newbie);
947 934 return (NULL);
948 935 }
949 936
950 937 return (newbie);
951 938 }
952 939
953 940 /*
954 941 * Initialize a SADB address extension at the address specified by addrext.
955 942 * Return a pointer to the end of the new address extension.
956 943 */
957 944 static uint8_t *
958 945 sadb_make_addr_ext(uint8_t *start, uint8_t *end, uint16_t exttype,
959 946 sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto, int prefix)
960 947 {
961 948 struct sockaddr_in *sin;
962 949 struct sockaddr_in6 *sin6;
963 950 uint8_t *cur = start;
964 951 int addrext_len;
965 952 int sin_len;
966 953 sadb_address_t *addrext = (sadb_address_t *)cur;
967 954
968 955 if (cur == NULL)
969 956 return (NULL);
970 957
971 958 cur += sizeof (*addrext);
972 959 if (cur > end)
973 960 return (NULL);
974 961
975 962 addrext->sadb_address_proto = proto;
976 963 addrext->sadb_address_prefixlen = prefix;
977 964 addrext->sadb_address_reserved = 0;
978 965 addrext->sadb_address_exttype = exttype;
979 966
980 967 switch (af) {
981 968 case AF_INET:
982 969 sin = (struct sockaddr_in *)cur;
983 970 sin_len = sizeof (*sin);
984 971 cur += sin_len;
985 972 if (cur > end)
986 973 return (NULL);
987 974
988 975 sin->sin_family = af;
989 976 bzero(sin->sin_zero, sizeof (sin->sin_zero));
990 977 sin->sin_port = port;
991 978 IPSA_COPY_ADDR(&sin->sin_addr, addr, af);
992 979 break;
993 980 case AF_INET6:
994 981 sin6 = (struct sockaddr_in6 *)cur;
995 982 sin_len = sizeof (*sin6);
996 983 cur += sin_len;
997 984 if (cur > end)
998 985 return (NULL);
999 986
1000 987 bzero(sin6, sizeof (*sin6));
1001 988 sin6->sin6_family = af;
1002 989 sin6->sin6_port = port;
1003 990 IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af);
1004 991 break;
1005 992 }
1006 993
1007 994 addrext_len = roundup(cur - start, sizeof (uint64_t));
1008 995 addrext->sadb_address_len = SADB_8TO64(addrext_len);
1009 996
1010 997 cur = start + addrext_len;
1011 998 if (cur > end)
1012 999 cur = NULL;
1013 1000
1014 1001 return (cur);
1015 1002 }
1016 1003
1017 1004 /*
1018 1005 * Construct a key management cookie extension.
1019 1006 */
1020 1007
1021 1008 static uint8_t *
1022 1009 sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint32_t kmc)
1023 1010 {
1024 1011 sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur;
1025 1012
1026 1013 if (cur == NULL)
1027 1014 return (NULL);
1028 1015
1029 1016 cur += sizeof (*kmcext);
1030 1017
1031 1018 if (cur > end)
1032 1019 return (NULL);
1033 1020
1034 1021 kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
1035 1022 kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
1036 1023 kmcext->sadb_x_kmc_proto = kmp;
1037 1024 kmcext->sadb_x_kmc_cookie = kmc;
1038 1025 kmcext->sadb_x_kmc_reserved = 0;
1039 1026
1040 1027 return (cur);
1041 1028 }
1042 1029
1043 1030 /*
1044 1031 * Given an original message header with sufficient space following it, and an
1045 1032 * SA, construct a full PF_KEY message with all of the relevant extensions.
1046 1033 * This is mostly used for SADB_GET, and SADB_DUMP.
1047 1034 */
1048 1035 static mblk_t *
1049 1036 sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg)
1050 1037 {
1051 1038 int alloclen, addrsize, paddrsize, authsize, encrsize;
1052 1039 int srcidsize, dstidsize, senslen, osenslen;
1053 1040 sa_family_t fam, pfam; /* Address family for SADB_EXT_ADDRESS */
1054 1041 /* src/dst and proxy sockaddrs. */
1055 1042 /*
1056 1043 * The following are pointers into the PF_KEY message this PF_KEY
1057 1044 * message creates.
1058 1045 */
1059 1046 sadb_msg_t *newsamsg;
1060 1047 sadb_sa_t *assoc;
1061 1048 sadb_lifetime_t *lt;
1062 1049 sadb_key_t *key;
1063 1050 sadb_ident_t *ident;
1064 1051 sadb_sens_t *sens;
1065 1052 sadb_ext_t *walker; /* For when we need a generic ext. pointer. */
1066 1053 sadb_x_replay_ctr_t *repl_ctr;
1067 1054 sadb_x_pair_t *pair_ext;
1068 1055
1069 1056 mblk_t *mp;
1070 1057 uint8_t *cur, *end;
1071 1058 /* These indicate the presence of the above extension fields. */
1072 1059 boolean_t soft = B_FALSE, hard = B_FALSE;
1073 1060 boolean_t isrc = B_FALSE, idst = B_FALSE;
1074 1061 boolean_t auth = B_FALSE, encr = B_FALSE;
1075 1062 boolean_t sensinteg = B_FALSE, osensinteg = B_FALSE;
1076 1063 boolean_t srcid = B_FALSE, dstid = B_FALSE;
1077 1064 boolean_t idle;
1078 1065 boolean_t paired;
1079 1066 uint32_t otherspi;
1080 1067
1081 1068 /* First off, figure out the allocation length for this message. */
1082 1069 /*
1083 1070 * Constant stuff. This includes base, SA, address (src, dst),
1084 1071 * and lifetime (current).
1085 1072 */
1086 1073 alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) +
1087 1074 sizeof (sadb_lifetime_t);
1088 1075
1089 1076 fam = ipsa->ipsa_addrfam;
1090 1077 switch (fam) {
1091 1078 case AF_INET:
1092 1079 addrsize = roundup(sizeof (struct sockaddr_in) +
1093 1080 sizeof (sadb_address_t), sizeof (uint64_t));
1094 1081 break;
1095 1082 case AF_INET6:
1096 1083 addrsize = roundup(sizeof (struct sockaddr_in6) +
1097 1084 sizeof (sadb_address_t), sizeof (uint64_t));
1098 1085 break;
1099 1086 default:
1100 1087 return (NULL);
1101 1088 }
1102 1089 /*
1103 1090 * Allocate TWO address extensions, for source and destination.
1104 1091 * (Thus, the * 2.)
1105 1092 */
1106 1093 alloclen += addrsize * 2;
1107 1094 if (ipsa->ipsa_flags & IPSA_F_NATT_REM)
1108 1095 alloclen += addrsize;
1109 1096 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC)
1110 1097 alloclen += addrsize;
1111 1098
1112 1099 if (ipsa->ipsa_flags & IPSA_F_PAIRED) {
1113 1100 paired = B_TRUE;
1114 1101 alloclen += sizeof (sadb_x_pair_t);
1115 1102 otherspi = ipsa->ipsa_otherspi;
1116 1103 } else {
1117 1104 paired = B_FALSE;
1118 1105 }
1119 1106
1120 1107 /* How 'bout other lifetimes? */
1121 1108 if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 ||
1122 1109 ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) {
1123 1110 alloclen += sizeof (sadb_lifetime_t);
1124 1111 soft = B_TRUE;
1125 1112 }
1126 1113
1127 1114 if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 ||
1128 1115 ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) {
1129 1116 alloclen += sizeof (sadb_lifetime_t);
1130 1117 hard = B_TRUE;
1131 1118 }
1132 1119
1133 1120 if (ipsa->ipsa_idleaddlt != 0 || ipsa->ipsa_idleuselt != 0) {
1134 1121 alloclen += sizeof (sadb_lifetime_t);
1135 1122 idle = B_TRUE;
1136 1123 } else {
1137 1124 idle = B_FALSE;
1138 1125 }
1139 1126
1140 1127 /* Inner addresses. */
1141 1128 if (ipsa->ipsa_innerfam != 0) {
1142 1129 pfam = ipsa->ipsa_innerfam;
1143 1130 switch (pfam) {
1144 1131 case AF_INET6:
1145 1132 paddrsize = roundup(sizeof (struct sockaddr_in6) +
1146 1133 sizeof (sadb_address_t), sizeof (uint64_t));
1147 1134 break;
1148 1135 case AF_INET:
1149 1136 paddrsize = roundup(sizeof (struct sockaddr_in) +
1150 1137 sizeof (sadb_address_t), sizeof (uint64_t));
1151 1138 break;
1152 1139 default:
1153 1140 cmn_err(CE_PANIC,
1154 1141 "IPsec SADB: Proxy length failure.\n");
1155 1142 break;
1156 1143 }
1157 1144 isrc = B_TRUE;
1158 1145 idst = B_TRUE;
1159 1146 alloclen += 2 * paddrsize;
1160 1147 }
1161 1148
1162 1149 /* For the following fields, assume that length != 0 ==> stuff */
1163 1150 if (ipsa->ipsa_authkeylen != 0) {
1164 1151 authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen,
1165 1152 sizeof (uint64_t));
1166 1153 alloclen += authsize;
1167 1154 auth = B_TRUE;
1168 1155 }
1169 1156
1170 1157 if (ipsa->ipsa_encrkeylen != 0) {
1171 1158 encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen +
1172 1159 ipsa->ipsa_nonce_len, sizeof (uint64_t));
1173 1160 alloclen += encrsize;
1174 1161 encr = B_TRUE;
1175 1162 } else {
1176 1163 encr = B_FALSE;
1177 1164 }
1178 1165
1179 1166 if (ipsa->ipsa_tsl != NULL) {
1180 1167 senslen = sadb_sens_len_from_label(ipsa->ipsa_tsl);
1181 1168 alloclen += senslen;
1182 1169 sensinteg = B_TRUE;
1183 1170 }
1184 1171
1185 1172 if (ipsa->ipsa_otsl != NULL) {
1186 1173 osenslen = sadb_sens_len_from_label(ipsa->ipsa_otsl);
1187 1174 alloclen += osenslen;
1188 1175 osensinteg = B_TRUE;
1189 1176 }
1190 1177
1191 1178 /*
1192 1179 * Must use strlen() here for lengths. Identities use NULL
1193 1180 * pointers to indicate their nonexistence.
1194 1181 */
1195 1182 if (ipsa->ipsa_src_cid != NULL) {
1196 1183 srcidsize = roundup(sizeof (sadb_ident_t) +
1197 1184 strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1,
1198 1185 sizeof (uint64_t));
1199 1186 alloclen += srcidsize;
1200 1187 srcid = B_TRUE;
1201 1188 }
1202 1189
1203 1190 if (ipsa->ipsa_dst_cid != NULL) {
1204 1191 dstidsize = roundup(sizeof (sadb_ident_t) +
1205 1192 strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1,
1206 1193 sizeof (uint64_t));
1207 1194 alloclen += dstidsize;
1208 1195 dstid = B_TRUE;
1209 1196 }
1210 1197
1211 1198 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0))
1212 1199 alloclen += sizeof (sadb_x_kmc_t);
1213 1200
1214 1201 if (ipsa->ipsa_replay != 0) {
1215 1202 alloclen += sizeof (sadb_x_replay_ctr_t);
1216 1203 }
1217 1204
1218 1205 /* Make sure the allocation length is a multiple of 8 bytes. */
1219 1206 ASSERT((alloclen & 0x7) == 0);
1220 1207
1221 1208 /* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */
1222 1209 mp = allocb(alloclen, BPRI_HI);
1223 1210 if (mp == NULL)
1224 1211 return (NULL);
1225 1212 bzero(mp->b_rptr, alloclen);
1226 1213
1227 1214 mp->b_wptr += alloclen;
1228 1215 end = mp->b_wptr;
1229 1216 newsamsg = (sadb_msg_t *)mp->b_rptr;
1230 1217 *newsamsg = *samsg;
1231 1218 newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen);
1232 1219
1233 1220 mutex_enter(&ipsa->ipsa_lock); /* Since I'm grabbing SA fields... */
1234 1221
1235 1222 newsamsg->sadb_msg_satype = ipsa->ipsa_type;
1236 1223
1237 1224 assoc = (sadb_sa_t *)(newsamsg + 1);
1238 1225 assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc));
1239 1226 assoc->sadb_sa_exttype = SADB_EXT_SA;
1240 1227 assoc->sadb_sa_spi = ipsa->ipsa_spi;
1241 1228 assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize;
1242 1229 assoc->sadb_sa_state = ipsa->ipsa_state;
1243 1230 assoc->sadb_sa_auth = ipsa->ipsa_auth_alg;
1244 1231 assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg;
1245 1232 assoc->sadb_sa_flags = ipsa->ipsa_flags;
1246 1233
1247 1234 lt = (sadb_lifetime_t *)(assoc + 1);
1248 1235 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1249 1236 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
1250 1237 /* We do not support the concept. */
1251 1238 lt->sadb_lifetime_allocations = 0;
1252 1239 lt->sadb_lifetime_bytes = ipsa->ipsa_bytes;
1253 1240 lt->sadb_lifetime_addtime = ipsa->ipsa_addtime;
1254 1241 lt->sadb_lifetime_usetime = ipsa->ipsa_usetime;
1255 1242
1256 1243 if (hard) {
1257 1244 lt++;
1258 1245 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1259 1246 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1260 1247 lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc;
1261 1248 lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt;
1262 1249 lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt;
1263 1250 lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt;
1264 1251 }
1265 1252
1266 1253 if (soft) {
1267 1254 lt++;
1268 1255 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1269 1256 lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1270 1257 lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc;
1271 1258 lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt;
1272 1259 lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt;
1273 1260 lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt;
1274 1261 }
1275 1262
1276 1263 if (idle) {
1277 1264 lt++;
1278 1265 lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt));
1279 1266 lt->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
1280 1267 lt->sadb_lifetime_addtime = ipsa->ipsa_idleaddlt;
1281 1268 lt->sadb_lifetime_usetime = ipsa->ipsa_idleuselt;
1282 1269 }
1283 1270
1284 1271 cur = (uint8_t *)(lt + 1);
1285 1272
1286 1273 /* NOTE: Don't fill in ports here if we are a tunnel-mode SA. */
1287 1274 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam,
1288 1275 ipsa->ipsa_srcaddr, (!isrc && !idst) ? SA_SRCPORT(ipsa) : 0,
1289 1276 SA_PROTO(ipsa), 0);
1290 1277 if (cur == NULL) {
1291 1278 freemsg(mp);
1292 1279 mp = NULL;
1293 1280 goto bail;
1294 1281 }
1295 1282
1296 1283 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam,
1297 1284 ipsa->ipsa_dstaddr, (!isrc && !idst) ? SA_DSTPORT(ipsa) : 0,
1298 1285 SA_PROTO(ipsa), 0);
1299 1286 if (cur == NULL) {
1300 1287 freemsg(mp);
1301 1288 mp = NULL;
1302 1289 goto bail;
1303 1290 }
1304 1291
1305 1292 if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) {
1306 1293 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC,
1307 1294 fam, &ipsa->ipsa_natt_addr_loc, ipsa->ipsa_local_nat_port,
1308 1295 IPPROTO_UDP, 0);
1309 1296 if (cur == NULL) {
1310 1297 freemsg(mp);
1311 1298 mp = NULL;
1312 1299 goto bail;
1313 1300 }
1314 1301 }
1315 1302
1316 1303 if (ipsa->ipsa_flags & IPSA_F_NATT_REM) {
1317 1304 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM,
1318 1305 fam, &ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_nat_port,
1319 1306 IPPROTO_UDP, 0);
1320 1307 if (cur == NULL) {
1321 1308 freemsg(mp);
1322 1309 mp = NULL;
1323 1310 goto bail;
1324 1311 }
1325 1312 }
1326 1313
1327 1314 /* If we are a tunnel-mode SA, fill in the inner-selectors. */
1328 1315 if (isrc) {
1329 1316 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
1330 1317 pfam, ipsa->ipsa_innersrc, SA_SRCPORT(ipsa),
1331 1318 SA_IPROTO(ipsa), ipsa->ipsa_innersrcpfx);
1332 1319 if (cur == NULL) {
1333 1320 freemsg(mp);
1334 1321 mp = NULL;
1335 1322 goto bail;
1336 1323 }
1337 1324 }
1338 1325
1339 1326 if (idst) {
1340 1327 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
1341 1328 pfam, ipsa->ipsa_innerdst, SA_DSTPORT(ipsa),
1342 1329 SA_IPROTO(ipsa), ipsa->ipsa_innerdstpfx);
1343 1330 if (cur == NULL) {
1344 1331 freemsg(mp);
1345 1332 mp = NULL;
1346 1333 goto bail;
1347 1334 }
1348 1335 }
1349 1336
1350 1337 if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) {
1351 1338 cur = sadb_make_kmc_ext(cur, end,
1352 1339 ipsa->ipsa_kmp, ipsa->ipsa_kmc);
1353 1340 if (cur == NULL) {
1354 1341 freemsg(mp);
1355 1342 mp = NULL;
1356 1343 goto bail;
1357 1344 }
1358 1345 }
1359 1346
1360 1347 walker = (sadb_ext_t *)cur;
1361 1348 if (auth) {
1362 1349 key = (sadb_key_t *)walker;
1363 1350 key->sadb_key_len = SADB_8TO64(authsize);
1364 1351 key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
1365 1352 key->sadb_key_bits = ipsa->ipsa_authkeybits;
1366 1353 key->sadb_key_reserved = 0;
1367 1354 bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen);
1368 1355 walker = (sadb_ext_t *)((uint64_t *)walker +
1369 1356 walker->sadb_ext_len);
1370 1357 }
1371 1358
1372 1359 if (encr) {
1373 1360 uint8_t *buf_ptr;
1374 1361 key = (sadb_key_t *)walker;
1375 1362 key->sadb_key_len = SADB_8TO64(encrsize);
1376 1363 key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1377 1364 key->sadb_key_bits = ipsa->ipsa_encrkeybits;
1378 1365 key->sadb_key_reserved = ipsa->ipsa_saltbits;
1379 1366 buf_ptr = (uint8_t *)(key + 1);
1380 1367 bcopy(ipsa->ipsa_encrkey, buf_ptr, ipsa->ipsa_encrkeylen);
1381 1368 if (ipsa->ipsa_salt != NULL) {
1382 1369 buf_ptr += ipsa->ipsa_encrkeylen;
1383 1370 bcopy(ipsa->ipsa_salt, buf_ptr, ipsa->ipsa_saltlen);
1384 1371 }
1385 1372 walker = (sadb_ext_t *)((uint64_t *)walker +
1386 1373 walker->sadb_ext_len);
1387 1374 }
1388 1375
1389 1376 if (srcid) {
1390 1377 ident = (sadb_ident_t *)walker;
1391 1378 ident->sadb_ident_len = SADB_8TO64(srcidsize);
1392 1379 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
1393 1380 ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type;
1394 1381 ident->sadb_ident_id = 0;
1395 1382 ident->sadb_ident_reserved = 0;
1396 1383 (void) strcpy((char *)(ident + 1),
1397 1384 ipsa->ipsa_src_cid->ipsid_cid);
1398 1385 walker = (sadb_ext_t *)((uint64_t *)walker +
1399 1386 walker->sadb_ext_len);
1400 1387 }
1401 1388
1402 1389 if (dstid) {
1403 1390 ident = (sadb_ident_t *)walker;
1404 1391 ident->sadb_ident_len = SADB_8TO64(dstidsize);
1405 1392 ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
1406 1393 ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type;
1407 1394 ident->sadb_ident_id = 0;
1408 1395 ident->sadb_ident_reserved = 0;
1409 1396 (void) strcpy((char *)(ident + 1),
1410 1397 ipsa->ipsa_dst_cid->ipsid_cid);
1411 1398 walker = (sadb_ext_t *)((uint64_t *)walker +
1412 1399 walker->sadb_ext_len);
1413 1400 }
1414 1401
1415 1402 if (sensinteg) {
1416 1403 sens = (sadb_sens_t *)walker;
1417 1404 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
1418 1405 ipsa->ipsa_tsl, senslen);
1419 1406
1420 1407 walker = (sadb_ext_t *)((uint64_t *)walker +
1421 1408 walker->sadb_ext_len);
1422 1409 }
1423 1410
1424 1411 if (osensinteg) {
1425 1412 sens = (sadb_sens_t *)walker;
1426 1413
1427 1414 sadb_sens_from_label(sens, SADB_X_EXT_OUTER_SENS,
1428 1415 ipsa->ipsa_otsl, osenslen);
1429 1416 if (ipsa->ipsa_mac_exempt)
1430 1417 sens->sadb_x_sens_flags = SADB_X_SENS_IMPLICIT;
1431 1418
1432 1419 walker = (sadb_ext_t *)((uint64_t *)walker +
1433 1420 walker->sadb_ext_len);
1434 1421 }
1435 1422
1436 1423 if (paired) {
1437 1424 pair_ext = (sadb_x_pair_t *)walker;
1438 1425
1439 1426 pair_ext->sadb_x_pair_len = SADB_8TO64(sizeof (sadb_x_pair_t));
1440 1427 pair_ext->sadb_x_pair_exttype = SADB_X_EXT_PAIR;
1441 1428 pair_ext->sadb_x_pair_spi = otherspi;
1442 1429
1443 1430 walker = (sadb_ext_t *)((uint64_t *)walker +
1444 1431 walker->sadb_ext_len);
1445 1432 }
1446 1433
1447 1434 if (ipsa->ipsa_replay != 0) {
1448 1435 repl_ctr = (sadb_x_replay_ctr_t *)walker;
1449 1436 repl_ctr->sadb_x_rc_len = SADB_8TO64(sizeof (*repl_ctr));
1450 1437 repl_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE;
1451 1438 repl_ctr->sadb_x_rc_replay32 = ipsa->ipsa_replay;
1452 1439 repl_ctr->sadb_x_rc_replay64 = 0;
1453 1440 walker = (sadb_ext_t *)(repl_ctr + 1);
1454 1441 }
1455 1442
1456 1443 bail:
1457 1444 /* Pardon any delays... */
1458 1445 mutex_exit(&ipsa->ipsa_lock);
1459 1446
1460 1447 return (mp);
1461 1448 }
1462 1449
1463 1450 /*
1464 1451 * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN)
1465 1452 * and adjust base message accordingly.
1466 1453 *
1467 1454 * Assume message is pulled up in one piece of contiguous memory.
1468 1455 *
1469 1456 * Say if we start off with:
1470 1457 *
1471 1458 * +------+----+-------------+-----------+---------------+---------------+
1472 1459 * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime |
1473 1460 * +------+----+-------------+-----------+---------------+---------------+
1474 1461 *
1475 1462 * we will end up with
1476 1463 *
1477 1464 * +------+----+-------------+-----------+---------------+
1478 1465 * | base | SA | source addr | dest addr | soft lifetime |
1479 1466 * +------+----+-------------+-----------+---------------+
1480 1467 */
1481 1468 static void
1482 1469 sadb_strip(sadb_msg_t *samsg)
1483 1470 {
1484 1471 sadb_ext_t *ext;
1485 1472 uint8_t *target = NULL;
|
↓ open down ↓ |
721 lines elided |
↑ open up ↑ |
1486 1473 uint8_t *msgend;
1487 1474 int sofar = SADB_8TO64(sizeof (*samsg));
1488 1475 int copylen;
1489 1476
1490 1477 ext = (sadb_ext_t *)(samsg + 1);
1491 1478 msgend = (uint8_t *)samsg;
1492 1479 msgend += SADB_64TO8(samsg->sadb_msg_len);
1493 1480 while ((uint8_t *)ext < msgend) {
1494 1481 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1495 1482 ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1496 - ext->sadb_ext_type == SADB_X_EXT_EDUMP ||
1497 1483 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1498 1484 /*
1499 1485 * Aha! I found a header to be erased.
1500 1486 */
1501 1487
1502 1488 if (target != NULL) {
1503 1489 /*
1504 1490 * If I had a previous header to be erased,
1505 1491 * copy over it. I can get away with just
1506 1492 * copying backwards because the target will
1507 1493 * always be 8 bytes behind the source.
1508 1494 */
1509 1495 copylen = ((uint8_t *)ext) - (target +
1510 1496 SADB_64TO8(
1511 1497 ((sadb_ext_t *)target)->sadb_ext_len));
1512 1498 ovbcopy(((uint8_t *)ext - copylen), target,
1513 1499 copylen);
1514 1500 target += copylen;
1515 1501 ((sadb_ext_t *)target)->sadb_ext_len =
1516 1502 SADB_8TO64(((uint8_t *)ext) - target +
1517 1503 SADB_64TO8(ext->sadb_ext_len));
1518 1504 } else {
1519 1505 target = (uint8_t *)ext;
1520 1506 }
1521 1507 } else {
1522 1508 sofar += ext->sadb_ext_len;
1523 1509 }
1524 1510
1525 1511 ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len);
1526 1512 }
1527 1513
1528 1514 ASSERT((uint8_t *)ext == msgend);
1529 1515
1530 1516 if (target != NULL) {
1531 1517 copylen = ((uint8_t *)ext) - (target +
1532 1518 SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len));
1533 1519 if (copylen != 0)
1534 1520 ovbcopy(((uint8_t *)ext - copylen), target, copylen);
1535 1521 }
1536 1522
1537 1523 /* Adjust samsg. */
1538 1524 samsg->sadb_msg_len = (uint16_t)sofar;
1539 1525
1540 1526 /* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */
1541 1527 }
1542 1528
1543 1529 /*
1544 1530 * AH needs to send an error to PF_KEY. Assume mp points to an M_CTL
1545 1531 * followed by an M_DATA with a PF_KEY message in it. The serial of
1546 1532 * the sending keysock instance is included.
1547 1533 */
1548 1534 void
1549 1535 sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic,
1550 1536 uint_t serial)
1551 1537 {
1552 1538 mblk_t *msg = mp->b_cont;
1553 1539 sadb_msg_t *samsg;
1554 1540 keysock_out_t *kso;
1555 1541
1556 1542 /*
1557 1543 * Enough functions call this to merit a NULL queue check.
1558 1544 */
1559 1545 if (pfkey_q == NULL) {
1560 1546 freemsg(mp);
1561 1547 return;
1562 1548 }
1563 1549
1564 1550 ASSERT(msg != NULL);
1565 1551 ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t));
1566 1552 ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t));
1567 1553 samsg = (sadb_msg_t *)msg->b_rptr;
1568 1554 kso = (keysock_out_t *)mp->b_rptr;
1569 1555
1570 1556 kso->ks_out_type = KEYSOCK_OUT;
1571 1557 kso->ks_out_len = sizeof (*kso);
1572 1558 kso->ks_out_serial = serial;
1573 1559
1574 1560 /*
1575 1561 * Only send the base message up in the event of an error.
1576 1562 * Don't worry about bzero()-ing, because it was probably bogus
1577 1563 * anyway.
1578 1564 */
1579 1565 msg->b_wptr = msg->b_rptr + sizeof (*samsg);
1580 1566 samsg = (sadb_msg_t *)msg->b_rptr;
1581 1567 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
1582 1568 samsg->sadb_msg_errno = (uint8_t)error;
1583 1569 if (diagnostic != SADB_X_DIAGNOSTIC_PRESET)
1584 1570 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1585 1571
1586 1572 putnext(pfkey_q, mp);
1587 1573 }
1588 1574
1589 1575 /*
1590 1576 * Send a successful return packet back to keysock via the queue in pfkey_q.
1591 1577 *
1592 1578 * Often, an SA is associated with the reply message, it's passed in if needed,
1593 1579 * and NULL if not. BTW, that ipsa will have its refcnt appropriately held,
1594 1580 * and the caller will release said refcnt.
1595 1581 */
1596 1582 void
1597 1583 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1598 1584 keysock_in_t *ksi, ipsa_t *ipsa)
1599 1585 {
1600 1586 keysock_out_t *kso;
1601 1587 mblk_t *mp1;
1602 1588 sadb_msg_t *newsamsg;
|
↓ open down ↓ |
96 lines elided |
↑ open up ↑ |
1603 1589 uint8_t *oldend;
1604 1590
1605 1591 ASSERT((mp->b_cont != NULL) &&
1606 1592 ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1607 1593 ((void *)mp->b_rptr == (void *)ksi));
1608 1594
1609 1595 switch (samsg->sadb_msg_type) {
1610 1596 case SADB_ADD:
1611 1597 case SADB_UPDATE:
1612 1598 case SADB_X_UPDATEPAIR:
1613 - case SADB_X_DELPAIR_STATE:
1614 1599 case SADB_FLUSH:
1615 1600 case SADB_DUMP:
1616 1601 /*
1617 1602 * I have all of the message already. I just need to strip
1618 1603 * out the keying material and echo the message back.
1619 1604 *
1620 1605 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1621 1606 * work. When DUMP reaches here, it should only be a base
1622 1607 * message.
1623 1608 */
1624 1609 justecho:
1610 + ASSERT(samsg->sadb_msg_type != SADB_DUMP ||
1611 + samsg->sadb_msg_len == SADB_8TO64(sizeof (sadb_msg_t)));
1625 1612 if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1626 - ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL ||
1627 - ksi->ks_in_extv[SADB_X_EXT_EDUMP] != NULL) {
1613 + ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL) {
1628 1614 sadb_strip(samsg);
1629 1615 /* Assume PF_KEY message is contiguous. */
1630 1616 ASSERT(mp->b_cont->b_cont == NULL);
1631 1617 oldend = mp->b_cont->b_wptr;
1632 1618 mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1633 1619 SADB_64TO8(samsg->sadb_msg_len);
1634 1620 bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1635 1621 }
1636 1622 break;
1637 1623 case SADB_GET:
1638 1624 /*
1639 1625 * Do a lot of work here, because of the ipsa I just found.
1640 1626 * First construct the new PF_KEY message, then abandon
1641 1627 * the old one.
1642 1628 */
1643 1629 mp1 = sadb_sa2msg(ipsa, samsg);
1644 1630 if (mp1 == NULL) {
1645 1631 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1646 1632 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1647 1633 return;
1648 1634 }
1649 1635 freemsg(mp->b_cont);
1650 1636 mp->b_cont = mp1;
1651 1637 break;
1652 1638 case SADB_DELETE:
1653 1639 case SADB_X_DELPAIR:
1654 1640 if (ipsa == NULL)
1655 1641 goto justecho;
1656 1642 /*
1657 1643 * Because listening KMds may require more info, treat
1658 1644 * DELETE like a special case of GET.
1659 1645 */
1660 1646 mp1 = sadb_sa2msg(ipsa, samsg);
1661 1647 if (mp1 == NULL) {
1662 1648 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1663 1649 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1664 1650 return;
1665 1651 }
1666 1652 newsamsg = (sadb_msg_t *)mp1->b_rptr;
1667 1653 sadb_strip(newsamsg);
1668 1654 oldend = mp1->b_wptr;
1669 1655 mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len);
1670 1656 bzero(mp1->b_wptr, oldend - mp1->b_wptr);
1671 1657 freemsg(mp->b_cont);
1672 1658 mp->b_cont = mp1;
1673 1659 break;
1674 1660 default:
1675 1661 if (mp != NULL)
1676 1662 freemsg(mp);
1677 1663 return;
1678 1664 }
1679 1665
1680 1666 /* ksi is now null and void. */
1681 1667 kso = (keysock_out_t *)ksi;
1682 1668 kso->ks_out_type = KEYSOCK_OUT;
1683 1669 kso->ks_out_len = sizeof (*kso);
1684 1670 kso->ks_out_serial = ksi->ks_in_serial;
1685 1671 /* We're ready to send... */
1686 1672 putnext(pfkey_q, mp);
1687 1673 }
1688 1674
1689 1675 /*
1690 1676 * Set up a global pfkey_q instance for AH, ESP, or some other consumer.
1691 1677 */
1692 1678 void
1693 1679 sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp,
1694 1680 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype)
1695 1681 {
1696 1682 keysock_hello_ack_t *kha;
1697 1683 queue_t *oldq;
1698 1684
1699 1685 ASSERT(OTHERQ(q) != NULL);
1700 1686
1701 1687 /*
1702 1688 * First, check atomically that I'm the first and only keysock
1703 1689 * instance.
1704 1690 *
1705 1691 * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp),
1706 1692 * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY
1707 1693 * messages.
1708 1694 */
1709 1695
1710 1696 oldq = atomic_cas_ptr((void **)pfkey_qp, NULL, OTHERQ(q));
1711 1697 if (oldq != NULL) {
1712 1698 ASSERT(oldq != q);
1713 1699 cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n",
1714 1700 (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other");
1715 1701 freemsg(mp);
1716 1702 return;
1717 1703 }
1718 1704
1719 1705 kha = (keysock_hello_ack_t *)mp->b_rptr;
1720 1706 kha->ks_hello_len = sizeof (keysock_hello_ack_t);
1721 1707 kha->ks_hello_type = KEYSOCK_HELLO_ACK;
1722 1708 kha->ks_hello_satype = (uint8_t)satype;
1723 1709
1724 1710 /*
1725 1711 * If we made it past the atomic_cas_ptr, then we have "exclusive"
1726 1712 * access to the timeout handle. Fire it off after the default ager
1727 1713 * interval.
1728 1714 */
1729 1715 *top = qtimeout(*pfkey_qp, ager, agerarg,
1730 1716 drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000));
1731 1717
1732 1718 putnext(*pfkey_qp, mp);
1733 1719 }
1734 1720
1735 1721 /*
1736 1722 * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate.
1737 1723 *
1738 1724 * Check addresses themselves for wildcard or multicast.
1739 1725 * Check ire table for local/non-local/broadcast.
1740 1726 */
1741 1727 int
1742 1728 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial,
1743 1729 netstack_t *ns)
1744 1730 {
1745 1731 sadb_address_t *addr = (sadb_address_t *)ext;
1746 1732 struct sockaddr_in *sin;
1747 1733 struct sockaddr_in6 *sin6;
1748 1734 int diagnostic, type;
1749 1735 boolean_t normalized = B_FALSE;
1750 1736
1751 1737 ASSERT(ext != NULL);
1752 1738 ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) ||
1753 1739 (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) ||
1754 1740 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ||
1755 1741 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) ||
1756 1742 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) ||
1757 1743 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM));
1758 1744
1759 1745 /* Assign both sockaddrs, the compiler will do the right thing. */
1760 1746 sin = (struct sockaddr_in *)(addr + 1);
1761 1747 sin6 = (struct sockaddr_in6 *)(addr + 1);
1762 1748
1763 1749 if (sin6->sin6_family == AF_INET6) {
1764 1750 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1765 1751 /*
1766 1752 * Convert to an AF_INET sockaddr. This means the
1767 1753 * return messages will have the extra space, but have
1768 1754 * AF_INET sockaddrs instead of AF_INET6.
1769 1755 *
1770 1756 * Yes, RFC 2367 isn't clear on what to do here w.r.t.
1771 1757 * mapped addresses, but since AF_INET6 ::ffff:<v4> is
1772 1758 * equal to AF_INET <v4>, it shouldnt be a huge
1773 1759 * problem.
1774 1760 */
1775 1761 sin->sin_family = AF_INET;
1776 1762 IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
1777 1763 &sin->sin_addr);
1778 1764 bzero(&sin->sin_zero, sizeof (sin->sin_zero));
1779 1765 normalized = B_TRUE;
1780 1766 }
1781 1767 } else if (sin->sin_family != AF_INET) {
1782 1768 switch (ext->sadb_ext_type) {
1783 1769 case SADB_EXT_ADDRESS_SRC:
1784 1770 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF;
1785 1771 break;
1786 1772 case SADB_EXT_ADDRESS_DST:
1787 1773 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
1788 1774 break;
1789 1775 case SADB_X_EXT_ADDRESS_INNER_SRC:
1790 1776 diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF;
1791 1777 break;
1792 1778 case SADB_X_EXT_ADDRESS_INNER_DST:
1793 1779 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF;
1794 1780 break;
1795 1781 case SADB_X_EXT_ADDRESS_NATT_LOC:
1796 1782 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF;
1797 1783 break;
1798 1784 case SADB_X_EXT_ADDRESS_NATT_REM:
1799 1785 diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF;
1800 1786 break;
1801 1787 /* There is no default, see above ASSERT. */
1802 1788 }
1803 1789 bail:
1804 1790 if (pfkey_q != NULL) {
1805 1791 sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic,
1806 1792 serial);
1807 1793 } else {
1808 1794 /*
1809 1795 * Scribble in sadb_msg that we got passed in.
1810 1796 * Overload "mp" to be an sadb_msg pointer.
1811 1797 */
1812 1798 sadb_msg_t *samsg = (sadb_msg_t *)mp;
1813 1799
1814 1800 samsg->sadb_msg_errno = EINVAL;
1815 1801 samsg->sadb_x_msg_diagnostic = diagnostic;
1816 1802 }
1817 1803 return (KS_IN_ADDR_UNKNOWN);
1818 1804 }
1819 1805
1820 1806 if (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC ||
1821 1807 ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) {
1822 1808 /*
1823 1809 * We need only check for prefix issues.
1824 1810 */
1825 1811
1826 1812 /* Set diagnostic now, in case we need it later. */
1827 1813 diagnostic =
1828 1814 (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ?
1829 1815 SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC :
1830 1816 SADB_X_DIAGNOSTIC_PREFIX_INNER_DST;
1831 1817
1832 1818 if (normalized)
1833 1819 addr->sadb_address_prefixlen -= 96;
1834 1820
1835 1821 /*
1836 1822 * Verify and mask out inner-addresses based on prefix length.
1837 1823 */
1838 1824 if (sin->sin_family == AF_INET) {
1839 1825 if (addr->sadb_address_prefixlen > 32)
1840 1826 goto bail;
1841 1827 sin->sin_addr.s_addr &=
1842 1828 ip_plen_to_mask(addr->sadb_address_prefixlen);
1843 1829 } else {
1844 1830 in6_addr_t mask;
1845 1831
1846 1832 ASSERT(sin->sin_family == AF_INET6);
1847 1833 /*
1848 1834 * ip_plen_to_mask_v6() returns NULL if the value in
1849 1835 * question is out of range.
1850 1836 */
1851 1837 if (ip_plen_to_mask_v6(addr->sadb_address_prefixlen,
1852 1838 &mask) == NULL)
1853 1839 goto bail;
1854 1840 sin6->sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
1855 1841 sin6->sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
1856 1842 sin6->sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
1857 1843 sin6->sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
1858 1844 }
1859 1845
1860 1846 /* We don't care in these cases. */
1861 1847 return (KS_IN_ADDR_DONTCARE);
1862 1848 }
1863 1849
1864 1850 if (sin->sin_family == AF_INET6) {
1865 1851 /* Check the easy ones now. */
1866 1852 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
1867 1853 return (KS_IN_ADDR_MBCAST);
1868 1854 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
1869 1855 return (KS_IN_ADDR_UNSPEC);
1870 1856 /*
1871 1857 * At this point, we're a unicast IPv6 address.
1872 1858 *
1873 1859 * XXX Zones alert -> me/notme decision needs to be tempered
1874 1860 * by what zone we're in when we go to zone-aware IPsec.
1875 1861 */
1876 1862 if (ip_type_v6(&sin6->sin6_addr, ns->netstack_ip) ==
1877 1863 IRE_LOCAL) {
1878 1864 /* Hey hey, it's local. */
1879 1865 return (KS_IN_ADDR_ME);
1880 1866 }
1881 1867 } else {
1882 1868 ASSERT(sin->sin_family == AF_INET);
1883 1869 if (sin->sin_addr.s_addr == INADDR_ANY)
1884 1870 return (KS_IN_ADDR_UNSPEC);
1885 1871 if (CLASSD(sin->sin_addr.s_addr))
1886 1872 return (KS_IN_ADDR_MBCAST);
1887 1873 /*
1888 1874 * At this point we're a unicast or broadcast IPv4 address.
1889 1875 *
1890 1876 * Check if the address is IRE_BROADCAST or IRE_LOCAL.
1891 1877 *
1892 1878 * XXX Zones alert -> me/notme decision needs to be tempered
1893 1879 * by what zone we're in when we go to zone-aware IPsec.
1894 1880 */
1895 1881 type = ip_type_v4(sin->sin_addr.s_addr, ns->netstack_ip);
1896 1882 switch (type) {
1897 1883 case IRE_LOCAL:
1898 1884 return (KS_IN_ADDR_ME);
1899 1885 case IRE_BROADCAST:
1900 1886 return (KS_IN_ADDR_MBCAST);
1901 1887 }
1902 1888 }
1903 1889
1904 1890 return (KS_IN_ADDR_NOTME);
1905 1891 }
1906 1892
1907 1893 /*
1908 1894 * Address normalizations and reality checks for inbound PF_KEY messages.
1909 1895 *
1910 1896 * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert
1911 1897 * the source to AF_INET. Do the same for the inner sources.
1912 1898 */
1913 1899 boolean_t
1914 1900 sadb_addrfix(keysock_in_t *ksi, queue_t *pfkey_q, mblk_t *mp, netstack_t *ns)
1915 1901 {
1916 1902 struct sockaddr_in *src, *isrc;
1917 1903 struct sockaddr_in6 *dst, *idst;
1918 1904 sadb_address_t *srcext, *dstext;
1919 1905 uint16_t sport;
1920 1906 sadb_ext_t **extv = ksi->ks_in_extv;
1921 1907 int rc;
1922 1908
1923 1909 if (extv[SADB_EXT_ADDRESS_SRC] != NULL) {
1924 1910 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_SRC],
1925 1911 ksi->ks_in_serial, ns);
1926 1912 if (rc == KS_IN_ADDR_UNKNOWN)
1927 1913 return (B_FALSE);
1928 1914 if (rc == KS_IN_ADDR_MBCAST) {
1929 1915 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1930 1916 SADB_X_DIAGNOSTIC_BAD_SRC, ksi->ks_in_serial);
1931 1917 return (B_FALSE);
1932 1918 }
1933 1919 ksi->ks_in_srctype = rc;
1934 1920 }
1935 1921
1936 1922 if (extv[SADB_EXT_ADDRESS_DST] != NULL) {
1937 1923 rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_DST],
1938 1924 ksi->ks_in_serial, ns);
1939 1925 if (rc == KS_IN_ADDR_UNKNOWN)
1940 1926 return (B_FALSE);
1941 1927 if (rc == KS_IN_ADDR_UNSPEC) {
1942 1928 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1943 1929 SADB_X_DIAGNOSTIC_BAD_DST, ksi->ks_in_serial);
1944 1930 return (B_FALSE);
1945 1931 }
1946 1932 ksi->ks_in_dsttype = rc;
1947 1933 }
1948 1934
1949 1935 /*
1950 1936 * NAT-Traversal addrs are simple enough to not require all of
1951 1937 * the checks in sadb_addrcheck(). Just normalize or reject if not
1952 1938 * AF_INET.
1953 1939 */
1954 1940 if (extv[SADB_X_EXT_ADDRESS_NATT_LOC] != NULL) {
1955 1941 rc = sadb_addrcheck(pfkey_q, mp,
1956 1942 extv[SADB_X_EXT_ADDRESS_NATT_LOC], ksi->ks_in_serial, ns);
1957 1943
1958 1944 /*
1959 1945 * Local NAT-T addresses never use an IRE_LOCAL, so it should
1960 1946 * always be NOTME, or UNSPEC (to handle both tunnel mode
1961 1947 * AND local-port flexibility).
1962 1948 */
1963 1949 if (rc != KS_IN_ADDR_NOTME && rc != KS_IN_ADDR_UNSPEC) {
1964 1950 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1965 1951 SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC,
1966 1952 ksi->ks_in_serial);
1967 1953 return (B_FALSE);
1968 1954 }
1969 1955 src = (struct sockaddr_in *)
1970 1956 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_LOC]) + 1);
1971 1957 if (src->sin_family != AF_INET) {
1972 1958 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1973 1959 SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF,
1974 1960 ksi->ks_in_serial);
1975 1961 return (B_FALSE);
1976 1962 }
1977 1963 }
1978 1964
1979 1965 if (extv[SADB_X_EXT_ADDRESS_NATT_REM] != NULL) {
1980 1966 rc = sadb_addrcheck(pfkey_q, mp,
1981 1967 extv[SADB_X_EXT_ADDRESS_NATT_REM], ksi->ks_in_serial, ns);
1982 1968
1983 1969 /*
1984 1970 * Remote NAT-T addresses never use an IRE_LOCAL, so it should
1985 1971 * always be NOTME, or UNSPEC if it's a tunnel-mode SA.
1986 1972 */
1987 1973 if (rc != KS_IN_ADDR_NOTME &&
1988 1974 !(extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL &&
1989 1975 rc == KS_IN_ADDR_UNSPEC)) {
1990 1976 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1991 1977 SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM,
1992 1978 ksi->ks_in_serial);
1993 1979 return (B_FALSE);
1994 1980 }
1995 1981 src = (struct sockaddr_in *)
1996 1982 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_REM]) + 1);
1997 1983 if (src->sin_family != AF_INET) {
1998 1984 sadb_pfkey_error(pfkey_q, mp, EINVAL,
1999 1985 SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF,
2000 1986 ksi->ks_in_serial);
2001 1987 return (B_FALSE);
2002 1988 }
2003 1989 }
2004 1990
2005 1991 if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL) {
2006 1992 if (extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) {
2007 1993 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2008 1994 SADB_X_DIAGNOSTIC_MISSING_INNER_DST,
2009 1995 ksi->ks_in_serial);
2010 1996 return (B_FALSE);
2011 1997 }
2012 1998
2013 1999 if (sadb_addrcheck(pfkey_q, mp,
2014 2000 extv[SADB_X_EXT_ADDRESS_INNER_DST], ksi->ks_in_serial, ns)
2015 2001 == KS_IN_ADDR_UNKNOWN ||
2016 2002 sadb_addrcheck(pfkey_q, mp,
2017 2003 extv[SADB_X_EXT_ADDRESS_INNER_SRC], ksi->ks_in_serial, ns)
2018 2004 == KS_IN_ADDR_UNKNOWN)
2019 2005 return (B_FALSE);
2020 2006
2021 2007 isrc = (struct sockaddr_in *)
2022 2008 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC]) +
2023 2009 1);
2024 2010 idst = (struct sockaddr_in6 *)
2025 2011 (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST]) +
2026 2012 1);
2027 2013 if (isrc->sin_family != idst->sin6_family) {
2028 2014 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2029 2015 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH,
2030 2016 ksi->ks_in_serial);
2031 2017 return (B_FALSE);
2032 2018 }
2033 2019 } else if (extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) {
2034 2020 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2035 2021 SADB_X_DIAGNOSTIC_MISSING_INNER_SRC,
2036 2022 ksi->ks_in_serial);
2037 2023 return (B_FALSE);
2038 2024 } else {
2039 2025 isrc = NULL; /* For inner/outer port check below. */
2040 2026 }
2041 2027
2042 2028 dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST];
2043 2029 srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC];
2044 2030
2045 2031 if (dstext == NULL || srcext == NULL)
2046 2032 return (B_TRUE);
2047 2033
2048 2034 dst = (struct sockaddr_in6 *)(dstext + 1);
2049 2035 src = (struct sockaddr_in *)(srcext + 1);
2050 2036
2051 2037 if (isrc != NULL &&
2052 2038 (isrc->sin_port != 0 || idst->sin6_port != 0) &&
2053 2039 (src->sin_port != 0 || dst->sin6_port != 0)) {
2054 2040 /* Can't set inner and outer ports in one SA. */
2055 2041 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2056 2042 SADB_X_DIAGNOSTIC_DUAL_PORT_SETS,
2057 2043 ksi->ks_in_serial);
2058 2044 return (B_FALSE);
2059 2045 }
2060 2046
2061 2047 if (dst->sin6_family == src->sin_family)
2062 2048 return (B_TRUE);
2063 2049
2064 2050 if (srcext->sadb_address_proto != dstext->sadb_address_proto) {
2065 2051 if (srcext->sadb_address_proto == 0) {
2066 2052 srcext->sadb_address_proto = dstext->sadb_address_proto;
2067 2053 } else if (dstext->sadb_address_proto == 0) {
2068 2054 dstext->sadb_address_proto = srcext->sadb_address_proto;
2069 2055 } else {
2070 2056 /* Inequal protocols, neither were 0. Report error. */
2071 2057 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2072 2058 SADB_X_DIAGNOSTIC_PROTO_MISMATCH,
2073 2059 ksi->ks_in_serial);
2074 2060 return (B_FALSE);
2075 2061 }
2076 2062 }
2077 2063
2078 2064 /*
2079 2065 * With the exception of an unspec IPv6 source and an IPv4
2080 2066 * destination, address families MUST me matched.
2081 2067 */
2082 2068 if (src->sin_family == AF_INET ||
2083 2069 ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC) {
2084 2070 sadb_pfkey_error(pfkey_q, mp, EINVAL,
2085 2071 SADB_X_DIAGNOSTIC_AF_MISMATCH, ksi->ks_in_serial);
2086 2072 return (B_FALSE);
2087 2073 }
2088 2074
2089 2075 /*
2090 2076 * Convert "src" to AF_INET INADDR_ANY. We rely on sin_port being
2091 2077 * in the same place for sockaddr_in and sockaddr_in6.
2092 2078 */
2093 2079 sport = src->sin_port;
2094 2080 bzero(src, sizeof (*src));
2095 2081 src->sin_family = AF_INET;
2096 2082 src->sin_port = sport;
2097 2083
2098 2084 return (B_TRUE);
2099 2085 }
2100 2086
2101 2087 /*
2102 2088 * Set the results in "addrtype", given an IRE as requested by
2103 2089 * sadb_addrcheck().
2104 2090 */
2105 2091 int
2106 2092 sadb_addrset(ire_t *ire)
2107 2093 {
2108 2094 if ((ire->ire_type & IRE_BROADCAST) ||
2109 2095 (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) ||
2110 2096 (ire->ire_ipversion == IPV6_VERSION &&
2111 2097 IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))))
2112 2098 return (KS_IN_ADDR_MBCAST);
2113 2099 if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK))
2114 2100 return (KS_IN_ADDR_ME);
2115 2101 return (KS_IN_ADDR_NOTME);
2116 2102 }
2117 2103
2118 2104 /*
2119 2105 * Match primitives..
2120 2106 * !!! TODO: short term: inner selectors
2121 2107 * ipv6 scope id (ifindex)
2122 2108 * longer term: zone id. sensitivity label. uid.
2123 2109 */
2124 2110 boolean_t
2125 2111 sadb_match_spi(ipsa_query_t *sq, ipsa_t *sa)
2126 2112 {
2127 2113 return (sq->spi == sa->ipsa_spi);
2128 2114 }
2129 2115
2130 2116 boolean_t
2131 2117 sadb_match_dst_v6(ipsa_query_t *sq, ipsa_t *sa)
2132 2118 {
2133 2119 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_dstaddr, sq->dstaddr, AF_INET6));
2134 2120 }
2135 2121
2136 2122 boolean_t
2137 2123 sadb_match_src_v6(ipsa_query_t *sq, ipsa_t *sa)
2138 2124 {
2139 2125 return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_srcaddr, sq->srcaddr, AF_INET6));
2140 2126 }
2141 2127
2142 2128 boolean_t
2143 2129 sadb_match_dst_v4(ipsa_query_t *sq, ipsa_t *sa)
2144 2130 {
2145 2131 return (sq->dstaddr[0] == sa->ipsa_dstaddr[0]);
2146 2132 }
2147 2133
2148 2134 boolean_t
2149 2135 sadb_match_src_v4(ipsa_query_t *sq, ipsa_t *sa)
2150 2136 {
2151 2137 return (sq->srcaddr[0] == sa->ipsa_srcaddr[0]);
2152 2138 }
2153 2139
2154 2140 boolean_t
2155 2141 sadb_match_dstid(ipsa_query_t *sq, ipsa_t *sa)
2156 2142 {
2157 2143 return ((sa->ipsa_dst_cid != NULL) &&
2158 2144 (sq->didtype == sa->ipsa_dst_cid->ipsid_type) &&
2159 2145 (strcmp(sq->didstr, sa->ipsa_dst_cid->ipsid_cid) == 0));
2160 2146
2161 2147 }
2162 2148 boolean_t
2163 2149 sadb_match_srcid(ipsa_query_t *sq, ipsa_t *sa)
2164 2150 {
2165 2151 return ((sa->ipsa_src_cid != NULL) &&
2166 2152 (sq->sidtype == sa->ipsa_src_cid->ipsid_type) &&
2167 2153 (strcmp(sq->sidstr, sa->ipsa_src_cid->ipsid_cid) == 0));
2168 2154 }
2169 2155
2170 2156 boolean_t
2171 2157 sadb_match_kmc(ipsa_query_t *sq, ipsa_t *sa)
2172 2158 {
2173 2159 #define M(a, b) (((a) == 0) || ((b) == 0) || ((a) == (b)))
2174 2160
2175 2161 return (M(sq->kmc, sa->ipsa_kmc) && M(sq->kmp, sa->ipsa_kmp));
2176 2162
2177 2163 #undef M
2178 2164 }
2179 2165
2180 2166 /*
2181 2167 * Common function which extracts several PF_KEY extensions for ease of
2182 2168 * SADB matching.
2183 2169 *
2184 2170 * XXX TODO: weed out ipsa_query_t fields not used during matching
2185 2171 * or afterwards?
2186 2172 */
2187 2173 int
2188 2174 sadb_form_query(keysock_in_t *ksi, uint32_t req, uint32_t match,
2189 2175 ipsa_query_t *sq, int *diagnostic)
2190 2176 {
2191 2177 int i;
2192 2178 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2193 2179
2194 2180 for (i = 0; i < IPSA_NMATCH; i++)
2195 2181 sq->matchers[i] = NULL;
2196 2182
2197 2183 ASSERT((req & ~match) == 0);
2198 2184
2199 2185 sq->req = req;
2200 2186 sq->dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2201 2187 sq->srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2202 2188 sq->assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2203 2189
2204 2190 if ((req & IPSA_Q_DST) && (sq->dstext == NULL)) {
2205 2191 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2206 2192 return (EINVAL);
2207 2193 }
2208 2194 if ((req & IPSA_Q_SRC) && (sq->srcext == NULL)) {
2209 2195 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2210 2196 return (EINVAL);
2211 2197 }
2212 2198 if ((req & IPSA_Q_SA) && (sq->assoc == NULL)) {
2213 2199 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2214 2200 return (EINVAL);
2215 2201 }
2216 2202
2217 2203 if (match & IPSA_Q_SA) {
2218 2204 *mfpp++ = sadb_match_spi;
2219 2205 sq->spi = sq->assoc->sadb_sa_spi;
2220 2206 }
2221 2207
2222 2208 if (sq->dstext != NULL)
2223 2209 sq->dst = (struct sockaddr_in *)(sq->dstext + 1);
2224 2210 else {
2225 2211 sq->dst = NULL;
2226 2212 sq->dst6 = NULL;
2227 2213 sq->dstaddr = NULL;
2228 2214 }
2229 2215
2230 2216 if (sq->srcext != NULL)
2231 2217 sq->src = (struct sockaddr_in *)(sq->srcext + 1);
2232 2218 else {
2233 2219 sq->src = NULL;
2234 2220 sq->src6 = NULL;
2235 2221 sq->srcaddr = NULL;
2236 2222 }
2237 2223
2238 2224 if (sq->dst != NULL)
2239 2225 sq->af = sq->dst->sin_family;
2240 2226 else if (sq->src != NULL)
2241 2227 sq->af = sq->src->sin_family;
2242 2228 else
2243 2229 sq->af = AF_INET;
2244 2230
2245 2231 if (sq->af == AF_INET6) {
2246 2232 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2247 2233 *mfpp++ = sadb_match_dst_v6;
2248 2234 sq->dst6 = (struct sockaddr_in6 *)sq->dst;
2249 2235 sq->dstaddr = (uint32_t *)&(sq->dst6->sin6_addr);
2250 2236 } else {
2251 2237 match &= ~IPSA_Q_DST;
2252 2238 sq->dstaddr = ALL_ZEROES_PTR;
2253 2239 }
2254 2240
2255 2241 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2256 2242 sq->src6 = (struct sockaddr_in6 *)(sq->srcext + 1);
2257 2243 sq->srcaddr = (uint32_t *)&sq->src6->sin6_addr;
2258 2244 if (sq->src6->sin6_family != AF_INET6) {
2259 2245 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2260 2246 return (EINVAL);
2261 2247 }
2262 2248 *mfpp++ = sadb_match_src_v6;
2263 2249 } else {
2264 2250 match &= ~IPSA_Q_SRC;
2265 2251 sq->srcaddr = ALL_ZEROES_PTR;
2266 2252 }
2267 2253 } else {
2268 2254 sq->src6 = sq->dst6 = NULL;
2269 2255 if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) {
2270 2256 *mfpp++ = sadb_match_dst_v4;
2271 2257 sq->dstaddr = (uint32_t *)&sq->dst->sin_addr;
2272 2258 } else {
2273 2259 match &= ~IPSA_Q_DST;
2274 2260 sq->dstaddr = ALL_ZEROES_PTR;
2275 2261 }
2276 2262 if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) {
2277 2263 sq->srcaddr = (uint32_t *)&sq->src->sin_addr;
2278 2264 if (sq->src->sin_family != AF_INET) {
2279 2265 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
2280 2266 return (EINVAL);
2281 2267 }
2282 2268 *mfpp++ = sadb_match_src_v4;
2283 2269 } else {
2284 2270 match &= ~IPSA_Q_SRC;
2285 2271 sq->srcaddr = ALL_ZEROES_PTR;
2286 2272 }
2287 2273 }
2288 2274
2289 2275 sq->dstid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
2290 2276 if ((match & IPSA_Q_DSTID) && (sq->dstid != NULL)) {
2291 2277 sq->didstr = (char *)(sq->dstid + 1);
2292 2278 sq->didtype = sq->dstid->sadb_ident_type;
2293 2279 *mfpp++ = sadb_match_dstid;
2294 2280 }
2295 2281
2296 2282 sq->srcid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
2297 2283
2298 2284 if ((match & IPSA_Q_SRCID) && (sq->srcid != NULL)) {
2299 2285 sq->sidstr = (char *)(sq->srcid + 1);
2300 2286 sq->sidtype = sq->srcid->sadb_ident_type;
2301 2287 *mfpp++ = sadb_match_srcid;
2302 2288 }
2303 2289
2304 2290 sq->kmcext = (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2305 2291 sq->kmc = 0;
2306 2292 sq->kmp = 0;
2307 2293
2308 2294 if ((match & IPSA_Q_KMC) && (sq->kmcext)) {
2309 2295 sq->kmc = sq->kmcext->sadb_x_kmc_cookie;
2310 2296 sq->kmp = sq->kmcext->sadb_x_kmc_proto;
2311 2297 *mfpp++ = sadb_match_kmc;
2312 2298 }
2313 2299
2314 2300 if (match & (IPSA_Q_INBOUND|IPSA_Q_OUTBOUND)) {
2315 2301 if (sq->af == AF_INET6)
2316 2302 sq->sp = &sq->spp->s_v6;
2317 2303 else
2318 2304 sq->sp = &sq->spp->s_v4;
2319 2305 } else {
2320 2306 sq->sp = NULL;
2321 2307 }
2322 2308
2323 2309 if (match & IPSA_Q_INBOUND) {
2324 2310 sq->inhash = INBOUND_HASH(sq->sp, sq->assoc->sadb_sa_spi);
2325 2311 sq->inbound = &sq->sp->sdb_if[sq->inhash];
2326 2312 } else {
2327 2313 sq->inhash = 0;
2328 2314 sq->inbound = NULL;
2329 2315 }
2330 2316
2331 2317 if (match & IPSA_Q_OUTBOUND) {
2332 2318 if (sq->af == AF_INET6) {
2333 2319 sq->outhash = OUTBOUND_HASH_V6(sq->sp, *(sq->dstaddr));
2334 2320 } else {
2335 2321 sq->outhash = OUTBOUND_HASH_V4(sq->sp, *(sq->dstaddr));
2336 2322 }
2337 2323 sq->outbound = &sq->sp->sdb_of[sq->outhash];
2338 2324 } else {
2339 2325 sq->outhash = 0;
2340 2326 sq->outbound = NULL;
2341 2327 }
2342 2328 sq->match = match;
2343 2329 return (0);
2344 2330 }
2345 2331
2346 2332 /*
2347 2333 * Match an initialized query structure with a security association;
2348 2334 * return B_TRUE on a match, B_FALSE on a miss.
2349 2335 * Applies match functions set up by sadb_form_query() until one returns false.
2350 2336 */
2351 2337 boolean_t
2352 2338 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2353 2339 {
2354 2340 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2355 2341 ipsa_match_fn_t mfp;
2356 2342
2357 2343 for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2358 2344 if (!mfp(sq, sa))
2359 2345 return (B_FALSE);
|
↓ open down ↓ |
722 lines elided |
↑ open up ↑ |
2360 2346 }
2361 2347 return (B_TRUE);
2362 2348 }
2363 2349
2364 2350 /*
2365 2351 * Walker callback function to delete sa's based on src/dst address.
2366 2352 * Assumes that we're called with *head locked, no other locks held;
2367 2353 * Conveniently, and not coincidentally, this is both what sadb_walker
2368 2354 * gives us and also what sadb_unlinkassoc expects.
2369 2355 */
2370 -struct sadb_purge_state
2371 -{
2372 - ipsa_query_t sq;
2373 - boolean_t inbnd;
2374 - uint8_t sadb_sa_state;
2375 -};
2376 -
2377 2356 static void
2378 2357 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2379 2358 {
2380 - struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2359 + ipsa_query_t *query = (ipsa_query_t *)cookie;
2381 2360
2382 2361 ASSERT(MUTEX_HELD(&head->isaf_lock));
2383 2362
2384 2363 mutex_enter(&entry->ipsa_lock);
2385 2364
2386 2365 if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2387 - !sadb_match_query(&ps->sq, entry)) {
2366 + !sadb_match_query(query, entry)) {
2388 2367 mutex_exit(&entry->ipsa_lock);
2389 2368 return;
2390 2369 }
2391 2370
2392 2371 entry->ipsa_state = IPSA_STATE_DEAD;
2393 2372 (void) sadb_torch_assoc(head, entry);
2394 2373 }
2395 2374
2396 2375 /*
2397 2376 * Common code to purge an SA with a matching src or dst address.
2398 2377 * Don't kill larval SA's in such a purge.
2399 2378 */
2400 2379 int
2401 2380 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2402 2381 int *diagnostic, queue_t *pfkey_q)
2403 2382 {
2404 - struct sadb_purge_state ps;
2383 + ipsa_query_t query;
2405 2384 int error = sadb_form_query(ksi, 0,
2406 2385 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2407 - &ps.sq, diagnostic);
2386 + &query, diagnostic);
2408 2387
2409 2388 if (error != 0)
2410 2389 return (error);
2411 2390
2412 2391 /*
2413 2392 * This is simple, crude, and effective.
2414 2393 * Unimplemented optimizations (TBD):
2415 2394 * - we can limit how many places we search based on where we
2416 2395 * think the SA is filed.
2417 2396 * - if we get a dst address, we can hash based on dst addr to find
2418 2397 * the correct bucket in the outbound table.
2419 2398 */
2420 - ps.inbnd = B_TRUE;
2421 - sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &ps);
2422 - ps.inbnd = B_FALSE;
2423 - sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &ps);
2399 + sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &query);
2400 + sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &query);
2424 2401
2425 2402 ASSERT(mp->b_cont != NULL);
2426 2403 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2427 2404 NULL);
2428 2405 return (0);
2429 2406 }
2430 2407
2431 -static void
2432 -sadb_delpair_state_one(isaf_t *head, ipsa_t *entry, void *cookie)
2433 -{
2434 - struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2435 - isaf_t *inbound_bucket;
2436 - ipsa_t *peer_assoc;
2437 - ipsa_query_t *sq = &ps->sq;
2438 -
2439 - ASSERT(MUTEX_HELD(&head->isaf_lock));
2440 -
2441 - mutex_enter(&entry->ipsa_lock);
2442 -
2443 - if ((entry->ipsa_state != ps->sadb_sa_state) ||
2444 - ((sq->srcaddr != NULL) &&
2445 - !IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, sq->srcaddr, sq->af))) {
2446 - mutex_exit(&entry->ipsa_lock);
2447 - return;
2448 - }
2449 -
2450 - /*
2451 - * The isaf_t *, which is passed in , is always an outbound bucket,
2452 - * and we are preserving the outbound-then-inbound hash-bucket lock
2453 - * ordering. The sadb_walker() which triggers this function is called
2454 - * only on the outbound fanout, and the corresponding inbound bucket
2455 - * lock is safe to acquire here.
2456 - */
2457 -
2458 - if (entry->ipsa_haspeer) {
2459 - inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_spi);
2460 - mutex_enter(&inbound_bucket->isaf_lock);
2461 - peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2462 - entry->ipsa_spi, entry->ipsa_srcaddr,
2463 - entry->ipsa_dstaddr, entry->ipsa_addrfam);
2464 - } else {
2465 - inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_otherspi);
2466 - mutex_enter(&inbound_bucket->isaf_lock);
2467 - peer_assoc = ipsec_getassocbyspi(inbound_bucket,
2468 - entry->ipsa_otherspi, entry->ipsa_dstaddr,
2469 - entry->ipsa_srcaddr, entry->ipsa_addrfam);
2470 - }
2471 -
2472 - entry->ipsa_state = IPSA_STATE_DEAD;
2473 - (void) sadb_torch_assoc(head, entry);
2474 - if (peer_assoc != NULL) {
2475 - mutex_enter(&peer_assoc->ipsa_lock);
2476 - peer_assoc->ipsa_state = IPSA_STATE_DEAD;
2477 - (void) sadb_torch_assoc(inbound_bucket, peer_assoc);
2478 - }
2479 - mutex_exit(&inbound_bucket->isaf_lock);
2480 -}
2481 -
2482 -static int
2483 -sadb_delpair_state(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2484 - int *diagnostic, queue_t *pfkey_q)
2485 -{
2486 - sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2487 - struct sadb_purge_state ps;
2488 - int error;
2489 -
2490 - ps.sq.spp = spp; /* XXX param */
2491 -
2492 - error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SRC,
2493 - IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2494 - &ps.sq, diagnostic);
2495 - if (error != 0)
2496 - return (error);
2497 -
2498 - ps.inbnd = B_FALSE;
2499 - ps.sadb_sa_state = assoc->sadb_sa_state;
2500 - sadb_walker(ps.sq.sp->sdb_of, ps.sq.sp->sdb_hashsize,
2501 - sadb_delpair_state_one, &ps);
2502 -
2503 - ASSERT(mp->b_cont != NULL);
2504 - sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
2505 - ksi, NULL);
2506 - return (0);
2507 -}
2508 -
2509 2408 /*
2510 2409 * Common code to delete/get an SA.
2511 2410 */
2512 2411 int
2513 2412 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2514 2413 int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2515 2414 {
2516 2415 ipsa_query_t sq;
2517 2416 ipsa_t *echo_target = NULL;
2518 2417 ipsap_t ipsapp;
2519 2418 uint_t error = 0;
2520 2419
2521 - if (sadb_msg_type == SADB_X_DELPAIR_STATE)
2522 - return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q));
2523 -
2524 2420 sq.spp = spp; /* XXX param */
2525 2421 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2526 2422 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2527 2423 &sq, diagnostic);
2528 2424 if (error != 0)
2529 2425 return (error);
2530 2426
2531 2427 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2532 2428 if (error != 0) {
2533 2429 return (error);
2534 2430 }
2535 2431
2536 2432 echo_target = ipsapp.ipsap_sa_ptr;
2537 2433 if (echo_target == NULL)
2538 2434 echo_target = ipsapp.ipsap_psa_ptr;
2539 2435
2540 2436 if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2541 2437 /*
2542 2438 * Bucket locks will be required if SA is actually unlinked.
2543 2439 * get_ipsa_pair() returns valid hash bucket pointers even
2544 2440 * if it can't find a pair SA pointer. To prevent a potential
2545 2441 * deadlock, always lock the outbound bucket before the inbound.
2546 2442 */
2547 2443 if (ipsapp.in_inbound_table) {
2548 2444 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2549 2445 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2550 2446 } else {
2551 2447 mutex_enter(&ipsapp.ipsap_bucket->isaf_lock);
2552 2448 mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock);
2553 2449 }
2554 2450
2555 2451 if (ipsapp.ipsap_sa_ptr != NULL) {
2556 2452 mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
2557 2453 ipsapp.ipsap_sa_ptr->ipsa_state = IPSA_STATE_DEAD;
2558 2454 (void) sadb_torch_assoc(ipsapp.ipsap_bucket,
2559 2455 ipsapp.ipsap_sa_ptr);
2560 2456 /*
2561 2457 * sadb_torch_assoc() releases the ipsa_lock
2562 2458 * and calls sadb_unlinkassoc() which does a
2563 2459 * IPSA_REFRELE.
2564 2460 */
2565 2461 }
2566 2462 if (ipsapp.ipsap_psa_ptr != NULL) {
2567 2463 mutex_enter(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2568 2464 if (sadb_msg_type == SADB_X_DELPAIR ||
2569 2465 ipsapp.ipsap_psa_ptr->ipsa_haspeer) {
2570 2466 ipsapp.ipsap_psa_ptr->ipsa_state =
2571 2467 IPSA_STATE_DEAD;
2572 2468 (void) sadb_torch_assoc(ipsapp.ipsap_pbucket,
2573 2469 ipsapp.ipsap_psa_ptr);
2574 2470 } else {
2575 2471 /*
2576 2472 * Only half of the "pair" has been deleted.
2577 2473 * Update the remaining SA and remove references
2578 2474 * to its pair SA, which is now gone.
2579 2475 */
2580 2476 ipsapp.ipsap_psa_ptr->ipsa_otherspi = 0;
2581 2477 ipsapp.ipsap_psa_ptr->ipsa_flags &=
2582 2478 ~IPSA_F_PAIRED;
2583 2479 mutex_exit(&ipsapp.ipsap_psa_ptr->ipsa_lock);
2584 2480 }
2585 2481 } else if (sadb_msg_type == SADB_X_DELPAIR) {
2586 2482 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
2587 2483 error = ESRCH;
2588 2484 }
2589 2485 mutex_exit(&ipsapp.ipsap_bucket->isaf_lock);
2590 2486 mutex_exit(&ipsapp.ipsap_pbucket->isaf_lock);
2591 2487 }
2592 2488
2593 2489 ASSERT(mp->b_cont != NULL);
2594 2490
2595 2491 if (error == 0)
2596 2492 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)
2597 2493 mp->b_cont->b_rptr, ksi, echo_target);
2598 2494
2599 2495 destroy_ipsa_pair(&ipsapp);
2600 2496
2601 2497 return (error);
2602 2498 }
2603 2499
2604 2500 /*
2605 2501 * This function takes a sadb_sa_t and finds the ipsa_t structure
2606 2502 * and the isaf_t (hash bucket) that its stored under. If the security
2607 2503 * association has a peer, the ipsa_t structure and bucket for that security
2608 2504 * association are also searched for. The "pair" of ipsa_t's and isaf_t's
2609 2505 * are returned as a ipsap_t.
2610 2506 *
2611 2507 * The hash buckets are returned for convenience, if the calling function
2612 2508 * needs to use the hash bucket locks, say to remove the SA's, it should
2613 2509 * take care to observe the convention of locking outbound bucket then
2614 2510 * inbound bucket. The flag in_inbound_table provides direction.
2615 2511 *
2616 2512 * Note that a "pair" is defined as one (but not both) of the following:
2617 2513 *
2618 2514 * A security association which has a soft reference to another security
2619 2515 * association via its SPI.
2620 2516 *
2621 2517 * A security association that is not obviously "inbound" or "outbound" so
2622 2518 * it appears in both hash tables, the "peer" being the same security
2623 2519 * association in the other hash table.
2624 2520 *
2625 2521 * This function will return NULL if the ipsa_t can't be found in the
2626 2522 * inbound or outbound hash tables (not found). If only one ipsa_t is
2627 2523 * found, the pair ipsa_t will be NULL. Both isaf_t values are valid
2628 2524 * provided at least one ipsa_t is found.
2629 2525 */
2630 2526 static int
2631 2527 get_ipsa_pair(ipsa_query_t *sq, ipsap_t *ipsapp, int *diagnostic)
2632 2528 {
2633 2529 uint32_t pair_srcaddr[IPSA_MAX_ADDRLEN];
2634 2530 uint32_t pair_dstaddr[IPSA_MAX_ADDRLEN];
2635 2531 uint32_t pair_spi;
2636 2532
2637 2533 init_ipsa_pair(ipsapp);
2638 2534
2639 2535 ipsapp->in_inbound_table = B_FALSE;
2640 2536
2641 2537 /* Lock down both buckets. */
2642 2538 mutex_enter(&sq->outbound->isaf_lock);
2643 2539 mutex_enter(&sq->inbound->isaf_lock);
2644 2540
2645 2541 if (sq->assoc->sadb_sa_flags & IPSA_F_INBOUND) {
2646 2542 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2647 2543 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2648 2544 if (ipsapp->ipsap_sa_ptr != NULL) {
2649 2545 ipsapp->ipsap_bucket = sq->inbound;
2650 2546 ipsapp->ipsap_pbucket = sq->outbound;
2651 2547 ipsapp->in_inbound_table = B_TRUE;
2652 2548 } else {
2653 2549 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->outbound,
2654 2550 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2655 2551 sq->af);
2656 2552 ipsapp->ipsap_bucket = sq->outbound;
2657 2553 ipsapp->ipsap_pbucket = sq->inbound;
2658 2554 }
2659 2555 } else {
2660 2556 /* IPSA_F_OUTBOUND is set *or* no directions flags set. */
2661 2557 ipsapp->ipsap_sa_ptr =
2662 2558 ipsec_getassocbyspi(sq->outbound,
2663 2559 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2664 2560 if (ipsapp->ipsap_sa_ptr != NULL) {
2665 2561 ipsapp->ipsap_bucket = sq->outbound;
2666 2562 ipsapp->ipsap_pbucket = sq->inbound;
2667 2563 } else {
2668 2564 ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound,
2669 2565 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr,
2670 2566 sq->af);
2671 2567 ipsapp->ipsap_bucket = sq->inbound;
2672 2568 ipsapp->ipsap_pbucket = sq->outbound;
2673 2569 if (ipsapp->ipsap_sa_ptr != NULL)
2674 2570 ipsapp->in_inbound_table = B_TRUE;
2675 2571 }
2676 2572 }
2677 2573
2678 2574 if (ipsapp->ipsap_sa_ptr == NULL) {
2679 2575 mutex_exit(&sq->outbound->isaf_lock);
2680 2576 mutex_exit(&sq->inbound->isaf_lock);
2681 2577 *diagnostic = SADB_X_DIAGNOSTIC_SA_NOTFOUND;
2682 2578 return (ESRCH);
2683 2579 }
2684 2580
2685 2581 if ((ipsapp->ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) &&
2686 2582 ipsapp->in_inbound_table) {
2687 2583 mutex_exit(&sq->outbound->isaf_lock);
2688 2584 mutex_exit(&sq->inbound->isaf_lock);
2689 2585 return (0);
2690 2586 }
2691 2587
2692 2588 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2693 2589 if (ipsapp->ipsap_sa_ptr->ipsa_haspeer) {
2694 2590 /*
2695 2591 * haspeer implies no sa_pairing, look for same spi
2696 2592 * in other hashtable.
2697 2593 */
2698 2594 ipsapp->ipsap_psa_ptr =
2699 2595 ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2700 2596 sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af);
2701 2597 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2702 2598 mutex_exit(&sq->outbound->isaf_lock);
2703 2599 mutex_exit(&sq->inbound->isaf_lock);
2704 2600 return (0);
2705 2601 }
2706 2602 pair_spi = ipsapp->ipsap_sa_ptr->ipsa_otherspi;
2707 2603 IPSA_COPY_ADDR(&pair_srcaddr,
2708 2604 ipsapp->ipsap_sa_ptr->ipsa_srcaddr, sq->af);
2709 2605 IPSA_COPY_ADDR(&pair_dstaddr,
2710 2606 ipsapp->ipsap_sa_ptr->ipsa_dstaddr, sq->af);
2711 2607 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
2712 2608 mutex_exit(&sq->inbound->isaf_lock);
2713 2609 mutex_exit(&sq->outbound->isaf_lock);
2714 2610
2715 2611 if (pair_spi == 0) {
2716 2612 ASSERT(ipsapp->ipsap_bucket != NULL);
2717 2613 ASSERT(ipsapp->ipsap_pbucket != NULL);
2718 2614 return (0);
2719 2615 }
2720 2616
2721 2617 /* found sa in outbound sadb, peer should be inbound */
2722 2618
2723 2619 if (ipsapp->in_inbound_table) {
2724 2620 /* Found SA in inbound table, pair will be in outbound. */
2725 2621 if (sq->af == AF_INET6) {
2726 2622 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V6(sq->sp,
2727 2623 *(uint32_t *)pair_srcaddr);
2728 2624 } else {
2729 2625 ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V4(sq->sp,
2730 2626 *(uint32_t *)pair_srcaddr);
2731 2627 }
2732 2628 } else {
2733 2629 ipsapp->ipsap_pbucket = INBOUND_BUCKET(sq->sp, pair_spi);
2734 2630 }
2735 2631 mutex_enter(&ipsapp->ipsap_pbucket->isaf_lock);
2736 2632 ipsapp->ipsap_psa_ptr = ipsec_getassocbyspi(ipsapp->ipsap_pbucket,
2737 2633 pair_spi, pair_dstaddr, pair_srcaddr, sq->af);
2738 2634 mutex_exit(&ipsapp->ipsap_pbucket->isaf_lock);
2739 2635 ASSERT(ipsapp->ipsap_bucket != NULL);
2740 2636 ASSERT(ipsapp->ipsap_pbucket != NULL);
2741 2637 return (0);
2742 2638 }
2743 2639
2744 2640 /*
2745 2641 * Perform NAT-traversal cached checksum offset calculations here.
2746 2642 */
2747 2643 static void
2748 2644 sadb_nat_calculations(ipsa_t *newbie, sadb_address_t *natt_loc_ext,
2749 2645 sadb_address_t *natt_rem_ext, uint32_t *src_addr_ptr,
2750 2646 uint32_t *dst_addr_ptr)
2751 2647 {
2752 2648 struct sockaddr_in *natt_loc, *natt_rem;
2753 2649 uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL;
2754 2650 uint32_t running_sum = 0;
2755 2651
2756 2652 #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) + ((x) >> 16)
2757 2653
2758 2654 if (natt_rem_ext != NULL) {
2759 2655 uint32_t l_src;
2760 2656 uint32_t l_rem;
2761 2657
2762 2658 natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1);
2763 2659
2764 2660 /* Ensured by sadb_addrfix(). */
2765 2661 ASSERT(natt_rem->sin_family == AF_INET);
2766 2662
2767 2663 natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr);
2768 2664 newbie->ipsa_remote_nat_port = natt_rem->sin_port;
2769 2665 l_src = *src_addr_ptr;
2770 2666 l_rem = *natt_rem_ptr;
2771 2667
2772 2668 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2773 2669 newbie->ipsa_natt_addr_rem = *natt_rem_ptr;
2774 2670
2775 2671 l_src = ntohl(l_src);
2776 2672 DOWN_SUM(l_src);
2777 2673 DOWN_SUM(l_src);
2778 2674 l_rem = ntohl(l_rem);
2779 2675 DOWN_SUM(l_rem);
2780 2676 DOWN_SUM(l_rem);
2781 2677
2782 2678 /*
2783 2679 * We're 1's complement for checksums, so check for wraparound
2784 2680 * here.
2785 2681 */
2786 2682 if (l_rem > l_src)
2787 2683 l_src--;
2788 2684
2789 2685 running_sum += l_src - l_rem;
2790 2686
2791 2687 DOWN_SUM(running_sum);
2792 2688 DOWN_SUM(running_sum);
2793 2689 }
2794 2690
2795 2691 if (natt_loc_ext != NULL) {
2796 2692 natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1);
2797 2693
2798 2694 /* Ensured by sadb_addrfix(). */
2799 2695 ASSERT(natt_loc->sin_family == AF_INET);
2800 2696
2801 2697 natt_loc_ptr = (uint32_t *)(&natt_loc->sin_addr);
2802 2698 newbie->ipsa_local_nat_port = natt_loc->sin_port;
2803 2699
2804 2700 /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */
2805 2701 newbie->ipsa_natt_addr_loc = *natt_loc_ptr;
2806 2702
2807 2703 /*
2808 2704 * NAT-T port agility means we may have natt_loc_ext, but
2809 2705 * only for a local-port change.
2810 2706 */
2811 2707 if (natt_loc->sin_addr.s_addr != INADDR_ANY) {
2812 2708 uint32_t l_dst = ntohl(*dst_addr_ptr);
2813 2709 uint32_t l_loc = ntohl(*natt_loc_ptr);
2814 2710
2815 2711 DOWN_SUM(l_loc);
2816 2712 DOWN_SUM(l_loc);
2817 2713 DOWN_SUM(l_dst);
2818 2714 DOWN_SUM(l_dst);
2819 2715
2820 2716 /*
2821 2717 * We're 1's complement for checksums, so check for
2822 2718 * wraparound here.
2823 2719 */
2824 2720 if (l_loc > l_dst)
2825 2721 l_dst--;
2826 2722
2827 2723 running_sum += l_dst - l_loc;
2828 2724 DOWN_SUM(running_sum);
2829 2725 DOWN_SUM(running_sum);
2830 2726 }
2831 2727 }
2832 2728
2833 2729 newbie->ipsa_inbound_cksum = running_sum;
2834 2730 #undef DOWN_SUM
2835 2731 }
2836 2732
2837 2733 /*
2838 2734 * This function is called from consumers that need to insert a fully-grown
2839 2735 * security association into its tables. This function takes into account that
2840 2736 * SAs can be "inbound", "outbound", or "both". The "primary" and "secondary"
2841 2737 * hash bucket parameters are set in order of what the SA will be most of the
2842 2738 * time. (For example, an SA with an unspecified source, and a multicast
2843 2739 * destination will primarily be an outbound SA. OTOH, if that destination
2844 2740 * is unicast for this node, then the SA will primarily be inbound.)
2845 2741 *
2846 2742 * It takes a lot of parameters because even if clone is B_FALSE, this needs
2847 2743 * to check both buckets for purposes of collision.
2848 2744 *
2849 2745 * Return 0 upon success. Return various errnos (ENOMEM, EEXIST) for
2850 2746 * various error conditions. We may need to set samsg->sadb_x_msg_diagnostic
2851 2747 * with additional diagnostic information because there is at least one EINVAL
2852 2748 * case here.
2853 2749 */
2854 2750 int
2855 2751 sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
2856 2752 keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary,
2857 2753 ipsa_t *newbie, boolean_t clone, boolean_t is_inbound, int *diagnostic,
2858 2754 netstack_t *ns, sadbp_t *spp)
2859 2755 {
2860 2756 ipsa_t *newbie_clone = NULL, *scratch;
2861 2757 ipsap_t ipsapp;
2862 2758 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
2863 2759 sadb_address_t *srcext =
2864 2760 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
2865 2761 sadb_address_t *dstext =
2866 2762 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
2867 2763 sadb_address_t *isrcext =
2868 2764 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC];
2869 2765 sadb_address_t *idstext =
2870 2766 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_DST];
2871 2767 sadb_x_kmc_t *kmcext =
2872 2768 (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE];
2873 2769 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
2874 2770 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
2875 2771 sadb_sens_t *sens =
2876 2772 (sadb_sens_t *)ksi->ks_in_extv[SADB_EXT_SENSITIVITY];
2877 2773 sadb_sens_t *osens =
2878 2774 (sadb_sens_t *)ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS];
2879 2775 sadb_x_pair_t *pair_ext =
2880 2776 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
2881 2777 sadb_x_replay_ctr_t *replayext =
2882 2778 (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
2883 2779 int salt_offset;
2884 2780 uint8_t *buf_ptr;
2885 2781 struct sockaddr_in *src, *dst, *isrc, *idst;
2886 2782 struct sockaddr_in6 *src6, *dst6, *isrc6, *idst6;
2887 2783 sadb_lifetime_t *soft =
2888 2784 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
2889 2785 sadb_lifetime_t *hard =
2890 2786 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
2891 2787 sadb_lifetime_t *idle =
2892 2788 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
2893 2789 sa_family_t af;
2894 2790 int error = 0;
2895 2791 boolean_t isupdate = (newbie != NULL);
2896 2792 uint32_t *src_addr_ptr, *dst_addr_ptr, *isrc_addr_ptr, *idst_addr_ptr;
2897 2793 ipsec_stack_t *ipss = ns->netstack_ipsec;
2898 2794 ip_stack_t *ipst = ns->netstack_ip;
2899 2795 ipsec_alginfo_t *alg;
2900 2796 boolean_t async = B_FALSE;
2901 2797
2902 2798 init_ipsa_pair(&ipsapp);
2903 2799
2904 2800 if (srcext == NULL) {
2905 2801 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
2906 2802 return (EINVAL);
2907 2803 }
2908 2804 if (dstext == NULL) {
2909 2805 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
2910 2806 return (EINVAL);
2911 2807 }
2912 2808 if (assoc == NULL) {
2913 2809 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
2914 2810 return (EINVAL);
2915 2811 }
2916 2812
2917 2813 src = (struct sockaddr_in *)(srcext + 1);
2918 2814 src6 = (struct sockaddr_in6 *)(srcext + 1);
2919 2815 dst = (struct sockaddr_in *)(dstext + 1);
2920 2816 dst6 = (struct sockaddr_in6 *)(dstext + 1);
2921 2817 if (isrcext != NULL) {
2922 2818 isrc = (struct sockaddr_in *)(isrcext + 1);
2923 2819 isrc6 = (struct sockaddr_in6 *)(isrcext + 1);
2924 2820 ASSERT(idstext != NULL);
2925 2821 idst = (struct sockaddr_in *)(idstext + 1);
2926 2822 idst6 = (struct sockaddr_in6 *)(idstext + 1);
2927 2823 } else {
2928 2824 isrc = NULL;
2929 2825 isrc6 = NULL;
2930 2826 }
2931 2827
2932 2828 af = src->sin_family;
2933 2829
2934 2830 if (af == AF_INET) {
2935 2831 src_addr_ptr = (uint32_t *)&src->sin_addr;
2936 2832 dst_addr_ptr = (uint32_t *)&dst->sin_addr;
2937 2833 } else {
2938 2834 ASSERT(af == AF_INET6);
2939 2835 src_addr_ptr = (uint32_t *)&src6->sin6_addr;
2940 2836 dst_addr_ptr = (uint32_t *)&dst6->sin6_addr;
2941 2837 }
2942 2838
2943 2839 /*
2944 2840 * Check to see if the new SA will be cloned AND paired. The
2945 2841 * reason a SA will be cloned is the source or destination addresses
2946 2842 * are not specific enough to determine if the SA goes in the outbound
2947 2843 * or the inbound hash table, so its cloned and put in both. If
2948 2844 * the SA is paired, it's soft linked to another SA for the other
2949 2845 * direction. Keeping track and looking up SA's that are direction
2950 2846 * unspecific and linked is too hard.
2951 2847 */
2952 2848 if (clone && (pair_ext != NULL)) {
2953 2849 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
2954 2850 return (EINVAL);
2955 2851 }
2956 2852
2957 2853 if (!isupdate) {
2958 2854 newbie = sadb_makelarvalassoc(assoc->sadb_sa_spi,
2959 2855 src_addr_ptr, dst_addr_ptr, af, ns);
2960 2856 if (newbie == NULL)
2961 2857 return (ENOMEM);
2962 2858 }
2963 2859
2964 2860 mutex_enter(&newbie->ipsa_lock);
2965 2861
2966 2862 if (isrc != NULL) {
2967 2863 if (isrc->sin_family == AF_INET) {
2968 2864 if (srcext->sadb_address_proto != IPPROTO_ENCAP) {
2969 2865 if (srcext->sadb_address_proto != 0) {
2970 2866 /*
2971 2867 * Mismatched outer-packet protocol
2972 2868 * and inner-packet address family.
2973 2869 */
2974 2870 mutex_exit(&newbie->ipsa_lock);
2975 2871 error = EPROTOTYPE;
2976 2872 *diagnostic =
2977 2873 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
2978 2874 goto error;
2979 2875 } else {
2980 2876 /* Fill in with explicit protocol. */
2981 2877 srcext->sadb_address_proto =
2982 2878 IPPROTO_ENCAP;
2983 2879 dstext->sadb_address_proto =
2984 2880 IPPROTO_ENCAP;
2985 2881 }
2986 2882 }
2987 2883 isrc_addr_ptr = (uint32_t *)&isrc->sin_addr;
2988 2884 idst_addr_ptr = (uint32_t *)&idst->sin_addr;
2989 2885 } else {
2990 2886 ASSERT(isrc->sin_family == AF_INET6);
2991 2887 if (srcext->sadb_address_proto != IPPROTO_IPV6) {
2992 2888 if (srcext->sadb_address_proto != 0) {
2993 2889 /*
2994 2890 * Mismatched outer-packet protocol
2995 2891 * and inner-packet address family.
2996 2892 */
2997 2893 mutex_exit(&newbie->ipsa_lock);
2998 2894 error = EPROTOTYPE;
2999 2895 *diagnostic =
3000 2896 SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
3001 2897 goto error;
3002 2898 } else {
3003 2899 /* Fill in with explicit protocol. */
3004 2900 srcext->sadb_address_proto =
3005 2901 IPPROTO_IPV6;
3006 2902 dstext->sadb_address_proto =
3007 2903 IPPROTO_IPV6;
3008 2904 }
3009 2905 }
3010 2906 isrc_addr_ptr = (uint32_t *)&isrc6->sin6_addr;
3011 2907 idst_addr_ptr = (uint32_t *)&idst6->sin6_addr;
3012 2908 }
3013 2909 newbie->ipsa_innerfam = isrc->sin_family;
3014 2910
3015 2911 IPSA_COPY_ADDR(newbie->ipsa_innersrc, isrc_addr_ptr,
3016 2912 newbie->ipsa_innerfam);
3017 2913 IPSA_COPY_ADDR(newbie->ipsa_innerdst, idst_addr_ptr,
3018 2914 newbie->ipsa_innerfam);
3019 2915 newbie->ipsa_innersrcpfx = isrcext->sadb_address_prefixlen;
3020 2916 newbie->ipsa_innerdstpfx = idstext->sadb_address_prefixlen;
3021 2917
3022 2918 /* Unique value uses inner-ports for Tunnel Mode... */
3023 2919 newbie->ipsa_unique_id = SA_UNIQUE_ID(isrc->sin_port,
3024 2920 idst->sin_port, dstext->sadb_address_proto,
3025 2921 idstext->sadb_address_proto);
3026 2922 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
3027 2923 idst->sin_port, dstext->sadb_address_proto,
3028 2924 idstext->sadb_address_proto);
3029 2925 } else {
3030 2926 /* ... and outer-ports for Transport Mode. */
3031 2927 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
3032 2928 dst->sin_port, dstext->sadb_address_proto, 0);
3033 2929 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
3034 2930 dst->sin_port, dstext->sadb_address_proto, 0);
3035 2931 }
|
↓ open down ↓ |
502 lines elided |
↑ open up ↑ |
3036 2932 if (newbie->ipsa_unique_mask != (uint64_t)0)
3037 2933 newbie->ipsa_flags |= IPSA_F_UNIQUE;
3038 2934
3039 2935 sadb_nat_calculations(newbie,
3040 2936 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
3041 2937 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
3042 2938 src_addr_ptr, dst_addr_ptr);
3043 2939
3044 2940 newbie->ipsa_type = samsg->sadb_msg_satype;
3045 2941
3046 - ASSERT((assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
3047 - (assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE));
2942 + ASSERT(assoc->sadb_sa_state == SADB_SASTATE_MATURE);
3048 2943 newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
3049 2944 newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
3050 2945
3051 2946 newbie->ipsa_flags |= assoc->sadb_sa_flags;
3052 2947 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
3053 2948 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
3054 2949 mutex_exit(&newbie->ipsa_lock);
3055 2950 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
3056 2951 error = EINVAL;
3057 2952 goto error;
3058 2953 }
3059 2954 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
3060 2955 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
3061 2956 mutex_exit(&newbie->ipsa_lock);
3062 2957 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
3063 2958 error = EINVAL;
3064 2959 goto error;
3065 2960 }
3066 2961 if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
3067 2962 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3068 2963 mutex_exit(&newbie->ipsa_lock);
3069 2964 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
3070 2965 error = EINVAL;
3071 2966 goto error;
3072 2967 }
3073 2968 /*
3074 2969 * If unspecified source address, force replay_wsize to 0.
3075 2970 * This is because an SA that has multiple sources of secure
3076 2971 * traffic cannot enforce a replay counter w/o synchronizing the
3077 2972 * senders.
3078 2973 */
3079 2974 if (ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC)
3080 2975 newbie->ipsa_replay_wsize = assoc->sadb_sa_replay;
3081 2976 else
3082 2977 newbie->ipsa_replay_wsize = 0;
3083 2978
3084 2979 newbie->ipsa_addtime = gethrestime_sec();
3085 2980
3086 2981 if (kmcext != NULL) {
3087 2982 newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
3088 2983 newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie;
3089 2984 }
3090 2985
3091 2986 /*
3092 2987 * XXX CURRENT lifetime checks MAY BE needed for an UPDATE.
3093 2988 * The spec says that one can update current lifetimes, but
3094 2989 * that seems impractical, especially in the larval-to-mature
3095 2990 * update that this function performs.
3096 2991 */
3097 2992 if (soft != NULL) {
3098 2993 newbie->ipsa_softaddlt = soft->sadb_lifetime_addtime;
3099 2994 newbie->ipsa_softuselt = soft->sadb_lifetime_usetime;
3100 2995 newbie->ipsa_softbyteslt = soft->sadb_lifetime_bytes;
3101 2996 newbie->ipsa_softalloc = soft->sadb_lifetime_allocations;
3102 2997 SET_EXPIRE(newbie, softaddlt, softexpiretime);
3103 2998 }
3104 2999 if (hard != NULL) {
3105 3000 newbie->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
3106 3001 newbie->ipsa_harduselt = hard->sadb_lifetime_usetime;
3107 3002 newbie->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
3108 3003 newbie->ipsa_hardalloc = hard->sadb_lifetime_allocations;
3109 3004 SET_EXPIRE(newbie, hardaddlt, hardexpiretime);
3110 3005 }
3111 3006 if (idle != NULL) {
3112 3007 newbie->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
3113 3008 newbie->ipsa_idleuselt = idle->sadb_lifetime_usetime;
3114 3009 newbie->ipsa_idleexpiretime = newbie->ipsa_addtime +
3115 3010 newbie->ipsa_idleaddlt;
3116 3011 newbie->ipsa_idletime = newbie->ipsa_idleaddlt;
3117 3012 }
3118 3013
3119 3014 newbie->ipsa_authtmpl = NULL;
3120 3015 newbie->ipsa_encrtmpl = NULL;
3121 3016
3122 3017 #ifdef IPSEC_LATENCY_TEST
3123 3018 if (akey != NULL && newbie->ipsa_auth_alg != SADB_AALG_NONE) {
3124 3019 #else
3125 3020 if (akey != NULL) {
3126 3021 #endif
3127 3022 async = (ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
3128 3023 IPSEC_ALGS_EXEC_ASYNC);
3129 3024
3130 3025 newbie->ipsa_authkeybits = akey->sadb_key_bits;
3131 3026 newbie->ipsa_authkeylen = SADB_1TO8(akey->sadb_key_bits);
3132 3027 /* In case we have to round up to the next byte... */
3133 3028 if ((akey->sadb_key_bits & 0x7) != 0)
3134 3029 newbie->ipsa_authkeylen++;
3135 3030 newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen,
3136 3031 KM_NOSLEEP);
3137 3032 if (newbie->ipsa_authkey == NULL) {
3138 3033 error = ENOMEM;
3139 3034 mutex_exit(&newbie->ipsa_lock);
3140 3035 goto error;
3141 3036 }
3142 3037 bcopy(akey + 1, newbie->ipsa_authkey, newbie->ipsa_authkeylen);
3143 3038 bzero(akey + 1, newbie->ipsa_authkeylen);
3144 3039
3145 3040 /*
3146 3041 * Pre-initialize the kernel crypto framework key
3147 3042 * structure.
3148 3043 */
3149 3044 newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
3150 3045 newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
3151 3046 newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
3152 3047
3153 3048 mutex_enter(&ipss->ipsec_alg_lock);
3154 3049 alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
3155 3050 [newbie->ipsa_auth_alg];
3156 3051 if (alg != NULL && ALG_VALID(alg)) {
3157 3052 newbie->ipsa_amech.cm_type = alg->alg_mech_type;
3158 3053 newbie->ipsa_amech.cm_param =
3159 3054 (char *)&newbie->ipsa_mac_len;
3160 3055 newbie->ipsa_amech.cm_param_len = sizeof (size_t);
3161 3056 newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
3162 3057 } else {
3163 3058 newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
3164 3059 }
3165 3060 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
3166 3061 mutex_exit(&ipss->ipsec_alg_lock);
3167 3062 if (error != 0) {
3168 3063 mutex_exit(&newbie->ipsa_lock);
3169 3064 /*
3170 3065 * An error here indicates that alg is the wrong type
3171 3066 * (IE: not authentication) or its not in the alg tables
3172 3067 * created by ipsecalgs(1m), or Kcf does not like the
3173 3068 * parameters passed in with this algorithm, which is
3174 3069 * probably a coding error!
3175 3070 */
3176 3071 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3177 3072
3178 3073 goto error;
3179 3074 }
3180 3075 }
3181 3076
3182 3077 if (ekey != NULL) {
3183 3078 mutex_enter(&ipss->ipsec_alg_lock);
3184 3079 async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
3185 3080 IPSEC_ALGS_EXEC_ASYNC);
3186 3081 alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
3187 3082 [newbie->ipsa_encr_alg];
3188 3083
3189 3084 if (alg != NULL && ALG_VALID(alg)) {
3190 3085 newbie->ipsa_emech.cm_type = alg->alg_mech_type;
3191 3086 newbie->ipsa_datalen = alg->alg_datalen;
3192 3087 if (alg->alg_flags & ALG_FLAG_COUNTERMODE)
3193 3088 newbie->ipsa_flags |= IPSA_F_COUNTERMODE;
3194 3089
3195 3090 if (alg->alg_flags & ALG_FLAG_COMBINED) {
3196 3091 newbie->ipsa_flags |= IPSA_F_COMBINED;
3197 3092 newbie->ipsa_mac_len = alg->alg_icvlen;
3198 3093 }
3199 3094
3200 3095 if (alg->alg_flags & ALG_FLAG_CCM)
3201 3096 newbie->ipsa_noncefunc = ccm_params_init;
3202 3097 else if (alg->alg_flags & ALG_FLAG_GCM)
3203 3098 newbie->ipsa_noncefunc = gcm_params_init;
3204 3099 else newbie->ipsa_noncefunc = cbc_params_init;
3205 3100
3206 3101 newbie->ipsa_saltlen = alg->alg_saltlen;
3207 3102 newbie->ipsa_saltbits = SADB_8TO1(newbie->ipsa_saltlen);
3208 3103 newbie->ipsa_iv_len = alg->alg_ivlen;
3209 3104 newbie->ipsa_nonce_len = newbie->ipsa_saltlen +
3210 3105 newbie->ipsa_iv_len;
3211 3106 newbie->ipsa_emech.cm_param = NULL;
3212 3107 newbie->ipsa_emech.cm_param_len = 0;
3213 3108 } else {
3214 3109 newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
3215 3110 }
3216 3111 mutex_exit(&ipss->ipsec_alg_lock);
3217 3112
3218 3113 /*
3219 3114 * The byte stream following the sadb_key_t is made up of:
3220 3115 * key bytes, [salt bytes], [IV initial value]
3221 3116 * All of these have variable length. The IV is typically
3222 3117 * randomly generated by this function and not passed in.
3223 3118 * By supporting the injection of a known IV, the whole
3224 3119 * IPsec subsystem and the underlying crypto subsystem
3225 3120 * can be tested with known test vectors.
3226 3121 *
3227 3122 * The keying material has been checked by ext_check()
3228 3123 * and ipsec_valid_key_size(), after removing salt/IV
3229 3124 * bits, whats left is the encryption key. If this is too
3230 3125 * short, ipsec_create_ctx_tmpl() will fail and the SA
3231 3126 * won't get created.
3232 3127 *
3233 3128 * set ipsa_encrkeylen to length of key only.
3234 3129 */
3235 3130 newbie->ipsa_encrkeybits = ekey->sadb_key_bits;
3236 3131 newbie->ipsa_encrkeybits -= ekey->sadb_key_reserved;
3237 3132 newbie->ipsa_encrkeybits -= newbie->ipsa_saltbits;
3238 3133 newbie->ipsa_encrkeylen = SADB_1TO8(newbie->ipsa_encrkeybits);
3239 3134
3240 3135 /* In case we have to round up to the next byte... */
3241 3136 if ((ekey->sadb_key_bits & 0x7) != 0)
3242 3137 newbie->ipsa_encrkeylen++;
3243 3138
3244 3139 newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen,
3245 3140 KM_NOSLEEP);
3246 3141 if (newbie->ipsa_encrkey == NULL) {
3247 3142 error = ENOMEM;
3248 3143 mutex_exit(&newbie->ipsa_lock);
3249 3144 goto error;
3250 3145 }
3251 3146
3252 3147 buf_ptr = (uint8_t *)(ekey + 1);
3253 3148 bcopy(buf_ptr, newbie->ipsa_encrkey, newbie->ipsa_encrkeylen);
3254 3149
3255 3150 if (newbie->ipsa_flags & IPSA_F_COMBINED) {
3256 3151 /*
3257 3152 * Combined mode algs need a nonce. Copy the salt and
3258 3153 * IV into a buffer. The ipsa_nonce is a pointer into
3259 3154 * this buffer, some bytes at the start of the buffer
3260 3155 * may be unused, depends on the salt length. The IV
3261 3156 * is 64 bit aligned so it can be incremented as a
3262 3157 * uint64_t. Zero out key in samsg_t before freeing.
3263 3158 */
3264 3159
3265 3160 newbie->ipsa_nonce_buf = kmem_alloc(
3266 3161 sizeof (ipsec_nonce_t), KM_NOSLEEP);
3267 3162 if (newbie->ipsa_nonce_buf == NULL) {
3268 3163 error = ENOMEM;
3269 3164 mutex_exit(&newbie->ipsa_lock);
3270 3165 goto error;
3271 3166 }
3272 3167 /*
3273 3168 * Initialize nonce and salt pointers to point
3274 3169 * to the nonce buffer. This is just in case we get
3275 3170 * bad data, the pointers will be valid, the data
3276 3171 * won't be.
3277 3172 *
3278 3173 * See sadb.h for layout of nonce.
3279 3174 */
3280 3175 newbie->ipsa_iv = &newbie->ipsa_nonce_buf->iv;
3281 3176 newbie->ipsa_salt = (uint8_t *)newbie->ipsa_nonce_buf;
3282 3177 newbie->ipsa_nonce = newbie->ipsa_salt;
3283 3178 if (newbie->ipsa_saltlen != 0) {
3284 3179 salt_offset = MAXSALTSIZE -
3285 3180 newbie->ipsa_saltlen;
3286 3181 newbie->ipsa_salt = (uint8_t *)
3287 3182 &newbie->ipsa_nonce_buf->salt[salt_offset];
3288 3183 newbie->ipsa_nonce = newbie->ipsa_salt;
3289 3184 buf_ptr += newbie->ipsa_encrkeylen;
3290 3185 bcopy(buf_ptr, newbie->ipsa_salt,
3291 3186 newbie->ipsa_saltlen);
3292 3187 }
3293 3188 /*
3294 3189 * The IV for CCM/GCM mode increments, it should not
3295 3190 * repeat. Get a random value for the IV, make a
3296 3191 * copy, the SA will expire when/if the IV ever
3297 3192 * wraps back to the initial value. If an Initial IV
3298 3193 * is passed in via PF_KEY, save this in the SA.
3299 3194 * Initialising IV for inbound is pointless as its
3300 3195 * taken from the inbound packet.
3301 3196 */
3302 3197 if (!is_inbound) {
3303 3198 if (ekey->sadb_key_reserved != 0) {
3304 3199 buf_ptr += newbie->ipsa_saltlen;
3305 3200 bcopy(buf_ptr, (uint8_t *)newbie->
3306 3201 ipsa_iv, SADB_1TO8(ekey->
3307 3202 sadb_key_reserved));
3308 3203 } else {
3309 3204 (void) random_get_pseudo_bytes(
3310 3205 (uint8_t *)newbie->ipsa_iv,
3311 3206 newbie->ipsa_iv_len);
3312 3207 }
3313 3208 newbie->ipsa_iv_softexpire =
3314 3209 (*newbie->ipsa_iv) << 9;
3315 3210 newbie->ipsa_iv_hardexpire = *newbie->ipsa_iv;
3316 3211 }
3317 3212 }
3318 3213 bzero((ekey + 1), SADB_1TO8(ekey->sadb_key_bits));
3319 3214
3320 3215 /*
3321 3216 * Pre-initialize the kernel crypto framework key
3322 3217 * structure.
3323 3218 */
3324 3219 newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
3325 3220 newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
3326 3221 newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
3327 3222
3328 3223 mutex_enter(&ipss->ipsec_alg_lock);
3329 3224 error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
3330 3225 mutex_exit(&ipss->ipsec_alg_lock);
3331 3226 if (error != 0) {
3332 3227 mutex_exit(&newbie->ipsa_lock);
3333 3228 /* See above for error explanation. */
3334 3229 *diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
3335 3230 goto error;
3336 3231 }
3337 3232 }
3338 3233
3339 3234 if (async)
3340 3235 newbie->ipsa_flags |= IPSA_F_ASYNC;
3341 3236
3342 3237 /*
3343 3238 * Ptrs to processing functions.
3344 3239 */
3345 3240 if (newbie->ipsa_type == SADB_SATYPE_ESP)
3346 3241 ipsecesp_init_funcs(newbie);
3347 3242 else
3348 3243 ipsecah_init_funcs(newbie);
3349 3244 ASSERT(newbie->ipsa_output_func != NULL &&
3350 3245 newbie->ipsa_input_func != NULL);
3351 3246
3352 3247 /*
3353 3248 * Certificate ID stuff.
3354 3249 */
3355 3250 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC] != NULL) {
3356 3251 sadb_ident_t *id =
3357 3252 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC];
3358 3253
3359 3254 /*
3360 3255 * Can assume strlen() will return okay because ext_check() in
3361 3256 * keysock.c prepares the string for us.
3362 3257 */
3363 3258 newbie->ipsa_src_cid = ipsid_lookup(id->sadb_ident_type,
3364 3259 (char *)(id+1), ns);
3365 3260 if (newbie->ipsa_src_cid == NULL) {
3366 3261 error = ENOMEM;
3367 3262 mutex_exit(&newbie->ipsa_lock);
3368 3263 goto error;
3369 3264 }
3370 3265 }
3371 3266
3372 3267 if (ksi->ks_in_extv[SADB_EXT_IDENTITY_DST] != NULL) {
3373 3268 sadb_ident_t *id =
3374 3269 (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST];
3375 3270
3376 3271 /*
3377 3272 * Can assume strlen() will return okay because ext_check() in
3378 3273 * keysock.c prepares the string for us.
3379 3274 */
3380 3275 newbie->ipsa_dst_cid = ipsid_lookup(id->sadb_ident_type,
3381 3276 (char *)(id+1), ns);
3382 3277 if (newbie->ipsa_dst_cid == NULL) {
3383 3278 error = ENOMEM;
3384 3279 mutex_exit(&newbie->ipsa_lock);
3385 3280 goto error;
3386 3281 }
3387 3282 }
3388 3283
3389 3284 /*
3390 3285 * sensitivity label handling code:
3391 3286 * Convert sens + bitmap into cred_t, and associate it
3392 3287 * with the new SA.
3393 3288 */
3394 3289 if (sens != NULL) {
3395 3290 uint64_t *bitmap = (uint64_t *)(sens + 1);
3396 3291
3397 3292 newbie->ipsa_tsl = sadb_label_from_sens(sens, bitmap);
3398 3293 }
3399 3294
3400 3295 /*
3401 3296 * Likewise for outer sensitivity.
3402 3297 */
3403 3298 if (osens != NULL) {
3404 3299 uint64_t *bitmap = (uint64_t *)(osens + 1);
3405 3300 ts_label_t *tsl, *effective_tsl;
3406 3301 uint32_t *peer_addr_ptr;
3407 3302 zoneid_t zoneid = GLOBAL_ZONEID;
3408 3303 zone_t *zone;
3409 3304
3410 3305 peer_addr_ptr = is_inbound ? src_addr_ptr : dst_addr_ptr;
3411 3306
3412 3307 tsl = sadb_label_from_sens(osens, bitmap);
3413 3308 newbie->ipsa_mac_exempt = CONN_MAC_DEFAULT;
3414 3309
3415 3310 if (osens->sadb_x_sens_flags & SADB_X_SENS_IMPLICIT) {
3416 3311 newbie->ipsa_mac_exempt = CONN_MAC_IMPLICIT;
3417 3312 }
3418 3313
3419 3314 error = tsol_check_dest(tsl, peer_addr_ptr,
3420 3315 (af == AF_INET6)?IPV6_VERSION:IPV4_VERSION,
3421 3316 newbie->ipsa_mac_exempt, B_TRUE, &effective_tsl);
3422 3317 if (error != 0) {
3423 3318 label_rele(tsl);
3424 3319 mutex_exit(&newbie->ipsa_lock);
3425 3320 goto error;
3426 3321 }
3427 3322
3428 3323 if (effective_tsl != NULL) {
3429 3324 label_rele(tsl);
3430 3325 tsl = effective_tsl;
3431 3326 }
3432 3327
3433 3328 newbie->ipsa_otsl = tsl;
3434 3329
3435 3330 zone = zone_find_by_label(tsl);
3436 3331 if (zone != NULL) {
3437 3332 zoneid = zone->zone_id;
3438 3333 zone_rele(zone);
3439 3334 }
3440 3335 /*
3441 3336 * For exclusive stacks we set the zoneid to zero to operate
3442 3337 * as if in the global zone for tsol_compute_label_v4/v6
3443 3338 */
3444 3339 if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID)
3445 3340 zoneid = GLOBAL_ZONEID;
3446 3341
3447 3342 if (af == AF_INET6) {
3448 3343 error = tsol_compute_label_v6(tsl, zoneid,
3449 3344 (in6_addr_t *)peer_addr_ptr,
3450 3345 newbie->ipsa_opt_storage, ipst);
3451 3346 } else {
3452 3347 error = tsol_compute_label_v4(tsl, zoneid,
3453 3348 *peer_addr_ptr, newbie->ipsa_opt_storage, ipst);
3454 3349 }
3455 3350 if (error != 0) {
3456 3351 mutex_exit(&newbie->ipsa_lock);
3457 3352 goto error;
3458 3353 }
3459 3354 }
3460 3355
3461 3356
3462 3357 if (replayext != NULL) {
3463 3358 if ((replayext->sadb_x_rc_replay32 == 0) &&
3464 3359 (replayext->sadb_x_rc_replay64 != 0)) {
3465 3360 error = EOPNOTSUPP;
3466 3361 *diagnostic = SADB_X_DIAGNOSTIC_INVALID_REPLAY;
3467 3362 mutex_exit(&newbie->ipsa_lock);
3468 3363 goto error;
3469 3364 }
3470 3365 newbie->ipsa_replay = replayext->sadb_x_rc_replay32;
3471 3366 }
3472 3367
3473 3368 /* now that the SA has been updated, set its new state */
3474 3369 newbie->ipsa_state = assoc->sadb_sa_state;
3475 3370
3476 3371 if (clone) {
3477 3372 newbie->ipsa_haspeer = B_TRUE;
3478 3373 } else {
3479 3374 if (!is_inbound) {
3480 3375 lifetime_fuzz(newbie);
3481 3376 }
3482 3377 }
3483 3378 /*
3484 3379 * The less locks I hold when doing an insertion and possible cloning,
3485 3380 * the better!
3486 3381 */
3487 3382 mutex_exit(&newbie->ipsa_lock);
3488 3383
3489 3384 if (clone) {
3490 3385 newbie_clone = sadb_cloneassoc(newbie);
3491 3386
3492 3387 if (newbie_clone == NULL) {
3493 3388 error = ENOMEM;
3494 3389 goto error;
3495 3390 }
3496 3391 }
3497 3392
3498 3393 /*
3499 3394 * Enter the bucket locks. The order of entry is outbound,
3500 3395 * inbound. We map "primary" and "secondary" into outbound and inbound
3501 3396 * based on the destination address type. If the destination address
3502 3397 * type is for a node that isn't mine (or potentially mine), the
3503 3398 * "primary" bucket is the outbound one.
3504 3399 */
3505 3400 if (!is_inbound) {
3506 3401 /* primary == outbound */
3507 3402 mutex_enter(&primary->isaf_lock);
3508 3403 mutex_enter(&secondary->isaf_lock);
3509 3404 } else {
3510 3405 /* primary == inbound */
3511 3406 mutex_enter(&secondary->isaf_lock);
3512 3407 mutex_enter(&primary->isaf_lock);
3513 3408 }
3514 3409
3515 3410 /*
3516 3411 * sadb_insertassoc() doesn't increment the reference
3517 3412 * count. We therefore have to increment the
3518 3413 * reference count one more time to reflect the
3519 3414 * pointers of the table that reference this SA.
3520 3415 */
3521 3416 IPSA_REFHOLD(newbie);
3522 3417
3523 3418 if (isupdate) {
3524 3419 /*
3525 3420 * Unlink from larval holding cell in the "inbound" fanout.
3526 3421 */
3527 3422 ASSERT(newbie->ipsa_linklock == &primary->isaf_lock ||
3528 3423 newbie->ipsa_linklock == &secondary->isaf_lock);
3529 3424 sadb_unlinkassoc(newbie);
3530 3425 }
3531 3426
3532 3427 mutex_enter(&newbie->ipsa_lock);
3533 3428 error = sadb_insertassoc(newbie, primary);
3534 3429 mutex_exit(&newbie->ipsa_lock);
3535 3430
3536 3431 if (error != 0) {
3537 3432 /*
3538 3433 * Since sadb_insertassoc() failed, we must decrement the
3539 3434 * refcount again so the cleanup code will actually free
3540 3435 * the offending SA.
3541 3436 */
3542 3437 IPSA_REFRELE(newbie);
3543 3438 goto error_unlock;
3544 3439 }
3545 3440
3546 3441 if (newbie_clone != NULL) {
3547 3442 mutex_enter(&newbie_clone->ipsa_lock);
3548 3443 error = sadb_insertassoc(newbie_clone, secondary);
3549 3444 mutex_exit(&newbie_clone->ipsa_lock);
3550 3445 if (error != 0) {
3551 3446 /* Collision in secondary table. */
3552 3447 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3553 3448 goto error_unlock;
3554 3449 }
3555 3450 IPSA_REFHOLD(newbie_clone);
3556 3451 } else {
3557 3452 ASSERT(primary != secondary);
3558 3453 scratch = ipsec_getassocbyspi(secondary, newbie->ipsa_spi,
3559 3454 ALL_ZEROES_PTR, newbie->ipsa_dstaddr, af);
3560 3455 if (scratch != NULL) {
3561 3456 /* Collision in secondary table. */
3562 3457 sadb_unlinkassoc(newbie); /* This does REFRELE. */
3563 3458 /* Set the error, since ipsec_getassocbyspi() can't. */
3564 3459 error = EEXIST;
3565 3460 goto error_unlock;
3566 3461 }
3567 3462 }
3568 3463
3569 3464 /* OKAY! So let's do some reality check assertions. */
3570 3465
3571 3466 ASSERT(MUTEX_NOT_HELD(&newbie->ipsa_lock));
3572 3467 ASSERT(newbie_clone == NULL ||
3573 3468 (MUTEX_NOT_HELD(&newbie_clone->ipsa_lock)));
3574 3469
3575 3470 error_unlock:
3576 3471
3577 3472 /*
3578 3473 * We can exit the locks in any order. Only entrance needs to
3579 3474 * follow any protocol.
3580 3475 */
3581 3476 mutex_exit(&secondary->isaf_lock);
3582 3477 mutex_exit(&primary->isaf_lock);
3583 3478
3584 3479 if (pair_ext != NULL && error == 0) {
3585 3480 /* update pair_spi if it exists. */
3586 3481 ipsa_query_t sq;
3587 3482
3588 3483 sq.spp = spp; /* XXX param */
3589 3484 error = sadb_form_query(ksi, IPSA_Q_DST, IPSA_Q_SRC|IPSA_Q_DST|
3590 3485 IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND, &sq, diagnostic);
3591 3486 if (error)
3592 3487 return (error);
3593 3488
3594 3489 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
3595 3490
3596 3491 if (error != 0)
3597 3492 goto error;
3598 3493
3599 3494 if (ipsapp.ipsap_psa_ptr != NULL) {
3600 3495 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
3601 3496 error = EINVAL;
3602 3497 } else {
3603 3498 /* update_pairing() sets diagnostic */
3604 3499 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
3605 3500 }
3606 3501 }
3607 3502 /* Common error point for this routine. */
3608 3503 error:
3609 3504 if (newbie != NULL) {
3610 3505 if (error != 0) {
3611 3506 /* This SA is broken, let the reaper clean up. */
3612 3507 mutex_enter(&newbie->ipsa_lock);
3613 3508 newbie->ipsa_state = IPSA_STATE_DEAD;
3614 3509 newbie->ipsa_hardexpiretime = 1;
3615 3510 mutex_exit(&newbie->ipsa_lock);
3616 3511 }
3617 3512 IPSA_REFRELE(newbie);
3618 3513 }
3619 3514 if (newbie_clone != NULL) {
3620 3515 IPSA_REFRELE(newbie_clone);
3621 3516 }
3622 3517
3623 3518 if (error == 0) {
3624 3519 /*
3625 3520 * Construct favorable PF_KEY return message and send to
3626 3521 * keysock. Update the flags in the original keysock message
3627 3522 * to reflect the actual flags in the new SA.
3628 3523 * (Q: Do I need to pass "newbie"? If I do,
3629 3524 * make sure to REFHOLD, call, then REFRELE.)
3630 3525 */
3631 3526 assoc->sadb_sa_flags = newbie->ipsa_flags;
3632 3527 sadb_pfkey_echo(pfkey_q, mp, samsg, ksi, NULL);
3633 3528 }
3634 3529
3635 3530 destroy_ipsa_pair(&ipsapp);
3636 3531 return (error);
3637 3532 }
3638 3533
3639 3534 /*
3640 3535 * Set the time of first use for a security association. Update any
3641 3536 * expiration times as a result.
3642 3537 */
3643 3538 void
3644 3539 sadb_set_usetime(ipsa_t *assoc)
3645 3540 {
3646 3541 time_t snapshot = gethrestime_sec();
3647 3542
3648 3543 mutex_enter(&assoc->ipsa_lock);
3649 3544 assoc->ipsa_lastuse = snapshot;
3650 3545 assoc->ipsa_idleexpiretime = snapshot + assoc->ipsa_idletime;
3651 3546
3652 3547 /*
3653 3548 * Caller does check usetime before calling me usually, and
3654 3549 * double-checking is better than a mutex_enter/exit hit.
3655 3550 */
3656 3551 if (assoc->ipsa_usetime == 0) {
3657 3552 /*
3658 3553 * This is redundant for outbound SA's, as
3659 3554 * ipsec_getassocbyconn() sets the IPSA_F_USED flag already.
3660 3555 * Inbound SAs, however, have no such protection.
3661 3556 */
3662 3557 assoc->ipsa_flags |= IPSA_F_USED;
3663 3558 assoc->ipsa_usetime = snapshot;
3664 3559
3665 3560 /*
3666 3561 * After setting the use time, see if we have a use lifetime
3667 3562 * that would cause the actual SA expiration time to shorten.
3668 3563 */
3669 3564 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
3670 3565 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
3671 3566 }
3672 3567 mutex_exit(&assoc->ipsa_lock);
3673 3568 }
3674 3569
3675 3570 /*
3676 3571 * Send up a PF_KEY expire message for this association.
3677 3572 */
3678 3573 static void
3679 3574 sadb_expire_assoc(queue_t *pfkey_q, ipsa_t *assoc)
3680 3575 {
3681 3576 mblk_t *mp, *mp1;
3682 3577 int alloclen, af;
3683 3578 sadb_msg_t *samsg;
3684 3579 sadb_lifetime_t *current, *expire;
3685 3580 sadb_sa_t *saext;
3686 3581 uint8_t *end;
3687 3582 boolean_t tunnel_mode;
3688 3583
3689 3584 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3690 3585
3691 3586 /* Don't bother sending if there's no queue. */
3692 3587 if (pfkey_q == NULL)
3693 3588 return;
3694 3589
3695 3590 mp = sadb_keysock_out(0);
3696 3591 if (mp == NULL) {
3697 3592 /* cmn_err(CE_WARN, */
3698 3593 /* "sadb_expire_assoc: Can't allocate KEYSOCK_OUT.\n"); */
3699 3594 return;
3700 3595 }
3701 3596
3702 3597 alloclen = sizeof (*samsg) + sizeof (*current) + sizeof (*expire) +
3703 3598 2 * sizeof (sadb_address_t) + sizeof (*saext);
3704 3599
3705 3600 af = assoc->ipsa_addrfam;
3706 3601 switch (af) {
3707 3602 case AF_INET:
3708 3603 alloclen += 2 * sizeof (struct sockaddr_in);
3709 3604 break;
3710 3605 case AF_INET6:
3711 3606 alloclen += 2 * sizeof (struct sockaddr_in6);
3712 3607 break;
3713 3608 default:
3714 3609 /* Won't happen unless there's a kernel bug. */
3715 3610 freeb(mp);
3716 3611 cmn_err(CE_WARN,
3717 3612 "sadb_expire_assoc: Unknown address length.\n");
3718 3613 return;
3719 3614 }
3720 3615
3721 3616 tunnel_mode = (assoc->ipsa_flags & IPSA_F_TUNNEL);
3722 3617 if (tunnel_mode) {
3723 3618 alloclen += 2 * sizeof (sadb_address_t);
3724 3619 switch (assoc->ipsa_innerfam) {
3725 3620 case AF_INET:
3726 3621 alloclen += 2 * sizeof (struct sockaddr_in);
3727 3622 break;
3728 3623 case AF_INET6:
3729 3624 alloclen += 2 * sizeof (struct sockaddr_in6);
3730 3625 break;
3731 3626 default:
3732 3627 /* Won't happen unless there's a kernel bug. */
3733 3628 freeb(mp);
3734 3629 cmn_err(CE_WARN, "sadb_expire_assoc: "
3735 3630 "Unknown inner address length.\n");
3736 3631 return;
3737 3632 }
3738 3633 }
3739 3634
3740 3635 mp->b_cont = allocb(alloclen, BPRI_HI);
3741 3636 if (mp->b_cont == NULL) {
3742 3637 freeb(mp);
3743 3638 /* cmn_err(CE_WARN, */
3744 3639 /* "sadb_expire_assoc: Can't allocate message.\n"); */
3745 3640 return;
3746 3641 }
3747 3642
3748 3643 mp1 = mp;
3749 3644 mp = mp->b_cont;
3750 3645 end = mp->b_wptr + alloclen;
3751 3646
3752 3647 samsg = (sadb_msg_t *)mp->b_wptr;
3753 3648 mp->b_wptr += sizeof (*samsg);
3754 3649 samsg->sadb_msg_version = PF_KEY_V2;
3755 3650 samsg->sadb_msg_type = SADB_EXPIRE;
3756 3651 samsg->sadb_msg_errno = 0;
3757 3652 samsg->sadb_msg_satype = assoc->ipsa_type;
3758 3653 samsg->sadb_msg_len = SADB_8TO64(alloclen);
3759 3654 samsg->sadb_msg_reserved = 0;
3760 3655 samsg->sadb_msg_seq = 0;
3761 3656 samsg->sadb_msg_pid = 0;
3762 3657
3763 3658 saext = (sadb_sa_t *)mp->b_wptr;
3764 3659 mp->b_wptr += sizeof (*saext);
3765 3660 saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
3766 3661 saext->sadb_sa_exttype = SADB_EXT_SA;
3767 3662 saext->sadb_sa_spi = assoc->ipsa_spi;
3768 3663 saext->sadb_sa_replay = assoc->ipsa_replay_wsize;
3769 3664 saext->sadb_sa_state = assoc->ipsa_state;
3770 3665 saext->sadb_sa_auth = assoc->ipsa_auth_alg;
3771 3666 saext->sadb_sa_encrypt = assoc->ipsa_encr_alg;
3772 3667 saext->sadb_sa_flags = assoc->ipsa_flags;
3773 3668
3774 3669 current = (sadb_lifetime_t *)mp->b_wptr;
3775 3670 mp->b_wptr += sizeof (sadb_lifetime_t);
3776 3671 current->sadb_lifetime_len = SADB_8TO64(sizeof (*current));
3777 3672 current->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
3778 3673 /* We do not support the concept. */
3779 3674 current->sadb_lifetime_allocations = 0;
3780 3675 current->sadb_lifetime_bytes = assoc->ipsa_bytes;
3781 3676 current->sadb_lifetime_addtime = assoc->ipsa_addtime;
3782 3677 current->sadb_lifetime_usetime = assoc->ipsa_usetime;
3783 3678
3784 3679 expire = (sadb_lifetime_t *)mp->b_wptr;
3785 3680 mp->b_wptr += sizeof (*expire);
3786 3681 expire->sadb_lifetime_len = SADB_8TO64(sizeof (*expire));
3787 3682
3788 3683 if (assoc->ipsa_state == IPSA_STATE_DEAD) {
3789 3684 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
3790 3685 expire->sadb_lifetime_allocations = assoc->ipsa_hardalloc;
3791 3686 expire->sadb_lifetime_bytes = assoc->ipsa_hardbyteslt;
3792 3687 expire->sadb_lifetime_addtime = assoc->ipsa_hardaddlt;
3793 3688 expire->sadb_lifetime_usetime = assoc->ipsa_harduselt;
3794 3689 } else if (assoc->ipsa_state == IPSA_STATE_DYING) {
3795 3690 expire->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
3796 3691 expire->sadb_lifetime_allocations = assoc->ipsa_softalloc;
3797 3692 expire->sadb_lifetime_bytes = assoc->ipsa_softbyteslt;
3798 3693 expire->sadb_lifetime_addtime = assoc->ipsa_softaddlt;
3799 3694 expire->sadb_lifetime_usetime = assoc->ipsa_softuselt;
3800 3695 } else {
3801 3696 ASSERT(assoc->ipsa_state == IPSA_STATE_MATURE);
3802 3697 expire->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE;
3803 3698 expire->sadb_lifetime_allocations = 0;
3804 3699 expire->sadb_lifetime_bytes = 0;
3805 3700 expire->sadb_lifetime_addtime = assoc->ipsa_idleaddlt;
3806 3701 expire->sadb_lifetime_usetime = assoc->ipsa_idleuselt;
3807 3702 }
3808 3703
3809 3704 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_SRC,
3810 3705 af, assoc->ipsa_srcaddr, tunnel_mode ? 0 : SA_SRCPORT(assoc),
3811 3706 SA_PROTO(assoc), 0);
3812 3707 ASSERT(mp->b_wptr != NULL);
3813 3708
3814 3709 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end, SADB_EXT_ADDRESS_DST,
3815 3710 af, assoc->ipsa_dstaddr, tunnel_mode ? 0 : SA_DSTPORT(assoc),
3816 3711 SA_PROTO(assoc), 0);
3817 3712 ASSERT(mp->b_wptr != NULL);
3818 3713
3819 3714 if (tunnel_mode) {
3820 3715 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3821 3716 SADB_X_EXT_ADDRESS_INNER_SRC, assoc->ipsa_innerfam,
3822 3717 assoc->ipsa_innersrc, SA_SRCPORT(assoc), SA_IPROTO(assoc),
3823 3718 assoc->ipsa_innersrcpfx);
3824 3719 ASSERT(mp->b_wptr != NULL);
3825 3720 mp->b_wptr = sadb_make_addr_ext(mp->b_wptr, end,
3826 3721 SADB_X_EXT_ADDRESS_INNER_DST, assoc->ipsa_innerfam,
3827 3722 assoc->ipsa_innerdst, SA_DSTPORT(assoc), SA_IPROTO(assoc),
3828 3723 assoc->ipsa_innerdstpfx);
3829 3724 ASSERT(mp->b_wptr != NULL);
3830 3725 }
3831 3726
3832 3727 /* Can just putnext, we're ready to go! */
3833 3728 putnext(pfkey_q, mp1);
3834 3729 }
3835 3730
3836 3731 /*
3837 3732 * "Age" the SA with the number of bytes that was used to protect traffic.
3838 3733 * Send an SADB_EXPIRE message if appropriate. Return B_TRUE if there was
3839 3734 * enough "charge" left in the SA to protect the data. Return B_FALSE
3840 3735 * otherwise. (If B_FALSE is returned, the association either was, or became
3841 3736 * DEAD.)
3842 3737 */
3843 3738 boolean_t
3844 3739 sadb_age_bytes(queue_t *pfkey_q, ipsa_t *assoc, uint64_t bytes,
3845 3740 boolean_t sendmsg)
3846 3741 {
3847 3742 boolean_t rc = B_TRUE;
3848 3743 uint64_t newtotal;
3849 3744
3850 3745 mutex_enter(&assoc->ipsa_lock);
3851 3746 newtotal = assoc->ipsa_bytes + bytes;
3852 3747 if (assoc->ipsa_hardbyteslt != 0 &&
3853 3748 newtotal >= assoc->ipsa_hardbyteslt) {
3854 3749 if (assoc->ipsa_state != IPSA_STATE_DEAD) {
3855 3750 /*
3856 3751 * Send EXPIRE message to PF_KEY. May wish to pawn
3857 3752 * this off on another non-interrupt thread. Also
3858 3753 * unlink this SA immediately.
3859 3754 */
3860 3755 assoc->ipsa_state = IPSA_STATE_DEAD;
3861 3756 if (sendmsg)
3862 3757 sadb_expire_assoc(pfkey_q, assoc);
3863 3758 /*
3864 3759 * Set non-zero expiration time so sadb_age_assoc()
3865 3760 * will work when reaping.
3866 3761 */
3867 3762 assoc->ipsa_hardexpiretime = (time_t)1;
3868 3763 } /* Else someone beat me to it! */
3869 3764 rc = B_FALSE;
3870 3765 } else if (assoc->ipsa_softbyteslt != 0 &&
3871 3766 (newtotal >= assoc->ipsa_softbyteslt)) {
3872 3767 if (assoc->ipsa_state < IPSA_STATE_DYING) {
3873 3768 /*
3874 3769 * Send EXPIRE message to PF_KEY. May wish to pawn
3875 3770 * this off on another non-interrupt thread.
3876 3771 */
3877 3772 assoc->ipsa_state = IPSA_STATE_DYING;
3878 3773 assoc->ipsa_bytes = newtotal;
3879 3774 if (sendmsg)
3880 3775 sadb_expire_assoc(pfkey_q, assoc);
3881 3776 } /* Else someone beat me to it! */
3882 3777 }
3883 3778 if (rc == B_TRUE)
3884 3779 assoc->ipsa_bytes = newtotal;
3885 3780 mutex_exit(&assoc->ipsa_lock);
3886 3781 return (rc);
3887 3782 }
3888 3783
3889 3784 /*
3890 3785 * "Torch" an individual SA. Returns NULL, so it can be tail-called from
3891 3786 * sadb_age_assoc().
3892 3787 */
3893 3788 static ipsa_t *
3894 3789 sadb_torch_assoc(isaf_t *head, ipsa_t *sa)
3895 3790 {
3896 3791 ASSERT(MUTEX_HELD(&head->isaf_lock));
3897 3792 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
3898 3793 ASSERT(sa->ipsa_state == IPSA_STATE_DEAD);
3899 3794
3900 3795 /*
3901 3796 * Force cached SAs to be revalidated..
3902 3797 */
3903 3798 head->isaf_gen++;
3904 3799
3905 3800 mutex_exit(&sa->ipsa_lock);
3906 3801 sadb_unlinkassoc(sa);
3907 3802
3908 3803 return (NULL);
3909 3804 }
3910 3805
3911 3806 /*
3912 3807 * Do various SA-is-idle activities depending on delta (the number of idle
3913 3808 * seconds on the SA) and/or other properties of the SA.
3914 3809 *
3915 3810 * Return B_TRUE if I've sent a packet, because I have to drop the
3916 3811 * association's mutex before sending a packet out the wire.
3917 3812 */
3918 3813 /* ARGSUSED */
3919 3814 static boolean_t
3920 3815 sadb_idle_activities(ipsa_t *assoc, time_t delta, boolean_t inbound)
3921 3816 {
3922 3817 ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
3923 3818 int nat_t_interval = espstack->ipsecesp_nat_keepalive_interval;
3924 3819
3925 3820 ASSERT(MUTEX_HELD(&assoc->ipsa_lock));
3926 3821
3927 3822 if (!inbound && (assoc->ipsa_flags & IPSA_F_NATT_LOC) &&
3928 3823 delta >= nat_t_interval &&
3929 3824 gethrestime_sec() - assoc->ipsa_last_nat_t_ka >= nat_t_interval) {
3930 3825 ASSERT(assoc->ipsa_type == SADB_SATYPE_ESP);
3931 3826 assoc->ipsa_last_nat_t_ka = gethrestime_sec();
3932 3827 mutex_exit(&assoc->ipsa_lock);
3933 3828 ipsecesp_send_keepalive(assoc);
3934 3829 return (B_TRUE);
3935 3830 }
3936 3831 return (B_FALSE);
3937 3832 }
3938 3833
3939 3834 /*
3940 3835 * Return "assoc" if haspeer is true and I send an expire. This allows
3941 3836 * the consumers' aging functions to tidy up an expired SA's peer.
3942 3837 */
3943 3838 static ipsa_t *
|
↓ open down ↓ |
886 lines elided |
↑ open up ↑ |
3944 3839 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3945 3840 time_t current, int reap_delay, boolean_t inbound)
3946 3841 {
3947 3842 ipsa_t *retval = NULL;
3948 3843 boolean_t dropped_mutex = B_FALSE;
3949 3844
3950 3845 ASSERT(MUTEX_HELD(&head->isaf_lock));
3951 3846
3952 3847 mutex_enter(&assoc->ipsa_lock);
3953 3848
3954 - if (((assoc->ipsa_state == IPSA_STATE_LARVAL) ||
3955 - ((assoc->ipsa_state == IPSA_STATE_IDLE) ||
3956 - (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) &&
3957 - (assoc->ipsa_hardexpiretime != 0))) &&
3958 - (assoc->ipsa_hardexpiretime <= current)) {
3849 + /*
3850 + * Be aggressive in reaping expired LARVAL SAs.
3851 + */
3852 + if (assoc->ipsa_state == IPSA_STATE_LARVAL &&
3853 + assoc->ipsa_hardexpiretime <= current) {
3959 3854 assoc->ipsa_state = IPSA_STATE_DEAD;
3960 3855 return (sadb_torch_assoc(head, assoc));
3961 3856 }
3962 3857
3963 3858 /*
3964 3859 * Check lifetimes. Fortunately, SA setup is done
3965 3860 * such that there are only two times to look at,
3966 3861 * softexpiretime, and hardexpiretime.
3967 3862 *
3968 3863 * Check hard first.
3969 3864 */
3970 3865
3971 3866 if (assoc->ipsa_hardexpiretime != 0 &&
3972 3867 assoc->ipsa_hardexpiretime <= current) {
3973 3868 if (assoc->ipsa_state == IPSA_STATE_DEAD)
3974 3869 return (sadb_torch_assoc(head, assoc));
3975 3870
3976 3871 /*
3977 3872 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3978 3873 */
3979 3874 assoc->ipsa_state = IPSA_STATE_DEAD;
3980 3875 if (assoc->ipsa_haspeer || assoc->ipsa_otherspi != 0) {
3981 3876 /*
3982 3877 * If the SA is paired or peered with another, put
3983 3878 * a copy on a list which can be processed later, the
3984 3879 * pair/peer SA needs to be updated so the both die
3985 3880 * at the same time.
3986 3881 *
3987 3882 * If I return assoc, I have to bump up its reference
3988 3883 * count to keep with the ipsa_t reference count
3989 3884 * semantics.
3990 3885 */
3991 3886 IPSA_REFHOLD(assoc);
3992 3887 retval = assoc;
3993 3888 }
3994 3889 sadb_expire_assoc(pfkey_q, assoc);
3995 3890 assoc->ipsa_hardexpiretime = current + reap_delay;
3996 3891 } else if (assoc->ipsa_softexpiretime != 0 &&
3997 3892 assoc->ipsa_softexpiretime <= current &&
3998 3893 assoc->ipsa_state < IPSA_STATE_DYING) {
3999 3894 /*
4000 3895 * Send EXPIRE message to PF_KEY. May wish to pawn
4001 3896 * this off on another non-interrupt thread.
4002 3897 */
4003 3898 assoc->ipsa_state = IPSA_STATE_DYING;
4004 3899 if (assoc->ipsa_haspeer) {
4005 3900 /*
4006 3901 * If the SA has a peer, update the peer's state
4007 3902 * on SOFT_EXPIRE, this is mostly to prevent two
4008 3903 * expire messages from effectively the same SA.
4009 3904 *
4010 3905 * Don't care about paired SA's, then can (and should)
4011 3906 * be able to soft expire at different times.
4012 3907 *
|
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
4013 3908 * If I return assoc, I have to bump up its
4014 3909 * reference count to keep with the ipsa_t reference
4015 3910 * count semantics.
4016 3911 */
4017 3912 IPSA_REFHOLD(assoc);
4018 3913 retval = assoc;
4019 3914 }
4020 3915 sadb_expire_assoc(pfkey_q, assoc);
4021 3916 } else if (assoc->ipsa_idletime != 0 &&
4022 3917 assoc->ipsa_idleexpiretime <= current) {
4023 - if (assoc->ipsa_state == IPSA_STATE_ACTIVE_ELSEWHERE) {
4024 - assoc->ipsa_state = IPSA_STATE_IDLE;
4025 - }
4026 -
4027 - /*
4028 - * Need to handle Mature case
4029 - */
3918 + /* Only issue an IDLE expiration if we're in mature state. */
4030 3919 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
4031 3920 sadb_expire_assoc(pfkey_q, assoc);
4032 3921 }
4033 3922 } else {
4034 3923 /* Check idle time activities. */
4035 3924 dropped_mutex = sadb_idle_activities(assoc,
4036 3925 current - assoc->ipsa_lastuse, inbound);
4037 3926 }
4038 3927
4039 3928 if (!dropped_mutex)
4040 3929 mutex_exit(&assoc->ipsa_lock);
4041 3930 return (retval);
4042 3931 }
4043 3932
4044 3933 /*
4045 3934 * Called by a consumer protocol to do ther dirty work of reaping dead
4046 3935 * Security Associations.
4047 3936 *
4048 3937 * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
4049 3938 * SA's that are already marked DEAD, so expired SA's are only reaped
4050 3939 * the second time sadb_ager() runs.
4051 3940 */
4052 3941 void
4053 3942 sadb_ager(sadb_t *sp, queue_t *pfkey_q, int reap_delay, netstack_t *ns)
4054 3943 {
4055 3944 int i;
4056 3945 isaf_t *bucket;
4057 3946 ipsa_t *assoc, *spare;
4058 3947 iacqf_t *acqlist;
4059 3948 ipsacq_t *acqrec, *spareacq;
4060 3949 templist_t *haspeerlist, *newbie;
4061 3950 /* Snapshot current time now. */
4062 3951 time_t current = gethrestime_sec();
4063 3952 haspeerlist = NULL;
4064 3953
4065 3954 /*
4066 3955 * Do my dirty work. This includes aging real entries, aging
4067 3956 * larvals, and aging outstanding ACQUIREs.
4068 3957 *
4069 3958 * I hope I don't tie up resources for too long.
4070 3959 */
4071 3960
4072 3961 /* Age acquires. */
4073 3962
4074 3963 for (i = 0; i < sp->sdb_hashsize; i++) {
4075 3964 acqlist = &sp->sdb_acq[i];
4076 3965 mutex_enter(&acqlist->iacqf_lock);
4077 3966 for (acqrec = acqlist->iacqf_ipsacq; acqrec != NULL;
4078 3967 acqrec = spareacq) {
4079 3968 spareacq = acqrec->ipsacq_next;
4080 3969 if (current > acqrec->ipsacq_expire)
4081 3970 sadb_destroy_acquire(acqrec, ns);
4082 3971 }
4083 3972 mutex_exit(&acqlist->iacqf_lock);
4084 3973 }
4085 3974
4086 3975 /* Age inbound associations. */
4087 3976 for (i = 0; i < sp->sdb_hashsize; i++) {
4088 3977 bucket = &(sp->sdb_if[i]);
4089 3978 mutex_enter(&bucket->isaf_lock);
4090 3979 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4091 3980 assoc = spare) {
4092 3981 spare = assoc->ipsa_next;
4093 3982 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4094 3983 reap_delay, B_TRUE) != NULL) {
4095 3984 /*
4096 3985 * Put SA's which have a peer or SA's which
4097 3986 * are paired on a list for processing after
4098 3987 * all the hash tables have been walked.
4099 3988 *
4100 3989 * sadb_age_assoc() increments the refcnt,
4101 3990 * effectively doing an IPSA_REFHOLD().
4102 3991 */
4103 3992 newbie = kmem_alloc(sizeof (*newbie),
4104 3993 KM_NOSLEEP);
4105 3994 if (newbie == NULL) {
4106 3995 /*
4107 3996 * Don't forget to REFRELE().
4108 3997 */
4109 3998 IPSA_REFRELE(assoc);
4110 3999 continue; /* for loop... */
4111 4000 }
4112 4001 newbie->next = haspeerlist;
4113 4002 newbie->ipsa = assoc;
4114 4003 haspeerlist = newbie;
4115 4004 }
4116 4005 }
4117 4006 mutex_exit(&bucket->isaf_lock);
4118 4007 }
4119 4008
4120 4009 age_pair_peer_list(haspeerlist, sp, B_FALSE);
4121 4010 haspeerlist = NULL;
4122 4011
4123 4012 /* Age outbound associations. */
4124 4013 for (i = 0; i < sp->sdb_hashsize; i++) {
4125 4014 bucket = &(sp->sdb_of[i]);
4126 4015 mutex_enter(&bucket->isaf_lock);
4127 4016 for (assoc = bucket->isaf_ipsa; assoc != NULL;
4128 4017 assoc = spare) {
4129 4018 spare = assoc->ipsa_next;
4130 4019 if (sadb_age_assoc(bucket, pfkey_q, assoc, current,
4131 4020 reap_delay, B_FALSE) != NULL) {
4132 4021 /*
4133 4022 * sadb_age_assoc() increments the refcnt,
4134 4023 * effectively doing an IPSA_REFHOLD().
4135 4024 */
4136 4025 newbie = kmem_alloc(sizeof (*newbie),
4137 4026 KM_NOSLEEP);
4138 4027 if (newbie == NULL) {
4139 4028 /*
4140 4029 * Don't forget to REFRELE().
4141 4030 */
4142 4031 IPSA_REFRELE(assoc);
4143 4032 continue; /* for loop... */
4144 4033 }
4145 4034 newbie->next = haspeerlist;
4146 4035 newbie->ipsa = assoc;
4147 4036 haspeerlist = newbie;
4148 4037 }
4149 4038 }
4150 4039 mutex_exit(&bucket->isaf_lock);
4151 4040 }
4152 4041
4153 4042 age_pair_peer_list(haspeerlist, sp, B_TRUE);
4154 4043
4155 4044 /*
4156 4045 * Run a GC pass to clean out dead identities.
4157 4046 */
4158 4047 ipsid_gc(ns);
4159 4048 }
4160 4049
4161 4050 /*
4162 4051 * Figure out when to reschedule the ager.
4163 4052 */
4164 4053 timeout_id_t
4165 4054 sadb_retimeout(hrtime_t begin, queue_t *pfkey_q, void (*ager)(void *),
4166 4055 void *agerarg, uint_t *intp, uint_t intmax, short mid)
4167 4056 {
4168 4057 hrtime_t end = gethrtime();
4169 4058 uint_t interval = *intp; /* "interval" is in ms. */
4170 4059
4171 4060 /*
4172 4061 * See how long this took. If it took too long, increase the
4173 4062 * aging interval.
4174 4063 */
4175 4064 if ((end - begin) > MSEC2NSEC(interval)) {
4176 4065 if (interval >= intmax) {
4177 4066 /* XXX Rate limit this? Or recommend flush? */
4178 4067 (void) strlog(mid, 0, 0, SL_ERROR | SL_WARN,
4179 4068 "Too many SA's to age out in %d msec.\n",
4180 4069 intmax);
4181 4070 } else {
4182 4071 /* Double by shifting by one bit. */
4183 4072 interval <<= 1;
4184 4073 interval = min(interval, intmax);
4185 4074 }
4186 4075 } else if ((end - begin) <= (MSEC2NSEC(interval) / 2) &&
4187 4076 interval > SADB_AGE_INTERVAL_DEFAULT) {
4188 4077 /*
4189 4078 * If I took less than half of the interval, then I should
4190 4079 * ratchet the interval back down. Never automatically
4191 4080 * shift below the default aging interval.
4192 4081 *
4193 4082 * NOTE:This even overrides manual setting of the age
4194 4083 * interval using NDD to lower the setting past the
4195 4084 * default. In other words, if you set the interval
4196 4085 * lower than the default, and your SADB gets too big,
4197 4086 * the interval will only self-lower back to the default.
4198 4087 */
4199 4088 /* Halve by shifting one bit. */
4200 4089 interval >>= 1;
4201 4090 interval = max(interval, SADB_AGE_INTERVAL_DEFAULT);
4202 4091 }
4203 4092 *intp = interval;
4204 4093 return (qtimeout(pfkey_q, ager, agerarg,
4205 4094 drv_usectohz(interval * (MICROSEC / MILLISEC))));
4206 4095 }
4207 4096
4208 4097
4209 4098 /*
4210 4099 * Update the lifetime values of an SA. This is the path an SADB_UPDATE
4211 4100 * message takes when updating a MATURE or DYING SA.
4212 4101 */
4213 4102 static void
4214 4103 sadb_update_lifetimes(ipsa_t *assoc, sadb_lifetime_t *hard,
4215 4104 sadb_lifetime_t *soft, sadb_lifetime_t *idle, boolean_t outbound)
4216 4105 {
4217 4106 mutex_enter(&assoc->ipsa_lock);
4218 4107
4219 4108 /*
4220 4109 * XXX RFC 2367 mentions how an SADB_EXT_LIFETIME_CURRENT can be
4221 4110 * passed in during an update message. We currently don't handle
4222 4111 * these.
4223 4112 */
4224 4113
4225 4114 if (hard != NULL) {
4226 4115 if (hard->sadb_lifetime_bytes != 0)
4227 4116 assoc->ipsa_hardbyteslt = hard->sadb_lifetime_bytes;
4228 4117 if (hard->sadb_lifetime_usetime != 0)
4229 4118 assoc->ipsa_harduselt = hard->sadb_lifetime_usetime;
4230 4119 if (hard->sadb_lifetime_addtime != 0)
4231 4120 assoc->ipsa_hardaddlt = hard->sadb_lifetime_addtime;
4232 4121 if (assoc->ipsa_hardaddlt != 0) {
4233 4122 assoc->ipsa_hardexpiretime =
4234 4123 assoc->ipsa_addtime + assoc->ipsa_hardaddlt;
4235 4124 }
4236 4125 if (assoc->ipsa_harduselt != 0 &&
4237 4126 assoc->ipsa_flags & IPSA_F_USED) {
4238 4127 UPDATE_EXPIRE(assoc, harduselt, hardexpiretime);
4239 4128 }
4240 4129 if (hard->sadb_lifetime_allocations != 0)
4241 4130 assoc->ipsa_hardalloc = hard->sadb_lifetime_allocations;
4242 4131 }
4243 4132
4244 4133 if (soft != NULL) {
4245 4134 if (soft->sadb_lifetime_bytes != 0) {
4246 4135 if (soft->sadb_lifetime_bytes >
4247 4136 assoc->ipsa_hardbyteslt) {
4248 4137 assoc->ipsa_softbyteslt =
4249 4138 assoc->ipsa_hardbyteslt;
4250 4139 } else {
4251 4140 assoc->ipsa_softbyteslt =
4252 4141 soft->sadb_lifetime_bytes;
4253 4142 }
4254 4143 }
4255 4144 if (soft->sadb_lifetime_usetime != 0) {
4256 4145 if (soft->sadb_lifetime_usetime >
4257 4146 assoc->ipsa_harduselt) {
4258 4147 assoc->ipsa_softuselt =
4259 4148 assoc->ipsa_harduselt;
4260 4149 } else {
4261 4150 assoc->ipsa_softuselt =
4262 4151 soft->sadb_lifetime_usetime;
4263 4152 }
4264 4153 }
4265 4154 if (soft->sadb_lifetime_addtime != 0) {
4266 4155 if (soft->sadb_lifetime_addtime >
4267 4156 assoc->ipsa_hardexpiretime) {
4268 4157 assoc->ipsa_softexpiretime =
4269 4158 assoc->ipsa_hardexpiretime;
4270 4159 } else {
4271 4160 assoc->ipsa_softaddlt =
4272 4161 soft->sadb_lifetime_addtime;
4273 4162 }
4274 4163 }
4275 4164 if (assoc->ipsa_softaddlt != 0) {
4276 4165 assoc->ipsa_softexpiretime =
4277 4166 assoc->ipsa_addtime + assoc->ipsa_softaddlt;
4278 4167 }
4279 4168 if (assoc->ipsa_softuselt != 0 &&
4280 4169 assoc->ipsa_flags & IPSA_F_USED) {
4281 4170 UPDATE_EXPIRE(assoc, softuselt, softexpiretime);
4282 4171 }
4283 4172 if (outbound && assoc->ipsa_softexpiretime != 0) {
4284 4173 if (assoc->ipsa_state == IPSA_STATE_MATURE)
4285 4174 lifetime_fuzz(assoc);
4286 4175 }
4287 4176
4288 4177 if (soft->sadb_lifetime_allocations != 0)
4289 4178 assoc->ipsa_softalloc = soft->sadb_lifetime_allocations;
4290 4179 }
4291 4180
4292 4181 if (idle != NULL) {
4293 4182 time_t current = gethrestime_sec();
4294 4183 if ((assoc->ipsa_idleexpiretime <= current) &&
4295 4184 (assoc->ipsa_idleaddlt == idle->sadb_lifetime_addtime)) {
4296 4185 assoc->ipsa_idleexpiretime =
4297 4186 current + assoc->ipsa_idleaddlt;
4298 4187 }
4299 4188 if (idle->sadb_lifetime_addtime != 0)
4300 4189 assoc->ipsa_idleaddlt = idle->sadb_lifetime_addtime;
4301 4190 if (idle->sadb_lifetime_usetime != 0)
4302 4191 assoc->ipsa_idleuselt = idle->sadb_lifetime_usetime;
4303 4192 if (assoc->ipsa_idleaddlt != 0) {
4304 4193 assoc->ipsa_idleexpiretime =
4305 4194 current + idle->sadb_lifetime_addtime;
4306 4195 assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4307 4196 }
4308 4197 if (assoc->ipsa_idleuselt != 0) {
4309 4198 if (assoc->ipsa_idletime != 0) {
4310 4199 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4311 4200 assoc->ipsa_idleuselt);
4312 4201 assoc->ipsa_idleexpiretime =
4313 4202 current + assoc->ipsa_idletime;
|
↓ open down ↓ |
274 lines elided |
↑ open up ↑ |
4314 4203 } else {
4315 4204 assoc->ipsa_idleexpiretime =
4316 4205 current + assoc->ipsa_idleuselt;
4317 4206 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4318 4207 }
4319 4208 }
4320 4209 }
4321 4210 mutex_exit(&assoc->ipsa_lock);
4322 4211 }
4323 4212
4324 -static int
4325 -sadb_update_state(ipsa_t *assoc, uint_t new_state, mblk_t **ipkt_lst)
4326 -{
4327 - int rcode = 0;
4328 - time_t current = gethrestime_sec();
4329 -
4330 - mutex_enter(&assoc->ipsa_lock);
4331 -
4332 - switch (new_state) {
4333 - case SADB_X_SASTATE_ACTIVE_ELSEWHERE:
4334 - if (assoc->ipsa_state == SADB_X_SASTATE_IDLE) {
4335 - assoc->ipsa_state = IPSA_STATE_ACTIVE_ELSEWHERE;
4336 - assoc->ipsa_idleexpiretime =
4337 - current + assoc->ipsa_idletime;
4338 - }
4339 - break;
4340 - case SADB_X_SASTATE_IDLE:
4341 - if (assoc->ipsa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4342 - assoc->ipsa_state = IPSA_STATE_IDLE;
4343 - assoc->ipsa_idleexpiretime =
4344 - current + assoc->ipsa_idletime;
4345 - } else {
4346 - rcode = EINVAL;
4347 - }
4348 - break;
4349 -
4350 - case SADB_X_SASTATE_ACTIVE:
4351 - if (assoc->ipsa_state != SADB_X_SASTATE_IDLE) {
4352 - rcode = EINVAL;
4353 - break;
4354 - }
4355 - assoc->ipsa_state = IPSA_STATE_MATURE;
4356 - assoc->ipsa_idleexpiretime = current + assoc->ipsa_idletime;
4357 -
4358 - if (ipkt_lst == NULL) {
4359 - break;
4360 - }
4361 -
4362 - if (assoc->ipsa_bpkt_head != NULL) {
4363 - *ipkt_lst = assoc->ipsa_bpkt_head;
4364 - assoc->ipsa_bpkt_head = assoc->ipsa_bpkt_tail = NULL;
4365 - assoc->ipsa_mblkcnt = 0;
4366 - } else {
4367 - *ipkt_lst = NULL;
4368 - }
4369 - break;
4370 - default:
4371 - rcode = EINVAL;
4372 - break;
4373 - }
4374 -
4375 - mutex_exit(&assoc->ipsa_lock);
4376 - return (rcode);
4377 -}
4378 -
4379 4213 /*
4380 4214 * Check a proposed KMC update for sanity.
4381 4215 */
4382 4216 static int
4383 4217 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4384 4218 {
4385 4219 uint32_t kmp = sq->kmp;
4386 4220 uint32_t kmc = sq->kmc;
4387 4221
4388 4222 if (sa == NULL)
4389 4223 return (0);
4390 4224
4391 4225 if (sa->ipsa_state == IPSA_STATE_DEAD)
4392 4226 return (ESRCH); /* DEAD == Not there, in this case. */
4393 4227
4394 4228 if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
4395 4229 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4396 4230 return (EINVAL);
4397 4231 }
4398 4232
4399 4233 if ((kmc != 0) && ((sa->ipsa_kmc != 0) || (sa->ipsa_kmc != kmc))) {
4400 4234 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
4401 4235 return (EINVAL);
4402 4236 }
4403 4237
4404 4238 return (0);
4405 4239 }
4406 4240
4407 4241 /*
4408 4242 * Actually update the KMC info.
4409 4243 */
4410 4244 static void
4411 4245 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4412 4246 {
4413 4247 uint32_t kmp = sq->kmp;
4414 4248 uint32_t kmc = sq->kmc;
4415 4249
4416 4250 if (kmp != 0)
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
4417 4251 sa->ipsa_kmp = kmp;
4418 4252 if (kmc != 0)
4419 4253 sa->ipsa_kmc = kmc;
4420 4254 }
4421 4255
4422 4256 /*
4423 4257 * Common code to update an SA.
4424 4258 */
4425 4259
4426 4260 int
4427 -sadb_update_sa(mblk_t *mp, keysock_in_t *ksi, mblk_t **ipkt_lst,
4261 +sadb_update_sa(mblk_t *mp, keysock_in_t *ksi,
4428 4262 sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4429 4263 int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4430 4264 netstack_t *ns, uint8_t sadb_msg_type)
4431 4265 {
4432 4266 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4433 4267 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
4434 - sadb_x_replay_ctr_t *replext =
4435 - (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE];
4436 4268 sadb_lifetime_t *soft =
4437 4269 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4438 4270 sadb_lifetime_t *hard =
4439 4271 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4440 4272 sadb_lifetime_t *idle =
4441 4273 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4442 4274 sadb_x_pair_t *pair_ext =
4443 4275 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4444 4276 ipsa_t *echo_target = NULL;
4445 4277 ipsap_t ipsapp;
4446 4278 ipsa_query_t sq;
4447 - time_t current = gethrestime_sec();
4448 4279
4449 4280 sq.spp = spp; /* XXX param */
4450 4281 int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4451 4282 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
4452 4283 &sq, diagnostic);
4453 4284
4454 4285 if (error != 0)
4455 4286 return (error);
4456 4287
4457 4288 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4458 4289 if (error != 0)
4459 4290 return (error);
4460 4291
4461 4292 if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4462 4293 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4463 4294 /*
4464 4295 * REFRELE the target and let the add_sa_func()
4465 4296 * deal with updating a larval SA.
4466 4297 */
4467 4298 destroy_ipsa_pair(&ipsapp);
4468 4299 return (add_sa_func(mp, ksi, diagnostic, ns));
4469 4300 }
4470 4301 }
4471 4302
4472 4303 /*
4473 4304 * At this point we have an UPDATE to a MATURE SA. There should
4474 4305 * not be any keying material present.
4475 4306 */
4476 4307 if (akey != NULL) {
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
4477 4308 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4478 4309 error = EINVAL;
4479 4310 goto bail;
4480 4311 }
4481 4312 if (ekey != NULL) {
4482 4313 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4483 4314 error = EINVAL;
4484 4315 goto bail;
4485 4316 }
4486 4317
4487 - if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE) {
4488 - if (ipsapp.ipsap_sa_ptr != NULL &&
4489 - ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4490 - if ((error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4491 - sq.assoc->sadb_sa_state, NULL)) != 0) {
4492 - *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4493 - goto bail;
4494 - }
4495 - }
4496 - if (ipsapp.ipsap_psa_ptr != NULL &&
4497 - ipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_IDLE) {
4498 - if ((error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4499 - sq.assoc->sadb_sa_state, NULL)) != 0) {
4500 - *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4501 - goto bail;
4502 - }
4503 - }
4504 - }
4505 - if (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE) {
4506 - if (ipsapp.ipsap_sa_ptr != NULL) {
4507 - error = sadb_update_state(ipsapp.ipsap_sa_ptr,
4508 - sq.assoc->sadb_sa_state,
4509 - (ipsapp.ipsap_sa_ptr->ipsa_flags &
4510 - IPSA_F_INBOUND) ? ipkt_lst : NULL);
4511 - if (error) {
4512 - *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4513 - goto bail;
4514 - }
4515 - }
4516 - if (ipsapp.ipsap_psa_ptr != NULL) {
4517 - error = sadb_update_state(ipsapp.ipsap_psa_ptr,
4518 - sq.assoc->sadb_sa_state,
4519 - (ipsapp.ipsap_psa_ptr->ipsa_flags &
4520 - IPSA_F_INBOUND) ? ipkt_lst : NULL);
4521 - if (error) {
4522 - *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4523 - goto bail;
4524 - }
4525 - }
4526 - sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4527 - ksi, echo_target);
4528 - goto bail;
4529 - }
4530 -
4531 4318 /*
4532 4319 * Reality checks for updates of active associations.
4533 4320 * Sundry first-pass UPDATE-specific reality checks.
4534 4321 * Have to do the checks here, because it's after the add_sa code.
4535 4322 * XXX STATS : logging/stats here?
4536 4323 */
4537 4324
4538 - if (!((sq.assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
4539 - (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE))) {
4325 + if (sq.assoc->sadb_sa_state != SADB_SASTATE_MATURE) {
4540 4326 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4541 4327 error = EINVAL;
4542 4328 goto bail;
4543 4329 }
4544 4330 if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4545 4331 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4546 4332 error = EINVAL;
4547 4333 goto bail;
4548 4334 }
4549 4335 if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4550 4336 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4551 4337 error = EOPNOTSUPP;
4552 4338 goto bail;
4553 4339 }
4554 4340
4555 4341 if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4556 4342 error = EINVAL;
4557 4343 goto bail;
4558 4344 }
4559 4345
4560 4346 if ((*diagnostic = sadb_labelchk(ksi)) != 0)
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
4561 4347 return (EINVAL);
4562 4348
4563 4349 error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4564 4350 if (error != 0)
4565 4351 goto bail;
4566 4352
4567 4353 error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4568 4354 if (error != 0)
4569 4355 goto bail;
4570 4356
4571 -
4572 4357 if (ipsapp.ipsap_sa_ptr != NULL) {
4573 - /*
4574 - * Do not allow replay value change for MATURE or LARVAL SA.
4575 - */
4576 -
4577 - if ((replext != NULL) &&
4578 - ((ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) ||
4579 - (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_MATURE))) {
4580 - *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4581 - error = EINVAL;
4582 - goto bail;
4583 - }
4584 - }
4585 -
4586 -
4587 - if (ipsapp.ipsap_sa_ptr != NULL) {
4588 4358 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4589 4359 idle, B_TRUE);
4590 4360 sadb_update_kmc(&sq, ipsapp.ipsap_sa_ptr);
4591 - if ((replext != NULL) &&
4592 - (ipsapp.ipsap_sa_ptr->ipsa_replay_wsize != 0)) {
4593 - /*
4594 - * If an inbound SA, update the replay counter
4595 - * and check off all the other sequence number
4596 - */
4597 - if (ksi->ks_in_dsttype == KS_IN_ADDR_ME) {
4598 - if (!sadb_replay_check(ipsapp.ipsap_sa_ptr,
4599 - replext->sadb_x_rc_replay32)) {
4600 - *diagnostic =
4601 - SADB_X_DIAGNOSTIC_INVALID_REPLAY;
4602 - error = EINVAL;
4603 - goto bail;
4604 - }
4605 - mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4606 - ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4607 - current +
4608 - ipsapp.ipsap_sa_ptr->ipsa_idletime;
4609 - mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4610 - } else {
4611 - mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4612 - ipsapp.ipsap_sa_ptr->ipsa_replay =
4613 - replext->sadb_x_rc_replay32;
4614 - ipsapp.ipsap_sa_ptr->ipsa_idleexpiretime =
4615 - current +
4616 - ipsapp.ipsap_sa_ptr->ipsa_idletime;
4617 - mutex_exit(&ipsapp.ipsap_sa_ptr->ipsa_lock);
4618 - }
4619 - }
4620 4361 }
4621 4362
4622 4363 if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4623 4364 if (ipsapp.ipsap_psa_ptr != NULL) {
4624 4365 sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4625 4366 idle, B_FALSE);
4626 4367 sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4627 4368 } else {
4628 4369 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4629 4370 error = ESRCH;
4630 4371 goto bail;
4631 4372 }
4632 4373 }
4633 4374
4634 4375 if (pair_ext != NULL)
4635 4376 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4636 4377
4637 4378 if (error == 0)
4638 4379 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4639 4380 ksi, echo_target);
4640 4381 bail:
4641 4382
4642 4383 destroy_ipsa_pair(&ipsapp);
4643 4384
4644 4385 return (error);
4645 4386 }
4646 4387
4647 4388
4648 4389 static int
4649 4390 update_pairing(ipsap_t *ipsapp, ipsa_query_t *sq, keysock_in_t *ksi,
4650 4391 int *diagnostic)
4651 4392 {
4652 4393 sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
4653 4394 sadb_x_pair_t *pair_ext =
4654 4395 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4655 4396 int error = 0;
4656 4397 ipsap_t oipsapp;
4657 4398 boolean_t undo_pair = B_FALSE;
4658 4399 uint32_t ipsa_flags;
4659 4400
4660 4401 if (pair_ext->sadb_x_pair_spi == 0 || pair_ext->sadb_x_pair_spi ==
4661 4402 assoc->sadb_sa_spi) {
4662 4403 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4663 4404 return (EINVAL);
4664 4405 }
4665 4406
4666 4407 /*
4667 4408 * Assume for now that the spi value provided in the SADB_UPDATE
4668 4409 * message was valid, update the SA with its pair spi value.
4669 4410 * If the spi turns out to be bogus or the SA no longer exists
4670 4411 * then this will be detected when the reverse update is made
4671 4412 * below.
4672 4413 */
4673 4414 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4674 4415 ipsapp->ipsap_sa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4675 4416 ipsapp->ipsap_sa_ptr->ipsa_otherspi = pair_ext->sadb_x_pair_spi;
4676 4417 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4677 4418
4678 4419 /*
4679 4420 * After updating the ipsa_otherspi element of the SA, get_ipsa_pair()
4680 4421 * should now return pointers to the SA *AND* its pair, if this is not
4681 4422 * the case, the "otherspi" either did not exist or was deleted. Also
4682 4423 * check that "otherspi" is not already paired. If everything looks
4683 4424 * good, complete the update. IPSA_REFRELE the first pair_pointer
4684 4425 * after this update to ensure its not deleted until we are done.
4685 4426 */
4686 4427 error = get_ipsa_pair(sq, &oipsapp, diagnostic);
4687 4428 if (error != 0) {
4688 4429 /*
4689 4430 * This should never happen, calling function still has
4690 4431 * IPSA_REFHELD on the SA we just updated.
4691 4432 */
4692 4433 return (error); /* XXX EINVAL instead of ESRCH? */
4693 4434 }
4694 4435
4695 4436 if (oipsapp.ipsap_psa_ptr == NULL) {
4696 4437 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4697 4438 error = EINVAL;
4698 4439 undo_pair = B_TRUE;
4699 4440 } else {
4700 4441 ipsa_flags = oipsapp.ipsap_psa_ptr->ipsa_flags;
4701 4442 if ((oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DEAD) ||
4702 4443 (oipsapp.ipsap_psa_ptr->ipsa_state == IPSA_STATE_DYING)) {
4703 4444 /* Its dead Jim! */
4704 4445 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4705 4446 undo_pair = B_TRUE;
4706 4447 } else if ((ipsa_flags & (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) ==
4707 4448 (IPSA_F_OUTBOUND | IPSA_F_INBOUND)) {
4708 4449 /* This SA is in both hashtables. */
4709 4450 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_INAPPROPRIATE;
4710 4451 undo_pair = B_TRUE;
4711 4452 } else if (ipsa_flags & IPSA_F_PAIRED) {
4712 4453 /* This SA is already paired with another. */
4713 4454 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_ALREADY;
4714 4455 undo_pair = B_TRUE;
4715 4456 }
4716 4457 }
4717 4458
4718 4459 if (undo_pair) {
4719 4460 /* The pair SA does not exist. */
4720 4461 mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4721 4462 ipsapp->ipsap_sa_ptr->ipsa_flags &= ~IPSA_F_PAIRED;
4722 4463 ipsapp->ipsap_sa_ptr->ipsa_otherspi = 0;
4723 4464 mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock);
4724 4465 } else {
4725 4466 mutex_enter(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4726 4467 oipsapp.ipsap_psa_ptr->ipsa_otherspi = assoc->sadb_sa_spi;
4727 4468 oipsapp.ipsap_psa_ptr->ipsa_flags |= IPSA_F_PAIRED;
4728 4469 mutex_exit(&oipsapp.ipsap_psa_ptr->ipsa_lock);
4729 4470 }
4730 4471
4731 4472 destroy_ipsa_pair(&oipsapp);
4732 4473 return (error);
4733 4474 }
4734 4475
4735 4476 /*
4736 4477 * The following functions deal with ACQUIRE LISTS. An ACQUIRE list is
4737 4478 * a list of outstanding SADB_ACQUIRE messages. If ipsec_getassocbyconn() fails
4738 4479 * for an outbound datagram, that datagram is queued up on an ACQUIRE record,
4739 4480 * and an SADB_ACQUIRE message is sent up. Presumably, a user-space key
4740 4481 * management daemon will process the ACQUIRE, use a SADB_GETSPI to reserve
4741 4482 * an SPI value and a larval SA, then SADB_UPDATE the larval SA, and ADD the
4742 4483 * other direction's SA.
4743 4484 */
4744 4485
4745 4486 /*
4746 4487 * Check the ACQUIRE lists. If there's an existing ACQUIRE record,
4747 4488 * grab it, lock it, and return it. Otherwise return NULL.
4748 4489 *
4749 4490 * XXX MLS number of arguments getting unwieldy here
4750 4491 */
4751 4492 static ipsacq_t *
4752 4493 sadb_checkacquire(iacqf_t *bucket, ipsec_action_t *ap, ipsec_policy_t *pp,
4753 4494 uint32_t *src, uint32_t *dst, uint32_t *isrc, uint32_t *idst,
4754 4495 uint64_t unique_id, ts_label_t *tsl)
4755 4496 {
4756 4497 ipsacq_t *walker;
4757 4498 sa_family_t fam;
4758 4499 uint32_t blank_address[4] = {0, 0, 0, 0};
4759 4500
4760 4501 if (isrc == NULL) {
4761 4502 ASSERT(idst == NULL);
4762 4503 isrc = idst = blank_address;
4763 4504 }
4764 4505
4765 4506 /*
4766 4507 * Scan list for duplicates. Check for UNIQUE, src/dest, policy.
4767 4508 *
4768 4509 * XXX May need search for duplicates based on other things too!
4769 4510 */
4770 4511 for (walker = bucket->iacqf_ipsacq; walker != NULL;
4771 4512 walker = walker->ipsacq_next) {
4772 4513 mutex_enter(&walker->ipsacq_lock);
4773 4514 fam = walker->ipsacq_addrfam;
4774 4515 if (IPSA_ARE_ADDR_EQUAL(dst, walker->ipsacq_dstaddr, fam) &&
4775 4516 IPSA_ARE_ADDR_EQUAL(src, walker->ipsacq_srcaddr, fam) &&
4776 4517 ip_addr_match((uint8_t *)isrc, walker->ipsacq_innersrcpfx,
4777 4518 (in6_addr_t *)walker->ipsacq_innersrc) &&
4778 4519 ip_addr_match((uint8_t *)idst, walker->ipsacq_innerdstpfx,
4779 4520 (in6_addr_t *)walker->ipsacq_innerdst) &&
4780 4521 (ap == walker->ipsacq_act) &&
4781 4522 (pp == walker->ipsacq_policy) &&
4782 4523 /* XXX do deep compares of ap/pp? */
4783 4524 (unique_id == walker->ipsacq_unique_id) &&
4784 4525 (ipsec_label_match(tsl, walker->ipsacq_tsl)))
4785 4526 break; /* everything matched */
4786 4527 mutex_exit(&walker->ipsacq_lock);
4787 4528 }
4788 4529
4789 4530 return (walker);
4790 4531 }
4791 4532
4792 4533 /*
4793 4534 * For this mblk, insert a new acquire record. Assume bucket contains addrs
4794 4535 * of all of the same length. Give up (and drop) if memory
4795 4536 * cannot be allocated for a new one; otherwise, invoke callback to
4796 4537 * send the acquire up..
4797 4538 *
4798 4539 * In cases where we need both AH and ESP, add the SA to the ESP ACQUIRE
4799 4540 * list. The ah_add_sa_finish() routines can look at the packet's attached
4800 4541 * attributes and handle this case specially.
4801 4542 */
4802 4543 void
4803 4544 sadb_acquire(mblk_t *datamp, ip_xmit_attr_t *ixa, boolean_t need_ah,
4804 4545 boolean_t need_esp)
4805 4546 {
4806 4547 mblk_t *asyncmp;
4807 4548 sadbp_t *spp;
4808 4549 sadb_t *sp;
4809 4550 ipsacq_t *newbie;
4810 4551 iacqf_t *bucket;
4811 4552 mblk_t *extended;
4812 4553 ipha_t *ipha = (ipha_t *)datamp->b_rptr;
4813 4554 ip6_t *ip6h = (ip6_t *)datamp->b_rptr;
4814 4555 uint32_t *src, *dst, *isrc, *idst;
4815 4556 ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
4816 4557 ipsec_action_t *ap = ixa->ixa_ipsec_action;
4817 4558 sa_family_t af;
4818 4559 int hashoffset;
4819 4560 uint32_t seq;
4820 4561 uint64_t unique_id = 0;
4821 4562 ipsec_selector_t sel;
4822 4563 boolean_t tunnel_mode = (ixa->ixa_flags & IXAF_IPSEC_TUNNEL) != 0;
4823 4564 ts_label_t *tsl = NULL;
4824 4565 netstack_t *ns = ixa->ixa_ipst->ips_netstack;
4825 4566 ipsec_stack_t *ipss = ns->netstack_ipsec;
4826 4567 sadb_sens_t *sens = NULL;
4827 4568 int sens_len;
4828 4569
4829 4570 ASSERT((pp != NULL) || (ap != NULL));
4830 4571
4831 4572 ASSERT(need_ah != NULL || need_esp != NULL);
4832 4573
4833 4574 /* Assign sadb pointers */
4834 4575 if (need_esp) { /* ESP for AH+ESP */
4835 4576 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
4836 4577
4837 4578 spp = &espstack->esp_sadb;
4838 4579 } else {
4839 4580 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
4840 4581
4841 4582 spp = &ahstack->ah_sadb;
4842 4583 }
4843 4584 sp = (ixa->ixa_flags & IXAF_IS_IPV4) ? &spp->s_v4 : &spp->s_v6;
4844 4585
4845 4586 if (is_system_labeled())
4846 4587 tsl = ixa->ixa_tsl;
4847 4588
4848 4589 if (ap == NULL)
4849 4590 ap = pp->ipsp_act;
4850 4591
4851 4592 ASSERT(ap != NULL);
4852 4593
4853 4594 if (ap->ipa_act.ipa_apply.ipp_use_unique || tunnel_mode)
4854 4595 unique_id = SA_FORM_UNIQUE_ID(ixa);
4855 4596
4856 4597 /*
4857 4598 * Set up an ACQUIRE record.
4858 4599 *
4859 4600 * Immediately, make sure the ACQUIRE sequence number doesn't slip
4860 4601 * below the lowest point allowed in the kernel. (In other words,
4861 4602 * make sure the high bit on the sequence number is set.)
4862 4603 */
4863 4604
4864 4605 seq = keysock_next_seq(ns) | IACQF_LOWEST_SEQ;
4865 4606
4866 4607 if (IPH_HDR_VERSION(ipha) == IP_VERSION) {
4867 4608 src = (uint32_t *)&ipha->ipha_src;
4868 4609 dst = (uint32_t *)&ipha->ipha_dst;
4869 4610 af = AF_INET;
4870 4611 hashoffset = OUTBOUND_HASH_V4(sp, ipha->ipha_dst);
4871 4612 ASSERT(ixa->ixa_flags & IXAF_IS_IPV4);
4872 4613 } else {
4873 4614 ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION);
4874 4615 src = (uint32_t *)&ip6h->ip6_src;
4875 4616 dst = (uint32_t *)&ip6h->ip6_dst;
4876 4617 af = AF_INET6;
4877 4618 hashoffset = OUTBOUND_HASH_V6(sp, ip6h->ip6_dst);
4878 4619 ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4));
4879 4620 }
4880 4621
4881 4622 if (tunnel_mode) {
4882 4623 if (pp == NULL) {
4883 4624 /*
4884 4625 * Tunnel mode with no policy pointer means this is a
4885 4626 * reflected ICMP (like a ECHO REQUEST) that came in
4886 4627 * with self-encapsulated protection. Until we better
4887 4628 * support this, drop the packet.
4888 4629 */
4889 4630 ip_drop_packet(datamp, B_FALSE, NULL,
4890 4631 DROPPER(ipss, ipds_spd_got_selfencap),
4891 4632 &ipss->ipsec_spd_dropper);
4892 4633 return;
4893 4634 }
4894 4635 /* Snag inner addresses. */
4895 4636 isrc = ixa->ixa_ipsec_insrc;
4896 4637 idst = ixa->ixa_ipsec_indst;
4897 4638 } else {
4898 4639 isrc = idst = NULL;
4899 4640 }
4900 4641
4901 4642 /*
4902 4643 * Check buckets to see if there is an existing entry. If so,
4903 4644 * grab it. sadb_checkacquire locks newbie if found.
4904 4645 */
4905 4646 bucket = &(sp->sdb_acq[hashoffset]);
4906 4647 mutex_enter(&bucket->iacqf_lock);
4907 4648 newbie = sadb_checkacquire(bucket, ap, pp, src, dst, isrc, idst,
4908 4649 unique_id, tsl);
4909 4650
4910 4651 if (newbie == NULL) {
4911 4652 /*
4912 4653 * Otherwise, allocate a new one.
4913 4654 */
4914 4655 newbie = kmem_zalloc(sizeof (*newbie), KM_NOSLEEP);
4915 4656 if (newbie == NULL) {
4916 4657 mutex_exit(&bucket->iacqf_lock);
4917 4658 ip_drop_packet(datamp, B_FALSE, NULL,
4918 4659 DROPPER(ipss, ipds_sadb_acquire_nomem),
4919 4660 &ipss->ipsec_sadb_dropper);
4920 4661 return;
4921 4662 }
4922 4663 newbie->ipsacq_policy = pp;
4923 4664 if (pp != NULL) {
4924 4665 IPPOL_REFHOLD(pp);
4925 4666 }
4926 4667 IPACT_REFHOLD(ap);
4927 4668 newbie->ipsacq_act = ap;
4928 4669 newbie->ipsacq_linklock = &bucket->iacqf_lock;
4929 4670 newbie->ipsacq_next = bucket->iacqf_ipsacq;
4930 4671 newbie->ipsacq_ptpn = &bucket->iacqf_ipsacq;
4931 4672 if (newbie->ipsacq_next != NULL)
4932 4673 newbie->ipsacq_next->ipsacq_ptpn = &newbie->ipsacq_next;
4933 4674
4934 4675 bucket->iacqf_ipsacq = newbie;
4935 4676 mutex_init(&newbie->ipsacq_lock, NULL, MUTEX_DEFAULT, NULL);
4936 4677 mutex_enter(&newbie->ipsacq_lock);
4937 4678 }
4938 4679
4939 4680 /*
4940 4681 * XXX MLS does it actually help us to drop the bucket lock here?
4941 4682 * we have inserted a half-built, locked acquire record into the
4942 4683 * bucket. any competing thread will now be able to lock the bucket
4943 4684 * to scan it, but will immediately pile up on the new acquire
4944 4685 * record's lock; I don't think we gain anything here other than to
4945 4686 * disperse blame for lock contention.
4946 4687 *
4947 4688 * we might be able to dispense with acquire record locks entirely..
4948 4689 * just use the bucket locks..
4949 4690 */
4950 4691
4951 4692 mutex_exit(&bucket->iacqf_lock);
4952 4693
4953 4694 /*
4954 4695 * This assert looks silly for now, but we may need to enter newbie's
4955 4696 * mutex during a search.
4956 4697 */
4957 4698 ASSERT(MUTEX_HELD(&newbie->ipsacq_lock));
4958 4699
4959 4700 /*
4960 4701 * Make the ip_xmit_attr_t into something we can queue.
4961 4702 * If no memory it frees datamp.
4962 4703 */
4963 4704 asyncmp = ip_xmit_attr_to_mblk(ixa);
4964 4705 if (asyncmp != NULL)
4965 4706 linkb(asyncmp, datamp);
4966 4707
4967 4708 /* Queue up packet. Use b_next. */
4968 4709
4969 4710 if (asyncmp == NULL) {
4970 4711 /* Statistics for allocation failure */
4971 4712 if (ixa->ixa_flags & IXAF_IS_IPV4) {
4972 4713 BUMP_MIB(&ixa->ixa_ipst->ips_ip_mib,
4973 4714 ipIfStatsOutDiscards);
4974 4715 } else {
4975 4716 BUMP_MIB(&ixa->ixa_ipst->ips_ip6_mib,
4976 4717 ipIfStatsOutDiscards);
4977 4718 }
4978 4719 ip_drop_output("No memory for asyncmp", datamp, NULL);
4979 4720 freemsg(datamp);
4980 4721 } else if (newbie->ipsacq_numpackets == 0) {
4981 4722 /* First one. */
4982 4723 newbie->ipsacq_mp = asyncmp;
4983 4724 newbie->ipsacq_numpackets = 1;
4984 4725 newbie->ipsacq_expire = gethrestime_sec();
4985 4726 /*
4986 4727 * Extended ACQUIRE with both AH+ESP will use ESP's timeout
4987 4728 * value.
4988 4729 */
4989 4730 newbie->ipsacq_expire += *spp->s_acquire_timeout;
4990 4731 newbie->ipsacq_seq = seq;
4991 4732 newbie->ipsacq_addrfam = af;
4992 4733
4993 4734 newbie->ipsacq_srcport = ixa->ixa_ipsec_src_port;
4994 4735 newbie->ipsacq_dstport = ixa->ixa_ipsec_dst_port;
4995 4736 newbie->ipsacq_icmp_type = ixa->ixa_ipsec_icmp_type;
4996 4737 newbie->ipsacq_icmp_code = ixa->ixa_ipsec_icmp_code;
4997 4738 if (tunnel_mode) {
4998 4739 newbie->ipsacq_inneraddrfam = ixa->ixa_ipsec_inaf;
4999 4740 newbie->ipsacq_proto = ixa->ixa_ipsec_inaf == AF_INET6 ?
5000 4741 IPPROTO_IPV6 : IPPROTO_ENCAP;
5001 4742 newbie->ipsacq_innersrcpfx = ixa->ixa_ipsec_insrcpfx;
5002 4743 newbie->ipsacq_innerdstpfx = ixa->ixa_ipsec_indstpfx;
5003 4744 IPSA_COPY_ADDR(newbie->ipsacq_innersrc,
5004 4745 ixa->ixa_ipsec_insrc, ixa->ixa_ipsec_inaf);
5005 4746 IPSA_COPY_ADDR(newbie->ipsacq_innerdst,
5006 4747 ixa->ixa_ipsec_indst, ixa->ixa_ipsec_inaf);
5007 4748 } else {
5008 4749 newbie->ipsacq_proto = ixa->ixa_ipsec_proto;
5009 4750 }
5010 4751 newbie->ipsacq_unique_id = unique_id;
5011 4752
5012 4753 if (ixa->ixa_tsl != NULL) {
5013 4754 label_hold(ixa->ixa_tsl);
5014 4755 newbie->ipsacq_tsl = ixa->ixa_tsl;
5015 4756 }
5016 4757 } else {
5017 4758 /* Scan to the end of the list & insert. */
5018 4759 mblk_t *lastone = newbie->ipsacq_mp;
5019 4760
5020 4761 while (lastone->b_next != NULL)
5021 4762 lastone = lastone->b_next;
5022 4763 lastone->b_next = asyncmp;
5023 4764 if (newbie->ipsacq_numpackets++ == ipsacq_maxpackets) {
5024 4765 newbie->ipsacq_numpackets = ipsacq_maxpackets;
5025 4766 lastone = newbie->ipsacq_mp;
5026 4767 newbie->ipsacq_mp = lastone->b_next;
5027 4768 lastone->b_next = NULL;
5028 4769
5029 4770 /* Freeing the async message */
5030 4771 lastone = ip_xmit_attr_free_mblk(lastone);
5031 4772 ip_drop_packet(lastone, B_FALSE, NULL,
5032 4773 DROPPER(ipss, ipds_sadb_acquire_toofull),
5033 4774 &ipss->ipsec_sadb_dropper);
5034 4775 } else {
5035 4776 IP_ACQUIRE_STAT(ipss, qhiwater,
5036 4777 newbie->ipsacq_numpackets);
5037 4778 }
5038 4779 }
5039 4780
5040 4781 /*
5041 4782 * Reset addresses. Set them to the most recently added mblk chain,
5042 4783 * so that the address pointers in the acquire record will point
5043 4784 * at an mblk still attached to the acquire list.
5044 4785 */
5045 4786
5046 4787 newbie->ipsacq_srcaddr = src;
5047 4788 newbie->ipsacq_dstaddr = dst;
5048 4789
5049 4790 /*
5050 4791 * If the acquire record has more than one queued packet, we've
5051 4792 * already sent an ACQUIRE, and don't need to repeat ourself.
5052 4793 */
5053 4794 if (newbie->ipsacq_seq != seq || newbie->ipsacq_numpackets > 1) {
5054 4795 /* I have an acquire outstanding already! */
5055 4796 mutex_exit(&newbie->ipsacq_lock);
5056 4797 return;
5057 4798 }
5058 4799
5059 4800 if (!keysock_extended_reg(ns))
5060 4801 goto punt_extended;
5061 4802 /*
5062 4803 * Construct an extended ACQUIRE. There are logging
5063 4804 * opportunities here in failure cases.
5064 4805 */
5065 4806 bzero(&sel, sizeof (sel));
5066 4807 sel.ips_isv4 = (ixa->ixa_flags & IXAF_IS_IPV4) != 0;
5067 4808 if (tunnel_mode) {
5068 4809 sel.ips_protocol = (ixa->ixa_ipsec_inaf == AF_INET) ?
5069 4810 IPPROTO_ENCAP : IPPROTO_IPV6;
5070 4811 } else {
5071 4812 sel.ips_protocol = ixa->ixa_ipsec_proto;
5072 4813 sel.ips_local_port = ixa->ixa_ipsec_src_port;
5073 4814 sel.ips_remote_port = ixa->ixa_ipsec_dst_port;
5074 4815 }
5075 4816 sel.ips_icmp_type = ixa->ixa_ipsec_icmp_type;
5076 4817 sel.ips_icmp_code = ixa->ixa_ipsec_icmp_code;
5077 4818 sel.ips_is_icmp_inv_acq = 0;
5078 4819 if (af == AF_INET) {
5079 4820 sel.ips_local_addr_v4 = ipha->ipha_src;
5080 4821 sel.ips_remote_addr_v4 = ipha->ipha_dst;
5081 4822 } else {
5082 4823 sel.ips_local_addr_v6 = ip6h->ip6_src;
5083 4824 sel.ips_remote_addr_v6 = ip6h->ip6_dst;
5084 4825 }
5085 4826
5086 4827 extended = sadb_keysock_out(0);
5087 4828 if (extended == NULL)
5088 4829 goto punt_extended;
5089 4830
5090 4831 if (ixa->ixa_tsl != NULL) {
5091 4832 /*
5092 4833 * XXX MLS correct condition here?
5093 4834 * XXX MLS other credential attributes in acquire?
5094 4835 * XXX malloc failure? don't fall back to original?
5095 4836 */
5096 4837 sens = sadb_make_sens_ext(ixa->ixa_tsl, &sens_len);
5097 4838
5098 4839 if (sens == NULL) {
5099 4840 freeb(extended);
5100 4841 goto punt_extended;
5101 4842 }
5102 4843 }
5103 4844
5104 4845 extended->b_cont = sadb_extended_acquire(&sel, pp, ap, tunnel_mode,
5105 4846 seq, 0, sens, ns);
5106 4847
5107 4848 if (sens != NULL)
5108 4849 kmem_free(sens, sens_len);
5109 4850
5110 4851 if (extended->b_cont == NULL) {
5111 4852 freeb(extended);
5112 4853 goto punt_extended;
5113 4854 }
5114 4855
5115 4856 /*
5116 4857 * Send an ACQUIRE message (and possible an extended ACQUIRE) based on
5117 4858 * this new record. The send-acquire callback assumes that acqrec is
5118 4859 * already locked.
5119 4860 */
5120 4861 (*spp->s_acqfn)(newbie, extended, ns);
5121 4862 return;
5122 4863
5123 4864 punt_extended:
5124 4865 (*spp->s_acqfn)(newbie, NULL, ns);
5125 4866 }
5126 4867
5127 4868 /*
5128 4869 * Unlink and free an acquire record.
5129 4870 */
5130 4871 void
5131 4872 sadb_destroy_acquire(ipsacq_t *acqrec, netstack_t *ns)
5132 4873 {
5133 4874 mblk_t *mp;
5134 4875 ipsec_stack_t *ipss = ns->netstack_ipsec;
5135 4876
5136 4877 ASSERT(MUTEX_HELD(acqrec->ipsacq_linklock));
5137 4878
5138 4879 if (acqrec->ipsacq_policy != NULL) {
5139 4880 IPPOL_REFRELE(acqrec->ipsacq_policy);
5140 4881 }
5141 4882 if (acqrec->ipsacq_act != NULL) {
5142 4883 IPACT_REFRELE(acqrec->ipsacq_act);
5143 4884 }
5144 4885
5145 4886 /* Unlink */
5146 4887 *(acqrec->ipsacq_ptpn) = acqrec->ipsacq_next;
5147 4888 if (acqrec->ipsacq_next != NULL)
5148 4889 acqrec->ipsacq_next->ipsacq_ptpn = acqrec->ipsacq_ptpn;
5149 4890
5150 4891 if (acqrec->ipsacq_tsl != NULL) {
5151 4892 label_rele(acqrec->ipsacq_tsl);
5152 4893 acqrec->ipsacq_tsl = NULL;
5153 4894 }
5154 4895
5155 4896 /*
5156 4897 * Free hanging mp's.
5157 4898 *
5158 4899 * XXX Instead of freemsg(), perhaps use IPSEC_REQ_FAILED.
5159 4900 */
5160 4901
5161 4902 mutex_enter(&acqrec->ipsacq_lock);
5162 4903 while (acqrec->ipsacq_mp != NULL) {
5163 4904 mp = acqrec->ipsacq_mp;
5164 4905 acqrec->ipsacq_mp = mp->b_next;
5165 4906 mp->b_next = NULL;
5166 4907 /* Freeing the async message */
5167 4908 mp = ip_xmit_attr_free_mblk(mp);
5168 4909 ip_drop_packet(mp, B_FALSE, NULL,
5169 4910 DROPPER(ipss, ipds_sadb_acquire_timeout),
5170 4911 &ipss->ipsec_sadb_dropper);
5171 4912 }
5172 4913 mutex_exit(&acqrec->ipsacq_lock);
5173 4914
5174 4915 /* Free */
5175 4916 mutex_destroy(&acqrec->ipsacq_lock);
5176 4917 kmem_free(acqrec, sizeof (*acqrec));
5177 4918 }
5178 4919
5179 4920 /*
5180 4921 * Destroy an acquire list fanout.
5181 4922 */
5182 4923 static void
5183 4924 sadb_destroy_acqlist(iacqf_t **listp, uint_t numentries, boolean_t forever,
5184 4925 netstack_t *ns)
5185 4926 {
5186 4927 int i;
5187 4928 iacqf_t *list = *listp;
5188 4929
5189 4930 if (list == NULL)
5190 4931 return;
5191 4932
5192 4933 for (i = 0; i < numentries; i++) {
5193 4934 mutex_enter(&(list[i].iacqf_lock));
5194 4935 while (list[i].iacqf_ipsacq != NULL)
5195 4936 sadb_destroy_acquire(list[i].iacqf_ipsacq, ns);
5196 4937 mutex_exit(&(list[i].iacqf_lock));
5197 4938 if (forever)
5198 4939 mutex_destroy(&(list[i].iacqf_lock));
5199 4940 }
5200 4941
5201 4942 if (forever) {
5202 4943 *listp = NULL;
5203 4944 kmem_free(list, numentries * sizeof (*list));
5204 4945 }
5205 4946 }
5206 4947
5207 4948 /*
5208 4949 * Create an algorithm descriptor for an extended ACQUIRE. Filter crypto
5209 4950 * framework's view of reality vs. IPsec's. EF's wins, BTW.
5210 4951 */
5211 4952 static uint8_t *
5212 4953 sadb_new_algdesc(uint8_t *start, uint8_t *limit,
5213 4954 sadb_x_ecomb_t *ecomb, uint8_t satype, uint8_t algtype,
5214 4955 uint8_t alg, uint16_t minbits, uint16_t maxbits, ipsec_stack_t *ipss)
5215 4956 {
5216 4957 uint8_t *cur = start;
5217 4958 ipsec_alginfo_t *algp;
5218 4959 sadb_x_algdesc_t *algdesc = (sadb_x_algdesc_t *)cur;
5219 4960
5220 4961 cur += sizeof (*algdesc);
5221 4962 if (cur >= limit)
5222 4963 return (NULL);
5223 4964
5224 4965 ecomb->sadb_x_ecomb_numalgs++;
5225 4966
5226 4967 /*
5227 4968 * Normalize vs. crypto framework's limits. This way, you can specify
5228 4969 * a stronger policy, and when the framework loads a stronger version,
5229 4970 * you can just keep plowing w/o rewhacking your SPD.
5230 4971 */
5231 4972 mutex_enter(&ipss->ipsec_alg_lock);
5232 4973 algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
5233 4974 IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
5234 4975 if (algp == NULL) {
5235 4976 mutex_exit(&ipss->ipsec_alg_lock);
5236 4977 return (NULL); /* Algorithm doesn't exist. Fail gracefully. */
5237 4978 }
5238 4979 if (minbits < algp->alg_ef_minbits)
5239 4980 minbits = algp->alg_ef_minbits;
5240 4981 if (maxbits > algp->alg_ef_maxbits)
5241 4982 maxbits = algp->alg_ef_maxbits;
5242 4983 mutex_exit(&ipss->ipsec_alg_lock);
5243 4984
5244 4985 algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
5245 4986 algdesc->sadb_x_algdesc_satype = satype;
5246 4987 algdesc->sadb_x_algdesc_algtype = algtype;
5247 4988 algdesc->sadb_x_algdesc_alg = alg;
5248 4989 algdesc->sadb_x_algdesc_minbits = minbits;
5249 4990 algdesc->sadb_x_algdesc_maxbits = maxbits;
5250 4991
5251 4992 return (cur);
5252 4993 }
5253 4994
5254 4995 /*
5255 4996 * Convert the given ipsec_action_t into an ecomb starting at *ecomb
5256 4997 * which must fit before *limit
5257 4998 *
5258 4999 * return NULL if we ran out of room or a pointer to the end of the ecomb.
5259 5000 */
5260 5001 static uint8_t *
5261 5002 sadb_action_to_ecomb(uint8_t *start, uint8_t *limit, ipsec_action_t *act,
5262 5003 netstack_t *ns)
5263 5004 {
5264 5005 uint8_t *cur = start;
5265 5006 sadb_x_ecomb_t *ecomb = (sadb_x_ecomb_t *)cur;
5266 5007 ipsec_prot_t *ipp;
5267 5008 ipsec_stack_t *ipss = ns->netstack_ipsec;
5268 5009
5269 5010 cur += sizeof (*ecomb);
5270 5011 if (cur >= limit)
5271 5012 return (NULL);
5272 5013
5273 5014 ASSERT(act->ipa_act.ipa_type == IPSEC_ACT_APPLY);
5274 5015
5275 5016 ipp = &act->ipa_act.ipa_apply;
5276 5017
5277 5018 ecomb->sadb_x_ecomb_numalgs = 0;
5278 5019 ecomb->sadb_x_ecomb_reserved = 0;
5279 5020 ecomb->sadb_x_ecomb_reserved2 = 0;
5280 5021 /*
5281 5022 * No limits on allocations, since we really don't support that
5282 5023 * concept currently.
5283 5024 */
5284 5025 ecomb->sadb_x_ecomb_soft_allocations = 0;
5285 5026 ecomb->sadb_x_ecomb_hard_allocations = 0;
5286 5027
5287 5028 /*
5288 5029 * XXX TBD: Policy or global parameters will eventually be
5289 5030 * able to fill in some of these.
5290 5031 */
5291 5032 ecomb->sadb_x_ecomb_flags = 0;
5292 5033 ecomb->sadb_x_ecomb_soft_bytes = 0;
5293 5034 ecomb->sadb_x_ecomb_hard_bytes = 0;
5294 5035 ecomb->sadb_x_ecomb_soft_addtime = 0;
5295 5036 ecomb->sadb_x_ecomb_hard_addtime = 0;
5296 5037 ecomb->sadb_x_ecomb_soft_usetime = 0;
5297 5038 ecomb->sadb_x_ecomb_hard_usetime = 0;
5298 5039
5299 5040 if (ipp->ipp_use_ah) {
5300 5041 cur = sadb_new_algdesc(cur, limit, ecomb,
5301 5042 SADB_SATYPE_AH, SADB_X_ALGTYPE_AUTH, ipp->ipp_auth_alg,
5302 5043 ipp->ipp_ah_minbits, ipp->ipp_ah_maxbits, ipss);
5303 5044 if (cur == NULL)
5304 5045 return (NULL);
5305 5046 ipsecah_fill_defs(ecomb, ns);
5306 5047 }
5307 5048
5308 5049 if (ipp->ipp_use_esp) {
5309 5050 if (ipp->ipp_use_espa) {
5310 5051 cur = sadb_new_algdesc(cur, limit, ecomb,
5311 5052 SADB_SATYPE_ESP, SADB_X_ALGTYPE_AUTH,
5312 5053 ipp->ipp_esp_auth_alg,
5313 5054 ipp->ipp_espa_minbits,
5314 5055 ipp->ipp_espa_maxbits, ipss);
5315 5056 if (cur == NULL)
5316 5057 return (NULL);
5317 5058 }
5318 5059
5319 5060 cur = sadb_new_algdesc(cur, limit, ecomb,
5320 5061 SADB_SATYPE_ESP, SADB_X_ALGTYPE_CRYPT,
5321 5062 ipp->ipp_encr_alg,
5322 5063 ipp->ipp_espe_minbits,
5323 5064 ipp->ipp_espe_maxbits, ipss);
5324 5065 if (cur == NULL)
5325 5066 return (NULL);
5326 5067 /* Fill in lifetimes if and only if AH didn't already... */
5327 5068 if (!ipp->ipp_use_ah)
5328 5069 ipsecesp_fill_defs(ecomb, ns);
5329 5070 }
5330 5071
5331 5072 return (cur);
5332 5073 }
5333 5074
5334 5075 #include <sys/tsol/label_macro.h> /* XXX should not need this */
5335 5076
5336 5077 /*
5337 5078 * From a cred_t, construct a sensitivity label extension
5338 5079 *
5339 5080 * We send up a fixed-size sensitivity label bitmap, and are perhaps
5340 5081 * overly chummy with the underlying data structures here.
5341 5082 */
5342 5083
5343 5084 /* ARGSUSED */
5344 5085 int
5345 5086 sadb_sens_len_from_label(ts_label_t *tsl)
5346 5087 {
5347 5088 int baselen = sizeof (sadb_sens_t) + _C_LEN * 4;
5348 5089 return (roundup(baselen, sizeof (uint64_t)));
5349 5090 }
5350 5091
5351 5092 void
5352 5093 sadb_sens_from_label(sadb_sens_t *sens, int exttype, ts_label_t *tsl,
5353 5094 int senslen)
5354 5095 {
5355 5096 uint8_t *bitmap;
5356 5097 bslabel_t *sl;
5357 5098
5358 5099 /* LINTED */
5359 5100 ASSERT((_C_LEN & 1) == 0);
5360 5101 ASSERT((senslen & 7) == 0);
5361 5102
5362 5103 sl = label2bslabel(tsl);
5363 5104
5364 5105 sens->sadb_sens_exttype = exttype;
5365 5106 sens->sadb_sens_len = SADB_8TO64(senslen);
5366 5107
5367 5108 sens->sadb_sens_dpd = tsl->tsl_doi;
5368 5109 sens->sadb_sens_sens_level = LCLASS(sl);
5369 5110 sens->sadb_sens_integ_level = 0; /* TBD */
5370 5111 sens->sadb_sens_sens_len = _C_LEN >> 1;
5371 5112 sens->sadb_sens_integ_len = 0; /* TBD */
5372 5113 sens->sadb_x_sens_flags = 0;
5373 5114
5374 5115 bitmap = (uint8_t *)(sens + 1);
5375 5116 bcopy(&(((_bslabel_impl_t *)sl)->compartments), bitmap, _C_LEN * 4);
5376 5117 }
5377 5118
5378 5119 static sadb_sens_t *
5379 5120 sadb_make_sens_ext(ts_label_t *tsl, int *len)
5380 5121 {
5381 5122 /* XXX allocation failure? */
5382 5123 int sens_len = sadb_sens_len_from_label(tsl);
5383 5124
5384 5125 sadb_sens_t *sens = kmem_alloc(sens_len, KM_SLEEP);
5385 5126
5386 5127 sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY, tsl, sens_len);
5387 5128
5388 5129 *len = sens_len;
5389 5130
5390 5131 return (sens);
5391 5132 }
5392 5133
5393 5134 /*
5394 5135 * Okay, how do we report errors/invalid labels from this?
5395 5136 * With a special designated "not a label" cred_t ?
5396 5137 */
5397 5138 /* ARGSUSED */
5398 5139 ts_label_t *
5399 5140 sadb_label_from_sens(sadb_sens_t *sens, uint64_t *bitmap)
5400 5141 {
5401 5142 int bitmap_len = SADB_64TO8(sens->sadb_sens_sens_len);
5402 5143 bslabel_t sl;
5403 5144 ts_label_t *tsl;
5404 5145
5405 5146 if (sens->sadb_sens_integ_level != 0)
5406 5147 return (NULL);
5407 5148 if (sens->sadb_sens_integ_len != 0)
5408 5149 return (NULL);
5409 5150 if (bitmap_len > _C_LEN * 4)
5410 5151 return (NULL);
5411 5152
5412 5153 bsllow(&sl);
5413 5154 LCLASS_SET((_bslabel_impl_t *)&sl, sens->sadb_sens_sens_level);
5414 5155 bcopy(bitmap, &((_bslabel_impl_t *)&sl)->compartments,
5415 5156 bitmap_len);
5416 5157
5417 5158 tsl = labelalloc(&sl, sens->sadb_sens_dpd, KM_NOSLEEP);
5418 5159 if (tsl == NULL)
5419 5160 return (NULL);
5420 5161
5421 5162 if (sens->sadb_x_sens_flags & SADB_X_SENS_UNLABELED)
5422 5163 tsl->tsl_flags |= TSLF_UNLABELED;
5423 5164 return (tsl);
5424 5165 }
5425 5166
5426 5167 /* End XXX label-library-leakage */
5427 5168
5428 5169 /*
5429 5170 * Construct an extended ACQUIRE message based on a selector and the resulting
5430 5171 * IPsec action.
5431 5172 *
5432 5173 * NOTE: This is used by both inverse ACQUIRE and actual ACQUIRE
5433 5174 * generation. As a consequence, expect this function to evolve
5434 5175 * rapidly.
5435 5176 */
5436 5177 static mblk_t *
5437 5178 sadb_extended_acquire(ipsec_selector_t *sel, ipsec_policy_t *pol,
5438 5179 ipsec_action_t *act, boolean_t tunnel_mode, uint32_t seq, uint32_t pid,
5439 5180 sadb_sens_t *sens, netstack_t *ns)
5440 5181 {
5441 5182 mblk_t *mp;
5442 5183 sadb_msg_t *samsg;
5443 5184 uint8_t *start, *cur, *end;
5444 5185 uint32_t *saddrptr, *daddrptr;
5445 5186 sa_family_t af;
5446 5187 sadb_prop_t *eprop;
5447 5188 ipsec_action_t *ap, *an;
5448 5189 ipsec_selkey_t *ipsl;
5449 5190 uint8_t proto, pfxlen;
5450 5191 uint16_t lport, rport;
5451 5192 uint32_t kmp, kmc;
5452 5193
5453 5194 /*
5454 5195 * Find the action we want sooner rather than later..
5455 5196 */
5456 5197 an = NULL;
5457 5198 if (pol == NULL) {
5458 5199 ap = act;
5459 5200 } else {
5460 5201 ap = pol->ipsp_act;
5461 5202
5462 5203 if (ap != NULL)
5463 5204 an = ap->ipa_next;
5464 5205 }
5465 5206
5466 5207 /*
5467 5208 * Just take a swag for the allocation for now. We can always
5468 5209 * alter it later.
5469 5210 */
5470 5211 #define SADB_EXTENDED_ACQUIRE_SIZE 4096
5471 5212 mp = allocb(SADB_EXTENDED_ACQUIRE_SIZE, BPRI_HI);
5472 5213 if (mp == NULL)
5473 5214 return (NULL);
5474 5215
5475 5216 start = mp->b_rptr;
5476 5217 end = start + SADB_EXTENDED_ACQUIRE_SIZE;
5477 5218
5478 5219 cur = start;
5479 5220
5480 5221 samsg = (sadb_msg_t *)cur;
5481 5222 cur += sizeof (*samsg);
5482 5223
5483 5224 samsg->sadb_msg_version = PF_KEY_V2;
5484 5225 samsg->sadb_msg_type = SADB_ACQUIRE;
5485 5226 samsg->sadb_msg_errno = 0;
5486 5227 samsg->sadb_msg_reserved = 0;
5487 5228 samsg->sadb_msg_satype = 0;
5488 5229 samsg->sadb_msg_seq = seq;
5489 5230 samsg->sadb_msg_pid = pid;
5490 5231
5491 5232 if (tunnel_mode) {
5492 5233 /*
5493 5234 * Form inner address extensions based NOT on the inner
5494 5235 * selectors (i.e. the packet data), but on the policy's
5495 5236 * selector key (i.e. the policy's selector information).
5496 5237 *
5497 5238 * NOTE: The position of IPv4 and IPv6 addresses is the
5498 5239 * same in ipsec_selkey_t (unless the compiler does very
5499 5240 * strange things with unions, consult your local C language
5500 5241 * lawyer for details).
5501 5242 */
5502 5243 ASSERT(pol != NULL);
5503 5244
5504 5245 ipsl = &(pol->ipsp_sel->ipsl_key);
5505 5246 if (ipsl->ipsl_valid & IPSL_IPV4) {
5506 5247 af = AF_INET;
5507 5248 ASSERT(sel->ips_protocol == IPPROTO_ENCAP);
5508 5249 ASSERT(!(ipsl->ipsl_valid & IPSL_IPV6));
5509 5250 } else {
5510 5251 af = AF_INET6;
5511 5252 ASSERT(sel->ips_protocol == IPPROTO_IPV6);
5512 5253 ASSERT(ipsl->ipsl_valid & IPSL_IPV6);
5513 5254 }
5514 5255
5515 5256 if (ipsl->ipsl_valid & IPSL_LOCAL_ADDR) {
5516 5257 saddrptr = (uint32_t *)(&ipsl->ipsl_local);
5517 5258 pfxlen = ipsl->ipsl_local_pfxlen;
5518 5259 } else {
5519 5260 saddrptr = (uint32_t *)(&ipv6_all_zeros);
5520 5261 pfxlen = 0;
5521 5262 }
5522 5263 /* XXX What about ICMP type/code? */
5523 5264 lport = (ipsl->ipsl_valid & IPSL_LOCAL_PORT) ?
5524 5265 ipsl->ipsl_lport : 0;
5525 5266 proto = (ipsl->ipsl_valid & IPSL_PROTOCOL) ?
5526 5267 ipsl->ipsl_proto : 0;
5527 5268
5528 5269 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5529 5270 af, saddrptr, lport, proto, pfxlen);
5530 5271 if (cur == NULL) {
5531 5272 freeb(mp);
5532 5273 return (NULL);
5533 5274 }
5534 5275
5535 5276 if (ipsl->ipsl_valid & IPSL_REMOTE_ADDR) {
5536 5277 daddrptr = (uint32_t *)(&ipsl->ipsl_remote);
5537 5278 pfxlen = ipsl->ipsl_remote_pfxlen;
5538 5279 } else {
5539 5280 daddrptr = (uint32_t *)(&ipv6_all_zeros);
5540 5281 pfxlen = 0;
5541 5282 }
5542 5283 /* XXX What about ICMP type/code? */
5543 5284 rport = (ipsl->ipsl_valid & IPSL_REMOTE_PORT) ?
5544 5285 ipsl->ipsl_rport : 0;
5545 5286
5546 5287 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5547 5288 af, daddrptr, rport, proto, pfxlen);
5548 5289 if (cur == NULL) {
5549 5290 freeb(mp);
5550 5291 return (NULL);
5551 5292 }
5552 5293 /*
5553 5294 * TODO - if we go to 3408's dream of transport mode IP-in-IP
5554 5295 * _with_ inner-packet address selectors, we'll need to further
5555 5296 * distinguish tunnel mode here. For now, having inner
5556 5297 * addresses and/or ports is sufficient.
5557 5298 *
5558 5299 * Meanwhile, whack proto/ports to reflect IP-in-IP for the
5559 5300 * outer addresses.
5560 5301 */
5561 5302 proto = sel->ips_protocol; /* Either _ENCAP or _IPV6 */
5562 5303 lport = rport = 0;
5563 5304 } else if ((ap != NULL) && (!ap->ipa_want_unique)) {
5564 5305 proto = 0;
5565 5306 lport = 0;
5566 5307 rport = 0;
5567 5308 if (pol != NULL) {
5568 5309 ipsl = &(pol->ipsp_sel->ipsl_key);
5569 5310 if (ipsl->ipsl_valid & IPSL_PROTOCOL)
5570 5311 proto = ipsl->ipsl_proto;
5571 5312 if (ipsl->ipsl_valid & IPSL_REMOTE_PORT)
5572 5313 rport = ipsl->ipsl_rport;
5573 5314 if (ipsl->ipsl_valid & IPSL_LOCAL_PORT)
5574 5315 lport = ipsl->ipsl_lport;
5575 5316 }
5576 5317 } else {
5577 5318 proto = sel->ips_protocol;
5578 5319 lport = sel->ips_local_port;
5579 5320 rport = sel->ips_remote_port;
5580 5321 }
5581 5322
5582 5323 af = sel->ips_isv4 ? AF_INET : AF_INET6;
5583 5324
5584 5325 /*
5585 5326 * NOTE: The position of IPv4 and IPv6 addresses is the same in
5586 5327 * ipsec_selector_t.
5587 5328 */
5588 5329 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5589 5330 (uint32_t *)(&sel->ips_local_addr_v6), lport, proto, 0);
5590 5331
5591 5332 if (cur == NULL) {
5592 5333 freeb(mp);
5593 5334 return (NULL);
5594 5335 }
5595 5336
5596 5337 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5597 5338 (uint32_t *)(&sel->ips_remote_addr_v6), rport, proto, 0);
5598 5339
5599 5340 if (cur == NULL) {
5600 5341 freeb(mp);
5601 5342 return (NULL);
5602 5343 }
5603 5344
5604 5345 if (sens != NULL) {
5605 5346 uint8_t *sensext = cur;
5606 5347 int senslen = SADB_64TO8(sens->sadb_sens_len);
5607 5348
5608 5349 cur += senslen;
5609 5350 if (cur > end) {
5610 5351 freeb(mp);
5611 5352 return (NULL);
5612 5353 }
5613 5354 bcopy(sens, sensext, senslen);
5614 5355 }
5615 5356
5616 5357 /*
5617 5358 * This section will change a lot as policy evolves.
5618 5359 * For now, it'll be relatively simple.
5619 5360 */
5620 5361 eprop = (sadb_prop_t *)cur;
5621 5362 cur += sizeof (*eprop);
5622 5363 if (cur > end) {
5623 5364 /* no space left */
5624 5365 freeb(mp);
5625 5366 return (NULL);
5626 5367 }
5627 5368
5628 5369 eprop->sadb_prop_exttype = SADB_X_EXT_EPROP;
5629 5370 eprop->sadb_x_prop_ereserved = 0;
5630 5371 eprop->sadb_x_prop_numecombs = 0;
5631 5372 eprop->sadb_prop_replay = 32; /* default */
5632 5373
5633 5374 kmc = kmp = 0;
5634 5375
5635 5376 for (; ap != NULL; ap = an) {
5636 5377 an = (pol != NULL) ? ap->ipa_next : NULL;
5637 5378
5638 5379 /*
5639 5380 * Skip non-IPsec policies
5640 5381 */
5641 5382 if (ap->ipa_act.ipa_type != IPSEC_ACT_APPLY)
5642 5383 continue;
5643 5384
5644 5385 if (ap->ipa_act.ipa_apply.ipp_km_proto)
5645 5386 kmp = ap->ipa_act.ipa_apply.ipp_km_proto;
5646 5387 if (ap->ipa_act.ipa_apply.ipp_km_cookie)
5647 5388 kmc = ap->ipa_act.ipa_apply.ipp_km_cookie;
5648 5389 if (ap->ipa_act.ipa_apply.ipp_replay_depth) {
5649 5390 eprop->sadb_prop_replay =
5650 5391 ap->ipa_act.ipa_apply.ipp_replay_depth;
5651 5392 }
5652 5393
5653 5394 cur = sadb_action_to_ecomb(cur, end, ap, ns);
5654 5395 if (cur == NULL) { /* no space */
5655 5396 freeb(mp);
5656 5397 return (NULL);
5657 5398 }
5658 5399 eprop->sadb_x_prop_numecombs++;
5659 5400 }
5660 5401
5661 5402 if (eprop->sadb_x_prop_numecombs == 0) {
5662 5403 /*
5663 5404 * This will happen if we fail to find a policy
5664 5405 * allowing for IPsec processing.
5665 5406 * Construct an error message.
5666 5407 */
5667 5408 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg));
5668 5409 samsg->sadb_msg_errno = ENOENT;
5669 5410 samsg->sadb_x_msg_diagnostic = 0;
5670 5411 return (mp);
5671 5412 }
5672 5413
5673 5414 if ((kmp != 0) || (kmc != 0)) {
5674 5415 cur = sadb_make_kmc_ext(cur, end, kmp, kmc);
5675 5416 if (cur == NULL) {
5676 5417 freeb(mp);
5677 5418 return (NULL);
5678 5419 }
5679 5420 }
5680 5421
5681 5422 eprop->sadb_prop_len = SADB_8TO64(cur - (uint8_t *)eprop);
5682 5423 samsg->sadb_msg_len = SADB_8TO64(cur - start);
5683 5424 mp->b_wptr = cur;
5684 5425
5685 5426 return (mp);
5686 5427 }
5687 5428
5688 5429 /*
5689 5430 * Generic setup of an RFC 2367 ACQUIRE message. Caller sets satype.
5690 5431 *
5691 5432 * NOTE: This function acquires alg_lock as a side-effect if-and-only-if we
5692 5433 * succeed (i.e. return non-NULL). Caller MUST release it. This is to
5693 5434 * maximize code consolidation while preventing algorithm changes from messing
5694 5435 * with the callers finishing touches on the ACQUIRE itself.
5695 5436 */
5696 5437 mblk_t *
5697 5438 sadb_setup_acquire(ipsacq_t *acqrec, uint8_t satype, ipsec_stack_t *ipss)
5698 5439 {
5699 5440 uint_t allocsize;
5700 5441 mblk_t *pfkeymp, *msgmp;
5701 5442 sa_family_t af;
5702 5443 uint8_t *cur, *end;
5703 5444 sadb_msg_t *samsg;
5704 5445 uint16_t sport_typecode;
5705 5446 uint16_t dport_typecode;
5706 5447 uint8_t check_proto;
5707 5448 boolean_t tunnel_mode = (acqrec->ipsacq_inneraddrfam != 0);
5708 5449
5709 5450 ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5710 5451
5711 5452 pfkeymp = sadb_keysock_out(0);
5712 5453 if (pfkeymp == NULL)
5713 5454 return (NULL);
5714 5455
5715 5456 /*
5716 5457 * First, allocate a basic ACQUIRE message
5717 5458 */
5718 5459 allocsize = sizeof (sadb_msg_t) + sizeof (sadb_address_t) +
5719 5460 sizeof (sadb_address_t) + sizeof (sadb_prop_t);
5720 5461
5721 5462 /* Make sure there's enough to cover both AF_INET and AF_INET6. */
5722 5463 allocsize += 2 * sizeof (struct sockaddr_in6);
5723 5464
5724 5465 mutex_enter(&ipss->ipsec_alg_lock);
5725 5466 /* NOTE: The lock is now held through to this function's return. */
5726 5467 allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
5727 5468 ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
5728 5469
5729 5470 if (tunnel_mode) {
5730 5471 /* Tunnel mode! */
5731 5472 allocsize += 2 * sizeof (sadb_address_t);
5732 5473 /* Enough to cover both AF_INET and AF_INET6. */
5733 5474 allocsize += 2 * sizeof (struct sockaddr_in6);
5734 5475 }
5735 5476
5736 5477 msgmp = allocb(allocsize, BPRI_HI);
5737 5478 if (msgmp == NULL) {
5738 5479 freeb(pfkeymp);
5739 5480 mutex_exit(&ipss->ipsec_alg_lock);
5740 5481 return (NULL);
5741 5482 }
5742 5483
5743 5484 pfkeymp->b_cont = msgmp;
5744 5485 cur = msgmp->b_rptr;
5745 5486 end = cur + allocsize;
5746 5487 samsg = (sadb_msg_t *)cur;
5747 5488 cur += sizeof (sadb_msg_t);
5748 5489
5749 5490 af = acqrec->ipsacq_addrfam;
5750 5491 switch (af) {
5751 5492 case AF_INET:
5752 5493 check_proto = IPPROTO_ICMP;
5753 5494 break;
5754 5495 case AF_INET6:
5755 5496 check_proto = IPPROTO_ICMPV6;
5756 5497 break;
5757 5498 default:
5758 5499 /* This should never happen unless we have kernel bugs. */
5759 5500 cmn_err(CE_WARN,
5760 5501 "sadb_setup_acquire: corrupt ACQUIRE record.\n");
5761 5502 ASSERT(0);
5762 5503 mutex_exit(&ipss->ipsec_alg_lock);
5763 5504 return (NULL);
5764 5505 }
5765 5506
5766 5507 samsg->sadb_msg_version = PF_KEY_V2;
5767 5508 samsg->sadb_msg_type = SADB_ACQUIRE;
5768 5509 samsg->sadb_msg_satype = satype;
5769 5510 samsg->sadb_msg_errno = 0;
5770 5511 samsg->sadb_msg_pid = 0;
5771 5512 samsg->sadb_msg_reserved = 0;
5772 5513 samsg->sadb_msg_seq = acqrec->ipsacq_seq;
5773 5514
5774 5515 ASSERT(MUTEX_HELD(&acqrec->ipsacq_lock));
5775 5516
5776 5517 if ((acqrec->ipsacq_proto == check_proto) || tunnel_mode) {
5777 5518 sport_typecode = dport_typecode = 0;
5778 5519 } else {
5779 5520 sport_typecode = acqrec->ipsacq_srcport;
5780 5521 dport_typecode = acqrec->ipsacq_dstport;
5781 5522 }
5782 5523
5783 5524 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, af,
5784 5525 acqrec->ipsacq_srcaddr, sport_typecode, acqrec->ipsacq_proto, 0);
5785 5526
5786 5527 cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, af,
5787 5528 acqrec->ipsacq_dstaddr, dport_typecode, acqrec->ipsacq_proto, 0);
5788 5529
5789 5530 if (tunnel_mode) {
5790 5531 sport_typecode = acqrec->ipsacq_srcport;
5791 5532 dport_typecode = acqrec->ipsacq_dstport;
5792 5533 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC,
5793 5534 acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innersrc,
5794 5535 sport_typecode, acqrec->ipsacq_inner_proto,
5795 5536 acqrec->ipsacq_innersrcpfx);
5796 5537 cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST,
5797 5538 acqrec->ipsacq_inneraddrfam, acqrec->ipsacq_innerdst,
5798 5539 dport_typecode, acqrec->ipsacq_inner_proto,
5799 5540 acqrec->ipsacq_innerdstpfx);
5800 5541 }
5801 5542
5802 5543 /* XXX Insert identity information here. */
5803 5544
5804 5545 /* XXXMLS Insert sensitivity information here. */
5805 5546
5806 5547 if (cur != NULL)
5807 5548 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
5808 5549 else
5809 5550 mutex_exit(&ipss->ipsec_alg_lock);
5810 5551
5811 5552 return (pfkeymp);
5812 5553 }
5813 5554
|
↓ open down ↓ |
1184 lines elided |
↑ open up ↑ |
5814 5555 /*
5815 5556 * Given an SADB_GETSPI message, find an appropriately ranged SA and
5816 5557 * allocate an SA. If there are message improprieties, return (ipsa_t *)-1.
5817 5558 * If there was a memory allocation error, return NULL. (Assume NULL !=
5818 5559 * (ipsa_t *)-1).
5819 5560 *
5820 5561 * master_spi is passed in host order.
5821 5562 */
5822 5563 ipsa_t *
5823 5564 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5824 - netstack_t *ns, uint_t sa_type)
5565 + netstack_t *ns)
5825 5566 {
5826 5567 sadb_address_t *src =
5827 5568 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5828 5569 *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5829 5570 sadb_spirange_t *range =
5830 5571 (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5831 5572 struct sockaddr_in *ssa, *dsa;
5832 5573 struct sockaddr_in6 *ssa6, *dsa6;
5833 5574 uint32_t *srcaddr, *dstaddr;
5834 5575 sa_family_t af;
5835 5576 uint32_t add, min, max;
5836 5577
5837 5578 if (src == NULL) {
5838 5579 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
5839 5580 return ((ipsa_t *)-1);
5840 5581 }
5841 5582 if (dst == NULL) {
5842 5583 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
5843 5584 return ((ipsa_t *)-1);
5844 5585 }
5845 5586 if (range == NULL) {
5846 5587 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_RANGE;
5847 5588 return ((ipsa_t *)-1);
5848 5589 }
5849 5590
5850 5591 min = ntohl(range->sadb_spirange_min);
5851 5592 max = ntohl(range->sadb_spirange_max);
5852 5593 dsa = (struct sockaddr_in *)(dst + 1);
5853 5594 dsa6 = (struct sockaddr_in6 *)dsa;
5854 5595
5855 5596 ssa = (struct sockaddr_in *)(src + 1);
5856 5597 ssa6 = (struct sockaddr_in6 *)ssa;
5857 5598 ASSERT(dsa->sin_family == ssa->sin_family);
5858 5599
5859 5600 srcaddr = ALL_ZEROES_PTR;
5860 5601 af = dsa->sin_family;
5861 5602 switch (af) {
5862 5603 case AF_INET:
5863 5604 if (src != NULL)
5864 5605 srcaddr = (uint32_t *)(&ssa->sin_addr);
5865 5606 dstaddr = (uint32_t *)(&dsa->sin_addr);
5866 5607 break;
5867 5608 case AF_INET6:
5868 5609 if (src != NULL)
5869 5610 srcaddr = (uint32_t *)(&ssa6->sin6_addr);
5870 5611 dstaddr = (uint32_t *)(&dsa6->sin6_addr);
5871 5612 break;
5872 5613 default:
5873 5614 *diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF;
5874 5615 return ((ipsa_t *)-1);
5875 5616 }
5876 5617
5877 5618 if (master_spi < min || master_spi > max) {
5878 5619 /* Return a random value in the range. */
5879 5620 (void) random_get_pseudo_bytes((uint8_t *)&add, sizeof (add));
5880 5621 master_spi = min + (add % (max - min + 1));
5881 5622 }
5882 5623
5883 5624 /*
5884 5625 * Since master_spi is passed in host order, we need to htonl() it
5885 5626 * for the purposes of creating a new SA.
5886 5627 */
5887 5628 return (sadb_makelarvalassoc(htonl(master_spi), srcaddr, dstaddr, af,
5888 5629 ns));
5889 5630 }
5890 5631
5891 5632 /*
5892 5633 *
5893 5634 * Locate an ACQUIRE and nuke it. If I have an samsg that's larger than the
5894 5635 * base header, just ignore it. Otherwise, lock down the whole ACQUIRE list
5895 5636 * and scan for the sequence number in question. I may wish to accept an
5896 5637 * address pair with it, for easier searching.
5897 5638 *
5898 5639 * Caller frees the message, so we don't have to here.
5899 5640 *
5900 5641 * NOTE: The pfkey_q parameter may be used in the future for ACQUIRE
5901 5642 * failures.
5902 5643 */
5903 5644 /* ARGSUSED */
5904 5645 void
5905 5646 sadb_in_acquire(sadb_msg_t *samsg, sadbp_t *sp, queue_t *pfkey_q,
5906 5647 netstack_t *ns)
5907 5648 {
5908 5649 int i;
5909 5650 ipsacq_t *acqrec;
5910 5651 iacqf_t *bucket;
5911 5652
5912 5653 /*
5913 5654 * I only accept the base header for this!
5914 5655 * Though to be honest, requiring the dst address would help
5915 5656 * immensely.
5916 5657 *
5917 5658 * XXX There are already cases where I can get the dst address.
5918 5659 */
5919 5660 if (samsg->sadb_msg_len > SADB_8TO64(sizeof (*samsg)))
5920 5661 return;
5921 5662
5922 5663 /*
5923 5664 * Using the samsg->sadb_msg_seq, find the ACQUIRE record, delete it,
5924 5665 * (and in the future send a message to IP with the appropriate error
5925 5666 * number).
5926 5667 *
5927 5668 * Q: Do I want to reject if pid != 0?
5928 5669 */
5929 5670
5930 5671 for (i = 0; i < sp->s_v4.sdb_hashsize; i++) {
5931 5672 bucket = &sp->s_v4.sdb_acq[i];
5932 5673 mutex_enter(&bucket->iacqf_lock);
5933 5674 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5934 5675 acqrec = acqrec->ipsacq_next) {
5935 5676 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5936 5677 break; /* for acqrec... loop. */
5937 5678 }
5938 5679 if (acqrec != NULL)
5939 5680 break; /* for i = 0... loop. */
5940 5681
5941 5682 mutex_exit(&bucket->iacqf_lock);
5942 5683 }
5943 5684
5944 5685 if (acqrec == NULL) {
5945 5686 for (i = 0; i < sp->s_v6.sdb_hashsize; i++) {
5946 5687 bucket = &sp->s_v6.sdb_acq[i];
5947 5688 mutex_enter(&bucket->iacqf_lock);
5948 5689 for (acqrec = bucket->iacqf_ipsacq; acqrec != NULL;
5949 5690 acqrec = acqrec->ipsacq_next) {
5950 5691 if (samsg->sadb_msg_seq == acqrec->ipsacq_seq)
5951 5692 break; /* for acqrec... loop. */
5952 5693 }
5953 5694 if (acqrec != NULL)
5954 5695 break; /* for i = 0... loop. */
5955 5696
5956 5697 mutex_exit(&bucket->iacqf_lock);
5957 5698 }
5958 5699 }
5959 5700
5960 5701
5961 5702 if (acqrec == NULL)
5962 5703 return;
5963 5704
5964 5705 /*
5965 5706 * What do I do with the errno and IP? I may need mp's services a
5966 5707 * little more. See sadb_destroy_acquire() for future directions
5967 5708 * beyond free the mblk chain on the acquire record.
5968 5709 */
5969 5710
5970 5711 ASSERT(&bucket->iacqf_lock == acqrec->ipsacq_linklock);
5971 5712 sadb_destroy_acquire(acqrec, ns);
5972 5713 /* Have to exit mutex here, because of breaking out of for loop. */
5973 5714 mutex_exit(&bucket->iacqf_lock);
5974 5715 }
5975 5716
5976 5717 /*
5977 5718 * The following functions work with the replay windows of an SA. They assume
5978 5719 * the ipsa->ipsa_replay_arr is an array of uint64_t, and that the bit vector
5979 5720 * represents the highest sequence number packet received, and back
5980 5721 * (ipsa->ipsa_replay_wsize) packets.
5981 5722 */
5982 5723
5983 5724 /*
5984 5725 * Is the replay bit set?
5985 5726 */
5986 5727 static boolean_t
5987 5728 ipsa_is_replay_set(ipsa_t *ipsa, uint32_t offset)
5988 5729 {
5989 5730 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
5990 5731
5991 5732 return ((bit & ipsa->ipsa_replay_arr[offset >> 6]) ? B_TRUE : B_FALSE);
5992 5733 }
5993 5734
5994 5735 /*
5995 5736 * Shift the bits of the replay window over.
5996 5737 */
5997 5738 static void
5998 5739 ipsa_shift_replay(ipsa_t *ipsa, uint32_t shift)
5999 5740 {
6000 5741 int i;
6001 5742 int jump = ((shift - 1) >> 6) + 1;
6002 5743
6003 5744 if (shift == 0)
6004 5745 return;
6005 5746
6006 5747 for (i = (ipsa->ipsa_replay_wsize - 1) >> 6; i >= 0; i--) {
6007 5748 if (i + jump <= (ipsa->ipsa_replay_wsize - 1) >> 6) {
6008 5749 ipsa->ipsa_replay_arr[i + jump] |=
6009 5750 ipsa->ipsa_replay_arr[i] >> (64 - (shift & 63));
6010 5751 }
6011 5752 ipsa->ipsa_replay_arr[i] <<= shift;
6012 5753 }
6013 5754 }
6014 5755
6015 5756 /*
6016 5757 * Set a bit in the bit vector.
6017 5758 */
6018 5759 static void
6019 5760 ipsa_set_replay(ipsa_t *ipsa, uint32_t offset)
6020 5761 {
6021 5762 uint64_t bit = (uint64_t)1 << (uint64_t)(offset & 63);
6022 5763
6023 5764 ipsa->ipsa_replay_arr[offset >> 6] |= bit;
6024 5765 }
6025 5766
6026 5767 #define SADB_MAX_REPLAY_VALUE 0xffffffff
6027 5768
6028 5769 /*
6029 5770 * Assume caller has NOT done ntohl() already on seq. Check to see
6030 5771 * if replay sequence number "seq" has been seen already.
6031 5772 */
6032 5773 boolean_t
6033 5774 sadb_replay_check(ipsa_t *ipsa, uint32_t seq)
6034 5775 {
6035 5776 boolean_t rc;
6036 5777 uint32_t diff;
6037 5778
6038 5779 if (ipsa->ipsa_replay_wsize == 0)
6039 5780 return (B_TRUE);
6040 5781
6041 5782 /*
6042 5783 * NOTE: I've already checked for 0 on the wire in sadb_replay_peek().
6043 5784 */
6044 5785
6045 5786 /* Convert sequence number into host order before holding the mutex. */
6046 5787 seq = ntohl(seq);
6047 5788
6048 5789 mutex_enter(&ipsa->ipsa_lock);
6049 5790
6050 5791 /* Initialize inbound SA's ipsa_replay field to last one received. */
6051 5792 if (ipsa->ipsa_replay == 0)
6052 5793 ipsa->ipsa_replay = 1;
6053 5794
6054 5795 if (seq > ipsa->ipsa_replay) {
6055 5796 /*
6056 5797 * I have received a new "highest value received". Shift
6057 5798 * the replay window over.
6058 5799 */
6059 5800 diff = seq - ipsa->ipsa_replay;
6060 5801 if (diff < ipsa->ipsa_replay_wsize) {
6061 5802 /* In replay window, shift bits over. */
6062 5803 ipsa_shift_replay(ipsa, diff);
6063 5804 } else {
6064 5805 /* WAY FAR AHEAD, clear bits and start again. */
6065 5806 bzero(ipsa->ipsa_replay_arr,
6066 5807 sizeof (ipsa->ipsa_replay_arr));
6067 5808 }
6068 5809 ipsa_set_replay(ipsa, 0);
6069 5810 ipsa->ipsa_replay = seq;
6070 5811 rc = B_TRUE;
6071 5812 goto done;
6072 5813 }
6073 5814 diff = ipsa->ipsa_replay - seq;
6074 5815 if (diff >= ipsa->ipsa_replay_wsize || ipsa_is_replay_set(ipsa, diff)) {
6075 5816 rc = B_FALSE;
6076 5817 goto done;
6077 5818 }
6078 5819 /* Set this packet as seen. */
6079 5820 ipsa_set_replay(ipsa, diff);
6080 5821
6081 5822 rc = B_TRUE;
6082 5823 done:
6083 5824 mutex_exit(&ipsa->ipsa_lock);
6084 5825 return (rc);
6085 5826 }
6086 5827
6087 5828 /*
6088 5829 * "Peek" and see if we should even bother going through the effort of
6089 5830 * running an authentication check on the sequence number passed in.
6090 5831 * this takes into account packets that are below the replay window,
6091 5832 * and collisions with already replayed packets. Return B_TRUE if it
6092 5833 * is okay to proceed, B_FALSE if this packet should be dropped immediately.
6093 5834 * Assume same byte-ordering as sadb_replay_check.
6094 5835 */
6095 5836 boolean_t
6096 5837 sadb_replay_peek(ipsa_t *ipsa, uint32_t seq)
6097 5838 {
6098 5839 boolean_t rc = B_FALSE;
6099 5840 uint32_t diff;
6100 5841
6101 5842 if (ipsa->ipsa_replay_wsize == 0)
6102 5843 return (B_TRUE);
6103 5844
6104 5845 /*
6105 5846 * 0 is 0, regardless of byte order... :)
6106 5847 *
6107 5848 * If I get 0 on the wire (and there is a replay window) then the
6108 5849 * sender most likely wrapped. This ipsa may need to be marked or
6109 5850 * something.
6110 5851 */
6111 5852 if (seq == 0)
6112 5853 return (B_FALSE);
6113 5854
6114 5855 seq = ntohl(seq);
6115 5856 mutex_enter(&ipsa->ipsa_lock);
6116 5857 if (seq < ipsa->ipsa_replay - ipsa->ipsa_replay_wsize &&
6117 5858 ipsa->ipsa_replay >= ipsa->ipsa_replay_wsize)
6118 5859 goto done;
6119 5860
6120 5861 /*
6121 5862 * If I've hit 0xffffffff, then quite honestly, I don't need to
6122 5863 * bother with formalities. I'm not accepting any more packets
6123 5864 * on this SA.
6124 5865 */
6125 5866 if (ipsa->ipsa_replay == SADB_MAX_REPLAY_VALUE) {
6126 5867 /*
6127 5868 * Since we're already holding the lock, update the
6128 5869 * expire time ala. sadb_replay_delete() and return.
6129 5870 */
6130 5871 ipsa->ipsa_hardexpiretime = (time_t)1;
6131 5872 goto done;
6132 5873 }
6133 5874
6134 5875 if (seq <= ipsa->ipsa_replay) {
6135 5876 /*
6136 5877 * This seq is in the replay window. I'm not below it,
6137 5878 * because I already checked for that above!
6138 5879 */
6139 5880 diff = ipsa->ipsa_replay - seq;
6140 5881 if (ipsa_is_replay_set(ipsa, diff))
6141 5882 goto done;
6142 5883 }
6143 5884 /* Else return B_TRUE, I'm going to advance the window. */
6144 5885
6145 5886 rc = B_TRUE;
6146 5887 done:
6147 5888 mutex_exit(&ipsa->ipsa_lock);
6148 5889 return (rc);
6149 5890 }
6150 5891
6151 5892 /*
6152 5893 * Delete a single SA.
6153 5894 *
6154 5895 * For now, use the quick-and-dirty trick of making the association's
6155 5896 * hard-expire lifetime (time_t)1, ensuring deletion by the *_ager().
6156 5897 */
6157 5898 void
6158 5899 sadb_replay_delete(ipsa_t *assoc)
6159 5900 {
6160 5901 mutex_enter(&assoc->ipsa_lock);
6161 5902 assoc->ipsa_hardexpiretime = (time_t)1;
6162 5903 mutex_exit(&assoc->ipsa_lock);
6163 5904 }
6164 5905
6165 5906 /*
6166 5907 * Special front-end to ipsec_rl_strlog() dealing with SA failure.
6167 5908 * this is designed to take only a format string with "* %x * %s *", so
6168 5909 * that "spi" is printed first, then "addr" is converted using inet_pton().
6169 5910 *
6170 5911 * This is abstracted out to save the stack space for only when inet_pton()
6171 5912 * is called. Make sure "spi" is in network order; it usually is when this
6172 5913 * would get called.
6173 5914 */
6174 5915 void
6175 5916 ipsec_assocfailure(short mid, short sid, char level, ushort_t sl, char *fmt,
6176 5917 uint32_t spi, void *addr, int af, netstack_t *ns)
6177 5918 {
6178 5919 char buf[INET6_ADDRSTRLEN];
6179 5920
6180 5921 ASSERT(af == AF_INET6 || af == AF_INET);
6181 5922
6182 5923 ipsec_rl_strlog(ns, mid, sid, level, sl, fmt, ntohl(spi),
6183 5924 inet_ntop(af, addr, buf, sizeof (buf)));
6184 5925 }
6185 5926
6186 5927 /*
6187 5928 * Fills in a reference to the policy, if any, from the conn, in *ppp
6188 5929 */
6189 5930 static void
6190 5931 ipsec_conn_pol(ipsec_selector_t *sel, conn_t *connp, ipsec_policy_t **ppp)
6191 5932 {
6192 5933 ipsec_policy_t *pp;
6193 5934 ipsec_latch_t *ipl = connp->conn_latch;
6194 5935
6195 5936 if ((ipl != NULL) && (connp->conn_ixa->ixa_ipsec_policy != NULL)) {
6196 5937 pp = connp->conn_ixa->ixa_ipsec_policy;
6197 5938 IPPOL_REFHOLD(pp);
6198 5939 } else {
6199 5940 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, connp, sel,
6200 5941 connp->conn_netstack);
6201 5942 }
6202 5943 *ppp = pp;
6203 5944 }
6204 5945
6205 5946 /*
6206 5947 * The following functions scan through active conn_t structures
6207 5948 * and return a reference to the best-matching policy it can find.
6208 5949 * Caller must release the reference.
6209 5950 */
6210 5951 static void
6211 5952 ipsec_udp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6212 5953 {
6213 5954 connf_t *connfp;
6214 5955 conn_t *connp = NULL;
6215 5956 ipsec_selector_t portonly;
6216 5957
6217 5958 bzero((void *)&portonly, sizeof (portonly));
6218 5959
6219 5960 if (sel->ips_local_port == 0)
6220 5961 return;
6221 5962
6222 5963 connfp = &ipst->ips_ipcl_udp_fanout[IPCL_UDP_HASH(sel->ips_local_port,
6223 5964 ipst)];
6224 5965 mutex_enter(&connfp->connf_lock);
6225 5966
6226 5967 if (sel->ips_isv4) {
6227 5968 connp = connfp->connf_head;
6228 5969 while (connp != NULL) {
6229 5970 if (IPCL_UDP_MATCH(connp, sel->ips_local_port,
6230 5971 sel->ips_local_addr_v4, sel->ips_remote_port,
6231 5972 sel->ips_remote_addr_v4))
6232 5973 break;
6233 5974 connp = connp->conn_next;
6234 5975 }
6235 5976
6236 5977 if (connp == NULL) {
6237 5978 /* Try port-only match in IPv6. */
6238 5979 portonly.ips_local_port = sel->ips_local_port;
6239 5980 sel = &portonly;
6240 5981 }
6241 5982 }
6242 5983
6243 5984 if (connp == NULL) {
6244 5985 connp = connfp->connf_head;
6245 5986 while (connp != NULL) {
6246 5987 if (IPCL_UDP_MATCH_V6(connp, sel->ips_local_port,
6247 5988 sel->ips_local_addr_v6, sel->ips_remote_port,
6248 5989 sel->ips_remote_addr_v6))
6249 5990 break;
6250 5991 connp = connp->conn_next;
6251 5992 }
6252 5993
6253 5994 if (connp == NULL) {
6254 5995 mutex_exit(&connfp->connf_lock);
6255 5996 return;
6256 5997 }
6257 5998 }
6258 5999
6259 6000 CONN_INC_REF(connp);
6260 6001 mutex_exit(&connfp->connf_lock);
6261 6002
6262 6003 ipsec_conn_pol(sel, connp, ppp);
6263 6004 CONN_DEC_REF(connp);
6264 6005 }
6265 6006
6266 6007 static conn_t *
6267 6008 ipsec_find_listen_conn(uint16_t *pptr, ipsec_selector_t *sel, ip_stack_t *ipst)
6268 6009 {
6269 6010 connf_t *connfp;
6270 6011 conn_t *connp = NULL;
6271 6012 const in6_addr_t *v6addrmatch = &sel->ips_local_addr_v6;
6272 6013
6273 6014 if (sel->ips_local_port == 0)
6274 6015 return (NULL);
6275 6016
6276 6017 connfp = &ipst->ips_ipcl_bind_fanout[
6277 6018 IPCL_BIND_HASH(sel->ips_local_port, ipst)];
6278 6019 mutex_enter(&connfp->connf_lock);
6279 6020
6280 6021 if (sel->ips_isv4) {
6281 6022 connp = connfp->connf_head;
6282 6023 while (connp != NULL) {
6283 6024 if (IPCL_BIND_MATCH(connp, IPPROTO_TCP,
6284 6025 sel->ips_local_addr_v4, pptr[1]))
6285 6026 break;
6286 6027 connp = connp->conn_next;
6287 6028 }
6288 6029
6289 6030 if (connp == NULL) {
6290 6031 /* Match to all-zeroes. */
6291 6032 v6addrmatch = &ipv6_all_zeros;
6292 6033 }
6293 6034 }
6294 6035
6295 6036 if (connp == NULL) {
6296 6037 connp = connfp->connf_head;
6297 6038 while (connp != NULL) {
6298 6039 if (IPCL_BIND_MATCH_V6(connp, IPPROTO_TCP,
6299 6040 *v6addrmatch, pptr[1]))
6300 6041 break;
6301 6042 connp = connp->conn_next;
6302 6043 }
6303 6044
6304 6045 if (connp == NULL) {
6305 6046 mutex_exit(&connfp->connf_lock);
6306 6047 return (NULL);
6307 6048 }
6308 6049 }
6309 6050
6310 6051 CONN_INC_REF(connp);
6311 6052 mutex_exit(&connfp->connf_lock);
6312 6053 return (connp);
6313 6054 }
6314 6055
6315 6056 static void
6316 6057 ipsec_tcp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp, ip_stack_t *ipst)
6317 6058 {
6318 6059 connf_t *connfp;
6319 6060 conn_t *connp;
6320 6061 uint32_t ports;
6321 6062 uint16_t *pptr = (uint16_t *)&ports;
6322 6063
6323 6064 /*
6324 6065 * Find TCP state in the following order:
6325 6066 * 1.) Connected conns.
6326 6067 * 2.) Listeners.
6327 6068 *
6328 6069 * Even though #2 will be the common case for inbound traffic, only
6329 6070 * following this order insures correctness.
6330 6071 */
6331 6072
6332 6073 if (sel->ips_local_port == 0)
6333 6074 return;
6334 6075
6335 6076 /*
6336 6077 * 0 should be fport, 1 should be lport. SRC is the local one here.
6337 6078 * See ipsec_construct_inverse_acquire() for details.
6338 6079 */
6339 6080 pptr[0] = sel->ips_remote_port;
6340 6081 pptr[1] = sel->ips_local_port;
6341 6082
6342 6083 connfp = &ipst->ips_ipcl_conn_fanout[
6343 6084 IPCL_CONN_HASH(sel->ips_remote_addr_v4, ports, ipst)];
6344 6085 mutex_enter(&connfp->connf_lock);
6345 6086 connp = connfp->connf_head;
6346 6087
6347 6088 if (sel->ips_isv4) {
6348 6089 while (connp != NULL) {
6349 6090 if (IPCL_CONN_MATCH(connp, IPPROTO_TCP,
6350 6091 sel->ips_remote_addr_v4, sel->ips_local_addr_v4,
6351 6092 ports))
6352 6093 break;
6353 6094 connp = connp->conn_next;
6354 6095 }
6355 6096 } else {
6356 6097 while (connp != NULL) {
6357 6098 if (IPCL_CONN_MATCH_V6(connp, IPPROTO_TCP,
6358 6099 sel->ips_remote_addr_v6, sel->ips_local_addr_v6,
6359 6100 ports))
6360 6101 break;
6361 6102 connp = connp->conn_next;
6362 6103 }
6363 6104 }
6364 6105
6365 6106 if (connp != NULL) {
6366 6107 CONN_INC_REF(connp);
6367 6108 mutex_exit(&connfp->connf_lock);
6368 6109 } else {
6369 6110 mutex_exit(&connfp->connf_lock);
6370 6111
6371 6112 /* Try the listen hash. */
6372 6113 if ((connp = ipsec_find_listen_conn(pptr, sel, ipst)) == NULL)
6373 6114 return;
6374 6115 }
6375 6116
6376 6117 ipsec_conn_pol(sel, connp, ppp);
6377 6118 CONN_DEC_REF(connp);
6378 6119 }
6379 6120
6380 6121 static void
6381 6122 ipsec_sctp_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6382 6123 ip_stack_t *ipst)
6383 6124 {
6384 6125 conn_t *connp;
6385 6126 uint32_t ports;
6386 6127 uint16_t *pptr = (uint16_t *)&ports;
6387 6128
6388 6129 /*
6389 6130 * Find SCP state in the following order:
6390 6131 * 1.) Connected conns.
6391 6132 * 2.) Listeners.
6392 6133 *
6393 6134 * Even though #2 will be the common case for inbound traffic, only
6394 6135 * following this order insures correctness.
6395 6136 */
6396 6137
6397 6138 if (sel->ips_local_port == 0)
6398 6139 return;
6399 6140
6400 6141 /*
6401 6142 * 0 should be fport, 1 should be lport. SRC is the local one here.
6402 6143 * See ipsec_construct_inverse_acquire() for details.
6403 6144 */
6404 6145 pptr[0] = sel->ips_remote_port;
6405 6146 pptr[1] = sel->ips_local_port;
6406 6147
6407 6148 /*
6408 6149 * For labeled systems, there's no need to check the
6409 6150 * label here. It's known to be good as we checked
6410 6151 * before allowing the connection to become bound.
6411 6152 */
6412 6153 if (sel->ips_isv4) {
6413 6154 in6_addr_t src, dst;
6414 6155
6415 6156 IN6_IPADDR_TO_V4MAPPED(sel->ips_remote_addr_v4, &dst);
6416 6157 IN6_IPADDR_TO_V4MAPPED(sel->ips_local_addr_v4, &src);
6417 6158 connp = sctp_find_conn(&dst, &src, ports, ALL_ZONES,
6418 6159 0, ipst->ips_netstack->netstack_sctp);
6419 6160 } else {
6420 6161 connp = sctp_find_conn(&sel->ips_remote_addr_v6,
6421 6162 &sel->ips_local_addr_v6, ports, ALL_ZONES,
6422 6163 0, ipst->ips_netstack->netstack_sctp);
6423 6164 }
6424 6165 if (connp == NULL)
6425 6166 return;
6426 6167 ipsec_conn_pol(sel, connp, ppp);
6427 6168 CONN_DEC_REF(connp);
6428 6169 }
6429 6170
6430 6171 /*
6431 6172 * Fill in a query for the SPD (in "sel") using two PF_KEY address extensions.
6432 6173 * Returns 0 or errno, and always sets *diagnostic to something appropriate
6433 6174 * to PF_KEY.
6434 6175 *
6435 6176 * NOTE: For right now, this function (and ipsec_selector_t for that matter),
6436 6177 * ignore prefix lengths in the address extension. Since we match on first-
6437 6178 * entered policies, this shouldn't matter. Also, since we normalize prefix-
6438 6179 * set addresses to mask out the lower bits, we should get a suitable search
6439 6180 * key for the SPD anyway. This is the function to change if the assumption
6440 6181 * about suitable search keys is wrong.
6441 6182 */
6442 6183 static int
6443 6184 ipsec_get_inverse_acquire_sel(ipsec_selector_t *sel, sadb_address_t *srcext,
6444 6185 sadb_address_t *dstext, int *diagnostic)
6445 6186 {
6446 6187 struct sockaddr_in *src, *dst;
6447 6188 struct sockaddr_in6 *src6, *dst6;
6448 6189
6449 6190 *diagnostic = 0;
6450 6191
6451 6192 bzero(sel, sizeof (*sel));
6452 6193 sel->ips_protocol = srcext->sadb_address_proto;
6453 6194 dst = (struct sockaddr_in *)(dstext + 1);
6454 6195 if (dst->sin_family == AF_INET6) {
6455 6196 dst6 = (struct sockaddr_in6 *)dst;
6456 6197 src6 = (struct sockaddr_in6 *)(srcext + 1);
6457 6198 if (src6->sin6_family != AF_INET6) {
6458 6199 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6459 6200 return (EINVAL);
6460 6201 }
6461 6202 sel->ips_remote_addr_v6 = dst6->sin6_addr;
6462 6203 sel->ips_local_addr_v6 = src6->sin6_addr;
6463 6204 if (sel->ips_protocol == IPPROTO_ICMPV6) {
6464 6205 sel->ips_is_icmp_inv_acq = 1;
6465 6206 } else {
6466 6207 sel->ips_remote_port = dst6->sin6_port;
6467 6208 sel->ips_local_port = src6->sin6_port;
6468 6209 }
6469 6210 sel->ips_isv4 = B_FALSE;
6470 6211 } else {
6471 6212 src = (struct sockaddr_in *)(srcext + 1);
6472 6213 if (src->sin_family != AF_INET) {
6473 6214 *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6474 6215 return (EINVAL);
6475 6216 }
6476 6217 sel->ips_remote_addr_v4 = dst->sin_addr.s_addr;
6477 6218 sel->ips_local_addr_v4 = src->sin_addr.s_addr;
6478 6219 if (sel->ips_protocol == IPPROTO_ICMP) {
6479 6220 sel->ips_is_icmp_inv_acq = 1;
6480 6221 } else {
6481 6222 sel->ips_remote_port = dst->sin_port;
6482 6223 sel->ips_local_port = src->sin_port;
6483 6224 }
6484 6225 sel->ips_isv4 = B_TRUE;
6485 6226 }
6486 6227 return (0);
6487 6228 }
6488 6229
6489 6230 /*
6490 6231 * We have encapsulation.
6491 6232 * - Lookup tun_t by address and look for an associated
6492 6233 * tunnel policy
6493 6234 * - If there are inner selectors
6494 6235 * - check ITPF_P_TUNNEL and ITPF_P_ACTIVE
6495 6236 * - Look up tunnel policy based on selectors
6496 6237 * - Else
6497 6238 * - Sanity check the negotation
6498 6239 * - If appropriate, fall through to global policy
6499 6240 */
6500 6241 static int
6501 6242 ipsec_tun_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6502 6243 sadb_address_t *innsrcext, sadb_address_t *inndstext, ipsec_tun_pol_t *itp,
6503 6244 int *diagnostic)
6504 6245 {
6505 6246 int err;
6506 6247 ipsec_policy_head_t *polhead;
6507 6248
6508 6249 *diagnostic = 0;
6509 6250
6510 6251 /* Check for inner selectors and act appropriately */
6511 6252
6512 6253 if (innsrcext != NULL) {
6513 6254 /* Inner selectors present */
6514 6255 ASSERT(inndstext != NULL);
6515 6256 if ((itp == NULL) ||
6516 6257 (itp->itp_flags & (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) !=
6517 6258 (ITPF_P_ACTIVE | ITPF_P_TUNNEL)) {
6518 6259 /*
6519 6260 * If inner packet selectors, we must have negotiate
6520 6261 * tunnel and active policy. If the tunnel has
6521 6262 * transport-mode policy set on it, or has no policy,
6522 6263 * fail.
6523 6264 */
6524 6265 return (ENOENT);
6525 6266 } else {
6526 6267 /*
6527 6268 * Reset "sel" to indicate inner selectors. Pass
6528 6269 * inner PF_KEY address extensions for this to happen.
6529 6270 */
6530 6271 if ((err = ipsec_get_inverse_acquire_sel(sel,
6531 6272 innsrcext, inndstext, diagnostic)) != 0)
6532 6273 return (err);
6533 6274 /*
6534 6275 * Now look for a tunnel policy based on those inner
6535 6276 * selectors. (Common code is below.)
6536 6277 */
6537 6278 }
6538 6279 } else {
6539 6280 /* No inner selectors present */
6540 6281 if ((itp == NULL) || !(itp->itp_flags & ITPF_P_ACTIVE)) {
6541 6282 /*
6542 6283 * Transport mode negotiation with no tunnel policy
6543 6284 * configured - return to indicate a global policy
6544 6285 * check is needed.
6545 6286 */
6546 6287 return (0);
6547 6288 } else if (itp->itp_flags & ITPF_P_TUNNEL) {
6548 6289 /* Tunnel mode set with no inner selectors. */
6549 6290 return (ENOENT);
6550 6291 }
6551 6292 /*
6552 6293 * Else, this is a tunnel policy configured with ifconfig(1m)
6553 6294 * or "negotiate transport" with ipsecconf(1m). We have an
6554 6295 * itp with policy set based on any match, so don't bother
6555 6296 * changing fields in "sel".
6556 6297 */
6557 6298 }
6558 6299
6559 6300 ASSERT(itp != NULL);
6560 6301 polhead = itp->itp_policy;
6561 6302 ASSERT(polhead != NULL);
6562 6303 rw_enter(&polhead->iph_lock, RW_READER);
6563 6304 *ppp = ipsec_find_policy_head(NULL, polhead, IPSEC_TYPE_INBOUND, sel);
6564 6305 rw_exit(&polhead->iph_lock);
6565 6306
6566 6307 /*
6567 6308 * Don't default to global if we didn't find a matching policy entry.
6568 6309 * Instead, send ENOENT, just like if we hit a transport-mode tunnel.
6569 6310 */
6570 6311 if (*ppp == NULL)
6571 6312 return (ENOENT);
6572 6313
6573 6314 return (0);
6574 6315 }
6575 6316
6576 6317 /*
6577 6318 * For sctp conn_faddr is the primary address, hence this is of limited
6578 6319 * use for sctp.
6579 6320 */
6580 6321 static void
6581 6322 ipsec_oth_pol(ipsec_selector_t *sel, ipsec_policy_t **ppp,
6582 6323 ip_stack_t *ipst)
6583 6324 {
6584 6325 boolean_t isv4 = sel->ips_isv4;
6585 6326 connf_t *connfp;
6586 6327 conn_t *connp;
6587 6328
6588 6329 if (isv4) {
6589 6330 connfp = &ipst->ips_ipcl_proto_fanout_v4[sel->ips_protocol];
6590 6331 } else {
6591 6332 connfp = &ipst->ips_ipcl_proto_fanout_v6[sel->ips_protocol];
6592 6333 }
6593 6334
6594 6335 mutex_enter(&connfp->connf_lock);
6595 6336 for (connp = connfp->connf_head; connp != NULL;
6596 6337 connp = connp->conn_next) {
6597 6338 if (isv4) {
6598 6339 if ((connp->conn_laddr_v4 == INADDR_ANY ||
6599 6340 connp->conn_laddr_v4 == sel->ips_local_addr_v4) &&
6600 6341 (connp->conn_faddr_v4 == INADDR_ANY ||
6601 6342 connp->conn_faddr_v4 == sel->ips_remote_addr_v4))
6602 6343 break;
6603 6344 } else {
6604 6345 if ((IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) ||
6605 6346 IN6_ARE_ADDR_EQUAL(&connp->conn_laddr_v6,
6606 6347 &sel->ips_local_addr_v6)) &&
6607 6348 (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) ||
6608 6349 IN6_ARE_ADDR_EQUAL(&connp->conn_faddr_v6,
6609 6350 &sel->ips_remote_addr_v6)))
6610 6351 break;
6611 6352 }
6612 6353 }
6613 6354 if (connp == NULL) {
6614 6355 mutex_exit(&connfp->connf_lock);
6615 6356 return;
6616 6357 }
6617 6358
6618 6359 CONN_INC_REF(connp);
6619 6360 mutex_exit(&connfp->connf_lock);
6620 6361
6621 6362 ipsec_conn_pol(sel, connp, ppp);
6622 6363 CONN_DEC_REF(connp);
6623 6364 }
6624 6365
6625 6366 /*
6626 6367 * Construct an inverse ACQUIRE reply based on:
6627 6368 *
6628 6369 * 1.) Current global policy.
6629 6370 * 2.) An conn_t match depending on what all was passed in the extv[].
6630 6371 * 3.) A tunnel's policy head.
6631 6372 * ...
6632 6373 * N.) Other stuff TBD (e.g. identities)
6633 6374 *
6634 6375 * If there is an error, set sadb_msg_errno and sadb_x_msg_diagnostic
6635 6376 * in this function so the caller can extract them where appropriately.
6636 6377 *
6637 6378 * The SRC address is the local one - just like an outbound ACQUIRE message.
6638 6379 *
6639 6380 * XXX MLS: key management supplies a label which we just reflect back up
6640 6381 * again. clearly we need to involve the label in the rest of the checks.
6641 6382 */
6642 6383 mblk_t *
6643 6384 ipsec_construct_inverse_acquire(sadb_msg_t *samsg, sadb_ext_t *extv[],
6644 6385 netstack_t *ns)
6645 6386 {
6646 6387 int err;
6647 6388 int diagnostic;
6648 6389 sadb_address_t *srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC],
6649 6390 *dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST],
6650 6391 *innsrcext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC],
6651 6392 *inndstext = (sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST];
6652 6393 sadb_sens_t *sens = (sadb_sens_t *)extv[SADB_EXT_SENSITIVITY];
6653 6394 struct sockaddr_in6 *src, *dst;
6654 6395 struct sockaddr_in6 *isrc, *idst;
6655 6396 ipsec_tun_pol_t *itp = NULL;
6656 6397 ipsec_policy_t *pp = NULL;
6657 6398 ipsec_selector_t sel, isel;
6658 6399 mblk_t *retmp = NULL;
6659 6400 ip_stack_t *ipst = ns->netstack_ip;
6660 6401
6661 6402
6662 6403 /* Normalize addresses */
6663 6404 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)srcext, 0, ns)
6664 6405 == KS_IN_ADDR_UNKNOWN) {
6665 6406 err = EINVAL;
6666 6407 diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC;
6667 6408 goto bail;
6668 6409 }
6669 6410 src = (struct sockaddr_in6 *)(srcext + 1);
6670 6411 if (sadb_addrcheck(NULL, (mblk_t *)samsg, (sadb_ext_t *)dstext, 0, ns)
6671 6412 == KS_IN_ADDR_UNKNOWN) {
6672 6413 err = EINVAL;
6673 6414 diagnostic = SADB_X_DIAGNOSTIC_BAD_DST;
6674 6415 goto bail;
6675 6416 }
6676 6417 dst = (struct sockaddr_in6 *)(dstext + 1);
6677 6418 if (src->sin6_family != dst->sin6_family) {
6678 6419 err = EINVAL;
6679 6420 diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH;
6680 6421 goto bail;
6681 6422 }
6682 6423
6683 6424 /* Check for tunnel mode and act appropriately */
6684 6425 if (innsrcext != NULL) {
6685 6426 if (inndstext == NULL) {
6686 6427 err = EINVAL;
6687 6428 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_DST;
6688 6429 goto bail;
6689 6430 }
6690 6431 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6691 6432 (sadb_ext_t *)innsrcext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6692 6433 err = EINVAL;
6693 6434 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC;
6694 6435 goto bail;
6695 6436 }
6696 6437 isrc = (struct sockaddr_in6 *)(innsrcext + 1);
6697 6438 if (sadb_addrcheck(NULL, (mblk_t *)samsg,
6698 6439 (sadb_ext_t *)inndstext, 0, ns) == KS_IN_ADDR_UNKNOWN) {
6699 6440 err = EINVAL;
6700 6441 diagnostic = SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST;
6701 6442 goto bail;
6702 6443 }
6703 6444 idst = (struct sockaddr_in6 *)(inndstext + 1);
6704 6445 if (isrc->sin6_family != idst->sin6_family) {
6705 6446 err = EINVAL;
6706 6447 diagnostic = SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH;
6707 6448 goto bail;
6708 6449 }
6709 6450 if (isrc->sin6_family != AF_INET &&
6710 6451 isrc->sin6_family != AF_INET6) {
6711 6452 err = EINVAL;
6712 6453 diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_SRC_AF;
6713 6454 goto bail;
6714 6455 }
6715 6456 } else if (inndstext != NULL) {
6716 6457 err = EINVAL;
6717 6458 diagnostic = SADB_X_DIAGNOSTIC_MISSING_INNER_SRC;
6718 6459 goto bail;
6719 6460 }
6720 6461
6721 6462 /* Get selectors first, based on outer addresses */
6722 6463 err = ipsec_get_inverse_acquire_sel(&sel, srcext, dstext, &diagnostic);
6723 6464 if (err != 0)
6724 6465 goto bail;
6725 6466
6726 6467 /* Check for tunnel mode mismatches. */
6727 6468 if (innsrcext != NULL &&
6728 6469 ((isrc->sin6_family == AF_INET &&
6729 6470 sel.ips_protocol != IPPROTO_ENCAP && sel.ips_protocol != 0) ||
6730 6471 (isrc->sin6_family == AF_INET6 &&
6731 6472 sel.ips_protocol != IPPROTO_IPV6 && sel.ips_protocol != 0))) {
6732 6473 err = EPROTOTYPE;
6733 6474 goto bail;
6734 6475 }
6735 6476
6736 6477 /*
6737 6478 * Okay, we have the addresses and other selector information.
6738 6479 * Let's first find a conn...
6739 6480 */
6740 6481 pp = NULL;
6741 6482 switch (sel.ips_protocol) {
6742 6483 case IPPROTO_TCP:
6743 6484 ipsec_tcp_pol(&sel, &pp, ipst);
6744 6485 break;
6745 6486 case IPPROTO_UDP:
6746 6487 ipsec_udp_pol(&sel, &pp, ipst);
6747 6488 break;
6748 6489 case IPPROTO_SCTP:
6749 6490 ipsec_sctp_pol(&sel, &pp, ipst);
6750 6491 break;
6751 6492 case IPPROTO_ENCAP:
6752 6493 case IPPROTO_IPV6:
6753 6494 /*
6754 6495 * Assume sel.ips_remote_addr_* has the right address at
6755 6496 * that exact position.
6756 6497 */
6757 6498 itp = itp_get_byaddr((uint32_t *)(&sel.ips_local_addr_v6),
6758 6499 (uint32_t *)(&sel.ips_remote_addr_v6), src->sin6_family,
6759 6500 ipst);
6760 6501
6761 6502 if (innsrcext == NULL) {
6762 6503 /*
6763 6504 * Transport-mode tunnel, make sure we fake out isel
6764 6505 * to contain something based on the outer protocol.
6765 6506 */
6766 6507 bzero(&isel, sizeof (isel));
6767 6508 isel.ips_isv4 = (sel.ips_protocol == IPPROTO_ENCAP);
6768 6509 } /* Else isel is initialized by ipsec_tun_pol(). */
6769 6510 err = ipsec_tun_pol(&isel, &pp, innsrcext, inndstext, itp,
6770 6511 &diagnostic);
6771 6512 /*
6772 6513 * NOTE: isel isn't used for now, but in RFC 430x IPsec, it
6773 6514 * may be.
6774 6515 */
6775 6516 if (err != 0)
6776 6517 goto bail;
6777 6518 break;
6778 6519 default:
6779 6520 ipsec_oth_pol(&sel, &pp, ipst);
6780 6521 break;
6781 6522 }
6782 6523
6783 6524 /*
6784 6525 * If we didn't find a matching conn_t or other policy head, take a
6785 6526 * look in the global policy.
6786 6527 */
6787 6528 if (pp == NULL) {
6788 6529 pp = ipsec_find_policy(IPSEC_TYPE_OUTBOUND, NULL, &sel, ns);
6789 6530 if (pp == NULL) {
6790 6531 /* There's no global policy. */
6791 6532 err = ENOENT;
6792 6533 diagnostic = 0;
6793 6534 goto bail;
6794 6535 }
6795 6536 }
6796 6537
6797 6538 /*
6798 6539 * Now that we have a policy entry/widget, construct an ACQUIRE
6799 6540 * message based on that, fix fields where appropriate,
6800 6541 * and return the message.
6801 6542 */
6802 6543 retmp = sadb_extended_acquire(&sel, pp, NULL,
6803 6544 (itp != NULL && (itp->itp_flags & ITPF_P_TUNNEL)),
6804 6545 samsg->sadb_msg_seq, samsg->sadb_msg_pid, sens, ns);
6805 6546 if (pp != NULL) {
6806 6547 IPPOL_REFRELE(pp);
6807 6548 }
6808 6549 ASSERT(err == 0 && diagnostic == 0);
6809 6550 if (retmp == NULL)
6810 6551 err = ENOMEM;
6811 6552 bail:
6812 6553 if (itp != NULL) {
6813 6554 ITP_REFRELE(itp, ns);
6814 6555 }
6815 6556 samsg->sadb_msg_errno = (uint8_t)err;
6816 6557 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
6817 6558 return (retmp);
6818 6559 }
6819 6560
6820 6561 /*
6821 6562 * ipsa_lpkt is a one-element queue, only manipulated by the next two
6822 6563 * functions. They have to hold the ipsa_lock because of potential races
6823 6564 * between key management using SADB_UPDATE, and inbound packets that may
6824 6565 * queue up on the larval SA (hence the 'l' in "lpkt").
6825 6566 */
6826 6567
6827 6568 /*
6828 6569 * sadb_set_lpkt:
6829 6570 *
6830 6571 * Returns the passed-in packet if the SA is no longer larval.
6831 6572 *
6832 6573 * Returns NULL if the SA is larval, and needs to be swapped into the SA for
6833 6574 * processing after an SADB_UPDATE.
6834 6575 */
6835 6576 mblk_t *
6836 6577 sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira)
6837 6578 {
6838 6579 mblk_t *opkt;
6839 6580
6840 6581 mutex_enter(&ipsa->ipsa_lock);
6841 6582 opkt = ipsa->ipsa_lpkt;
6842 6583 if (ipsa->ipsa_state == IPSA_STATE_LARVAL) {
6843 6584 /*
6844 6585 * Consume npkt and place it in the LARVAL SA's inbound
6845 6586 * packet slot.
6846 6587 */
6847 6588 mblk_t *attrmp;
6848 6589
6849 6590 attrmp = ip_recv_attr_to_mblk(ira);
6850 6591 if (attrmp == NULL) {
6851 6592 ill_t *ill = ira->ira_ill;
6852 6593
6853 6594 BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
6854 6595 ip_drop_input("ipIfStatsInDiscards", npkt, ill);
6855 6596 freemsg(npkt);
6856 6597 opkt = NULL;
6857 6598 } else {
6858 6599 ASSERT(attrmp->b_cont == NULL);
6859 6600 attrmp->b_cont = npkt;
6860 6601 ipsa->ipsa_lpkt = attrmp;
6861 6602 }
6862 6603 npkt = NULL;
6863 6604 } else {
6864 6605 /*
6865 6606 * If not larval, we lost the race. NOTE: ipsa_lpkt may still
6866 6607 * have been non-NULL in the non-larval case, because of
6867 6608 * inbound packets arriving prior to sadb_common_add()
6868 6609 * transferring the SA completely out of larval state, but
6869 6610 * after lpkt was grabbed by the AH/ESP-specific add routines.
6870 6611 * We should clear the old ipsa_lpkt in this case to make sure
6871 6612 * that it doesn't linger on the now-MATURE IPsec SA, or get
6872 6613 * picked up as an out-of-order packet.
6873 6614 */
6874 6615 ipsa->ipsa_lpkt = NULL;
6875 6616 }
6876 6617 mutex_exit(&ipsa->ipsa_lock);
6877 6618
6878 6619 if (opkt != NULL) {
6879 6620 ipsec_stack_t *ipss;
6880 6621
6881 6622 ipss = ira->ira_ill->ill_ipst->ips_netstack->netstack_ipsec;
6882 6623 opkt = ip_recv_attr_free_mblk(opkt);
6883 6624 ip_drop_packet(opkt, B_TRUE, ira->ira_ill,
6884 6625 DROPPER(ipss, ipds_sadb_inlarval_replace),
6885 6626 &ipss->ipsec_sadb_dropper);
6886 6627 }
6887 6628 return (npkt);
6888 6629 }
6889 6630
6890 6631 /*
6891 6632 * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
6892 6633 * previous value.
6893 6634 */
6894 6635 mblk_t *
6895 6636 sadb_clear_lpkt(ipsa_t *ipsa)
6896 6637 {
|
↓ open down ↓ |
1062 lines elided |
↑ open up ↑ |
6897 6638 mblk_t *opkt;
6898 6639
6899 6640 mutex_enter(&ipsa->ipsa_lock);
6900 6641 opkt = ipsa->ipsa_lpkt;
6901 6642 ipsa->ipsa_lpkt = NULL;
6902 6643 mutex_exit(&ipsa->ipsa_lock);
6903 6644 return (opkt);
6904 6645 }
6905 6646
6906 6647 /*
6907 - * Buffer a packet that's in IDLE state as set by Solaris Clustering.
6908 - */
6909 -void
6910 -sadb_buf_pkt(ipsa_t *ipsa, mblk_t *bpkt, ip_recv_attr_t *ira)
6911 -{
6912 - netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack;
6913 - ipsec_stack_t *ipss = ns->netstack_ipsec;
6914 -
6915 - ASSERT(ipsa->ipsa_state == IPSA_STATE_IDLE);
6916 -
6917 - ip_drop_packet(bpkt, B_TRUE, ira->ira_ill,
6918 - DROPPER(ipss, ipds_sadb_inidle_overflow),
6919 - &ipss->ipsec_sadb_dropper);
6920 - return;
6921 -}
6922 -
6923 -/*
6924 - * Stub function that taskq_dispatch() invokes to take the mblk (in arg)
6925 - * and put into STREAMS again.
6926 - */
6927 -void
6928 -sadb_clear_buf_pkt(void *ipkt)
6929 -{
6930 - mblk_t *tmp, *buf_pkt;
6931 - ip_recv_attr_t iras;
6932 -
6933 - buf_pkt = (mblk_t *)ipkt;
6934 -
6935 - while (buf_pkt != NULL) {
6936 - mblk_t *data_mp;
6937 -
6938 - tmp = buf_pkt->b_next;
6939 - buf_pkt->b_next = NULL;
6940 -
6941 - data_mp = buf_pkt->b_cont;
6942 - buf_pkt->b_cont = NULL;
6943 - if (!ip_recv_attr_from_mblk(buf_pkt, &iras)) {
6944 - /* The ill or ip_stack_t disappeared on us. */
6945 - ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL);
6946 - freemsg(data_mp);
6947 - } else {
6948 - ip_input_post_ipsec(data_mp, &iras);
6949 - }
6950 - ira_cleanup(&iras, B_TRUE);
6951 - buf_pkt = tmp;
6952 - }
6953 -}
6954 -/*
6955 6648 * Walker callback used by sadb_alg_update() to free/create crypto
6956 6649 * context template when a crypto software provider is removed or
6957 6650 * added.
6958 6651 */
6959 6652
6960 6653 struct sadb_update_alg_state {
6961 6654 ipsec_algtype_t alg_type;
6962 6655 uint8_t alg_id;
6963 6656 boolean_t is_added;
6964 6657 boolean_t async_auth;
6965 6658 boolean_t async_encr;
6966 6659 };
6967 6660
6968 6661 static void
6969 6662 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
6970 6663 {
6971 6664 struct sadb_update_alg_state *update_state =
6972 6665 (struct sadb_update_alg_state *)cookie;
6973 6666 crypto_ctx_template_t *ctx_tmpl = NULL;
6974 6667
6975 6668 ASSERT(MUTEX_HELD(&head->isaf_lock));
6976 6669
6977 6670 if (entry->ipsa_state == IPSA_STATE_LARVAL)
6978 6671 return;
6979 6672
6980 6673 mutex_enter(&entry->ipsa_lock);
6981 6674
6982 6675 if ((entry->ipsa_encr_alg != SADB_EALG_NONE && entry->ipsa_encr_alg !=
6983 6676 SADB_EALG_NULL && update_state->async_encr) ||
6984 6677 (entry->ipsa_auth_alg != SADB_AALG_NONE &&
6985 6678 update_state->async_auth)) {
6986 6679 entry->ipsa_flags |= IPSA_F_ASYNC;
6987 6680 } else {
6988 6681 entry->ipsa_flags &= ~IPSA_F_ASYNC;
6989 6682 }
6990 6683
6991 6684 switch (update_state->alg_type) {
6992 6685 case IPSEC_ALG_AUTH:
6993 6686 if (entry->ipsa_auth_alg == update_state->alg_id)
6994 6687 ctx_tmpl = &entry->ipsa_authtmpl;
6995 6688 break;
6996 6689 case IPSEC_ALG_ENCR:
6997 6690 if (entry->ipsa_encr_alg == update_state->alg_id)
6998 6691 ctx_tmpl = &entry->ipsa_encrtmpl;
6999 6692 break;
7000 6693 default:
7001 6694 ctx_tmpl = NULL;
7002 6695 }
7003 6696
7004 6697 if (ctx_tmpl == NULL) {
7005 6698 mutex_exit(&entry->ipsa_lock);
7006 6699 return;
7007 6700 }
7008 6701
7009 6702 /*
7010 6703 * The context template of the SA may be affected by the change
7011 6704 * of crypto provider.
7012 6705 */
7013 6706 if (update_state->is_added) {
7014 6707 /* create the context template if not already done */
7015 6708 if (*ctx_tmpl == NULL) {
7016 6709 (void) ipsec_create_ctx_tmpl(entry,
7017 6710 update_state->alg_type);
7018 6711 }
7019 6712 } else {
7020 6713 /*
7021 6714 * The crypto provider was removed. If the context template
7022 6715 * exists but it is no longer valid, free it.
7023 6716 */
7024 6717 if (*ctx_tmpl != NULL)
7025 6718 ipsec_destroy_ctx_tmpl(entry, update_state->alg_type);
7026 6719 }
7027 6720
7028 6721 mutex_exit(&entry->ipsa_lock);
7029 6722 }
7030 6723
7031 6724 /*
7032 6725 * Invoked by IP when an software crypto provider has been updated, or if
7033 6726 * the crypto synchrony changes. The type and id of the corresponding
7034 6727 * algorithm is passed as argument. The type is set to ALL in the case of
7035 6728 * a synchrony change.
7036 6729 *
7037 6730 * is_added is B_TRUE if the provider was added, B_FALSE if it was
7038 6731 * removed. The function updates the SADB and free/creates the
7039 6732 * context templates associated with SAs if needed.
7040 6733 */
7041 6734
7042 6735 #define SADB_ALG_UPDATE_WALK(sadb, table) \
7043 6736 sadb_walker((sadb).table, (sadb).sdb_hashsize, sadb_alg_update_cb, \
7044 6737 &update_state)
7045 6738
7046 6739 void
7047 6740 sadb_alg_update(ipsec_algtype_t alg_type, uint8_t alg_id, boolean_t is_added,
7048 6741 netstack_t *ns)
7049 6742 {
7050 6743 struct sadb_update_alg_state update_state;
7051 6744 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
7052 6745 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
7053 6746 ipsec_stack_t *ipss = ns->netstack_ipsec;
7054 6747
7055 6748 update_state.alg_type = alg_type;
7056 6749 update_state.alg_id = alg_id;
7057 6750 update_state.is_added = is_added;
7058 6751 update_state.async_auth = ipss->ipsec_algs_exec_mode[IPSEC_ALG_AUTH] ==
7059 6752 IPSEC_ALGS_EXEC_ASYNC;
7060 6753 update_state.async_encr = ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
7061 6754 IPSEC_ALGS_EXEC_ASYNC;
7062 6755
7063 6756 if (alg_type == IPSEC_ALG_AUTH || alg_type == IPSEC_ALG_ALL) {
7064 6757 /* walk the AH tables only for auth. algorithm changes */
7065 6758 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_of);
7066 6759 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v4, sdb_if);
7067 6760 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_of);
7068 6761 SADB_ALG_UPDATE_WALK(ahstack->ah_sadb.s_v6, sdb_if);
7069 6762 }
7070 6763
7071 6764 /* walk the ESP tables */
7072 6765 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_of);
7073 6766 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v4, sdb_if);
7074 6767 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_of);
7075 6768 SADB_ALG_UPDATE_WALK(espstack->esp_sadb.s_v6, sdb_if);
7076 6769 }
7077 6770
7078 6771 /*
7079 6772 * Creates a context template for the specified SA. This function
7080 6773 * is called when an SA is created and when a context template needs
7081 6774 * to be created due to a change of software provider.
7082 6775 */
7083 6776 int
7084 6777 ipsec_create_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7085 6778 {
7086 6779 ipsec_alginfo_t *alg;
7087 6780 crypto_mechanism_t mech;
7088 6781 crypto_key_t *key;
7089 6782 crypto_ctx_template_t *sa_tmpl;
7090 6783 int rv;
7091 6784 ipsec_stack_t *ipss = sa->ipsa_netstack->netstack_ipsec;
7092 6785
7093 6786 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
7094 6787 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7095 6788
7096 6789 /* get pointers to the algorithm info, context template, and key */
7097 6790 switch (alg_type) {
7098 6791 case IPSEC_ALG_AUTH:
7099 6792 key = &sa->ipsa_kcfauthkey;
7100 6793 sa_tmpl = &sa->ipsa_authtmpl;
7101 6794 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_auth_alg];
7102 6795 break;
7103 6796 case IPSEC_ALG_ENCR:
7104 6797 key = &sa->ipsa_kcfencrkey;
7105 6798 sa_tmpl = &sa->ipsa_encrtmpl;
7106 6799 alg = ipss->ipsec_alglists[alg_type][sa->ipsa_encr_alg];
7107 6800 break;
7108 6801 default:
7109 6802 alg = NULL;
7110 6803 }
7111 6804
7112 6805 if (alg == NULL || !ALG_VALID(alg))
7113 6806 return (EINVAL);
7114 6807
7115 6808 /* initialize the mech info structure for the framework */
7116 6809 ASSERT(alg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
7117 6810 mech.cm_type = alg->alg_mech_type;
7118 6811 mech.cm_param = NULL;
7119 6812 mech.cm_param_len = 0;
7120 6813
7121 6814 /* create a new context template */
7122 6815 rv = crypto_create_ctx_template(&mech, key, sa_tmpl, KM_NOSLEEP);
7123 6816
7124 6817 /*
7125 6818 * CRYPTO_MECH_NOT_SUPPORTED can be returned if only hardware
7126 6819 * providers are available for that mechanism. In that case
7127 6820 * we don't fail, and will generate the context template from
7128 6821 * the framework callback when a software provider for that
7129 6822 * mechanism registers.
7130 6823 *
7131 6824 * The context template is assigned the special value
7132 6825 * IPSEC_CTX_TMPL_ALLOC if the allocation failed due to a
7133 6826 * lack of memory. No attempt will be made to use
7134 6827 * the context template if it is set to this value.
7135 6828 */
7136 6829 if (rv == CRYPTO_HOST_MEMORY) {
7137 6830 *sa_tmpl = IPSEC_CTX_TMPL_ALLOC;
7138 6831 } else if (rv != CRYPTO_SUCCESS) {
7139 6832 *sa_tmpl = NULL;
7140 6833 if (rv != CRYPTO_MECH_NOT_SUPPORTED)
7141 6834 return (EINVAL);
7142 6835 }
7143 6836
7144 6837 return (0);
7145 6838 }
7146 6839
7147 6840 /*
7148 6841 * Destroy the context template of the specified algorithm type
7149 6842 * of the specified SA. Must be called while holding the SA lock.
7150 6843 */
7151 6844 void
7152 6845 ipsec_destroy_ctx_tmpl(ipsa_t *sa, ipsec_algtype_t alg_type)
7153 6846 {
7154 6847 ASSERT(MUTEX_HELD(&sa->ipsa_lock));
7155 6848
7156 6849 if (alg_type == IPSEC_ALG_AUTH) {
7157 6850 if (sa->ipsa_authtmpl == IPSEC_CTX_TMPL_ALLOC)
7158 6851 sa->ipsa_authtmpl = NULL;
7159 6852 else if (sa->ipsa_authtmpl != NULL) {
7160 6853 crypto_destroy_ctx_template(sa->ipsa_authtmpl);
7161 6854 sa->ipsa_authtmpl = NULL;
7162 6855 }
7163 6856 } else {
7164 6857 ASSERT(alg_type == IPSEC_ALG_ENCR);
7165 6858 if (sa->ipsa_encrtmpl == IPSEC_CTX_TMPL_ALLOC)
7166 6859 sa->ipsa_encrtmpl = NULL;
7167 6860 else if (sa->ipsa_encrtmpl != NULL) {
7168 6861 crypto_destroy_ctx_template(sa->ipsa_encrtmpl);
7169 6862 sa->ipsa_encrtmpl = NULL;
7170 6863 }
7171 6864 }
7172 6865 }
7173 6866
7174 6867 /*
7175 6868 * Use the kernel crypto framework to check the validity of a key received
7176 6869 * via keysock. Returns 0 if the key is OK, -1 otherwise.
7177 6870 */
7178 6871 int
7179 6872 ipsec_check_key(crypto_mech_type_t mech_type, sadb_key_t *sadb_key,
7180 6873 boolean_t is_auth, int *diag)
7181 6874 {
7182 6875 crypto_mechanism_t mech;
7183 6876 crypto_key_t crypto_key;
7184 6877 int crypto_rc;
7185 6878
7186 6879 mech.cm_type = mech_type;
7187 6880 mech.cm_param = NULL;
7188 6881 mech.cm_param_len = 0;
7189 6882
7190 6883 crypto_key.ck_format = CRYPTO_KEY_RAW;
7191 6884 crypto_key.ck_data = sadb_key + 1;
7192 6885 crypto_key.ck_length = sadb_key->sadb_key_bits;
7193 6886
7194 6887 crypto_rc = crypto_key_check(&mech, &crypto_key);
7195 6888
7196 6889 switch (crypto_rc) {
7197 6890 case CRYPTO_SUCCESS:
7198 6891 return (0);
7199 6892 case CRYPTO_MECHANISM_INVALID:
7200 6893 case CRYPTO_MECH_NOT_SUPPORTED:
7201 6894 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AALG :
7202 6895 SADB_X_DIAGNOSTIC_BAD_EALG;
7203 6896 break;
7204 6897 case CRYPTO_KEY_SIZE_RANGE:
7205 6898 *diag = is_auth ? SADB_X_DIAGNOSTIC_BAD_AKEYBITS :
7206 6899 SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
7207 6900 break;
7208 6901 case CRYPTO_WEAK_KEY:
7209 6902 *diag = is_auth ? SADB_X_DIAGNOSTIC_WEAK_AKEY :
7210 6903 SADB_X_DIAGNOSTIC_WEAK_EKEY;
7211 6904 break;
7212 6905 }
7213 6906
7214 6907 return (-1);
7215 6908 }
7216 6909
7217 6910 /*
7218 6911 * Whack options in the outer IP header when ipsec changes the outer label
7219 6912 *
7220 6913 * This is inelegant and really could use refactoring.
7221 6914 */
7222 6915 mblk_t *
7223 6916 sadb_whack_label_v4(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7224 6917 ipdropper_t *dropper)
7225 6918 {
7226 6919 int delta;
7227 6920 int plen;
7228 6921 dblk_t *db;
7229 6922 int hlen;
7230 6923 uint8_t *opt_storage = assoc->ipsa_opt_storage;
7231 6924 ipha_t *ipha = (ipha_t *)mp->b_rptr;
7232 6925
7233 6926 plen = ntohs(ipha->ipha_length);
7234 6927
7235 6928 delta = tsol_remove_secopt(ipha, MBLKL(mp));
7236 6929 mp->b_wptr += delta;
7237 6930 plen += delta;
7238 6931
7239 6932 /* XXX XXX code copied from tsol_check_label */
7240 6933
7241 6934 /* Make sure we have room for the worst-case addition */
7242 6935 hlen = IPH_HDR_LENGTH(ipha) + opt_storage[IPOPT_OLEN];
7243 6936 hlen = (hlen + 3) & ~3;
7244 6937 if (hlen > IP_MAX_HDR_LENGTH)
7245 6938 hlen = IP_MAX_HDR_LENGTH;
7246 6939 hlen -= IPH_HDR_LENGTH(ipha);
7247 6940
7248 6941 db = mp->b_datap;
7249 6942 if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7250 6943 int copylen;
7251 6944 mblk_t *new_mp;
7252 6945
7253 6946 /* allocate enough to be meaningful, but not *too* much */
7254 6947 copylen = MBLKL(mp);
7255 6948 if (copylen > 256)
7256 6949 copylen = 256;
7257 6950 new_mp = allocb_tmpl(hlen + copylen +
7258 6951 (mp->b_rptr - mp->b_datap->db_base), mp);
7259 6952
7260 6953 if (new_mp == NULL) {
7261 6954 ip_drop_packet(mp, B_FALSE, NULL, counter, dropper);
7262 6955 return (NULL);
7263 6956 }
7264 6957
7265 6958 /* keep the bias */
7266 6959 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7267 6960 new_mp->b_wptr = new_mp->b_rptr + copylen;
7268 6961 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7269 6962 new_mp->b_cont = mp;
7270 6963 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7271 6964 new_mp->b_cont = mp->b_cont;
7272 6965 freeb(mp);
7273 6966 }
7274 6967 mp = new_mp;
7275 6968 ipha = (ipha_t *)mp->b_rptr;
7276 6969 }
7277 6970
7278 6971 delta = tsol_prepend_option(assoc->ipsa_opt_storage, ipha, MBLKL(mp));
7279 6972
7280 6973 ASSERT(delta != -1);
7281 6974
7282 6975 plen += delta;
7283 6976 mp->b_wptr += delta;
7284 6977
7285 6978 /*
7286 6979 * Paranoia
7287 6980 */
7288 6981 db = mp->b_datap;
7289 6982
7290 6983 ASSERT3P(mp->b_wptr, <=, db->db_lim);
7291 6984 ASSERT3P(mp->b_rptr, <=, db->db_lim);
7292 6985
7293 6986 ASSERT3P(mp->b_wptr, >=, db->db_base);
7294 6987 ASSERT3P(mp->b_rptr, >=, db->db_base);
7295 6988 /* End paranoia */
7296 6989
7297 6990 ipha->ipha_length = htons(plen);
7298 6991
7299 6992 return (mp);
7300 6993 }
7301 6994
7302 6995 mblk_t *
7303 6996 sadb_whack_label_v6(mblk_t *mp, ipsa_t *assoc, kstat_named_t *counter,
7304 6997 ipdropper_t *dropper)
7305 6998 {
7306 6999 int delta;
7307 7000 int plen;
7308 7001 dblk_t *db;
7309 7002 int hlen;
7310 7003 uint8_t *opt_storage = assoc->ipsa_opt_storage;
7311 7004 uint_t sec_opt_len; /* label option length not including type, len */
7312 7005 ip6_t *ip6h = (ip6_t *)mp->b_rptr;
7313 7006
7314 7007 plen = ntohs(ip6h->ip6_plen);
7315 7008
7316 7009 delta = tsol_remove_secopt_v6(ip6h, MBLKL(mp));
7317 7010 mp->b_wptr += delta;
7318 7011 plen += delta;
7319 7012
7320 7013 /* XXX XXX code copied from tsol_check_label_v6 */
7321 7014 /*
7322 7015 * Make sure we have room for the worst-case addition. Add 2 bytes for
7323 7016 * the hop-by-hop ext header's next header and length fields. Add
7324 7017 * another 2 bytes for the label option type, len and then round
7325 7018 * up to the next 8-byte multiple.
7326 7019 */
7327 7020 sec_opt_len = opt_storage[1];
7328 7021
7329 7022 db = mp->b_datap;
7330 7023 hlen = (4 + sec_opt_len + 7) & ~7;
7331 7024
7332 7025 if ((db->db_ref != 1) || (mp->b_wptr + hlen > db->db_lim)) {
7333 7026 int copylen;
7334 7027 mblk_t *new_mp;
7335 7028 uint16_t hdr_len;
7336 7029
7337 7030 hdr_len = ip_hdr_length_v6(mp, ip6h);
7338 7031 /*
7339 7032 * Allocate enough to be meaningful, but not *too* much.
7340 7033 * Also all the IPv6 extension headers must be in the same mblk
7341 7034 */
7342 7035 copylen = MBLKL(mp);
7343 7036 if (copylen > 256)
7344 7037 copylen = 256;
7345 7038 if (copylen < hdr_len)
7346 7039 copylen = hdr_len;
7347 7040 new_mp = allocb_tmpl(hlen + copylen +
7348 7041 (mp->b_rptr - mp->b_datap->db_base), mp);
7349 7042 if (new_mp == NULL) {
7350 7043 ip_drop_packet(mp, B_FALSE, NULL, counter, dropper);
7351 7044 return (NULL);
7352 7045 }
7353 7046
7354 7047 /* keep the bias */
7355 7048 new_mp->b_rptr += mp->b_rptr - mp->b_datap->db_base;
7356 7049 new_mp->b_wptr = new_mp->b_rptr + copylen;
7357 7050 bcopy(mp->b_rptr, new_mp->b_rptr, copylen);
7358 7051 new_mp->b_cont = mp;
7359 7052 if ((mp->b_rptr += copylen) >= mp->b_wptr) {
7360 7053 new_mp->b_cont = mp->b_cont;
7361 7054 freeb(mp);
7362 7055 }
7363 7056 mp = new_mp;
7364 7057 ip6h = (ip6_t *)mp->b_rptr;
7365 7058 }
7366 7059
7367 7060 delta = tsol_prepend_option_v6(assoc->ipsa_opt_storage,
7368 7061 ip6h, MBLKL(mp));
7369 7062
7370 7063 ASSERT(delta != -1);
7371 7064
7372 7065 plen += delta;
7373 7066 mp->b_wptr += delta;
7374 7067
7375 7068 /*
7376 7069 * Paranoia
7377 7070 */
7378 7071 db = mp->b_datap;
7379 7072
7380 7073 ASSERT3P(mp->b_wptr, <=, db->db_lim);
7381 7074 ASSERT3P(mp->b_rptr, <=, db->db_lim);
7382 7075
7383 7076 ASSERT3P(mp->b_wptr, >=, db->db_base);
7384 7077 ASSERT3P(mp->b_rptr, >=, db->db_base);
7385 7078 /* End paranoia */
7386 7079
7387 7080 ip6h->ip6_plen = htons(plen);
7388 7081
7389 7082 return (mp);
7390 7083 }
7391 7084
7392 7085 /* Whack the labels and update ip_xmit_attr_t as needed */
7393 7086 mblk_t *
7394 7087 sadb_whack_label(mblk_t *mp, ipsa_t *assoc, ip_xmit_attr_t *ixa,
7395 7088 kstat_named_t *counter, ipdropper_t *dropper)
7396 7089 {
7397 7090 int adjust;
7398 7091 int iplen;
7399 7092
7400 7093 if (ixa->ixa_flags & IXAF_IS_IPV4) {
7401 7094 ipha_t *ipha = (ipha_t *)mp->b_rptr;
7402 7095
7403 7096 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7404 7097 iplen = ntohs(ipha->ipha_length);
7405 7098 mp = sadb_whack_label_v4(mp, assoc, counter, dropper);
7406 7099 if (mp == NULL)
7407 7100 return (NULL);
7408 7101
7409 7102 ipha = (ipha_t *)mp->b_rptr;
7410 7103 ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION);
7411 7104 adjust = (int)ntohs(ipha->ipha_length) - iplen;
7412 7105 } else {
7413 7106 ip6_t *ip6h = (ip6_t *)mp->b_rptr;
7414 7107
7415 7108 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7416 7109 iplen = ntohs(ip6h->ip6_plen);
7417 7110 mp = sadb_whack_label_v6(mp, assoc, counter, dropper);
7418 7111 if (mp == NULL)
7419 7112 return (NULL);
7420 7113
7421 7114 ip6h = (ip6_t *)mp->b_rptr;
7422 7115 ASSERT(IPH_HDR_VERSION(ip6h) == IPV6_VERSION);
7423 7116 adjust = (int)ntohs(ip6h->ip6_plen) - iplen;
7424 7117 }
7425 7118 ixa->ixa_pktlen += adjust;
7426 7119 ixa->ixa_ip_hdr_length += adjust;
7427 7120 return (mp);
7428 7121 }
7429 7122
7430 7123 /*
7431 7124 * If this is an outgoing SA then add some fuzz to the
7432 7125 * SOFT EXPIRE time. The reason for this is to stop
7433 7126 * peers trying to renegotiate SOFT expiring SA's at
7434 7127 * the same time. The amount of fuzz needs to be at
7435 7128 * least 8 seconds which is the typical interval
7436 7129 * sadb_ager(), although this is only a guide as it
7437 7130 * selftunes.
7438 7131 */
7439 7132 static void
7440 7133 lifetime_fuzz(ipsa_t *assoc)
7441 7134 {
7442 7135 uint8_t rnd;
7443 7136
7444 7137 if (assoc->ipsa_softaddlt == 0)
7445 7138 return;
7446 7139
7447 7140 (void) random_get_pseudo_bytes(&rnd, sizeof (rnd));
7448 7141 rnd = (rnd & 0xF) + 8;
7449 7142 assoc->ipsa_softexpiretime -= rnd;
7450 7143 assoc->ipsa_softaddlt -= rnd;
7451 7144 }
7452 7145
7453 7146 static void
7454 7147 destroy_ipsa_pair(ipsap_t *ipsapp)
7455 7148 {
7456 7149 /*
7457 7150 * Because of the multi-line macro nature of IPSA_REFRELE, keep
7458 7151 * them in { }.
7459 7152 */
7460 7153 if (ipsapp->ipsap_sa_ptr != NULL) {
7461 7154 IPSA_REFRELE(ipsapp->ipsap_sa_ptr);
7462 7155 }
7463 7156 if (ipsapp->ipsap_psa_ptr != NULL) {
7464 7157 IPSA_REFRELE(ipsapp->ipsap_psa_ptr);
7465 7158 }
7466 7159 init_ipsa_pair(ipsapp);
7467 7160 }
7468 7161
7469 7162 static void
7470 7163 init_ipsa_pair(ipsap_t *ipsapp)
7471 7164 {
7472 7165 ipsapp->ipsap_bucket = NULL;
7473 7166 ipsapp->ipsap_sa_ptr = NULL;
7474 7167 ipsapp->ipsap_pbucket = NULL;
7475 7168 ipsapp->ipsap_psa_ptr = NULL;
7476 7169 }
7477 7170
7478 7171 /*
7479 7172 * The sadb_ager() function walks through the hash tables of SA's and ages
7480 7173 * them, if the SA expires as a result, its marked as DEAD and will be reaped
7481 7174 * the next time sadb_ager() runs. SA's which are paired or have a peer (same
7482 7175 * SA appears in both the inbound and outbound tables because its not possible
7483 7176 * to determine its direction) are placed on a list when they expire. This is
7484 7177 * to ensure that pair/peer SA's are reaped at the same time, even if they
7485 7178 * expire at different times.
7486 7179 *
7487 7180 * This function is called twice by sadb_ager(), one after processing the
7488 7181 * inbound table, then again after processing the outbound table.
7489 7182 */
7490 7183 void
7491 7184 age_pair_peer_list(templist_t *haspeerlist, sadb_t *sp, boolean_t outbound)
7492 7185 {
7493 7186 templist_t *listptr;
7494 7187 int outhash;
7495 7188 isaf_t *bucket;
7496 7189 boolean_t haspeer;
7497 7190 ipsa_t *peer_assoc, *dying;
7498 7191 /*
7499 7192 * Haspeer cases will contain both IPv4 and IPv6. This code
7500 7193 * is address independent.
7501 7194 */
7502 7195 while (haspeerlist != NULL) {
7503 7196 /* "dying" contains the SA that has a peer. */
7504 7197 dying = haspeerlist->ipsa;
7505 7198 haspeer = (dying->ipsa_haspeer);
7506 7199 listptr = haspeerlist;
7507 7200 haspeerlist = listptr->next;
7508 7201 kmem_free(listptr, sizeof (*listptr));
7509 7202 /*
7510 7203 * Pick peer bucket based on addrfam.
7511 7204 */
7512 7205 if (outbound) {
7513 7206 if (haspeer)
7514 7207 bucket = INBOUND_BUCKET(sp, dying->ipsa_spi);
7515 7208 else
7516 7209 bucket = INBOUND_BUCKET(sp,
7517 7210 dying->ipsa_otherspi);
7518 7211 } else { /* inbound */
7519 7212 if (haspeer) {
7520 7213 if (dying->ipsa_addrfam == AF_INET6) {
7521 7214 outhash = OUTBOUND_HASH_V6(sp,
7522 7215 *((in6_addr_t *)&dying->
7523 7216 ipsa_dstaddr));
7524 7217 } else {
7525 7218 outhash = OUTBOUND_HASH_V4(sp,
7526 7219 *((ipaddr_t *)&dying->
7527 7220 ipsa_dstaddr));
7528 7221 }
7529 7222 } else if (dying->ipsa_addrfam == AF_INET6) {
7530 7223 outhash = OUTBOUND_HASH_V6(sp,
7531 7224 *((in6_addr_t *)&dying->
7532 7225 ipsa_srcaddr));
7533 7226 } else {
7534 7227 outhash = OUTBOUND_HASH_V4(sp,
7535 7228 *((ipaddr_t *)&dying->
7536 7229 ipsa_srcaddr));
7537 7230 }
7538 7231 bucket = &(sp->sdb_of[outhash]);
7539 7232 }
7540 7233
7541 7234 mutex_enter(&bucket->isaf_lock);
7542 7235 /*
7543 7236 * "haspeer" SA's have the same src/dst address ordering,
7544 7237 * "paired" SA's have the src/dst addresses reversed.
7545 7238 */
7546 7239 if (haspeer) {
7547 7240 peer_assoc = ipsec_getassocbyspi(bucket,
7548 7241 dying->ipsa_spi, dying->ipsa_srcaddr,
7549 7242 dying->ipsa_dstaddr, dying->ipsa_addrfam);
7550 7243 } else {
7551 7244 peer_assoc = ipsec_getassocbyspi(bucket,
7552 7245 dying->ipsa_otherspi, dying->ipsa_dstaddr,
7553 7246 dying->ipsa_srcaddr, dying->ipsa_addrfam);
7554 7247 }
7555 7248
7556 7249 mutex_exit(&bucket->isaf_lock);
7557 7250 if (peer_assoc != NULL) {
7558 7251 mutex_enter(&peer_assoc->ipsa_lock);
7559 7252 mutex_enter(&dying->ipsa_lock);
7560 7253 if (!haspeer) {
7561 7254 /*
7562 7255 * Only SA's which have a "peer" or are
7563 7256 * "paired" end up on this list, so this
7564 7257 * must be a "paired" SA, update the flags
7565 7258 * to break the pair.
7566 7259 */
7567 7260 peer_assoc->ipsa_otherspi = 0;
7568 7261 peer_assoc->ipsa_flags &= ~IPSA_F_PAIRED;
7569 7262 dying->ipsa_otherspi = 0;
7570 7263 dying->ipsa_flags &= ~IPSA_F_PAIRED;
7571 7264 }
7572 7265 if (haspeer || outbound) {
7573 7266 /*
7574 7267 * Update the state of the "inbound" SA when
7575 7268 * the "outbound" SA has expired. Don't update
7576 7269 * the "outbound" SA when the "inbound" SA
7577 7270 * SA expires because setting the hard_addtime
7578 7271 * below will cause this to happen.
7579 7272 */
7580 7273 peer_assoc->ipsa_state = dying->ipsa_state;
7581 7274 }
7582 7275 if (dying->ipsa_state == IPSA_STATE_DEAD)
7583 7276 peer_assoc->ipsa_hardexpiretime = 1;
7584 7277
7585 7278 mutex_exit(&dying->ipsa_lock);
7586 7279 mutex_exit(&peer_assoc->ipsa_lock);
7587 7280 IPSA_REFRELE(peer_assoc);
7588 7281 }
7589 7282 IPSA_REFRELE(dying);
7590 7283 }
7591 7284 }
7592 7285
7593 7286 /*
7594 7287 * Ensure that the IV used for CCM mode never repeats. The IV should
7595 7288 * only be updated by this function. Also check to see if the IV
7596 7289 * is about to wrap and generate a SOFT Expire. This function is only
7597 7290 * called for outgoing packets, the IV for incomming packets is taken
7598 7291 * from the wire. If the outgoing SA needs to be expired, update
7599 7292 * the matching incomming SA.
7600 7293 */
7601 7294 boolean_t
7602 7295 update_iv(uint8_t *iv_ptr, queue_t *pfkey_q, ipsa_t *assoc,
7603 7296 ipsecesp_stack_t *espstack)
7604 7297 {
7605 7298 boolean_t rc = B_TRUE;
7606 7299 isaf_t *inbound_bucket;
7607 7300 sadb_t *sp;
7608 7301 ipsa_t *pair_sa = NULL;
7609 7302 int sa_new_state = 0;
7610 7303
7611 7304 /* For non counter modes, the IV is random data. */
7612 7305 if (!(assoc->ipsa_flags & IPSA_F_COUNTERMODE)) {
7613 7306 (void) random_get_pseudo_bytes(iv_ptr, assoc->ipsa_iv_len);
7614 7307 return (rc);
7615 7308 }
7616 7309
7617 7310 mutex_enter(&assoc->ipsa_lock);
7618 7311
7619 7312 (*assoc->ipsa_iv)++;
7620 7313
7621 7314 if (*assoc->ipsa_iv == assoc->ipsa_iv_hardexpire) {
7622 7315 sa_new_state = IPSA_STATE_DEAD;
7623 7316 rc = B_FALSE;
7624 7317 } else if (*assoc->ipsa_iv == assoc->ipsa_iv_softexpire) {
7625 7318 if (assoc->ipsa_state != IPSA_STATE_DYING) {
7626 7319 /*
7627 7320 * This SA may have already been expired when its
7628 7321 * PAIR_SA expired.
7629 7322 */
7630 7323 sa_new_state = IPSA_STATE_DYING;
7631 7324 }
7632 7325 }
7633 7326 if (sa_new_state) {
7634 7327 /*
7635 7328 * If there is a state change, we need to update this SA
7636 7329 * and its "pair", we can find the bucket for the "pair" SA
7637 7330 * while holding the ipsa_t mutex, but we won't actually
7638 7331 * update anything untill the ipsa_t mutex has been released
7639 7332 * for _this_ SA.
7640 7333 */
7641 7334 assoc->ipsa_state = sa_new_state;
7642 7335 if (assoc->ipsa_addrfam == AF_INET6) {
7643 7336 sp = &espstack->esp_sadb.s_v6;
7644 7337 } else {
7645 7338 sp = &espstack->esp_sadb.s_v4;
7646 7339 }
7647 7340 inbound_bucket = INBOUND_BUCKET(sp, assoc->ipsa_otherspi);
7648 7341 sadb_expire_assoc(pfkey_q, assoc);
7649 7342 }
7650 7343 if (rc == B_TRUE)
7651 7344 bcopy(assoc->ipsa_iv, iv_ptr, assoc->ipsa_iv_len);
7652 7345
7653 7346 mutex_exit(&assoc->ipsa_lock);
7654 7347
7655 7348 if (sa_new_state) {
7656 7349 /* Find the inbound SA, need to lock hash bucket. */
7657 7350 mutex_enter(&inbound_bucket->isaf_lock);
7658 7351 pair_sa = ipsec_getassocbyspi(inbound_bucket,
7659 7352 assoc->ipsa_otherspi, assoc->ipsa_dstaddr,
7660 7353 assoc->ipsa_srcaddr, assoc->ipsa_addrfam);
7661 7354 mutex_exit(&inbound_bucket->isaf_lock);
7662 7355 if (pair_sa != NULL) {
7663 7356 mutex_enter(&pair_sa->ipsa_lock);
7664 7357 pair_sa->ipsa_state = sa_new_state;
7665 7358 mutex_exit(&pair_sa->ipsa_lock);
7666 7359 IPSA_REFRELE(pair_sa);
7667 7360 }
7668 7361 }
7669 7362
7670 7363 return (rc);
7671 7364 }
7672 7365
7673 7366 void
7674 7367 ccm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7675 7368 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7676 7369 {
7677 7370 uchar_t *nonce;
7678 7371 crypto_mechanism_t *combined_mech;
7679 7372 CK_AES_CCM_PARAMS *params;
7680 7373
7681 7374 combined_mech = (crypto_mechanism_t *)cm_mech;
7682 7375 params = (CK_AES_CCM_PARAMS *)(combined_mech + 1);
7683 7376 nonce = (uchar_t *)(params + 1);
7684 7377 params->ulMACSize = assoc->ipsa_mac_len;
7685 7378 params->ulNonceSize = assoc->ipsa_nonce_len;
7686 7379 params->ulAuthDataSize = sizeof (esph_t);
7687 7380 params->ulDataSize = data_len;
7688 7381 params->nonce = nonce;
7689 7382 params->authData = esph;
7690 7383
7691 7384 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7692 7385 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_CCM_PARAMS);
7693 7386 cm_mech->combined_mech.cm_param = (caddr_t)params;
7694 7387 /* See gcm_params_init() for comments. */
7695 7388 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7696 7389 nonce += assoc->ipsa_saltlen;
7697 7390 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7698 7391 crypto_data->cd_miscdata = NULL;
7699 7392 }
7700 7393
7701 7394 /* ARGSUSED */
7702 7395 void
7703 7396 cbc_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7704 7397 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7705 7398 {
7706 7399 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7707 7400 cm_mech->combined_mech.cm_param_len = 0;
7708 7401 cm_mech->combined_mech.cm_param = NULL;
7709 7402 crypto_data->cd_miscdata = (char *)iv_ptr;
7710 7403 }
7711 7404
7712 7405 /* ARGSUSED */
7713 7406 void
7714 7407 gcm_params_init(ipsa_t *assoc, uchar_t *esph, uint_t data_len, uchar_t *iv_ptr,
7715 7408 ipsa_cm_mech_t *cm_mech, crypto_data_t *crypto_data)
7716 7409 {
7717 7410 uchar_t *nonce;
7718 7411 crypto_mechanism_t *combined_mech;
7719 7412 CK_AES_GCM_PARAMS *params;
7720 7413
7721 7414 combined_mech = (crypto_mechanism_t *)cm_mech;
7722 7415 params = (CK_AES_GCM_PARAMS *)(combined_mech + 1);
7723 7416 nonce = (uchar_t *)(params + 1);
7724 7417
7725 7418 params->pIv = nonce;
7726 7419 params->ulIvLen = assoc->ipsa_nonce_len;
7727 7420 params->ulIvBits = SADB_8TO1(assoc->ipsa_nonce_len);
7728 7421 params->pAAD = esph;
7729 7422 params->ulAADLen = sizeof (esph_t);
7730 7423 params->ulTagBits = SADB_8TO1(assoc->ipsa_mac_len);
7731 7424
7732 7425 cm_mech->combined_mech.cm_type = assoc->ipsa_emech.cm_type;
7733 7426 cm_mech->combined_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS);
7734 7427 cm_mech->combined_mech.cm_param = (caddr_t)params;
7735 7428 /*
7736 7429 * Create the nonce, which is made up of the salt and the IV.
7737 7430 * Copy the salt from the SA and the IV from the packet.
7738 7431 * For inbound packets we copy the IV from the packet because it
7739 7432 * was set by the sending system, for outbound packets we copy the IV
7740 7433 * from the packet because the IV in the SA may be changed by another
7741 7434 * thread, the IV in the packet was created while holding a mutex.
7742 7435 */
7743 7436 bcopy(assoc->ipsa_nonce, nonce, assoc->ipsa_saltlen);
7744 7437 nonce += assoc->ipsa_saltlen;
7745 7438 bcopy(iv_ptr, nonce, assoc->ipsa_iv_len);
7746 7439 crypto_data->cd_miscdata = NULL;
7747 7440 }
|
↓ open down ↓ |
783 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX