Print this page
First attempt at further IPsec cluster cleanup


1358 
1359 /* XXX refactor me */
1360 /*
1361  * Handle the SADB_GETSPI message.  Create a larval SA.
1362  */
1363 static void
1364 esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack)
1365 {
1366         ipsa_t *newbie, *target;
1367         isaf_t *outbound, *inbound;
1368         int rc, diagnostic;
1369         sadb_sa_t *assoc;
1370         keysock_out_t *kso;
1371         uint32_t newspi;
1372 
1373         /*
1374          * Randomly generate a proposed SPI value
1375          */
1376         (void) random_get_pseudo_bytes((uint8_t *)&newspi, sizeof (uint32_t));
1377         newbie = sadb_getspi(ksi, newspi, &diagnostic,
1378             espstack->ipsecesp_netstack, IPPROTO_ESP);
1379 
1380         if (newbie == NULL) {
1381                 sadb_pfkey_error(espstack->esp_pfkey_q, mp, ENOMEM, diagnostic,
1382                     ksi->ks_in_serial);
1383                 return;
1384         } else if (newbie == (ipsa_t *)-1) {
1385                 sadb_pfkey_error(espstack->esp_pfkey_q, mp, EINVAL, diagnostic,
1386                     ksi->ks_in_serial);
1387                 return;
1388         }
1389 
1390         /*
1391          * XXX - We may randomly collide.  We really should recover from this.
1392          *       Unfortunately, that could require spending way-too-much-time
1393          *       in here.  For now, let the user retry.
1394          */
1395 
1396         if (newbie->ipsa_addrfam == AF_INET6) {
1397                 outbound = OUTBOUND_BUCKET_V6(&espstack->esp_sadb.s_v6,
1398                     *(uint32_t *)(newbie->ipsa_dstaddr));


1551  * if the NAT-T remote port matches the received packet (which must have
1552  * passed ESP authentication, see esp_in_done() for the caller context).  If
1553  * there is a mismatch, the SAs are updated.  It is not important if we race
1554  * with a transmitting thread, as if there is a transmitting thread, it will
1555  * merely emit a packet that will most-likely be dropped.
1556  *
1557  * "ports" are ordered src,dst, and assoc is an inbound SA, where src should
1558  * match ipsa_remote_nat_port and dst should match ipsa_local_nat_port.
1559  */
1560 #ifdef _LITTLE_ENDIAN
1561 #define FIRST_16(x) ((x) & 0xFFFF)
1562 #define NEXT_16(x) (((x) >> 16) & 0xFFFF)
1563 #else
1564 #define FIRST_16(x) (((x) >> 16) & 0xFFFF)
1565 #define NEXT_16(x) ((x) & 0xFFFF)
1566 #endif
1567 static void
1568 esp_port_freshness(uint32_t ports, ipsa_t *assoc)
1569 {
1570         uint16_t remote = FIRST_16(ports);
1571         uint16_t local = NEXT_16(ports);
1572         ipsa_t *outbound_peer;
1573         isaf_t *bucket;
1574         ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
1575 
1576         /* We found a conn_t, therefore local != 0. */
1577         ASSERT(local != 0);
1578         /* Assume an IPv4 SA. */
1579         ASSERT(assoc->ipsa_addrfam == AF_INET);
1580 
1581         /*
1582          * On-the-wire rport == 0 means something's very wrong.
1583          * An unpaired SA is also useless to us.
1584          * If we are behind the NAT, don't bother.
1585          * A zero local NAT port defaults to 4500, so check that too.
1586          * And, of course, if the ports already match, we don't need to
1587          * bother.
1588          */
1589         if (remote == 0 || assoc->ipsa_otherspi == 0 ||
1590             (assoc->ipsa_flags & IPSA_F_BEHIND_NAT) ||
1591             (assoc->ipsa_remote_nat_port == 0 &&
1592             remote == htons(IPPORT_IKE_NATT)) ||
1593             remote == assoc->ipsa_remote_nat_port)
1594                 return;
1595 
1596         /* Try and snag the peer.   NOTE:  Assume IPv4 for now. */
1597         bucket = OUTBOUND_BUCKET_V4(&(espstack->esp_sadb.s_v4),


1736          * Remove ESP header and padding from packet.  I hope the compiler
1737          * spews "branch, predict taken" code for this.
1738          */
1739 
1740         if (esp_strip_header(data_mp, (ira->ira_flags & IRAF_IS_IPV4),
1741             ivlen, &counter, espstack)) {
1742 
1743                 if (is_system_labeled() && assoc->ipsa_tsl != NULL) {
1744                         if (!ip_recv_attr_replace_label(ira, assoc->ipsa_tsl)) {
1745                                 ip_drop_packet(data_mp, B_TRUE, ira->ira_ill,
1746                                     DROPPER(ipss, ipds_ah_nomem),
1747                                     &espstack->esp_dropper);
1748                                 BUMP_MIB(ira->ira_ill->ill_ip_mib,
1749                                     ipIfStatsInDiscards);
1750                                 return (NULL);
1751                         }
1752                 }
1753                 if (is_natt)
1754                         return (esp_fix_natt_checksums(data_mp, assoc));
1755 
1756                 if (assoc->ipsa_state == IPSA_STATE_IDLE) {
1757                         /*
1758                          * Cluster buffering case.  Tell caller that we're
1759                          * handling the packet.
1760                          */
1761                         sadb_buf_pkt(assoc, data_mp, ira);
1762                         return (NULL);
1763                 }
1764 
1765                 return (data_mp);
1766         }
1767 
1768         esp1dbg(espstack, ("esp_in_done: esp_strip_header() failed\n"));
1769 drop_and_bail:
1770         IP_ESP_BUMP_STAT(ipss, in_discards);
1771         ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, counter,
1772             &espstack->esp_dropper);
1773         BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
1774         return (NULL);
1775 }
1776 
1777 /*
1778  * Called upon failing the inbound ICV check. The message passed as
1779  * argument is freed.
1780  */
1781 static void
1782 esp_log_bad_auth(mblk_t *mp, ip_recv_attr_t *ira)
1783 {
1784         ipsa_t          *assoc = ira->ira_ipsec_esp_sa;


3603         }
3604         if (assoc == NULL) {
3605                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
3606                 return (EINVAL);
3607         }
3608         if (ekey == NULL && assoc->sadb_sa_encrypt != SADB_EALG_NULL) {
3609                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_EKEY;
3610                 return (EINVAL);
3611         }
3612 
3613         src = (struct sockaddr_in *)(srcext + 1);
3614         dst = (struct sockaddr_in *)(dstext + 1);
3615         natt_loc = (struct sockaddr_in *)(nttext_loc + 1);
3616         natt_loc6 = (struct sockaddr_in6 *)(nttext_loc + 1);
3617         natt_rem = (struct sockaddr_in *)(nttext_rem + 1);
3618         natt_rem6 = (struct sockaddr_in6 *)(nttext_rem + 1);
3619 
3620         /* Sundry ADD-specific reality checks. */
3621         /* XXX STATS :  Logging/stats here? */
3622 
3623         if ((assoc->sadb_sa_state != SADB_SASTATE_MATURE) &&
3624             (assoc->sadb_sa_state != SADB_X_SASTATE_ACTIVE_ELSEWHERE)) {
3625                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
3626                 return (EINVAL);
3627         }
3628         if (assoc->sadb_sa_encrypt == SADB_EALG_NONE) {
3629                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_EALG;
3630                 return (EINVAL);
3631         }
3632 
3633 #ifndef IPSEC_LATENCY_TEST
3634         if (assoc->sadb_sa_encrypt == SADB_EALG_NULL &&
3635             assoc->sadb_sa_auth == SADB_AALG_NONE) {
3636                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
3637                 return (EINVAL);
3638         }
3639 #endif
3640 
3641         if (assoc->sadb_sa_flags & ~espstack->esp_sadb.s_addflags) {
3642                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
3643                 return (EINVAL);
3644         }


3773                     diagnostic) != 0) {
3774                         mutex_exit(&ipss->ipsec_alg_lock);
3775                         return (EINVAL);
3776                 }
3777         }
3778         mutex_exit(&ipss->ipsec_alg_lock);
3779 
3780         return (esp_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
3781             diagnostic, espstack));
3782 }
3783 
3784 /*
3785  * Update a security association.  Updates come in two varieties.  The first
3786  * is an update of lifetimes on a non-larval SA.  The second is an update of
3787  * a larval SA, which ends up looking a lot more like an add.
3788  */
3789 static int
3790 esp_update_sa(mblk_t *mp, keysock_in_t *ksi, int *diagnostic,
3791     ipsecesp_stack_t *espstack, uint8_t sadb_msg_type)
3792 {
3793         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
3794         mblk_t    *buf_pkt;
3795         int rcode;
3796 
3797         sadb_address_t *dstext =
3798             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3799 
3800         if (dstext == NULL) {
3801                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
3802                 return (EINVAL);
3803         }
3804 
3805         rcode = sadb_update_sa(mp, ksi, &buf_pkt, &espstack->esp_sadb,
3806             diagnostic, espstack->esp_pfkey_q, esp_add_sa,
3807             espstack->ipsecesp_netstack, sadb_msg_type);
3808 
3809         if ((assoc->sadb_sa_state != SADB_X_SASTATE_ACTIVE) ||
3810             (rcode != 0)) {
3811                 return (rcode);
3812         }
3813 
3814         HANDLE_BUF_PKT(esp_taskq, espstack->ipsecesp_netstack->netstack_ipsec,
3815             espstack->esp_dropper, buf_pkt);
3816 
3817         return (rcode);
3818 }
3819 
3820 /* XXX refactor me */
3821 /*
3822  * Delete a security association.  This is REALLY likely to be code common to
3823  * both AH and ESP.  Find the association, then unlink it.
3824  */
3825 static int
3826 esp_del_sa(mblk_t *mp, keysock_in_t *ksi, int *diagnostic,
3827     ipsecesp_stack_t *espstack, uint8_t sadb_msg_type)
3828 {
3829         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
3830         sadb_address_t *dstext =
3831             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3832         sadb_address_t *srcext =
3833             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
3834         struct sockaddr_in *sin;
3835 
3836         if (assoc == NULL) {
3837                 if (dstext != NULL) {


3938          * AF_INET.  And do other address reality checks.
3939          */
3940         if (!sadb_addrfix(ksi, espstack->esp_pfkey_q, mp,
3941             espstack->ipsecesp_netstack) ||
3942             esp_pfkey_reality_failures(mp, ksi, espstack)) {
3943                 return;
3944         }
3945 
3946         switch (samsg->sadb_msg_type) {
3947         case SADB_ADD:
3948                 error = esp_add_sa(mp, ksi, &diagnostic,
3949                     espstack->ipsecesp_netstack);
3950                 if (error != 0) {
3951                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3952                             diagnostic, ksi->ks_in_serial);
3953                 }
3954                 /* else esp_add_sa() took care of things. */
3955                 break;
3956         case SADB_DELETE:
3957         case SADB_X_DELPAIR:
3958         case SADB_X_DELPAIR_STATE:
3959                 error = esp_del_sa(mp, ksi, &diagnostic, espstack,
3960                     samsg->sadb_msg_type);
3961                 if (error != 0) {
3962                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3963                             diagnostic, ksi->ks_in_serial);
3964                 }
3965                 /* Else esp_del_sa() took care of things. */
3966                 break;
3967         case SADB_GET:
3968                 error = sadb_delget_sa(mp, ksi, &espstack->esp_sadb,
3969                     &diagnostic, espstack->esp_pfkey_q, samsg->sadb_msg_type);
3970                 if (error != 0) {
3971                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3972                             diagnostic, ksi->ks_in_serial);
3973                 }
3974                 /* Else sadb_get_sa() took care of things. */
3975                 break;
3976         case SADB_FLUSH:
3977                 sadbp_flush(&espstack->esp_sadb, espstack->ipsecesp_netstack);
3978                 sadb_pfkey_echo(espstack->esp_pfkey_q, mp, samsg, ksi, NULL);




1358 
1359 /* XXX refactor me */
1360 /*
1361  * Handle the SADB_GETSPI message.  Create a larval SA.
1362  */
1363 static void
1364 esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack)
1365 {
1366         ipsa_t *newbie, *target;
1367         isaf_t *outbound, *inbound;
1368         int rc, diagnostic;
1369         sadb_sa_t *assoc;
1370         keysock_out_t *kso;
1371         uint32_t newspi;
1372 
1373         /*
1374          * Randomly generate a proposed SPI value
1375          */
1376         (void) random_get_pseudo_bytes((uint8_t *)&newspi, sizeof (uint32_t));
1377         newbie = sadb_getspi(ksi, newspi, &diagnostic,
1378             espstack->ipsecesp_netstack);
1379 
1380         if (newbie == NULL) {
1381                 sadb_pfkey_error(espstack->esp_pfkey_q, mp, ENOMEM, diagnostic,
1382                     ksi->ks_in_serial);
1383                 return;
1384         } else if (newbie == (ipsa_t *)-1) {
1385                 sadb_pfkey_error(espstack->esp_pfkey_q, mp, EINVAL, diagnostic,
1386                     ksi->ks_in_serial);
1387                 return;
1388         }
1389 
1390         /*
1391          * XXX - We may randomly collide.  We really should recover from this.
1392          *       Unfortunately, that could require spending way-too-much-time
1393          *       in here.  For now, let the user retry.
1394          */
1395 
1396         if (newbie->ipsa_addrfam == AF_INET6) {
1397                 outbound = OUTBOUND_BUCKET_V6(&espstack->esp_sadb.s_v6,
1398                     *(uint32_t *)(newbie->ipsa_dstaddr));


1551  * if the NAT-T remote port matches the received packet (which must have
1552  * passed ESP authentication, see esp_in_done() for the caller context).  If
1553  * there is a mismatch, the SAs are updated.  It is not important if we race
1554  * with a transmitting thread, as if there is a transmitting thread, it will
1555  * merely emit a packet that will most-likely be dropped.
1556  *
1557  * "ports" are ordered src,dst, and assoc is an inbound SA, where src should
1558  * match ipsa_remote_nat_port and dst should match ipsa_local_nat_port.
1559  */
1560 #ifdef _LITTLE_ENDIAN
1561 #define FIRST_16(x) ((x) & 0xFFFF)
1562 #define NEXT_16(x) (((x) >> 16) & 0xFFFF)
1563 #else
1564 #define FIRST_16(x) (((x) >> 16) & 0xFFFF)
1565 #define NEXT_16(x) ((x) & 0xFFFF)
1566 #endif
1567 static void
1568 esp_port_freshness(uint32_t ports, ipsa_t *assoc)
1569 {
1570         uint16_t remote = FIRST_16(ports);

1571         ipsa_t *outbound_peer;
1572         isaf_t *bucket;
1573         ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp;
1574 
1575         /* We found a conn_t, therefore local != 0. */
1576         ASSERT(NEXT_16(ports) != 0);
1577         /* Assume an IPv4 SA. */
1578         ASSERT(assoc->ipsa_addrfam == AF_INET);
1579 
1580         /*
1581          * On-the-wire rport == 0 means something's very wrong.
1582          * An unpaired SA is also useless to us.
1583          * If we are behind the NAT, don't bother.
1584          * A zero local NAT port defaults to 4500, so check that too.
1585          * And, of course, if the ports already match, we don't need to
1586          * bother.
1587          */
1588         if (remote == 0 || assoc->ipsa_otherspi == 0 ||
1589             (assoc->ipsa_flags & IPSA_F_BEHIND_NAT) ||
1590             (assoc->ipsa_remote_nat_port == 0 &&
1591             remote == htons(IPPORT_IKE_NATT)) ||
1592             remote == assoc->ipsa_remote_nat_port)
1593                 return;
1594 
1595         /* Try and snag the peer.   NOTE:  Assume IPv4 for now. */
1596         bucket = OUTBOUND_BUCKET_V4(&(espstack->esp_sadb.s_v4),


1735          * Remove ESP header and padding from packet.  I hope the compiler
1736          * spews "branch, predict taken" code for this.
1737          */
1738 
1739         if (esp_strip_header(data_mp, (ira->ira_flags & IRAF_IS_IPV4),
1740             ivlen, &counter, espstack)) {
1741 
1742                 if (is_system_labeled() && assoc->ipsa_tsl != NULL) {
1743                         if (!ip_recv_attr_replace_label(ira, assoc->ipsa_tsl)) {
1744                                 ip_drop_packet(data_mp, B_TRUE, ira->ira_ill,
1745                                     DROPPER(ipss, ipds_ah_nomem),
1746                                     &espstack->esp_dropper);
1747                                 BUMP_MIB(ira->ira_ill->ill_ip_mib,
1748                                     ipIfStatsInDiscards);
1749                                 return (NULL);
1750                         }
1751                 }
1752                 if (is_natt)
1753                         return (esp_fix_natt_checksums(data_mp, assoc));
1754 









1755                 return (data_mp);
1756         }
1757 
1758         esp1dbg(espstack, ("esp_in_done: esp_strip_header() failed\n"));
1759 drop_and_bail:
1760         IP_ESP_BUMP_STAT(ipss, in_discards);
1761         ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, counter,
1762             &espstack->esp_dropper);
1763         BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards);
1764         return (NULL);
1765 }
1766 
1767 /*
1768  * Called upon failing the inbound ICV check. The message passed as
1769  * argument is freed.
1770  */
1771 static void
1772 esp_log_bad_auth(mblk_t *mp, ip_recv_attr_t *ira)
1773 {
1774         ipsa_t          *assoc = ira->ira_ipsec_esp_sa;


3593         }
3594         if (assoc == NULL) {
3595                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA;
3596                 return (EINVAL);
3597         }
3598         if (ekey == NULL && assoc->sadb_sa_encrypt != SADB_EALG_NULL) {
3599                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_EKEY;
3600                 return (EINVAL);
3601         }
3602 
3603         src = (struct sockaddr_in *)(srcext + 1);
3604         dst = (struct sockaddr_in *)(dstext + 1);
3605         natt_loc = (struct sockaddr_in *)(nttext_loc + 1);
3606         natt_loc6 = (struct sockaddr_in6 *)(nttext_loc + 1);
3607         natt_rem = (struct sockaddr_in *)(nttext_rem + 1);
3608         natt_rem6 = (struct sockaddr_in6 *)(nttext_rem + 1);
3609 
3610         /* Sundry ADD-specific reality checks. */
3611         /* XXX STATS :  Logging/stats here? */
3612 
3613         if (assoc->sadb_sa_state != SADB_SASTATE_MATURE) {

3614                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SASTATE;
3615                 return (EINVAL);
3616         }
3617         if (assoc->sadb_sa_encrypt == SADB_EALG_NONE) {
3618                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_EALG;
3619                 return (EINVAL);
3620         }
3621 
3622 #ifndef IPSEC_LATENCY_TEST
3623         if (assoc->sadb_sa_encrypt == SADB_EALG_NULL &&
3624             assoc->sadb_sa_auth == SADB_AALG_NONE) {
3625                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
3626                 return (EINVAL);
3627         }
3628 #endif
3629 
3630         if (assoc->sadb_sa_flags & ~espstack->esp_sadb.s_addflags) {
3631                 *diagnostic = SADB_X_DIAGNOSTIC_BAD_SAFLAGS;
3632                 return (EINVAL);
3633         }


3762                     diagnostic) != 0) {
3763                         mutex_exit(&ipss->ipsec_alg_lock);
3764                         return (EINVAL);
3765                 }
3766         }
3767         mutex_exit(&ipss->ipsec_alg_lock);
3768 
3769         return (esp_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
3770             diagnostic, espstack));
3771 }
3772 
3773 /*
3774  * Update a security association.  Updates come in two varieties.  The first
3775  * is an update of lifetimes on a non-larval SA.  The second is an update of
3776  * a larval SA, which ends up looking a lot more like an add.
3777  */
3778 static int
3779 esp_update_sa(mblk_t *mp, keysock_in_t *ksi, int *diagnostic,
3780     ipsecesp_stack_t *espstack, uint8_t sadb_msg_type)
3781 {




3782         sadb_address_t *dstext =
3783             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3784 
3785         if (dstext == NULL) {
3786                 *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST;
3787                 return (EINVAL);
3788         }
3789 
3790         return (sadb_update_sa(mp, ksi, &espstack->esp_sadb, diagnostic,
3791             espstack->esp_pfkey_q, esp_add_sa, espstack->ipsecesp_netstack,
3792             sadb_msg_type));










3793 }
3794 
3795 /* XXX refactor me */
3796 /*
3797  * Delete a security association.  This is REALLY likely to be code common to
3798  * both AH and ESP.  Find the association, then unlink it.
3799  */
3800 static int
3801 esp_del_sa(mblk_t *mp, keysock_in_t *ksi, int *diagnostic,
3802     ipsecesp_stack_t *espstack, uint8_t sadb_msg_type)
3803 {
3804         sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA];
3805         sadb_address_t *dstext =
3806             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST];
3807         sadb_address_t *srcext =
3808             (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC];
3809         struct sockaddr_in *sin;
3810 
3811         if (assoc == NULL) {
3812                 if (dstext != NULL) {


3913          * AF_INET.  And do other address reality checks.
3914          */
3915         if (!sadb_addrfix(ksi, espstack->esp_pfkey_q, mp,
3916             espstack->ipsecesp_netstack) ||
3917             esp_pfkey_reality_failures(mp, ksi, espstack)) {
3918                 return;
3919         }
3920 
3921         switch (samsg->sadb_msg_type) {
3922         case SADB_ADD:
3923                 error = esp_add_sa(mp, ksi, &diagnostic,
3924                     espstack->ipsecesp_netstack);
3925                 if (error != 0) {
3926                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3927                             diagnostic, ksi->ks_in_serial);
3928                 }
3929                 /* else esp_add_sa() took care of things. */
3930                 break;
3931         case SADB_DELETE:
3932         case SADB_X_DELPAIR:

3933                 error = esp_del_sa(mp, ksi, &diagnostic, espstack,
3934                     samsg->sadb_msg_type);
3935                 if (error != 0) {
3936                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3937                             diagnostic, ksi->ks_in_serial);
3938                 }
3939                 /* Else esp_del_sa() took care of things. */
3940                 break;
3941         case SADB_GET:
3942                 error = sadb_delget_sa(mp, ksi, &espstack->esp_sadb,
3943                     &diagnostic, espstack->esp_pfkey_q, samsg->sadb_msg_type);
3944                 if (error != 0) {
3945                         sadb_pfkey_error(espstack->esp_pfkey_q, mp, error,
3946                             diagnostic, ksi->ks_in_serial);
3947                 }
3948                 /* Else sadb_get_sa() took care of things. */
3949                 break;
3950         case SADB_FLUSH:
3951                 sadbp_flush(&espstack->esp_sadb, espstack->ipsecesp_netstack);
3952                 sadb_pfkey_echo(espstack->esp_pfkey_q, mp, samsg, ksi, NULL);