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
↓ 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 {
↓ 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   *
↓ 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);
↓ 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
↓ 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
↓ 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:
↓ 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);
↓ 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;
↓ 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.
↓ 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)
↓ 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)
↓ 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);
↓ 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) {
↓ 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;
↓ 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;
↓ 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;
↓ open down ↓ 783 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX