79 * ipsecah_g_nd in ipsecah_init_nd.
80 * All of these are alterable, within the min/max values given, at run time.
81 */
82 static ipsecahparam_t lcl_param_arr[] = {
83 /* min max value name */
84 { 0, 3, 0, "ipsecah_debug"},
85 { 125, 32000, SADB_AGE_INTERVAL_DEFAULT, "ipsecah_age_interval"},
86 { 1, 10, 1, "ipsecah_reap_delay"},
87 { 1, SADB_MAX_REPLAY, 64, "ipsecah_replay_size"},
88 { 1, 300, 15, "ipsecah_acquire_timeout"},
89 { 1, 1800, 90, "ipsecah_larval_timeout"},
90 /* Default lifetime values for ACQUIRE messages. */
91 { 0, 0xffffffffU, 0, "ipsecah_default_soft_bytes"},
92 { 0, 0xffffffffU, 0, "ipsecah_default_hard_bytes"},
93 { 0, 0xffffffffU, 24000, "ipsecah_default_soft_addtime"},
94 { 0, 0xffffffffU, 28800, "ipsecah_default_hard_addtime"},
95 { 0, 0xffffffffU, 0, "ipsecah_default_soft_usetime"},
96 { 0, 0xffffffffU, 0, "ipsecah_default_hard_usetime"},
97 { 0, 1, 0, "ipsecah_log_unknown_spi"},
98 };
99 #define ipsecah_debug ipsecah_params[0].ipsecah_param_value
100 #define ipsecah_age_interval ipsecah_params[1].ipsecah_param_value
101 #define ipsecah_age_int_max ipsecah_params[1].ipsecah_param_max
102 #define ipsecah_reap_delay ipsecah_params[2].ipsecah_param_value
103 #define ipsecah_replay_size ipsecah_params[3].ipsecah_param_value
104 #define ipsecah_acquire_timeout ipsecah_params[4].ipsecah_param_value
105 #define ipsecah_larval_timeout ipsecah_params[5].ipsecah_param_value
106 #define ipsecah_default_soft_bytes ipsecah_params[6].ipsecah_param_value
107 #define ipsecah_default_hard_bytes ipsecah_params[7].ipsecah_param_value
108 #define ipsecah_default_soft_addtime ipsecah_params[8].ipsecah_param_value
109 #define ipsecah_default_hard_addtime ipsecah_params[9].ipsecah_param_value
110 #define ipsecah_default_soft_usetime ipsecah_params[10].ipsecah_param_value
111 #define ipsecah_default_hard_usetime ipsecah_params[11].ipsecah_param_value
112 #define ipsecah_log_unknown_spi ipsecah_params[12].ipsecah_param_value
113
114 #define ah0dbg(a) printf a
115 /* NOTE: != 0 instead of > 0 so lint doesn't complain. */
116 #define ah1dbg(ahstack, a) if (ahstack->ipsecah_debug != 0) printf a
117 #define ah2dbg(ahstack, a) if (ahstack->ipsecah_debug > 1) printf a
118 #define ah3dbg(ahstack, a) if (ahstack->ipsecah_debug > 2) printf a
119
120 /*
121 * XXX This is broken. Padding should be determined dynamically
122 * depending on the ICV size and IP version number so that the
123 * total AH header size is a multiple of 32 bits or 64 bits
124 * for V4 and V6 respectively. For 96bit ICVs we have no problems.
125 * Anything different from that, we need to fix our code.
126 */
127 #define IPV4_PADDING_ALIGN 0x04 /* Multiple of 32 bits */
128 #define IPV6_PADDING_ALIGN 0x04 /* Multiple of 32 bits */
129
130 /*
131 * Helper macro. Avoids a call to msgdsize if there is only one
132 * mblk in the chain.
133 */
134 #define AH_MSGSIZE(mp) ((mp)->b_cont != NULL ? msgdsize(mp) : MBLKL(mp))
135
136
137 static mblk_t *ah_auth_out_done(mblk_t *, ip_xmit_attr_t *, ipsec_crypto_t *);
138 static mblk_t *ah_auth_in_done(mblk_t *, ip_recv_attr_t *, ipsec_crypto_t *);
139 static mblk_t *ah_process_ip_options_v4(mblk_t *, ipsa_t *, int *, uint_t,
140 boolean_t, ipsecah_stack_t *);
141 static mblk_t *ah_process_ip_options_v6(mblk_t *, ipsa_t *, int *, uint_t,
142 boolean_t, ipsecah_stack_t *);
143 static void ah_getspi(mblk_t *, keysock_in_t *, ipsecah_stack_t *);
144 static void ah_inbound_restart(mblk_t *, ip_recv_attr_t *);
145
146 static mblk_t *ah_outbound(mblk_t *, ip_xmit_attr_t *);
147 static void ah_outbound_finish(mblk_t *, ip_xmit_attr_t *);
148
149 static int ipsecah_open(queue_t *, dev_t *, int, int, cred_t *);
150 static int ipsecah_close(queue_t *);
151 static void ipsecah_wput(queue_t *, mblk_t *);
152 static void ah_send_acquire(ipsacq_t *, mblk_t *, netstack_t *);
153 static boolean_t ah_register_out(uint32_t, uint32_t, uint_t, ipsecah_stack_t *,
154 cred_t *);
155 static void *ipsecah_stack_init(netstackid_t stackid, netstack_t *ns);
156 static void ipsecah_stack_fini(netstackid_t stackid, void *arg);
157
158 /* Setable in /etc/system */
159 uint32_t ah_hash_size = IPSEC_DEFAULT_HASH_SIZE;
160
161 static taskq_t *ah_taskq;
162
163 static struct module_info info = {
164 5136, "ipsecah", 0, INFPSZ, 65536, 1024
165 };
166
167 static struct qinit rinit = {
168 (pfi_t)putnext, NULL, ipsecah_open, ipsecah_close, NULL, &info,
169 NULL
170 };
171
172 static struct qinit winit = {
403 */
404 static void *
405 ipsecah_stack_init(netstackid_t stackid, netstack_t *ns)
406 {
407 ipsecah_stack_t *ahstack;
408 ipsecahparam_t *ahp;
409
410 ahstack = (ipsecah_stack_t *)kmem_zalloc(sizeof (*ahstack), KM_SLEEP);
411 ahstack->ipsecah_netstack = ns;
412
413 ahp = (ipsecahparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP);
414 ahstack->ipsecah_params = ahp;
415 bcopy(lcl_param_arr, ahp, sizeof (lcl_param_arr));
416
417 (void) ipsecah_param_register(&ahstack->ipsecah_g_nd, ahp,
418 A_CNT(lcl_param_arr));
419
420 (void) ah_kstat_init(ahstack, stackid);
421
422 ahstack->ah_sadb.s_acquire_timeout = &ahstack->ipsecah_acquire_timeout;
423 ahstack->ah_sadb.s_acqfn = ah_send_acquire;
424 sadbp_init("AH", &ahstack->ah_sadb, SADB_SATYPE_AH, ah_hash_size,
425 ahstack->ipsecah_netstack);
426
427 mutex_init(&ahstack->ipsecah_param_lock, NULL, MUTEX_DEFAULT, 0);
428
429 ip_drop_register(&ahstack->ah_dropper, "IPsec AH");
430 return (ahstack);
431 }
432
433 /*
434 * Destroy things for AH at module unload time.
435 */
436 void
437 ipsecah_ddi_destroy(void)
438 {
439 netstack_unregister(NS_IPSECAH);
440 taskq_destroy(ah_taskq);
441 }
442
443 /*
444 * Destroy things for AH for one stack... Never called?
445 */
446 static void
447 ipsecah_stack_fini(netstackid_t stackid, void *arg)
448 {
449 ipsecah_stack_t *ahstack = (ipsecah_stack_t *)arg;
450
451 if (ahstack->ah_pfkey_q != NULL) {
452 (void) quntimeout(ahstack->ah_pfkey_q, ahstack->ah_event);
453 }
454 ahstack->ah_sadb.s_acqfn = NULL;
455 ahstack->ah_sadb.s_acquire_timeout = NULL;
456 sadbp_destroy(&ahstack->ah_sadb, ahstack->ipsecah_netstack);
457 ip_drop_unregister(&ahstack->ah_dropper);
458 mutex_destroy(&ahstack->ipsecah_param_lock);
459 nd_free(&ahstack->ipsecah_g_nd);
460
461 kmem_free(ahstack->ipsecah_params, sizeof (lcl_param_arr));
462 ahstack->ipsecah_params = NULL;
463 kstat_delete_netstack(ahstack->ah_ksp, stackid);
464 ahstack->ah_ksp = NULL;
465 ahstack->ah_kstats = NULL;
466
467 kmem_free(ahstack, sizeof (*ahstack));
468 }
469
470 /*
471 * AH module open routine, which is here for keysock plumbing.
472 * Keysock is pushed over {AH,ESP} which is an artifact from the Bad Old
473 * Days of export control, and fears that ESP would not be allowed
474 * to be shipped at all by default. Eventually, keysock should
1719 }
1720
1721 inrc = sadb_age_bytes(ahstack->ah_pfkey_q, inassoc, bytes, B_TRUE);
1722 outrc = sadb_age_bytes(ahstack->ah_pfkey_q, outassoc, bytes, B_FALSE);
1723
1724 /*
1725 * REFRELE any peer SA.
1726 *
1727 * Because of the multi-line macro nature of IPSA_REFRELE, keep
1728 * them in { }.
1729 */
1730 if (inbound) {
1731 IPSA_REFRELE(outassoc);
1732 } else {
1733 IPSA_REFRELE(inassoc);
1734 }
1735
1736 return (inrc && outrc);
1737 }
1738
1739 /*
1740 * Perform the really difficult work of inserting the proposed situation.
1741 * Called while holding the algorithm lock.
1742 */
1743 static void
1744 ah_insert_prop(sadb_prop_t *prop, ipsacq_t *acqrec, uint_t combs,
1745 netstack_t *ns)
1746 {
1747 sadb_comb_t *comb = (sadb_comb_t *)(prop + 1);
1748 ipsec_action_t *ap;
1749 ipsec_prot_t *prot;
1750 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
1751 ipsec_stack_t *ipss = ns->netstack_ipsec;
1752
1753 ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
1754
1755 prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
1756 prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
1757 *(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */
1758
1759 prop->sadb_prop_replay = ahstack->ipsecah_replay_size;
1760
1761 /*
1762 * Based upon algorithm properties, and what-not, prioritize a
1763 * proposal, based on the ordering of the AH algorithms in the
1764 * alternatives in the policy rule or socket that was placed
1765 * in the acquire record.
1766 */
1767
1768 for (ap = acqrec->ipsacq_act; ap != NULL;
1769 ap = ap->ipa_next) {
1770 ipsec_alginfo_t *aalg;
1771
1772 if ((ap->ipa_act.ipa_type != IPSEC_POLICY_APPLY) ||
1773 (!ap->ipa_act.ipa_apply.ipp_use_ah))
1774 continue;
1775
1776 prot = &ap->ipa_act.ipa_apply;
1777
1778 ASSERT(prot->ipp_auth_alg > 0);
1779
1780 aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
1781 [prot->ipp_auth_alg];
1782 if (aalg == NULL || !ALG_VALID(aalg))
1783 continue;
1784
1785 /* XXX check aalg for duplicates??.. */
1786
1787 comb->sadb_comb_flags = 0;
1788 comb->sadb_comb_reserved = 0;
1789 comb->sadb_comb_encrypt = 0;
1790 comb->sadb_comb_encrypt_minbits = 0;
1791 comb->sadb_comb_encrypt_maxbits = 0;
1792
1793 comb->sadb_comb_auth = aalg->alg_id;
1794 comb->sadb_comb_auth_minbits =
1795 MAX(prot->ipp_ah_minbits, aalg->alg_ef_minbits);
1796 comb->sadb_comb_auth_maxbits =
1797 MIN(prot->ipp_ah_maxbits, aalg->alg_ef_maxbits);
1798
1799 /*
1800 * The following may be based on algorithm
1801 * properties, but in the meantime, we just pick
1802 * some good, sensible numbers. Key mgmt. can
1803 * (and perhaps should) be the place to finalize
1804 * such decisions.
1805 */
1806
1807 /*
1808 * No limits on allocations, since we really don't
1809 * support that concept currently.
1810 */
1811 comb->sadb_comb_soft_allocations = 0;
1812 comb->sadb_comb_hard_allocations = 0;
1813
1814 /*
1815 * These may want to come from policy rule..
1816 */
1817 comb->sadb_comb_soft_bytes =
1818 ahstack->ipsecah_default_soft_bytes;
1819 comb->sadb_comb_hard_bytes =
1820 ahstack->ipsecah_default_hard_bytes;
1821 comb->sadb_comb_soft_addtime =
1822 ahstack->ipsecah_default_soft_addtime;
1823 comb->sadb_comb_hard_addtime =
1824 ahstack->ipsecah_default_hard_addtime;
1825 comb->sadb_comb_soft_usetime =
1826 ahstack->ipsecah_default_soft_usetime;
1827 comb->sadb_comb_hard_usetime =
1828 ahstack->ipsecah_default_hard_usetime;
1829
1830 prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
1831 if (--combs == 0)
1832 return; /* out of space.. */
1833 comb++;
1834 }
1835 }
1836
1837 /*
1838 * Prepare and actually send the SADB_ACQUIRE message to PF_KEY.
1839 */
1840 static void
1841 ah_send_acquire(ipsacq_t *acqrec, mblk_t *extended, netstack_t *ns)
1842 {
1843 uint_t combs;
1844 sadb_msg_t *samsg;
1845 sadb_prop_t *prop;
1846 mblk_t *pfkeymp, *msgmp;
1847 ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
1848 ipsec_stack_t *ipss = ns->netstack_ipsec;
1849
1850 AH_BUMP_STAT(ahstack, acquire_requests);
1851
1852 if (ahstack->ah_pfkey_q == NULL) {
1853 mutex_exit(&acqrec->ipsacq_lock);
1854 return;
1855 }
1856
1857 /* Set up ACQUIRE. */
1858 pfkeymp = sadb_setup_acquire(acqrec, SADB_SATYPE_AH,
1859 ns->netstack_ipsec);
1860 if (pfkeymp == NULL) {
1861 ah0dbg(("sadb_setup_acquire failed.\n"));
1862 mutex_exit(&acqrec->ipsacq_lock);
1863 return;
1864 }
1865 ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
1866 combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
1867 msgmp = pfkeymp->b_cont;
1868 samsg = (sadb_msg_t *)(msgmp->b_rptr);
1869
1870 /* Insert proposal here. */
1871
1872 prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
1873 ah_insert_prop(prop, acqrec, combs, ns);
1874 samsg->sadb_msg_len += prop->sadb_prop_len;
1875 msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
1876
1877 rw_exit(&ipss->ipsec_alg_lock);
1878
1879 /*
1880 * Must mutex_exit() before sending PF_KEY message up, in
1881 * order to avoid recursive mutex_enter() if there are no registered
1882 * listeners.
1883 *
1884 * Once I've sent the message, I'm cool anyway.
1885 */
1886 mutex_exit(&acqrec->ipsacq_lock);
1887 if (extended != NULL) {
1888 putnext(ahstack->ah_pfkey_q, extended);
1889 }
1890 putnext(ahstack->ah_pfkey_q, pfkeymp);
1891 }
1892
1893 /* Refactor me */
1894 /*
1895 * Handle the SADB_GETSPI message. Create a larval SA.
1896 */
1897 static void
1898 ah_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecah_stack_t *ahstack)
1899 {
1900 ipsa_t *newbie, *target;
1901 isaf_t *outbound, *inbound;
1902 int rc, diagnostic;
1903 sadb_sa_t *assoc;
1904 keysock_out_t *kso;
1905 uint32_t newspi;
1906
1907 /*
1908 * Randomly generate a proposed SPI value.
1909 */
1910 if (cl_inet_getspi != NULL) {
1911 cl_inet_getspi(ahstack->ipsecah_netstack->netstack_stackid,
1912 IPPROTO_AH, (uint8_t *)&newspi, sizeof (uint32_t), NULL);
|
79 * ipsecah_g_nd in ipsecah_init_nd.
80 * All of these are alterable, within the min/max values given, at run time.
81 */
82 static ipsecahparam_t lcl_param_arr[] = {
83 /* min max value name */
84 { 0, 3, 0, "ipsecah_debug"},
85 { 125, 32000, SADB_AGE_INTERVAL_DEFAULT, "ipsecah_age_interval"},
86 { 1, 10, 1, "ipsecah_reap_delay"},
87 { 1, SADB_MAX_REPLAY, 64, "ipsecah_replay_size"},
88 { 1, 300, 15, "ipsecah_acquire_timeout"},
89 { 1, 1800, 90, "ipsecah_larval_timeout"},
90 /* Default lifetime values for ACQUIRE messages. */
91 { 0, 0xffffffffU, 0, "ipsecah_default_soft_bytes"},
92 { 0, 0xffffffffU, 0, "ipsecah_default_hard_bytes"},
93 { 0, 0xffffffffU, 24000, "ipsecah_default_soft_addtime"},
94 { 0, 0xffffffffU, 28800, "ipsecah_default_hard_addtime"},
95 { 0, 0xffffffffU, 0, "ipsecah_default_soft_usetime"},
96 { 0, 0xffffffffU, 0, "ipsecah_default_hard_usetime"},
97 { 0, 1, 0, "ipsecah_log_unknown_spi"},
98 };
99
100 #define ah0dbg(a) printf a
101 /* NOTE: != 0 instead of > 0 so lint doesn't complain. */
102 #define ah1dbg(ahstack, a) if (ahstack->ipsecah_debug != 0) printf a
103 #define ah2dbg(ahstack, a) if (ahstack->ipsecah_debug > 1) printf a
104 #define ah3dbg(ahstack, a) if (ahstack->ipsecah_debug > 2) printf a
105
106 /*
107 * XXX This is broken. Padding should be determined dynamically
108 * depending on the ICV size and IP version number so that the
109 * total AH header size is a multiple of 32 bits or 64 bits
110 * for V4 and V6 respectively. For 96bit ICVs we have no problems.
111 * Anything different from that, we need to fix our code.
112 */
113 #define IPV4_PADDING_ALIGN 0x04 /* Multiple of 32 bits */
114 #define IPV6_PADDING_ALIGN 0x04 /* Multiple of 32 bits */
115
116 /*
117 * Helper macro. Avoids a call to msgdsize if there is only one
118 * mblk in the chain.
119 */
120 #define AH_MSGSIZE(mp) ((mp)->b_cont != NULL ? msgdsize(mp) : MBLKL(mp))
121
122
123 static mblk_t *ah_auth_out_done(mblk_t *, ip_xmit_attr_t *, ipsec_crypto_t *);
124 static mblk_t *ah_auth_in_done(mblk_t *, ip_recv_attr_t *, ipsec_crypto_t *);
125 static mblk_t *ah_process_ip_options_v4(mblk_t *, ipsa_t *, int *, uint_t,
126 boolean_t, ipsecah_stack_t *);
127 static mblk_t *ah_process_ip_options_v6(mblk_t *, ipsa_t *, int *, uint_t,
128 boolean_t, ipsecah_stack_t *);
129 static void ah_getspi(mblk_t *, keysock_in_t *, ipsecah_stack_t *);
130 static void ah_inbound_restart(mblk_t *, ip_recv_attr_t *);
131
132 static mblk_t *ah_outbound(mblk_t *, ip_xmit_attr_t *);
133 static void ah_outbound_finish(mblk_t *, ip_xmit_attr_t *);
134
135 static int ipsecah_open(queue_t *, dev_t *, int, int, cred_t *);
136 static int ipsecah_close(queue_t *);
137 static void ipsecah_wput(queue_t *, mblk_t *);
138 static boolean_t ah_register_out(uint32_t, uint32_t, uint_t, ipsecah_stack_t *,
139 cred_t *);
140 static void *ipsecah_stack_init(netstackid_t stackid, netstack_t *ns);
141 static void ipsecah_stack_fini(netstackid_t stackid, void *arg);
142
143 /* Setable in /etc/system */
144 uint32_t ah_hash_size = IPSEC_DEFAULT_HASH_SIZE;
145
146 static taskq_t *ah_taskq;
147
148 static struct module_info info = {
149 5136, "ipsecah", 0, INFPSZ, 65536, 1024
150 };
151
152 static struct qinit rinit = {
153 (pfi_t)putnext, NULL, ipsecah_open, ipsecah_close, NULL, &info,
154 NULL
155 };
156
157 static struct qinit winit = {
388 */
389 static void *
390 ipsecah_stack_init(netstackid_t stackid, netstack_t *ns)
391 {
392 ipsecah_stack_t *ahstack;
393 ipsecahparam_t *ahp;
394
395 ahstack = (ipsecah_stack_t *)kmem_zalloc(sizeof (*ahstack), KM_SLEEP);
396 ahstack->ipsecah_netstack = ns;
397
398 ahp = (ipsecahparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP);
399 ahstack->ipsecah_params = ahp;
400 bcopy(lcl_param_arr, ahp, sizeof (lcl_param_arr));
401
402 (void) ipsecah_param_register(&ahstack->ipsecah_g_nd, ahp,
403 A_CNT(lcl_param_arr));
404
405 (void) ah_kstat_init(ahstack, stackid);
406
407 ahstack->ah_sadb.s_acquire_timeout = &ahstack->ipsecah_acquire_timeout;
408 sadbp_init("AH", &ahstack->ah_sadb, SADB_SATYPE_AH, ah_hash_size,
409 ahstack->ipsecah_netstack);
410
411 mutex_init(&ahstack->ipsecah_param_lock, NULL, MUTEX_DEFAULT, 0);
412
413 ip_drop_register(&ahstack->ah_dropper, "IPsec AH");
414 return (ahstack);
415 }
416
417 /*
418 * Destroy things for AH at module unload time.
419 */
420 void
421 ipsecah_ddi_destroy(void)
422 {
423 netstack_unregister(NS_IPSECAH);
424 taskq_destroy(ah_taskq);
425 }
426
427 /*
428 * Destroy things for AH for one stack... Never called?
429 */
430 static void
431 ipsecah_stack_fini(netstackid_t stackid, void *arg)
432 {
433 ipsecah_stack_t *ahstack = (ipsecah_stack_t *)arg;
434
435 if (ahstack->ah_pfkey_q != NULL) {
436 (void) quntimeout(ahstack->ah_pfkey_q, ahstack->ah_event);
437 }
438 ahstack->ah_sadb.s_acquire_timeout = NULL;
439 sadbp_destroy(&ahstack->ah_sadb, ahstack->ipsecah_netstack);
440 ip_drop_unregister(&ahstack->ah_dropper);
441 mutex_destroy(&ahstack->ipsecah_param_lock);
442 nd_free(&ahstack->ipsecah_g_nd);
443
444 kmem_free(ahstack->ipsecah_params, sizeof (lcl_param_arr));
445 ahstack->ipsecah_params = NULL;
446 kstat_delete_netstack(ahstack->ah_ksp, stackid);
447 ahstack->ah_ksp = NULL;
448 ahstack->ah_kstats = NULL;
449
450 kmem_free(ahstack, sizeof (*ahstack));
451 }
452
453 /*
454 * AH module open routine, which is here for keysock plumbing.
455 * Keysock is pushed over {AH,ESP} which is an artifact from the Bad Old
456 * Days of export control, and fears that ESP would not be allowed
457 * to be shipped at all by default. Eventually, keysock should
1702 }
1703
1704 inrc = sadb_age_bytes(ahstack->ah_pfkey_q, inassoc, bytes, B_TRUE);
1705 outrc = sadb_age_bytes(ahstack->ah_pfkey_q, outassoc, bytes, B_FALSE);
1706
1707 /*
1708 * REFRELE any peer SA.
1709 *
1710 * Because of the multi-line macro nature of IPSA_REFRELE, keep
1711 * them in { }.
1712 */
1713 if (inbound) {
1714 IPSA_REFRELE(outassoc);
1715 } else {
1716 IPSA_REFRELE(inassoc);
1717 }
1718
1719 return (inrc && outrc);
1720 }
1721
1722 /* Refactor me */
1723 /*
1724 * Handle the SADB_GETSPI message. Create a larval SA.
1725 */
1726 static void
1727 ah_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecah_stack_t *ahstack)
1728 {
1729 ipsa_t *newbie, *target;
1730 isaf_t *outbound, *inbound;
1731 int rc, diagnostic;
1732 sadb_sa_t *assoc;
1733 keysock_out_t *kso;
1734 uint32_t newspi;
1735
1736 /*
1737 * Randomly generate a proposed SPI value.
1738 */
1739 if (cl_inet_getspi != NULL) {
1740 cl_inet_getspi(ahstack->ipsecah_netstack->netstack_stackid,
1741 IPPROTO_AH, (uint8_t *)&newspi, sizeof (uint32_t), NULL);
|