Print this page
Bayard's initial drop, needs finishing, or at least testing.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/spdsock.c
          +++ new/usr/src/uts/common/inet/ip/spdsock.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
  23   24   */
  24   25  
  25   26  #include <sys/param.h>
  26   27  #include <sys/types.h>
  27   28  #include <sys/stream.h>
  28   29  #include <sys/strsubr.h>
  29   30  #include <sys/strsun.h>
  30   31  #include <sys/stropts.h>
  31   32  #include <sys/zone.h>
  32   33  #include <sys/vnode.h>
↓ open down ↓ 2228 lines elided ↑ open up ↑
2261 2262          uint_t algcount;
2262 2263          uint_t size;
2263 2264          mblk_t *m;
2264 2265          uint8_t *cur;
2265 2266          spd_msg_t *msg;
2266 2267          struct spd_ext_actions *act;
2267 2268          struct spd_attribute *attr;
2268 2269          spdsock_t *ss = (spdsock_t *)q->q_ptr;
2269 2270          ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2270 2271  
2271      -        mutex_enter(&ipss->ipsec_alg_lock);
     2272 +        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
2272 2273          /*
2273 2274           * The SPD client expects to receive separate entries for
2274 2275           * AH authentication and ESP authentication supported algorithms.
2275 2276           *
2276 2277           * Don't return the "any" algorithms, if defined, as no
2277 2278           * kernel policies can be set for these algorithms.
2278 2279           */
2279 2280          algcount = 2 * ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2280 2281              ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2281 2282  
↓ open down ↓ 7 lines elided ↑ open up ↑
2289 2290           * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2290 2291           */
2291 2292  
2292 2293          size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions) +
2293 2294              ATTRPERALG * sizeof (struct spd_attribute) * algcount;
2294 2295  
2295 2296          ASSERT(ALIGNED64(size));
2296 2297  
2297 2298          m = allocb(size, BPRI_HI);
2298 2299          if (m == NULL) {
2299      -                mutex_exit(&ipss->ipsec_alg_lock);
     2300 +                rw_exit(&ipss->ipsec_alg_lock);
2300 2301                  spdsock_error(q, mp, ENOMEM, 0);
2301 2302                  return;
2302 2303          }
2303 2304  
2304 2305          m->b_wptr = m->b_rptr + size;
2305 2306          cur = m->b_rptr;
2306 2307  
2307 2308          msg = (spd_msg_t *)cur;
2308 2309          bcopy(mp->b_rptr, cur, sizeof (*msg));
2309 2310  
↓ open down ↓ 50 lines elided ↑ open up ↑
2360 2361                                  EMITALGATTRS(SPDSOCK_ESP_AUTH);
2361 2362                          } else {
2362 2363                                  if (algid == SADB_EALG_NONE)
2363 2364                                          continue;
2364 2365                                  ASSERT(algtype == IPSEC_ALG_ENCR);
2365 2366                                  EMITALGATTRS(SPDSOCK_ESP_ENCR);
2366 2367                          }
2367 2368                  }
2368 2369          }
2369 2370  
2370      -        mutex_exit(&ipss->ipsec_alg_lock);
     2371 +        rw_exit(&ipss->ipsec_alg_lock);
2371 2372  
2372 2373  #undef EMITALGATTRS
2373 2374  #undef EMIT
2374 2375  #undef ATTRPERALG
2375 2376  
2376 2377          attr--;
2377 2378          attr->spd_attr_tag = SPD_ATTR_END;
2378 2379  
2379 2380          freemsg(mp);
2380 2381          qreply(q, m);
↓ open down ↓ 16 lines elided ↑ open up ↑
2397 2398          spd_msg_t *msg;
2398 2399          struct spd_ext_actions *act;
2399 2400          struct spd_attribute *attr;
2400 2401          ipsec_alginfo_t *alg;
2401 2402          uint_t algid;
2402 2403          uint_t i;
2403 2404          uint_t alg_size;
2404 2405          spdsock_t *ss = (spdsock_t *)q->q_ptr;
2405 2406          ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2406 2407  
2407      -        mutex_enter(&ipss->ipsec_alg_lock);
     2408 +        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
2408 2409  
2409 2410          /*
2410 2411           * For each algorithm, we encode:
2411 2412           * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2412 2413           *
2413 2414           * ALG_ID / ALG_PROTO / ALG_INCRBITS / ALG_NKEYSIZES / ALG_KEYSIZE*
2414 2415           * ALG_NBLOCKSIZES / ALG_BLOCKSIZE* / ALG_NPARAMS / ALG_PARAMS* /
2415 2416           * ALG_MECHNAME / ALG_FLAGS / {END, NEXT}
2416 2417           */
2417 2418  
↓ open down ↓ 12 lines elided ↑ open up ↑
2430 2431                              alg->alg_nblock_sizes + alg->alg_nparams) +
2431 2432                              CRYPTO_MAX_MECH_NAME;
2432 2433                          size += alg_size;
2433 2434                  }
2434 2435          }
2435 2436  
2436 2437          ASSERT(ALIGNED64(size));
2437 2438  
2438 2439          m = allocb(size, BPRI_HI);
2439 2440          if (m == NULL) {
2440      -                mutex_exit(&ipss->ipsec_alg_lock);
     2441 +                rw_exit(&ipss->ipsec_alg_lock);
2441 2442                  spdsock_error(q, mp, ENOMEM, 0);
2442 2443                  return;
2443 2444          }
2444 2445  
2445 2446          m->b_wptr = m->b_rptr + size;
2446 2447          cur = m->b_rptr;
2447 2448  
2448 2449          msg = (spd_msg_t *)cur;
2449 2450          bcopy(mp->b_rptr, cur, sizeof (*msg));
2450 2451  
↓ open down ↓ 13 lines elided ↑ open up ↑
2464 2465          act->spd_actions_count = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2465 2466              ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2466 2467          act->spd_actions_reserved = 0;
2467 2468  
2468 2469          /*
2469 2470           * If there aren't any algorithms registered, return an empty message.
2470 2471           * spdsock_get_ext() knows how to deal with this.
2471 2472           */
2472 2473          if (act->spd_actions_count == 0) {
2473 2474                  act->spd_actions_len = 0;
2474      -                mutex_exit(&ipss->ipsec_alg_lock);
     2475 +                rw_exit(&ipss->ipsec_alg_lock);
2475 2476                  goto error;
2476 2477          }
2477 2478  
2478 2479          attr = (struct spd_attribute *)cur;
2479 2480  
2480 2481  #define EMIT(tag, value) {                                      \
2481 2482                  attr->spd_attr_tag = (tag);                     \
2482 2483                  attr->spd_attr_value = (value);                 \
2483 2484                  attr++;                                         \
2484 2485          }
↓ open down ↓ 31 lines elided ↑ open up ↑
2516 2517  
2517 2518                          EMIT(SPD_ATTR_ALG_MECHNAME, CRYPTO_MAX_MECH_NAME);
2518 2519                          bcopy(alg->alg_mech_name, attr, CRYPTO_MAX_MECH_NAME);
2519 2520                          attr = (struct spd_attribute *)((char *)attr +
2520 2521                              CRYPTO_MAX_MECH_NAME);
2521 2522  
2522 2523                          EMIT(SPD_ATTR_NEXT, 0);
2523 2524                  }
2524 2525          }
2525 2526  
2526      -        mutex_exit(&ipss->ipsec_alg_lock);
     2527 +        rw_exit(&ipss->ipsec_alg_lock);
2527 2528  
2528 2529  #undef EMITALGATTRS
2529 2530  #undef EMIT
2530 2531  #undef ATTRPERALG
2531 2532  
2532 2533          attr--;
2533 2534          attr->spd_attr_tag = SPD_ATTR_END;
2534 2535  
2535 2536  error:
2536 2537          freemsg(mp);
↓ open down ↓ 1140 lines elided ↑ open up ↑
3677 3678                                          ASSERT(mt != CRYPTO_MECHANISM_INVALID);
3678 3679                                          algflags = ALG_FLAG_VALID;
3679 3680                                          break;
3680 3681                                  }
3681 3682                          }
3682 3683                          alg->alg_mech_type = mt;
3683 3684                          alg->alg_flags |= algflags;
3684 3685                  }
3685 3686          }
3686 3687  
3687      -        mutex_enter(&ipss->ipsec_alg_lock);
     3688 +        rw_enter(&ipss->ipsec_alg_lock, RW_WRITER);
3688 3689  
3689 3690          /*
3690 3691           * For each algorithm currently defined, check if it is
3691 3692           * present in the new tables created from the SPD_UPDATEALGS
3692 3693           * message received from user-space.
3693 3694           * Delete the algorithm entries that are currently defined
3694 3695           * but not part of the new tables.
3695 3696           */
3696 3697          for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3697 3698                  nalgs = ipss->ipsec_nalgs[algtype];
↓ open down ↓ 35 lines elided ↑ open up ↑
3733 3734                          }
3734 3735                          spds->spds_algs[algtype][algid] = NULL;
3735 3736                  }
3736 3737          }
3737 3738  
3738 3739          for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3739 3740                  ipss->ipsec_algs_exec_mode[algtype] =
3740 3741                      spds->spds_algs_exec_mode[algtype];
3741 3742          }
3742 3743  
3743      -        mutex_exit(&ipss->ipsec_alg_lock);
     3744 +        rw_exit(&ipss->ipsec_alg_lock);
3744 3745  
3745 3746          crypto_free_mech_list(mechs, mech_count);
3746 3747  
3747 3748          ipsecah_algs_changed(ns);
3748 3749          ipsecesp_algs_changed(ns);
3749 3750  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX