520 * information. Unfortunately, I don't
521 * have that handy.
522 */
523 ks0dbg(("Consumer went away while flushing or"
524 " dumping.\n"));
525 }
526 }
527 size = sizeof (keysock_consumer_t);
528 mutex_enter(&keystack->keystack_consumers_lock);
529 keystack->keystack_consumers[kc->kc_sa_type] = NULL;
530 mutex_exit(&keystack->keystack_consumers_lock);
531 mutex_destroy(&kc->kc_lock);
532 netstack_rele(kc->kc_keystack->keystack_netstack);
533 } else {
534 ks = (keysock_t *)ptr;
535 keystack = ks->keysock_keystack;
536
537 ks3dbg(keystack,
538 ("Driver close, PF_KEY socket is going away.\n"));
539 if ((ks->keysock_flags & KEYSOCK_EXTENDED) != 0)
540 atomic_add_32(&keystack->keystack_num_extended, -1);
541 size = sizeof (keysock_t);
542 mutex_enter(&keystack->keystack_list_lock);
543 *(ks->keysock_ptpn) = ks->keysock_next;
544 if (ks->keysock_next != NULL)
545 ks->keysock_next->keysock_ptpn = ks->keysock_ptpn;
546 mutex_exit(&keystack->keystack_list_lock);
547 mutex_destroy(&ks->keysock_lock);
548 vmem_free(keysock_vmem, (void *)(uintptr_t)ks->keysock_serial,
549 1);
550 netstack_rele(ks->keysock_keystack->keystack_netstack);
551 }
552
553 /* Now I'm free. */
554 kmem_free(ptr, size);
555 return (0);
556 }
557 /*
558 * Open routine for keysock.
559 */
560 /* ARGSUSED */
1548 if (downmp == NULL) {
1549 keysock_error(ks, mp, ENOMEM, 0);
1550 return;
1551 }
1552 /*
1553 * Since we've made it here, keysock_get_ext will work!
1554 */
1555 (void) keysock_get_ext(downextv,
1556 (sadb_msg_t *)downmp->b_rptr, msgdsize(downmp),
1557 keystack);
1558 keysock_passdown(ks, downmp, *satypes, downextv,
1559 B_FALSE);
1560 ++satypes;
1561 }
1562 freemsg(mp);
1563 }
1564
1565 /*
1566 * Set global to indicate we prefer an extended ACQUIRE.
1567 */
1568 atomic_add_32(&keystack->keystack_num_extended, 1);
1569 }
1570
1571 static void
1572 keysock_delpair_all(keysock_t *ks, mblk_t *mp, sadb_ext_t *extv[])
1573 {
1574 int i, start, finish;
1575 mblk_t *mp1 = NULL;
1576 keysock_stack_t *keystack = ks->keysock_keystack;
1577
1578 start = 0;
1579 finish = KEYSOCK_MAX_CONSUMERS - 1;
1580
1581 for (i = start; i <= finish; i++) {
1582 if (keystack->keystack_consumers[i] != NULL) {
1583 mp1 = copymsg(mp);
1584 if (mp1 == NULL) {
1585 keysock_error(ks, mp, ENOMEM,
1586 SADB_X_DIAGNOSTIC_NONE);
1587 return;
1588 }
2318 samsg->sadb_msg_len == SADB_8TO64(sizeof (*samsg)))) {
2319 /*
2320 * If I'm an end-of-FLUSH or an end-of-DUMP marker...
2321 */
2322 ASSERT(keystack->keystack_flushdump != 0);
2323 /* Am I flushing? */
2324
2325 mutex_enter(&kc->kc_lock);
2326 kc->kc_flags &= ~KC_FLUSHING;
2327 mutex_exit(&kc->kc_lock);
2328
2329 if (samsg->sadb_msg_errno != 0)
2330 keystack->keystack_flushdump_errno =
2331 samsg->sadb_msg_errno;
2332
2333 /*
2334 * Lower the atomic "flushing" count. If it's
2335 * the last one, send up the end-of-{FLUSH,DUMP} to
2336 * the appropriate PF_KEY socket.
2337 */
2338 if (atomic_add_32_nv(&keystack->keystack_flushdump,
2339 -1) != 0) {
2340 ks1dbg(keystack,
2341 ("One flush/dump message back from %d,"
2342 " more to go.\n", samsg->sadb_msg_satype));
2343 freemsg(mp1);
2344 return;
2345 }
2346
2347 samsg->sadb_msg_errno =
2348 (uint8_t)keystack->keystack_flushdump_errno;
2349 if (samsg->sadb_msg_type == SADB_DUMP) {
2350 samsg->sadb_msg_seq = 0;
2351 }
2352 }
2353 keysock_passup(mp1, samsg, serial, kc,
2354 (samsg->sadb_msg_type == SADB_DUMP), keystack);
2355 return;
2356 case KEYSOCK_HELLO_ACK:
2357 /* Aha, now we can link in the consumer! */
2358 ksa = (keysock_hello_ack_t *)ii;
2359 keysock_link_consumer(ksa->ks_hello_satype, kc);
2365 putnext(q, mp);
2366 }
2367 }
2368
2369 /*
2370 * So we can avoid external linking problems....
2371 */
2372 boolean_t
2373 keysock_extended_reg(netstack_t *ns)
2374 {
2375 keysock_stack_t *keystack = ns->netstack_keysock;
2376
2377 return (keystack->keystack_num_extended != 0);
2378 }
2379
2380 uint32_t
2381 keysock_next_seq(netstack_t *ns)
2382 {
2383 keysock_stack_t *keystack = ns->netstack_keysock;
2384
2385 return (atomic_add_32_nv(&keystack->keystack_acquire_seq, -1));
2386 }
|
520 * information. Unfortunately, I don't
521 * have that handy.
522 */
523 ks0dbg(("Consumer went away while flushing or"
524 " dumping.\n"));
525 }
526 }
527 size = sizeof (keysock_consumer_t);
528 mutex_enter(&keystack->keystack_consumers_lock);
529 keystack->keystack_consumers[kc->kc_sa_type] = NULL;
530 mutex_exit(&keystack->keystack_consumers_lock);
531 mutex_destroy(&kc->kc_lock);
532 netstack_rele(kc->kc_keystack->keystack_netstack);
533 } else {
534 ks = (keysock_t *)ptr;
535 keystack = ks->keysock_keystack;
536
537 ks3dbg(keystack,
538 ("Driver close, PF_KEY socket is going away.\n"));
539 if ((ks->keysock_flags & KEYSOCK_EXTENDED) != 0)
540 atomic_dec_32(&keystack->keystack_num_extended);
541 size = sizeof (keysock_t);
542 mutex_enter(&keystack->keystack_list_lock);
543 *(ks->keysock_ptpn) = ks->keysock_next;
544 if (ks->keysock_next != NULL)
545 ks->keysock_next->keysock_ptpn = ks->keysock_ptpn;
546 mutex_exit(&keystack->keystack_list_lock);
547 mutex_destroy(&ks->keysock_lock);
548 vmem_free(keysock_vmem, (void *)(uintptr_t)ks->keysock_serial,
549 1);
550 netstack_rele(ks->keysock_keystack->keystack_netstack);
551 }
552
553 /* Now I'm free. */
554 kmem_free(ptr, size);
555 return (0);
556 }
557 /*
558 * Open routine for keysock.
559 */
560 /* ARGSUSED */
1548 if (downmp == NULL) {
1549 keysock_error(ks, mp, ENOMEM, 0);
1550 return;
1551 }
1552 /*
1553 * Since we've made it here, keysock_get_ext will work!
1554 */
1555 (void) keysock_get_ext(downextv,
1556 (sadb_msg_t *)downmp->b_rptr, msgdsize(downmp),
1557 keystack);
1558 keysock_passdown(ks, downmp, *satypes, downextv,
1559 B_FALSE);
1560 ++satypes;
1561 }
1562 freemsg(mp);
1563 }
1564
1565 /*
1566 * Set global to indicate we prefer an extended ACQUIRE.
1567 */
1568 atomic_inc_32(&keystack->keystack_num_extended);
1569 }
1570
1571 static void
1572 keysock_delpair_all(keysock_t *ks, mblk_t *mp, sadb_ext_t *extv[])
1573 {
1574 int i, start, finish;
1575 mblk_t *mp1 = NULL;
1576 keysock_stack_t *keystack = ks->keysock_keystack;
1577
1578 start = 0;
1579 finish = KEYSOCK_MAX_CONSUMERS - 1;
1580
1581 for (i = start; i <= finish; i++) {
1582 if (keystack->keystack_consumers[i] != NULL) {
1583 mp1 = copymsg(mp);
1584 if (mp1 == NULL) {
1585 keysock_error(ks, mp, ENOMEM,
1586 SADB_X_DIAGNOSTIC_NONE);
1587 return;
1588 }
2318 samsg->sadb_msg_len == SADB_8TO64(sizeof (*samsg)))) {
2319 /*
2320 * If I'm an end-of-FLUSH or an end-of-DUMP marker...
2321 */
2322 ASSERT(keystack->keystack_flushdump != 0);
2323 /* Am I flushing? */
2324
2325 mutex_enter(&kc->kc_lock);
2326 kc->kc_flags &= ~KC_FLUSHING;
2327 mutex_exit(&kc->kc_lock);
2328
2329 if (samsg->sadb_msg_errno != 0)
2330 keystack->keystack_flushdump_errno =
2331 samsg->sadb_msg_errno;
2332
2333 /*
2334 * Lower the atomic "flushing" count. If it's
2335 * the last one, send up the end-of-{FLUSH,DUMP} to
2336 * the appropriate PF_KEY socket.
2337 */
2338 if (atomic_dec_32_nv(&keystack->keystack_flushdump) !=
2339 0) {
2340 ks1dbg(keystack,
2341 ("One flush/dump message back from %d,"
2342 " more to go.\n", samsg->sadb_msg_satype));
2343 freemsg(mp1);
2344 return;
2345 }
2346
2347 samsg->sadb_msg_errno =
2348 (uint8_t)keystack->keystack_flushdump_errno;
2349 if (samsg->sadb_msg_type == SADB_DUMP) {
2350 samsg->sadb_msg_seq = 0;
2351 }
2352 }
2353 keysock_passup(mp1, samsg, serial, kc,
2354 (samsg->sadb_msg_type == SADB_DUMP), keystack);
2355 return;
2356 case KEYSOCK_HELLO_ACK:
2357 /* Aha, now we can link in the consumer! */
2358 ksa = (keysock_hello_ack_t *)ii;
2359 keysock_link_consumer(ksa->ks_hello_satype, kc);
2365 putnext(q, mp);
2366 }
2367 }
2368
2369 /*
2370 * So we can avoid external linking problems....
2371 */
2372 boolean_t
2373 keysock_extended_reg(netstack_t *ns)
2374 {
2375 keysock_stack_t *keystack = ns->netstack_keysock;
2376
2377 return (keystack->keystack_num_extended != 0);
2378 }
2379
2380 uint32_t
2381 keysock_next_seq(netstack_t *ns)
2382 {
2383 keysock_stack_t *keystack = ns->netstack_keysock;
2384
2385 return (atomic_dec_32_nv(&keystack->keystack_acquire_seq));
2386 }
|