From d74f5eca2277b6a0ce0e8757a5a4b41f4dcbf8ba Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Mon, 20 Oct 2008 16:46:50 -0400 Subject: [PATCH] 6760006 Clustering-inspired sadb_buf_pkt() should be called from AH/ESP instead of IP. --- usr/src/uts/common/inet/ip/ip.c | 27 --------------------------- usr/src/uts/common/inet/ip/ipsecah.c | 8 ++++++++ usr/src/uts/common/inet/ip/ipsecesp.c | 10 ++++++++++ usr/src/uts/common/inet/ip/sadb.c | 19 +++++++++++++++++++ usr/src/uts/intel/ia32/ml/modstubs.s | 1 - usr/src/uts/sparc/ml/modstubs.s | 1 - 6 files changed, 37 insertions(+), 29 deletions(-) diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 0f73b35ddc..712c403291 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -17594,7 +17594,6 @@ ip_proto_input(queue_t *q, mblk_t *mp, ipha_t *ipha, ire_t *ire, case IPPROTO_AH: case IPPROTO_ESP: { ipsec_stack_t *ipss = ipst->ips_netstack->netstack_ipsec; - ipsa_t *assoc; /* * Fast path for AH/ESP. If this is the first time @@ -17678,7 +17677,6 @@ ip_proto_input(queue_t *q, mblk_t *mp, ipha_t *ipha, ire_t *ire, } ipsec_rc = ii->ipsec_in_esp_sa->ipsa_input_func( first_mp, esph); - assoc = ii->ipsec_in_esp_sa; } else { ah_t *ah = ipsec_inbound_ah_sa(first_mp, ns); if (ah == NULL) @@ -17687,35 +17685,10 @@ ip_proto_input(queue_t *q, mblk_t *mp, ipha_t *ipha, ire_t *ire, ASSERT(ii->ipsec_in_ah_sa->ipsa_input_func != NULL); ipsec_rc = ii->ipsec_in_ah_sa->ipsa_input_func( first_mp, ah); - assoc = ii->ipsec_in_ah_sa; } switch (ipsec_rc) { case IPSEC_STATUS_SUCCESS: - /* - * The packet is successfully processed but - * received on an SA which is in IDLE state. - * We queue the packet for subsequent - * processing after the SA moves to MATURE - * state. - */ - if ((assoc != NULL) && - (assoc->ipsa_state == IPSA_STATE_IDLE)) { - ASSERT(cl_inet_idlesa != NULL); - in6_addr_t srcaddr, dstaddr; - uint8_t protocol; - protocol = (assoc->ipsa_type == SADB_SATYPE_AH) - ? IPPROTO_AH : IPPROTO_ESP; - IPSA_COPY_ADDR(&srcaddr, assoc->ipsa_srcaddr, - assoc->ipsa_addrfam); - IPSA_COPY_ADDR(&dstaddr, assoc->ipsa_dstaddr, - assoc->ipsa_addrfam); - cl_inet_idlesa(protocol, assoc->ipsa_spi, - assoc->ipsa_addrfam, srcaddr, - dstaddr); - sadb_buf_pkt(assoc, first_mp, ns); - return; - } break; case IPSEC_STATUS_FAILED: BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards); diff --git a/usr/src/uts/common/inet/ip/ipsecah.c b/usr/src/uts/common/inet/ip/ipsecah.c index 29ae1f8d61..cf016d9ce7 100644 --- a/usr/src/uts/common/inet/ip/ipsecah.c +++ b/usr/src/uts/common/inet/ip/ipsecah.c @@ -4229,6 +4229,14 @@ ah_auth_in_done(mblk_t *ipsec_in) } freeb(phdr_mp); ipsec_in->b_cont = mp; + if (assoc->ipsa_state == IPSA_STATE_IDLE) { + /* + * Cluster buffering case. Tell caller that we're + * handling the packet. + */ + sadb_buf_pkt(assoc, ipsec_in, ns); + return (IPSEC_STATUS_PENDING); + } return (IPSEC_STATUS_SUCCESS); ah_in_discard: diff --git a/usr/src/uts/common/inet/ip/ipsecesp.c b/usr/src/uts/common/inet/ip/ipsecesp.c index 84049c0e3f..d3690f129e 100644 --- a/usr/src/uts/common/inet/ip/ipsecesp.c +++ b/usr/src/uts/common/inet/ip/ipsecesp.c @@ -1854,6 +1854,16 @@ esp_in_done(mblk_t *ipsec_in_mp) espstack)) { if (is_natt) return (esp_fix_natt_checksums(data_mp, assoc)); + + if (assoc->ipsa_state == IPSA_STATE_IDLE) { + /* + * Cluster buffering case. Tell caller that we're + * handling the packet. + */ + sadb_buf_pkt(assoc, ipsec_in_mp, ns); + return (IPSEC_STATUS_PENDING); + } + return (IPSEC_STATUS_SUCCESS); } diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c index a329a87da2..a34c2e7ff9 100644 --- a/usr/src/uts/common/inet/ip/sadb.c +++ b/usr/src/uts/common/inet/ip/sadb.c @@ -6883,12 +6883,31 @@ sadb_clear_lpkt(ipsa_t *ipsa) return (opkt); } +/* + * Buffer a packet that's in IDLE state as set by Solaris Clustering. + */ void sadb_buf_pkt(ipsa_t *ipsa, mblk_t *bpkt, netstack_t *ns) { ipsec_stack_t *ipss = ns->netstack_ipsec; + extern void (*cl_inet_idlesa)(uint8_t, uint32_t, sa_family_t, + in6_addr_t, in6_addr_t); + in6_addr_t *srcaddr = (in6_addr_t *)(&ipsa->ipsa_srcaddr); + in6_addr_t *dstaddr = (in6_addr_t *)(&ipsa->ipsa_dstaddr); ASSERT(ipsa->ipsa_state == IPSA_STATE_IDLE); + + if (cl_inet_idlesa == NULL) { + ip_drop_packet(bpkt, B_TRUE, NULL, NULL, + DROPPER(ipss, ipds_sadb_inidle_overflow), + &ipss->ipsec_sadb_dropper); + return; + } + + cl_inet_idlesa((ipsa->ipsa_type == SADB_SATYPE_AH) ? + IPPROTO_AH : IPPROTO_ESP, ipsa->ipsa_spi, ipsa->ipsa_addrfam, + *srcaddr, *dstaddr); + mutex_enter(&ipsa->ipsa_lock); ipsa->ipsa_mblkcnt++; if (ipsa->ipsa_bpkt_head == NULL) { diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s index e4e34559ab..a1352a260b 100644 --- a/usr/src/uts/intel/ia32/ml/modstubs.s +++ b/usr/src/uts/intel/ia32/ml/modstubs.s @@ -516,7 +516,6 @@ fcnname/**/_info: \ WSTUB(ipsecah, sadb_insertassoc, nomod_zero); WSTUB(ipsecah, ipsecah_in_assocfailure, nomod_zero); WSTUB(ipsecah, sadb_set_lpkt, nomod_zero); - WSTUB(ipsecah, sadb_buf_pkt, nomod_zero); WSTUB(ipsecah, ipsecah_icmp_error, nomod_zero); END_MODULE(ipsecah); #endif diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s index b83f3af53a..15377f736c 100644 --- a/usr/src/uts/sparc/ml/modstubs.s +++ b/usr/src/uts/sparc/ml/modstubs.s @@ -404,7 +404,6 @@ stubs_base: WSTUB(ipsecah, sadb_insertassoc, nomod_zero); WSTUB(ipsecah, ipsecah_in_assocfailure, nomod_zero); WSTUB(ipsecah, sadb_set_lpkt, nomod_zero); - WSTUB(ipsecah, sadb_buf_pkt, nomod_zero); WSTUB(ipsecah, ipsecah_icmp_error, nomod_zero); END_MODULE(ipsecah); #endif -- 2.11.4.GIT