560
561 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
562 if (mp != NULL) {
563 mp->b_datap->db_type = M_CTL;
564 mp->b_wptr += sizeof (ipsec_info_t);
565 kso = (keysock_out_t *)mp->b_rptr;
566 kso->ks_out_type = KEYSOCK_OUT;
567 kso->ks_out_len = sizeof (*kso);
568 kso->ks_out_serial = serial;
569 }
570
571 return (mp);
572 }
573
574 /*
575 * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
576 * to keysock.
577 */
578 static int
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)
581 {
582 int i, error = 0;
583 mblk_t *original_answer;
584 ipsa_t *walker;
585 sadb_msg_t *samsg;
586 time_t current;
587
588 /*
589 * For each IPSA hash bucket do:
590 * - Hold the mutex
591 * - Walk each entry, doing an sadb_dump_deliver() on it.
592 */
593 ASSERT(mp->b_cont != NULL);
594 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
595
596 original_answer = sadb_keysock_out(serial);
597 if (original_answer == NULL)
598 return (ENOMEM);
599
600 current = gethrestime_sec();
601 for (i = 0; i < num_entries; i++) {
602 mutex_enter(&fanout[i].isaf_lock);
603 for (walker = fanout[i].isaf_ipsa; walker != NULL;
604 walker = walker->ipsa_next) {
605 if (!do_peers && walker->ipsa_haspeer)
606 continue;
607 if ((active_time != 0) &&
608 ((current - walker->ipsa_lastuse) > active_time))
609 continue;
610 error = sadb_dump_deliver(pfkey_q, original_answer,
611 walker, samsg);
612 if (error == ENOBUFS) {
613 mblk_t *new_original_answer;
614
615 /* Ran out of dupb's. Try a copyb. */
616 new_original_answer = copyb(original_answer);
617 if (new_original_answer == NULL) {
618 error = ENOMEM;
619 } else {
620 freeb(original_answer);
621 original_answer = new_original_answer;
622 error = sadb_dump_deliver(pfkey_q,
623 original_answer, walker, samsg);
624 }
625 }
626 if (error != 0)
627 break; /* out of for loop. */
628 }
629 mutex_exit(&fanout[i].isaf_lock);
630 if (error != 0)
631 break; /* out of for loop. */
632 }
633
634 freeb(original_answer);
635 return (error);
636 }
637
638 /*
639 * Dump an entire SADB; outbound first, then inbound.
640 */
641
642 int
643 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
644 {
645 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
650 if (edump != NULL) {
651 active_time = edump->sadb_x_edump_timeout;
652 }
653
654 /* Dump outbound */
655 error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
656 sp->sdb_hashsize, B_TRUE, active_time);
657 if (error)
658 return (error);
659
660 /* 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);
663 }
664
665 /*
666 * Generic sadb table walker.
667 *
668 * Call "walkfn" for each SA in each bucket in "table"; pass the
669 * bucket, the entry and "cookie" to the callback function.
670 * Take care to ensure that walkfn can delete the SA without screwing
671 * up our traverse.
672 *
673 * The bucket is locked for the duration of the callback, both so that the
674 * callback can just call sadb_unlinkassoc() when it wants to delete something,
675 * and so that no new entries are added while we're walking the list.
676 */
677 static void
678 sadb_walker(isaf_t *table, uint_t numentries,
679 void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
680 void *cookie)
681 {
682 int i;
683 for (i = 0; i < numentries; i++) {
684 ipsa_t *entry, *next;
685
686 mutex_enter(&table[i].isaf_lock);
687
688 for (entry = table[i].isaf_ipsa; entry != NULL;
689 entry = next) {
690 next = entry->ipsa_next;
691 (*walkfn)(&table[i], entry, cookie);
692 }
693 mutex_exit(&table[i].isaf_lock);
694 }
695 }
696
697 /*
698 * Call me to free up a security association fanout. Use the forever
699 * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
700 * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
701 * when a module is unloaded).
702 */
703 static void
704 sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever,
705 boolean_t inbound)
706 {
707 int i;
708 isaf_t *table = *tablep;
709 ipsa_t *sa;
710
711 if (table == NULL)
712 return;
713
714 for (i = 0; i < numentries; i++) {
715 mutex_enter(&table[i].isaf_lock);
716 while ((sa = table[i].isaf_ipsa) != NULL) {
717 sadb_unlinkassoc(sa);
718 }
719 table[i].isaf_gen++;
720 mutex_exit(&table[i].isaf_lock);
721 if (forever)
722 mutex_destroy(&(table[i].isaf_lock));
723 }
724
725 if (forever) {
726 *tablep = NULL;
727 kmem_free(table, numentries * sizeof (*table));
728 }
729 }
730
731 /*
732 * Entry points to sadb_destroyer().
733 */
734 static void
735 sadb_flush(sadb_t *sp, netstack_t *ns)
736 {
737 /*
738 * Flush out each bucket, one at a time. Were it not for keysock's
739 * enforcement, there would be a subtlety where I could add on the
740 * heels of a flush. With keysock's enforcement, however, this
741 * makes ESP's job easy.
742 */
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);
745
746 /* For each acquire, destroy it; leave the bucket mutex alone. */
747 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
748 }
749
750 static void
751 sadb_destroy(sadb_t *sp, netstack_t *ns)
752 {
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);
755
756 /* For each acquire, destroy it, including the bucket mutex. */
757 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
758
759 ASSERT(sp->sdb_of == NULL);
760 ASSERT(sp->sdb_if == NULL);
761 ASSERT(sp->sdb_acq == NULL);
762 }
763
764 void
765 sadbp_flush(sadbp_t *spp, netstack_t *ns)
766 {
767 sadb_flush(&spp->s_v4, ns);
768 sadb_flush(&spp->s_v6, ns);
769 }
770
771 void
772 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
773 {
774 sadb_destroy(&spp->s_v4, ns);
1476 *
1477 * +------+----+-------------+-----------+---------------+
1478 * | base | SA | source addr | dest addr | soft lifetime |
1479 * +------+----+-------------+-----------+---------------+
1480 */
1481 static void
1482 sadb_strip(sadb_msg_t *samsg)
1483 {
1484 sadb_ext_t *ext;
1485 uint8_t *target = NULL;
1486 uint8_t *msgend;
1487 int sofar = SADB_8TO64(sizeof (*samsg));
1488 int copylen;
1489
1490 ext = (sadb_ext_t *)(samsg + 1);
1491 msgend = (uint8_t *)samsg;
1492 msgend += SADB_64TO8(samsg->sadb_msg_len);
1493 while ((uint8_t *)ext < msgend) {
1494 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1495 ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1496 ext->sadb_ext_type == SADB_X_EXT_EDUMP ||
1497 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1498 /*
1499 * Aha! I found a header to be erased.
1500 */
1501
1502 if (target != NULL) {
1503 /*
1504 * If I had a previous header to be erased,
1505 * copy over it. I can get away with just
1506 * copying backwards because the target will
1507 * always be 8 bytes behind the source.
1508 */
1509 copylen = ((uint8_t *)ext) - (target +
1510 SADB_64TO8(
1511 ((sadb_ext_t *)target)->sadb_ext_len));
1512 ovbcopy(((uint8_t *)ext - copylen), target,
1513 copylen);
1514 target += copylen;
1515 ((sadb_ext_t *)target)->sadb_ext_len =
1516 SADB_8TO64(((uint8_t *)ext) - target +
1593 * and NULL if not. BTW, that ipsa will have its refcnt appropriately held,
1594 * and the caller will release said refcnt.
1595 */
1596 void
1597 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1598 keysock_in_t *ksi, ipsa_t *ipsa)
1599 {
1600 keysock_out_t *kso;
1601 mblk_t *mp1;
1602 sadb_msg_t *newsamsg;
1603 uint8_t *oldend;
1604
1605 ASSERT((mp->b_cont != NULL) &&
1606 ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1607 ((void *)mp->b_rptr == (void *)ksi));
1608
1609 switch (samsg->sadb_msg_type) {
1610 case SADB_ADD:
1611 case SADB_UPDATE:
1612 case SADB_X_UPDATEPAIR:
1613 case SADB_X_DELPAIR_STATE:
1614 case SADB_FLUSH:
1615 case SADB_DUMP:
1616 /*
1617 * I have all of the message already. I just need to strip
1618 * out the keying material and echo the message back.
1619 *
1620 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1621 * work. When DUMP reaches here, it should only be a base
1622 * message.
1623 */
1624 justecho:
1625 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) {
1628 sadb_strip(samsg);
1629 /* Assume PF_KEY message is contiguous. */
1630 ASSERT(mp->b_cont->b_cont == NULL);
1631 oldend = mp->b_cont->b_wptr;
1632 mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1633 SADB_64TO8(samsg->sadb_msg_len);
1634 bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1635 }
1636 break;
1637 case SADB_GET:
1638 /*
1639 * Do a lot of work here, because of the ipsa I just found.
1640 * First construct the new PF_KEY message, then abandon
1641 * the old one.
1642 */
1643 mp1 = sadb_sa2msg(ipsa, samsg);
1644 if (mp1 == NULL) {
1645 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1646 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1647 return;
2350 */
2351 boolean_t
2352 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2353 {
2354 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2355 ipsa_match_fn_t mfp;
2356
2357 for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2358 if (!mfp(sq, sa))
2359 return (B_FALSE);
2360 }
2361 return (B_TRUE);
2362 }
2363
2364 /*
2365 * Walker callback function to delete sa's based on src/dst address.
2366 * Assumes that we're called with *head locked, no other locks held;
2367 * Conveniently, and not coincidentally, this is both what sadb_walker
2368 * gives us and also what sadb_unlinkassoc expects.
2369 */
2370 struct sadb_purge_state
2371 {
2372 ipsa_query_t sq;
2373 boolean_t inbnd;
2374 uint8_t sadb_sa_state;
2375 };
2376
2377 static void
2378 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2379 {
2380 struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie;
2381
2382 ASSERT(MUTEX_HELD(&head->isaf_lock));
2383
2384 mutex_enter(&entry->ipsa_lock);
2385
2386 if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2387 !sadb_match_query(&ps->sq, entry)) {
2388 mutex_exit(&entry->ipsa_lock);
2389 return;
2390 }
2391
2392 entry->ipsa_state = IPSA_STATE_DEAD;
2393 (void) sadb_torch_assoc(head, entry);
2394 }
2395
2396 /*
2397 * Common code to purge an SA with a matching src or dst address.
2398 * Don't kill larval SA's in such a purge.
2399 */
2400 int
2401 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2402 int *diagnostic, queue_t *pfkey_q)
2403 {
2404 struct sadb_purge_state ps;
2405 int error = sadb_form_query(ksi, 0,
2406 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2407 &ps.sq, diagnostic);
2408
2409 if (error != 0)
2410 return (error);
2411
2412 /*
2413 * This is simple, crude, and effective.
2414 * Unimplemented optimizations (TBD):
2415 * - we can limit how many places we search based on where we
2416 * think the SA is filed.
2417 * - if we get a dst address, we can hash based on dst addr to find
2418 * the correct bucket in the outbound table.
2419 */
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);
2424
2425 ASSERT(mp->b_cont != NULL);
2426 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2427 NULL);
2428 return (0);
2429 }
2430
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 /*
2510 * Common code to delete/get an SA.
2511 */
2512 int
2513 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2514 int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2515 {
2516 ipsa_query_t sq;
2517 ipsa_t *echo_target = NULL;
2518 ipsap_t ipsapp;
2519 uint_t error = 0;
2520
2521 if (sadb_msg_type == SADB_X_DELPAIR_STATE)
2522 return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q));
2523
2524 sq.spp = spp; /* XXX param */
2525 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2526 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2527 &sq, diagnostic);
2528 if (error != 0)
2529 return (error);
2530
2531 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2532 if (error != 0) {
2533 return (error);
2534 }
2535
2536 echo_target = ipsapp.ipsap_sa_ptr;
2537 if (echo_target == NULL)
2538 echo_target = ipsapp.ipsap_psa_ptr;
2539
2540 if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2541 /*
2542 * Bucket locks will be required if SA is actually unlinked.
2543 * get_ipsa_pair() returns valid hash bucket pointers even
3026 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
3027 idst->sin_port, dstext->sadb_address_proto,
3028 idstext->sadb_address_proto);
3029 } else {
3030 /* ... and outer-ports for Transport Mode. */
3031 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
3032 dst->sin_port, dstext->sadb_address_proto, 0);
3033 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
3034 dst->sin_port, dstext->sadb_address_proto, 0);
3035 }
3036 if (newbie->ipsa_unique_mask != (uint64_t)0)
3037 newbie->ipsa_flags |= IPSA_F_UNIQUE;
3038
3039 sadb_nat_calculations(newbie,
3040 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
3041 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
3042 src_addr_ptr, dst_addr_ptr);
3043
3044 newbie->ipsa_type = samsg->sadb_msg_satype;
3045
3046 ASSERT((assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
3047 (assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE));
3048 newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
3049 newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
3050
3051 newbie->ipsa_flags |= assoc->sadb_sa_flags;
3052 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
3053 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
3054 mutex_exit(&newbie->ipsa_lock);
3055 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
3056 error = EINVAL;
3057 goto error;
3058 }
3059 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
3060 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
3061 mutex_exit(&newbie->ipsa_lock);
3062 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
3063 error = EINVAL;
3064 goto error;
3065 }
3066 if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
3067 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3934 return (B_TRUE);
3935 }
3936 return (B_FALSE);
3937 }
3938
3939 /*
3940 * Return "assoc" if haspeer is true and I send an expire. This allows
3941 * the consumers' aging functions to tidy up an expired SA's peer.
3942 */
3943 static ipsa_t *
3944 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3945 time_t current, int reap_delay, boolean_t inbound)
3946 {
3947 ipsa_t *retval = NULL;
3948 boolean_t dropped_mutex = B_FALSE;
3949
3950 ASSERT(MUTEX_HELD(&head->isaf_lock));
3951
3952 mutex_enter(&assoc->ipsa_lock);
3953
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)) {
3959 assoc->ipsa_state = IPSA_STATE_DEAD;
3960 return (sadb_torch_assoc(head, assoc));
3961 }
3962
3963 /*
3964 * Check lifetimes. Fortunately, SA setup is done
3965 * such that there are only two times to look at,
3966 * softexpiretime, and hardexpiretime.
3967 *
3968 * Check hard first.
3969 */
3970
3971 if (assoc->ipsa_hardexpiretime != 0 &&
3972 assoc->ipsa_hardexpiretime <= current) {
3973 if (assoc->ipsa_state == IPSA_STATE_DEAD)
3974 return (sadb_torch_assoc(head, assoc));
3975
3976 /*
3977 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3978 */
4003 assoc->ipsa_state = IPSA_STATE_DYING;
4004 if (assoc->ipsa_haspeer) {
4005 /*
4006 * If the SA has a peer, update the peer's state
4007 * on SOFT_EXPIRE, this is mostly to prevent two
4008 * expire messages from effectively the same SA.
4009 *
4010 * Don't care about paired SA's, then can (and should)
4011 * be able to soft expire at different times.
4012 *
4013 * If I return assoc, I have to bump up its
4014 * reference count to keep with the ipsa_t reference
4015 * count semantics.
4016 */
4017 IPSA_REFHOLD(assoc);
4018 retval = assoc;
4019 }
4020 sadb_expire_assoc(pfkey_q, assoc);
4021 } else if (assoc->ipsa_idletime != 0 &&
4022 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 */
4030 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
4031 sadb_expire_assoc(pfkey_q, assoc);
4032 }
4033 } else {
4034 /* Check idle time activities. */
4035 dropped_mutex = sadb_idle_activities(assoc,
4036 current - assoc->ipsa_lastuse, inbound);
4037 }
4038
4039 if (!dropped_mutex)
4040 mutex_exit(&assoc->ipsa_lock);
4041 return (retval);
4042 }
4043
4044 /*
4045 * Called by a consumer protocol to do ther dirty work of reaping dead
4046 * Security Associations.
4047 *
4048 * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
4049 * SA's that are already marked DEAD, so expired SA's are only reaped
4304 assoc->ipsa_idleexpiretime =
4305 current + idle->sadb_lifetime_addtime;
4306 assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4307 }
4308 if (assoc->ipsa_idleuselt != 0) {
4309 if (assoc->ipsa_idletime != 0) {
4310 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4311 assoc->ipsa_idleuselt);
4312 assoc->ipsa_idleexpiretime =
4313 current + assoc->ipsa_idletime;
4314 } else {
4315 assoc->ipsa_idleexpiretime =
4316 current + assoc->ipsa_idleuselt;
4317 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4318 }
4319 }
4320 }
4321 mutex_exit(&assoc->ipsa_lock);
4322 }
4323
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 /*
4380 * Check a proposed KMC update for sanity.
4381 */
4382 static int
4383 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4384 {
4385 uint32_t kmp = sq->kmp;
4386 uint32_t kmc = sq->kmc;
4387
4388 if (sa == NULL)
4389 return (0);
4390
4391 if (sa->ipsa_state == IPSA_STATE_DEAD)
4392 return (ESRCH); /* DEAD == Not there, in this case. */
4393
4394 if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
4395 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4396 return (EINVAL);
4397 }
4398
4407 /*
4408 * Actually update the KMC info.
4409 */
4410 static void
4411 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4412 {
4413 uint32_t kmp = sq->kmp;
4414 uint32_t kmc = sq->kmc;
4415
4416 if (kmp != 0)
4417 sa->ipsa_kmp = kmp;
4418 if (kmc != 0)
4419 sa->ipsa_kmc = kmc;
4420 }
4421
4422 /*
4423 * Common code to update an SA.
4424 */
4425
4426 int
4427 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi, mblk_t **ipkt_lst,
4428 sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4429 int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4430 netstack_t *ns, uint8_t sadb_msg_type)
4431 {
4432 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4433 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 sadb_lifetime_t *soft =
4437 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4438 sadb_lifetime_t *hard =
4439 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4440 sadb_lifetime_t *idle =
4441 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4442 sadb_x_pair_t *pair_ext =
4443 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4444 ipsa_t *echo_target = NULL;
4445 ipsap_t ipsapp;
4446 ipsa_query_t sq;
4447 time_t current = gethrestime_sec();
4448
4449 sq.spp = spp; /* XXX param */
4450 int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4451 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
4452 &sq, diagnostic);
4453
4454 if (error != 0)
4455 return (error);
4456
4457 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4458 if (error != 0)
4459 return (error);
4460
4461 if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4462 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4463 /*
4464 * REFRELE the target and let the add_sa_func()
4465 * deal with updating a larval SA.
4466 */
4467 destroy_ipsa_pair(&ipsapp);
4468 return (add_sa_func(mp, ksi, diagnostic, ns));
4469 }
4470 }
4471
4472 /*
4473 * At this point we have an UPDATE to a MATURE SA. There should
4474 * not be any keying material present.
4475 */
4476 if (akey != NULL) {
4477 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4478 error = EINVAL;
4479 goto bail;
4480 }
4481 if (ekey != NULL) {
4482 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4483 error = EINVAL;
4484 goto bail;
4485 }
4486
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 /*
4532 * Reality checks for updates of active associations.
4533 * Sundry first-pass UPDATE-specific reality checks.
4534 * Have to do the checks here, because it's after the add_sa code.
4535 * XXX STATS : logging/stats here?
4536 */
4537
4538 if (!((sq.assoc->sadb_sa_state == SADB_SASTATE_MATURE) ||
4539 (sq.assoc->sadb_sa_state == SADB_X_SASTATE_ACTIVE_ELSEWHERE))) {
4540 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4541 error = EINVAL;
4542 goto bail;
4543 }
4544 if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4545 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4546 error = EINVAL;
4547 goto bail;
4548 }
4549 if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4550 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4551 error = EOPNOTSUPP;
4552 goto bail;
4553 }
4554
4555 if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4556 error = EINVAL;
4557 goto bail;
4558 }
4559
4560 if ((*diagnostic = sadb_labelchk(ksi)) != 0)
4561 return (EINVAL);
4562
4563 error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4564 if (error != 0)
4565 goto bail;
4566
4567 error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4568 if (error != 0)
4569 goto bail;
4570
4571
4572 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 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4589 idle, B_TRUE);
4590 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 }
4621
4622 if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4623 if (ipsapp.ipsap_psa_ptr != NULL) {
4624 sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4625 idle, B_FALSE);
4626 sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4627 } else {
4628 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4629 error = ESRCH;
4630 goto bail;
4631 }
4632 }
4633
4634 if (pair_ext != NULL)
4635 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4636
4637 if (error == 0)
4638 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4639 ksi, echo_target);
4640 bail:
5804 /* XXXMLS Insert sensitivity information here. */
5805
5806 if (cur != NULL)
5807 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
5808 else
5809 mutex_exit(&ipss->ipsec_alg_lock);
5810
5811 return (pfkeymp);
5812 }
5813
5814 /*
5815 * Given an SADB_GETSPI message, find an appropriately ranged SA and
5816 * allocate an SA. If there are message improprieties, return (ipsa_t *)-1.
5817 * If there was a memory allocation error, return NULL. (Assume NULL !=
5818 * (ipsa_t *)-1).
5819 *
5820 * master_spi is passed in host order.
5821 */
5822 ipsa_t *
5823 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5824 netstack_t *ns, uint_t sa_type)
5825 {
5826 sadb_address_t *src =
5827 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5828 *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5829 sadb_spirange_t *range =
5830 (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5831 struct sockaddr_in *ssa, *dsa;
5832 struct sockaddr_in6 *ssa6, *dsa6;
5833 uint32_t *srcaddr, *dstaddr;
5834 sa_family_t af;
5835 uint32_t add, min, max;
5836
5837 if (src == NULL) {
5838 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
5839 return ((ipsa_t *)-1);
5840 }
5841 if (dst == NULL) {
5842 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
5843 return ((ipsa_t *)-1);
5844 }
6887 return (npkt);
6888 }
6889
6890 /*
6891 * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
6892 * previous value.
6893 */
6894 mblk_t *
6895 sadb_clear_lpkt(ipsa_t *ipsa)
6896 {
6897 mblk_t *opkt;
6898
6899 mutex_enter(&ipsa->ipsa_lock);
6900 opkt = ipsa->ipsa_lpkt;
6901 ipsa->ipsa_lpkt = NULL;
6902 mutex_exit(&ipsa->ipsa_lock);
6903 return (opkt);
6904 }
6905
6906 /*
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 * Walker callback used by sadb_alg_update() to free/create crypto
6956 * context template when a crypto software provider is removed or
6957 * added.
6958 */
6959
6960 struct sadb_update_alg_state {
6961 ipsec_algtype_t alg_type;
6962 uint8_t alg_id;
6963 boolean_t is_added;
6964 boolean_t async_auth;
6965 boolean_t async_encr;
6966 };
6967
6968 static void
6969 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
6970 {
6971 struct sadb_update_alg_state *update_state =
6972 (struct sadb_update_alg_state *)cookie;
6973 crypto_ctx_template_t *ctx_tmpl = NULL;
6974
|
560
561 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
562 if (mp != NULL) {
563 mp->b_datap->db_type = M_CTL;
564 mp->b_wptr += sizeof (ipsec_info_t);
565 kso = (keysock_out_t *)mp->b_rptr;
566 kso->ks_out_type = KEYSOCK_OUT;
567 kso->ks_out_len = sizeof (*kso);
568 kso->ks_out_serial = serial;
569 }
570
571 return (mp);
572 }
573
574 /*
575 * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts
576 * to keysock.
577 */
578 static int
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)
581 {
582 int i, error = 0;
583 mblk_t *original_answer;
584 ipsa_t *walker;
585 sadb_msg_t *samsg;
586
587 /*
588 * For each IPSA hash bucket do:
589 * - Hold the mutex
590 * - Walk each entry, doing an sadb_dump_deliver() on it.
591 */
592 ASSERT(mp->b_cont != NULL);
593 samsg = (sadb_msg_t *)mp->b_cont->b_rptr;
594
595 original_answer = sadb_keysock_out(serial);
596 if (original_answer == NULL)
597 return (ENOMEM);
598
599 for (i = 0; i < num_entries; i++) {
600 mutex_enter(&fanout[i].isaf_lock);
601 for (walker = fanout[i].isaf_ipsa; walker != NULL;
602 walker = walker->ipsa_next) {
603 if (!do_peers && walker->ipsa_haspeer)
604 continue;
605 error = sadb_dump_deliver(pfkey_q, original_answer,
606 walker, samsg);
607 if (error == ENOBUFS) {
608 mblk_t *new_original_answer;
609
610 /* Ran out of dupb's. Try a copyb. */
611 new_original_answer = copyb(original_answer);
612 if (new_original_answer == NULL) {
613 error = ENOMEM;
614 } else {
615 freeb(original_answer);
616 original_answer = new_original_answer;
617 error = sadb_dump_deliver(pfkey_q,
618 original_answer, walker, samsg);
619 }
620 }
621 if (error != 0)
622 break; /* out of for loop. */
623 }
624 mutex_exit(&fanout[i].isaf_lock);
625 if (error != 0)
626 break; /* out of for loop. */
627 }
628
629 freeb(original_answer);
630 return (error);
631 }
632
633 /*
634 * Dump an entire SADB; outbound first, then inbound.
635 */
636
637 int
638 sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp)
639 {
640 int error;
641
642 /* Dump outbound */
643 error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of,
644 sp->sdb_hashsize, B_TRUE);
645 if (error)
646 return (error);
647
648 /* Dump inbound */
649 return (sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if,
650 sp->sdb_hashsize, B_FALSE));
651 }
652
653 /*
654 * Generic sadb table walker.
655 *
656 * Call "walkfn" for each SA in each bucket in "table"; pass the
657 * bucket, the entry and "cookie" to the callback function.
658 * Take care to ensure that walkfn can delete the SA without screwing
659 * up our traverse.
660 *
661 * The bucket is locked for the duration of the callback, both so that the
662 * callback can just call sadb_unlinkassoc() when it wants to delete something,
663 * and so that no new entries are added while we're walking the list.
664 */
665 static void
666 sadb_walker(isaf_t *table, uint_t numentries,
667 void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie),
668 void *cookie)
669 {
670 int i;
671 for (i = 0; i < numentries; i++) {
672 ipsa_t *entry, *next;
673
674 mutex_enter(&table[i].isaf_lock);
675
676 for (entry = table[i].isaf_ipsa; entry != NULL;
677 entry = next) {
678 next = entry->ipsa_next;
679 (*walkfn)(&table[i], entry, cookie);
680 }
681 mutex_exit(&table[i].isaf_lock);
682 }
683 }
684
685 /*
686 * Call me to free up a security association fanout. Use the forever
687 * variable to indicate freeing up the SAs (forever == B_FALSE, e.g.
688 * an SADB_FLUSH message), or destroying everything (forever == B_TRUE,
689 * when a netstack is destroyed or a module is unloaded).
690 */
691 static void
692 sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever)
693 {
694 int i;
695 isaf_t *table = *tablep;
696 ipsa_t *sa;
697
698 if (table == NULL)
699 return;
700
701 for (i = 0; i < numentries; i++) {
702 mutex_enter(&table[i].isaf_lock);
703 while ((sa = table[i].isaf_ipsa) != NULL) {
704 sadb_unlinkassoc(sa);
705 }
706 table[i].isaf_gen++;
707 mutex_exit(&table[i].isaf_lock);
708 if (forever)
709 mutex_destroy(&(table[i].isaf_lock));
710 }
711
712 if (forever) {
713 *tablep = NULL;
714 kmem_free(table, numentries * sizeof (*table));
715 }
716 }
717
718 /*
719 * Entry points to sadb_destroyer().
720 */
721 static void
722 sadb_flush(sadb_t *sp, netstack_t *ns)
723 {
724 /*
725 * Flush out each bucket, one at a time. Were it not for keysock's
726 * enforcement, there would be a subtlety where I could add on the
727 * heels of a flush. With keysock's enforcement, however, this
728 * makes ESP's job easy.
729 */
730 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE);
731 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE);
732
733 /* For each acquire, destroy it; leave the bucket mutex alone. */
734 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns);
735 }
736
737 static void
738 sadb_destroy(sadb_t *sp, netstack_t *ns)
739 {
740 sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE);
741 sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE);
742
743 /* For each acquire, destroy it, including the bucket mutex. */
744 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns);
745
746 ASSERT(sp->sdb_of == NULL);
747 ASSERT(sp->sdb_if == NULL);
748 ASSERT(sp->sdb_acq == NULL);
749 }
750
751 void
752 sadbp_flush(sadbp_t *spp, netstack_t *ns)
753 {
754 sadb_flush(&spp->s_v4, ns);
755 sadb_flush(&spp->s_v6, ns);
756 }
757
758 void
759 sadbp_destroy(sadbp_t *spp, netstack_t *ns)
760 {
761 sadb_destroy(&spp->s_v4, ns);
1463 *
1464 * +------+----+-------------+-----------+---------------+
1465 * | base | SA | source addr | dest addr | soft lifetime |
1466 * +------+----+-------------+-----------+---------------+
1467 */
1468 static void
1469 sadb_strip(sadb_msg_t *samsg)
1470 {
1471 sadb_ext_t *ext;
1472 uint8_t *target = NULL;
1473 uint8_t *msgend;
1474 int sofar = SADB_8TO64(sizeof (*samsg));
1475 int copylen;
1476
1477 ext = (sadb_ext_t *)(samsg + 1);
1478 msgend = (uint8_t *)samsg;
1479 msgend += SADB_64TO8(samsg->sadb_msg_len);
1480 while ((uint8_t *)ext < msgend) {
1481 if (ext->sadb_ext_type == SADB_EXT_RESERVED ||
1482 ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
1483 ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
1484 /*
1485 * Aha! I found a header to be erased.
1486 */
1487
1488 if (target != NULL) {
1489 /*
1490 * If I had a previous header to be erased,
1491 * copy over it. I can get away with just
1492 * copying backwards because the target will
1493 * always be 8 bytes behind the source.
1494 */
1495 copylen = ((uint8_t *)ext) - (target +
1496 SADB_64TO8(
1497 ((sadb_ext_t *)target)->sadb_ext_len));
1498 ovbcopy(((uint8_t *)ext - copylen), target,
1499 copylen);
1500 target += copylen;
1501 ((sadb_ext_t *)target)->sadb_ext_len =
1502 SADB_8TO64(((uint8_t *)ext) - target +
1579 * and NULL if not. BTW, that ipsa will have its refcnt appropriately held,
1580 * and the caller will release said refcnt.
1581 */
1582 void
1583 sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg,
1584 keysock_in_t *ksi, ipsa_t *ipsa)
1585 {
1586 keysock_out_t *kso;
1587 mblk_t *mp1;
1588 sadb_msg_t *newsamsg;
1589 uint8_t *oldend;
1590
1591 ASSERT((mp->b_cont != NULL) &&
1592 ((void *)samsg == (void *)mp->b_cont->b_rptr) &&
1593 ((void *)mp->b_rptr == (void *)ksi));
1594
1595 switch (samsg->sadb_msg_type) {
1596 case SADB_ADD:
1597 case SADB_UPDATE:
1598 case SADB_X_UPDATEPAIR:
1599 case SADB_FLUSH:
1600 case SADB_DUMP:
1601 /*
1602 * I have all of the message already. I just need to strip
1603 * out the keying material and echo the message back.
1604 *
1605 * NOTE: for SADB_DUMP, the function sadb_dump() did the
1606 * work. When DUMP reaches here, it should only be a base
1607 * message.
1608 */
1609 justecho:
1610 ASSERT(samsg->sadb_msg_type != SADB_DUMP ||
1611 samsg->sadb_msg_len == SADB_8TO64(sizeof (sadb_msg_t)));
1612 if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL ||
1613 ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL) {
1614 sadb_strip(samsg);
1615 /* Assume PF_KEY message is contiguous. */
1616 ASSERT(mp->b_cont->b_cont == NULL);
1617 oldend = mp->b_cont->b_wptr;
1618 mp->b_cont->b_wptr = mp->b_cont->b_rptr +
1619 SADB_64TO8(samsg->sadb_msg_len);
1620 bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr);
1621 }
1622 break;
1623 case SADB_GET:
1624 /*
1625 * Do a lot of work here, because of the ipsa I just found.
1626 * First construct the new PF_KEY message, then abandon
1627 * the old one.
1628 */
1629 mp1 = sadb_sa2msg(ipsa, samsg);
1630 if (mp1 == NULL) {
1631 sadb_pfkey_error(pfkey_q, mp, ENOMEM,
1632 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial);
1633 return;
2336 */
2337 boolean_t
2338 sadb_match_query(ipsa_query_t *sq, ipsa_t *sa)
2339 {
2340 ipsa_match_fn_t *mfpp = &(sq->matchers[0]);
2341 ipsa_match_fn_t mfp;
2342
2343 for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) {
2344 if (!mfp(sq, sa))
2345 return (B_FALSE);
2346 }
2347 return (B_TRUE);
2348 }
2349
2350 /*
2351 * Walker callback function to delete sa's based on src/dst address.
2352 * Assumes that we're called with *head locked, no other locks held;
2353 * Conveniently, and not coincidentally, this is both what sadb_walker
2354 * gives us and also what sadb_unlinkassoc expects.
2355 */
2356 static void
2357 sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie)
2358 {
2359 ipsa_query_t *query = (ipsa_query_t *)cookie;
2360
2361 ASSERT(MUTEX_HELD(&head->isaf_lock));
2362
2363 mutex_enter(&entry->ipsa_lock);
2364
2365 if (entry->ipsa_state == IPSA_STATE_LARVAL ||
2366 !sadb_match_query(query, entry)) {
2367 mutex_exit(&entry->ipsa_lock);
2368 return;
2369 }
2370
2371 entry->ipsa_state = IPSA_STATE_DEAD;
2372 (void) sadb_torch_assoc(head, entry);
2373 }
2374
2375 /*
2376 * Common code to purge an SA with a matching src or dst address.
2377 * Don't kill larval SA's in such a purge.
2378 */
2379 int
2380 sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp,
2381 int *diagnostic, queue_t *pfkey_q)
2382 {
2383 ipsa_query_t query;
2384 int error = sadb_form_query(ksi, 0,
2385 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC,
2386 &query, diagnostic);
2387
2388 if (error != 0)
2389 return (error);
2390
2391 /*
2392 * This is simple, crude, and effective.
2393 * Unimplemented optimizations (TBD):
2394 * - we can limit how many places we search based on where we
2395 * think the SA is filed.
2396 * - if we get a dst address, we can hash based on dst addr to find
2397 * the correct bucket in the outbound table.
2398 */
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);
2401
2402 ASSERT(mp->b_cont != NULL);
2403 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
2404 NULL);
2405 return (0);
2406 }
2407
2408 /*
2409 * Common code to delete/get an SA.
2410 */
2411 int
2412 sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp,
2413 int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type)
2414 {
2415 ipsa_query_t sq;
2416 ipsa_t *echo_target = NULL;
2417 ipsap_t ipsapp;
2418 uint_t error = 0;
2419
2420 sq.spp = spp; /* XXX param */
2421 error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA,
2422 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
2423 &sq, diagnostic);
2424 if (error != 0)
2425 return (error);
2426
2427 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
2428 if (error != 0) {
2429 return (error);
2430 }
2431
2432 echo_target = ipsapp.ipsap_sa_ptr;
2433 if (echo_target == NULL)
2434 echo_target = ipsapp.ipsap_psa_ptr;
2435
2436 if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) {
2437 /*
2438 * Bucket locks will be required if SA is actually unlinked.
2439 * get_ipsa_pair() returns valid hash bucket pointers even
2922 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(isrc->sin_port,
2923 idst->sin_port, dstext->sadb_address_proto,
2924 idstext->sadb_address_proto);
2925 } else {
2926 /* ... and outer-ports for Transport Mode. */
2927 newbie->ipsa_unique_id = SA_UNIQUE_ID(src->sin_port,
2928 dst->sin_port, dstext->sadb_address_proto, 0);
2929 newbie->ipsa_unique_mask = SA_UNIQUE_MASK(src->sin_port,
2930 dst->sin_port, dstext->sadb_address_proto, 0);
2931 }
2932 if (newbie->ipsa_unique_mask != (uint64_t)0)
2933 newbie->ipsa_flags |= IPSA_F_UNIQUE;
2934
2935 sadb_nat_calculations(newbie,
2936 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC],
2937 (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM],
2938 src_addr_ptr, dst_addr_ptr);
2939
2940 newbie->ipsa_type = samsg->sadb_msg_satype;
2941
2942 ASSERT(assoc->sadb_sa_state == SADB_SASTATE_MATURE);
2943 newbie->ipsa_auth_alg = assoc->sadb_sa_auth;
2944 newbie->ipsa_encr_alg = assoc->sadb_sa_encrypt;
2945
2946 newbie->ipsa_flags |= assoc->sadb_sa_flags;
2947 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_LOC &&
2948 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_LOC] == NULL) {
2949 mutex_exit(&newbie->ipsa_lock);
2950 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_LOC;
2951 error = EINVAL;
2952 goto error;
2953 }
2954 if (newbie->ipsa_flags & SADB_X_SAFLAGS_NATT_REM &&
2955 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_NATT_REM] == NULL) {
2956 mutex_exit(&newbie->ipsa_lock);
2957 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_NATT_REM;
2958 error = EINVAL;
2959 goto error;
2960 }
2961 if (newbie->ipsa_flags & SADB_X_SAFLAGS_TUNNEL &&
2962 ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL) {
3829 return (B_TRUE);
3830 }
3831 return (B_FALSE);
3832 }
3833
3834 /*
3835 * Return "assoc" if haspeer is true and I send an expire. This allows
3836 * the consumers' aging functions to tidy up an expired SA's peer.
3837 */
3838 static ipsa_t *
3839 sadb_age_assoc(isaf_t *head, queue_t *pfkey_q, ipsa_t *assoc,
3840 time_t current, int reap_delay, boolean_t inbound)
3841 {
3842 ipsa_t *retval = NULL;
3843 boolean_t dropped_mutex = B_FALSE;
3844
3845 ASSERT(MUTEX_HELD(&head->isaf_lock));
3846
3847 mutex_enter(&assoc->ipsa_lock);
3848
3849 /*
3850 * Be aggressive in reaping expired LARVAL SAs.
3851 */
3852 if (assoc->ipsa_state == IPSA_STATE_LARVAL &&
3853 assoc->ipsa_hardexpiretime <= current) {
3854 assoc->ipsa_state = IPSA_STATE_DEAD;
3855 return (sadb_torch_assoc(head, assoc));
3856 }
3857
3858 /*
3859 * Check lifetimes. Fortunately, SA setup is done
3860 * such that there are only two times to look at,
3861 * softexpiretime, and hardexpiretime.
3862 *
3863 * Check hard first.
3864 */
3865
3866 if (assoc->ipsa_hardexpiretime != 0 &&
3867 assoc->ipsa_hardexpiretime <= current) {
3868 if (assoc->ipsa_state == IPSA_STATE_DEAD)
3869 return (sadb_torch_assoc(head, assoc));
3870
3871 /*
3872 * Send SADB_EXPIRE with hard lifetime, delay for unlinking.
3873 */
3898 assoc->ipsa_state = IPSA_STATE_DYING;
3899 if (assoc->ipsa_haspeer) {
3900 /*
3901 * If the SA has a peer, update the peer's state
3902 * on SOFT_EXPIRE, this is mostly to prevent two
3903 * expire messages from effectively the same SA.
3904 *
3905 * Don't care about paired SA's, then can (and should)
3906 * be able to soft expire at different times.
3907 *
3908 * If I return assoc, I have to bump up its
3909 * reference count to keep with the ipsa_t reference
3910 * count semantics.
3911 */
3912 IPSA_REFHOLD(assoc);
3913 retval = assoc;
3914 }
3915 sadb_expire_assoc(pfkey_q, assoc);
3916 } else if (assoc->ipsa_idletime != 0 &&
3917 assoc->ipsa_idleexpiretime <= current) {
3918 /* Only issue an IDLE expiration if we're in mature state. */
3919 if (assoc->ipsa_state == IPSA_STATE_MATURE) {
3920 sadb_expire_assoc(pfkey_q, assoc);
3921 }
3922 } else {
3923 /* Check idle time activities. */
3924 dropped_mutex = sadb_idle_activities(assoc,
3925 current - assoc->ipsa_lastuse, inbound);
3926 }
3927
3928 if (!dropped_mutex)
3929 mutex_exit(&assoc->ipsa_lock);
3930 return (retval);
3931 }
3932
3933 /*
3934 * Called by a consumer protocol to do ther dirty work of reaping dead
3935 * Security Associations.
3936 *
3937 * NOTE: sadb_age_assoc() marks expired SA's as DEAD but only removed
3938 * SA's that are already marked DEAD, so expired SA's are only reaped
4193 assoc->ipsa_idleexpiretime =
4194 current + idle->sadb_lifetime_addtime;
4195 assoc->ipsa_idletime = idle->sadb_lifetime_addtime;
4196 }
4197 if (assoc->ipsa_idleuselt != 0) {
4198 if (assoc->ipsa_idletime != 0) {
4199 assoc->ipsa_idletime = min(assoc->ipsa_idletime,
4200 assoc->ipsa_idleuselt);
4201 assoc->ipsa_idleexpiretime =
4202 current + assoc->ipsa_idletime;
4203 } else {
4204 assoc->ipsa_idleexpiretime =
4205 current + assoc->ipsa_idleuselt;
4206 assoc->ipsa_idletime = assoc->ipsa_idleuselt;
4207 }
4208 }
4209 }
4210 mutex_exit(&assoc->ipsa_lock);
4211 }
4212
4213 /*
4214 * Check a proposed KMC update for sanity.
4215 */
4216 static int
4217 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
4218 {
4219 uint32_t kmp = sq->kmp;
4220 uint32_t kmc = sq->kmc;
4221
4222 if (sa == NULL)
4223 return (0);
4224
4225 if (sa->ipsa_state == IPSA_STATE_DEAD)
4226 return (ESRCH); /* DEAD == Not there, in this case. */
4227
4228 if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
4229 *diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
4230 return (EINVAL);
4231 }
4232
4241 /*
4242 * Actually update the KMC info.
4243 */
4244 static void
4245 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
4246 {
4247 uint32_t kmp = sq->kmp;
4248 uint32_t kmc = sq->kmc;
4249
4250 if (kmp != 0)
4251 sa->ipsa_kmp = kmp;
4252 if (kmc != 0)
4253 sa->ipsa_kmc = kmc;
4254 }
4255
4256 /*
4257 * Common code to update an SA.
4258 */
4259
4260 int
4261 sadb_update_sa(mblk_t *mp, keysock_in_t *ksi,
4262 sadbp_t *spp, int *diagnostic, queue_t *pfkey_q,
4263 int (*add_sa_func)(mblk_t *, keysock_in_t *, int *, netstack_t *),
4264 netstack_t *ns, uint8_t sadb_msg_type)
4265 {
4266 sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH];
4267 sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT];
4268 sadb_lifetime_t *soft =
4269 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_SOFT];
4270 sadb_lifetime_t *hard =
4271 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_EXT_LIFETIME_HARD];
4272 sadb_lifetime_t *idle =
4273 (sadb_lifetime_t *)ksi->ks_in_extv[SADB_X_EXT_LIFETIME_IDLE];
4274 sadb_x_pair_t *pair_ext =
4275 (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR];
4276 ipsa_t *echo_target = NULL;
4277 ipsap_t ipsapp;
4278 ipsa_query_t sq;
4279
4280 sq.spp = spp; /* XXX param */
4281 int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
4282 IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
4283 &sq, diagnostic);
4284
4285 if (error != 0)
4286 return (error);
4287
4288 error = get_ipsa_pair(&sq, &ipsapp, diagnostic);
4289 if (error != 0)
4290 return (error);
4291
4292 if (ipsapp.ipsap_psa_ptr == NULL && ipsapp.ipsap_sa_ptr != NULL) {
4293 if (ipsapp.ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) {
4294 /*
4295 * REFRELE the target and let the add_sa_func()
4296 * deal with updating a larval SA.
4297 */
4298 destroy_ipsa_pair(&ipsapp);
4299 return (add_sa_func(mp, ksi, diagnostic, ns));
4300 }
4301 }
4302
4303 /*
4304 * At this point we have an UPDATE to a MATURE SA. There should
4305 * not be any keying material present.
4306 */
4307 if (akey != NULL) {
4308 *diagnostic = SADB_X_DIAGNOSTIC_AKEY_PRESENT;
4309 error = EINVAL;
4310 goto bail;
4311 }
4312 if (ekey != NULL) {
4313 *diagnostic = SADB_X_DIAGNOSTIC_EKEY_PRESENT;
4314 error = EINVAL;
4315 goto bail;
4316 }
4317
4318 /*
4319 * Reality checks for updates of active associations.
4320 * Sundry first-pass UPDATE-specific reality checks.
4321 * Have to do the checks here, because it's after the add_sa code.
4322 * XXX STATS : logging/stats here?
4323 */
4324
4325 if (sq.assoc->sadb_sa_state != SADB_SASTATE_MATURE) {
4326 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
4327 error = EINVAL;
4328 goto bail;
4329 }
4330 if (sq.assoc->sadb_sa_flags & ~spp->s_updateflags) {
4331 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
4332 error = EINVAL;
4333 goto bail;
4334 }
4335 if (ksi->ks_in_extv[SADB_EXT_LIFETIME_CURRENT] != NULL) {
4336 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_LIFETIME;
4337 error = EOPNOTSUPP;
4338 goto bail;
4339 }
4340
4341 if ((*diagnostic = sadb_hardsoftchk(hard, soft, idle)) != 0) {
4342 error = EINVAL;
4343 goto bail;
4344 }
4345
4346 if ((*diagnostic = sadb_labelchk(ksi)) != 0)
4347 return (EINVAL);
4348
4349 error = sadb_check_kmc(&sq, ipsapp.ipsap_sa_ptr, diagnostic);
4350 if (error != 0)
4351 goto bail;
4352
4353 error = sadb_check_kmc(&sq, ipsapp.ipsap_psa_ptr, diagnostic);
4354 if (error != 0)
4355 goto bail;
4356
4357 if (ipsapp.ipsap_sa_ptr != NULL) {
4358 sadb_update_lifetimes(ipsapp.ipsap_sa_ptr, hard, soft,
4359 idle, B_TRUE);
4360 sadb_update_kmc(&sq, ipsapp.ipsap_sa_ptr);
4361 }
4362
4363 if (sadb_msg_type == SADB_X_UPDATEPAIR) {
4364 if (ipsapp.ipsap_psa_ptr != NULL) {
4365 sadb_update_lifetimes(ipsapp.ipsap_psa_ptr, hard, soft,
4366 idle, B_FALSE);
4367 sadb_update_kmc(&sq, ipsapp.ipsap_psa_ptr);
4368 } else {
4369 *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND;
4370 error = ESRCH;
4371 goto bail;
4372 }
4373 }
4374
4375 if (pair_ext != NULL)
4376 error = update_pairing(&ipsapp, &sq, ksi, diagnostic);
4377
4378 if (error == 0)
4379 sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr,
4380 ksi, echo_target);
4381 bail:
5545 /* XXXMLS Insert sensitivity information here. */
5546
5547 if (cur != NULL)
5548 samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
5549 else
5550 mutex_exit(&ipss->ipsec_alg_lock);
5551
5552 return (pfkeymp);
5553 }
5554
5555 /*
5556 * Given an SADB_GETSPI message, find an appropriately ranged SA and
5557 * allocate an SA. If there are message improprieties, return (ipsa_t *)-1.
5558 * If there was a memory allocation error, return NULL. (Assume NULL !=
5559 * (ipsa_t *)-1).
5560 *
5561 * master_spi is passed in host order.
5562 */
5563 ipsa_t *
5564 sadb_getspi(keysock_in_t *ksi, uint32_t master_spi, int *diagnostic,
5565 netstack_t *ns)
5566 {
5567 sadb_address_t *src =
5568 (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC],
5569 *dst = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
5570 sadb_spirange_t *range =
5571 (sadb_spirange_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE];
5572 struct sockaddr_in *ssa, *dsa;
5573 struct sockaddr_in6 *ssa6, *dsa6;
5574 uint32_t *srcaddr, *dstaddr;
5575 sa_family_t af;
5576 uint32_t add, min, max;
5577
5578 if (src == NULL) {
5579 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC;
5580 return ((ipsa_t *)-1);
5581 }
5582 if (dst == NULL) {
5583 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
5584 return ((ipsa_t *)-1);
5585 }
6628 return (npkt);
6629 }
6630
6631 /*
6632 * sadb_clear_lpkt: Atomically clear ipsa->ipsa_lpkt and return the
6633 * previous value.
6634 */
6635 mblk_t *
6636 sadb_clear_lpkt(ipsa_t *ipsa)
6637 {
6638 mblk_t *opkt;
6639
6640 mutex_enter(&ipsa->ipsa_lock);
6641 opkt = ipsa->ipsa_lpkt;
6642 ipsa->ipsa_lpkt = NULL;
6643 mutex_exit(&ipsa->ipsa_lock);
6644 return (opkt);
6645 }
6646
6647 /*
6648 * Walker callback used by sadb_alg_update() to free/create crypto
6649 * context template when a crypto software provider is removed or
6650 * added.
6651 */
6652
6653 struct sadb_update_alg_state {
6654 ipsec_algtype_t alg_type;
6655 uint8_t alg_id;
6656 boolean_t is_added;
6657 boolean_t async_auth;
6658 boolean_t async_encr;
6659 };
6660
6661 static void
6662 sadb_alg_update_cb(isaf_t *head, ipsa_t *entry, void *cookie)
6663 {
6664 struct sadb_update_alg_state *update_state =
6665 (struct sadb_update_alg_state *)cookie;
6666 crypto_ctx_template_t *ctx_tmpl = NULL;
6667
|