125cf1a30Sjl139090 /* 225cf1a30Sjl139090 * CDDL HEADER START 325cf1a30Sjl139090 * 425cf1a30Sjl139090 * The contents of this file are subject to the terms of the 525cf1a30Sjl139090 * Common Development and Distribution License (the "License"). 625cf1a30Sjl139090 * You may not use this file except in compliance with the License. 725cf1a30Sjl139090 * 825cf1a30Sjl139090 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925cf1a30Sjl139090 * or http://www.opensolaris.org/os/licensing. 1025cf1a30Sjl139090 * See the License for the specific language governing permissions 1125cf1a30Sjl139090 * and limitations under the License. 1225cf1a30Sjl139090 * 1325cf1a30Sjl139090 * When distributing Covered Code, include this CDDL HEADER in each 1425cf1a30Sjl139090 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525cf1a30Sjl139090 * If applicable, add the following below this CDDL HEADER, with the 1625cf1a30Sjl139090 * fields enclosed by brackets "[]" replaced with your own identifying 1725cf1a30Sjl139090 * information: Portions Copyright [yyyy] [name of copyright owner] 1825cf1a30Sjl139090 * 1925cf1a30Sjl139090 * CDDL HEADER END 2025cf1a30Sjl139090 */ 2125cf1a30Sjl139090 /* 226074f19fSZach Kissel * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2325cf1a30Sjl139090 * Use is subject to license terms. 2425cf1a30Sjl139090 */ 2525cf1a30Sjl139090 2625cf1a30Sjl139090 2725cf1a30Sjl139090 /* 2825cf1a30Sjl139090 * OPL IPSec Key Management Driver. 2925cf1a30Sjl139090 * 3025cf1a30Sjl139090 * This driver runs on a OPL Domain. It processes requests received 3125cf1a30Sjl139090 * from the OPL Service Processor (SP) via mailbox message. It passes 3225cf1a30Sjl139090 * these requests to the sckmd daemon by means of an /ioctl interface. 3325cf1a30Sjl139090 * 3425cf1a30Sjl139090 * Requests received from the SP consist of IPsec security associations 3525cf1a30Sjl139090 * (SAs) needed to secure the communication between SC and Domain daemons 3625cf1a30Sjl139090 * communicating using DSCP. 3725cf1a30Sjl139090 */ 3825cf1a30Sjl139090 3925cf1a30Sjl139090 #include <sys/types.h> 4025cf1a30Sjl139090 #include <sys/cmn_err.h> 4125cf1a30Sjl139090 #include <sys/kmem.h> 4225cf1a30Sjl139090 #include <sys/errno.h> 4325cf1a30Sjl139090 #include <sys/file.h> 4425cf1a30Sjl139090 #include <sys/open.h> 4525cf1a30Sjl139090 #include <sys/stat.h> 4625cf1a30Sjl139090 #include <sys/conf.h> 4725cf1a30Sjl139090 #include <sys/ddi.h> 4825cf1a30Sjl139090 #include <sys/cmn_err.h> 4925cf1a30Sjl139090 #include <sys/sunddi.h> 5025cf1a30Sjl139090 #include <sys/sunndi.h> 5125cf1a30Sjl139090 #include <sys/ddi_impldefs.h> 5225cf1a30Sjl139090 #include <sys/ndi_impldefs.h> 5325cf1a30Sjl139090 #include <sys/modctl.h> 5425cf1a30Sjl139090 #include <sys/disp.h> 5525cf1a30Sjl139090 #include <sys/note.h> 5625cf1a30Sjl139090 #include <sys/byteorder.h> 5725cf1a30Sjl139090 #include <sys/sdt.h> 5825cf1a30Sjl139090 5925cf1a30Sjl139090 #include <sys/scfd/scfdscpif.h> 6025cf1a30Sjl139090 #include <sys/oplkm_msg.h> 6125cf1a30Sjl139090 #include <sys/sckm_io.h> 6225cf1a30Sjl139090 #include <sys/oplkm.h> 6325cf1a30Sjl139090 6425cf1a30Sjl139090 #define OKM_NODENAME "oplkmdrv" /* Node name */ 6525cf1a30Sjl139090 #define OKM_TARGET_ID 0 /* Target ID */ 6625cf1a30Sjl139090 #define OKM_SM_TOUT 5000 /* small timeout (5msec) */ 6725cf1a30Sjl139090 #define OKM_LG_TOUT 50000 /* large timeout (50msec) */ 6825cf1a30Sjl139090 #define OKM_MB_TOUT 10000000 /* Mailbox timeout (10sec) */ 6925cf1a30Sjl139090 7025cf1a30Sjl139090 okms_t okms_global; /* Global instance structure */ 7125cf1a30Sjl139090 7225cf1a30Sjl139090 #ifdef DEBUG 7325cf1a30Sjl139090 uint32_t okm_debug = DBG_WARN; 7425cf1a30Sjl139090 #endif 7525cf1a30Sjl139090 7625cf1a30Sjl139090 /* 7725cf1a30Sjl139090 * Prototypes for the module related functions. 7825cf1a30Sjl139090 */ 7925cf1a30Sjl139090 int okm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 8025cf1a30Sjl139090 int okm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 8125cf1a30Sjl139090 int okm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result); 8225cf1a30Sjl139090 int okm_open(dev_t *devp, int flag, int otyp, struct cred *cred); 8325cf1a30Sjl139090 int okm_close(dev_t dev, int flag, int otyp, struct cred *cred); 8425cf1a30Sjl139090 int okm_ioctl(dev_t dev, int cmd, intptr_t data, int flag, 8525cf1a30Sjl139090 cred_t *cred, int *rvalp); 8625cf1a30Sjl139090 8725cf1a30Sjl139090 /* 8825cf1a30Sjl139090 * Prototypes for the internal functions. 8925cf1a30Sjl139090 */ 9025cf1a30Sjl139090 int okm_get_req(okms_t *okmsp, sckm_ioctl_getreq_t *ireqp, 9125cf1a30Sjl139090 intptr_t data, int flag); 9225cf1a30Sjl139090 int okm_process_req(okms_t *okmsp, okm_req_hdr_t *reqp, uint32_t len, 9325cf1a30Sjl139090 sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag); 9425cf1a30Sjl139090 int okm_process_status(okms_t *okmsp, sckm_ioctl_status_t *ireply); 9525cf1a30Sjl139090 void okm_event_handler(scf_event_t event, void *arg); 9625cf1a30Sjl139090 int okm_send_reply(okms_t *okmsp, uint32_t transid, uint32_t status, 9725cf1a30Sjl139090 uint32_t sadb_err, uint32_t sadb_ver); 9825cf1a30Sjl139090 int block_until_ready(okms_t *okmsp); 9925cf1a30Sjl139090 static int okm_copyin_ioctl_getreq(intptr_t userarg, 10025cf1a30Sjl139090 sckm_ioctl_getreq_t *driverarg, int flag); 10125cf1a30Sjl139090 static int okm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, 10225cf1a30Sjl139090 intptr_t userarg, int flag); 10325cf1a30Sjl139090 static void okm_cleanup(okms_t *okmsp); 10425cf1a30Sjl139090 static int okm_mbox_init(okms_t *okmsp); 10525cf1a30Sjl139090 static void okm_mbox_fini(okms_t *okmsp); 10625cf1a30Sjl139090 static clock_t okm_timeout_val(int error); 10725cf1a30Sjl139090 10825cf1a30Sjl139090 10925cf1a30Sjl139090 struct cb_ops okm_cb_ops = { 11025cf1a30Sjl139090 okm_open, /* open */ 11125cf1a30Sjl139090 okm_close, /* close */ 11225cf1a30Sjl139090 nodev, /* strategy */ 11325cf1a30Sjl139090 nodev, /* print */ 11425cf1a30Sjl139090 nodev, /* dump */ 11525cf1a30Sjl139090 nodev, /* read */ 11625cf1a30Sjl139090 nodev, /* write */ 11725cf1a30Sjl139090 okm_ioctl, /* ioctl */ 11825cf1a30Sjl139090 nodev, /* devmap */ 11925cf1a30Sjl139090 nodev, /* mmap */ 12025cf1a30Sjl139090 nodev, /* segmap */ 12125cf1a30Sjl139090 nochpoll, /* poll */ 12225cf1a30Sjl139090 ddi_prop_op, /* prop_op */ 12325cf1a30Sjl139090 0, /* streamtab */ 12425cf1a30Sjl139090 D_NEW | D_MP /* Driver compatibility flag */ 12525cf1a30Sjl139090 }; 12625cf1a30Sjl139090 12725cf1a30Sjl139090 struct dev_ops okm_ops = { 12825cf1a30Sjl139090 DEVO_REV, /* devo_rev, */ 12925cf1a30Sjl139090 0, /* refcnt */ 13025cf1a30Sjl139090 okm_info, /* get_dev_info */ 13125cf1a30Sjl139090 nulldev, /* identify */ 13225cf1a30Sjl139090 nulldev, /* probe */ 13325cf1a30Sjl139090 okm_attach, /* attach */ 13425cf1a30Sjl139090 okm_detach, /* detach */ 13525cf1a30Sjl139090 nodev, /* reset */ 13625cf1a30Sjl139090 &okm_cb_ops, /* driver operations */ 13719397407SSherry Moore (struct bus_ops *)0, /* no bus operations */ 13819397407SSherry Moore NULL, /* power */ 13919397407SSherry Moore ddi_quiesce_not_needed, /* quiesce */ 14025cf1a30Sjl139090 }; 14125cf1a30Sjl139090 14225cf1a30Sjl139090 struct modldrv modldrv = { 14325cf1a30Sjl139090 &mod_driverops, 14419397407SSherry Moore "OPL Key Management Driver", 14525cf1a30Sjl139090 &okm_ops, 14625cf1a30Sjl139090 }; 14725cf1a30Sjl139090 14825cf1a30Sjl139090 struct modlinkage modlinkage = { 14925cf1a30Sjl139090 MODREV_1, 15025cf1a30Sjl139090 &modldrv, 15125cf1a30Sjl139090 NULL 15225cf1a30Sjl139090 }; 15325cf1a30Sjl139090 15425cf1a30Sjl139090 15525cf1a30Sjl139090 /* 15625cf1a30Sjl139090 * _init - Module's init routine. 15725cf1a30Sjl139090 */ 15825cf1a30Sjl139090 int 15925cf1a30Sjl139090 _init(void) 16025cf1a30Sjl139090 { 16125cf1a30Sjl139090 int ret; 16225cf1a30Sjl139090 16325cf1a30Sjl139090 if ((ret = mod_install(&modlinkage)) != 0) { 16425cf1a30Sjl139090 cmn_err(CE_WARN, "mod_install failed, error = %d", ret); 16525cf1a30Sjl139090 } 16625cf1a30Sjl139090 return (ret); 16725cf1a30Sjl139090 } 16825cf1a30Sjl139090 16925cf1a30Sjl139090 /* 17025cf1a30Sjl139090 * _fini - Module's fini routine. 17125cf1a30Sjl139090 */ 17225cf1a30Sjl139090 int 17325cf1a30Sjl139090 _fini(void) 17425cf1a30Sjl139090 { 17525cf1a30Sjl139090 int ret; 17625cf1a30Sjl139090 17725cf1a30Sjl139090 if ((ret = mod_remove(&modlinkage)) != 0) { 17825cf1a30Sjl139090 return (ret); 17925cf1a30Sjl139090 } 18025cf1a30Sjl139090 return (ret); 18125cf1a30Sjl139090 } 18225cf1a30Sjl139090 18325cf1a30Sjl139090 /* 18425cf1a30Sjl139090 * _info - Module's info routine. 18525cf1a30Sjl139090 */ 18625cf1a30Sjl139090 int 18725cf1a30Sjl139090 _info(struct modinfo *modinfop) 18825cf1a30Sjl139090 { 18925cf1a30Sjl139090 return (mod_info(&modlinkage, modinfop)); 19025cf1a30Sjl139090 } 19125cf1a30Sjl139090 19225cf1a30Sjl139090 /* 19325cf1a30Sjl139090 * okm_attach - Module's attach routine. 19425cf1a30Sjl139090 * 19525cf1a30Sjl139090 * Description: Initializes the modules state structure and create 19625cf1a30Sjl139090 * the minor device node. 19725cf1a30Sjl139090 */ 19825cf1a30Sjl139090 int 19925cf1a30Sjl139090 okm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 20025cf1a30Sjl139090 { 20125cf1a30Sjl139090 int instance; 20225cf1a30Sjl139090 okms_t *okmsp = &okms_global; 20325cf1a30Sjl139090 20425cf1a30Sjl139090 instance = ddi_get_instance(dip); 20525cf1a30Sjl139090 20625cf1a30Sjl139090 /* Only one instance is supported. */ 20725cf1a30Sjl139090 if (instance != 0) { 20825cf1a30Sjl139090 return (DDI_FAILURE); 20925cf1a30Sjl139090 } 21025cf1a30Sjl139090 21125cf1a30Sjl139090 if (cmd != DDI_ATTACH) { 21225cf1a30Sjl139090 return (DDI_FAILURE); 21325cf1a30Sjl139090 } 21425cf1a30Sjl139090 21525cf1a30Sjl139090 okmsp->km_dip = dip; 2165c066ec2SJerry Gilliam okmsp->km_major = ddi_driver_major(dip); 21725cf1a30Sjl139090 okmsp->km_inst = instance; 21825cf1a30Sjl139090 21925cf1a30Sjl139090 /* 22025cf1a30Sjl139090 * Get an interrupt block cookie corresponding to the 22125cf1a30Sjl139090 * interrupt priority of the event handler. 22225cf1a30Sjl139090 * Assert that the event priority is not redefined to 22325cf1a30Sjl139090 * some other priority. 22425cf1a30Sjl139090 */ 22525cf1a30Sjl139090 /* LINTED */ 22625cf1a30Sjl139090 ASSERT(SCF_EVENT_PRI == DDI_SOFTINT_LOW); 22725cf1a30Sjl139090 if (ddi_get_soft_iblock_cookie(dip, SCF_EVENT_PRI, 22825cf1a30Sjl139090 &okmsp->km_ibcookie) != DDI_SUCCESS) { 22925cf1a30Sjl139090 cmn_err(CE_WARN, "ddi_get_soft_iblock_cookie failed."); 23025cf1a30Sjl139090 return (DDI_FAILURE); 23125cf1a30Sjl139090 } 23225cf1a30Sjl139090 mutex_init(&okmsp->km_lock, NULL, MUTEX_DRIVER, 23325cf1a30Sjl139090 (void *)okmsp->km_ibcookie); 23425cf1a30Sjl139090 okmsp->km_clean |= OKM_CLEAN_LOCK; 23525cf1a30Sjl139090 cv_init(&okmsp->km_wait, NULL, CV_DRIVER, NULL); 23625cf1a30Sjl139090 okmsp->km_clean |= OKM_CLEAN_CV; 23725cf1a30Sjl139090 23825cf1a30Sjl139090 /* 23925cf1a30Sjl139090 * set clean_node ahead as remove_node has to be called even 24025cf1a30Sjl139090 * if create node fails. 24125cf1a30Sjl139090 */ 24225cf1a30Sjl139090 okmsp->km_clean |= OKM_CLEAN_NODE; 24325cf1a30Sjl139090 if (ddi_create_minor_node(dip, OKM_NODENAME, S_IFCHR, 24425cf1a30Sjl139090 instance, NULL, NULL) == DDI_FAILURE) { 24525cf1a30Sjl139090 cmn_err(CE_WARN, "Device node creation failed"); 24625cf1a30Sjl139090 okm_cleanup(okmsp); 24725cf1a30Sjl139090 return (DDI_FAILURE); 24825cf1a30Sjl139090 } 24925cf1a30Sjl139090 25025cf1a30Sjl139090 ddi_set_driver_private(dip, (caddr_t)okmsp); 25125cf1a30Sjl139090 ddi_report_dev(dip); 25225cf1a30Sjl139090 return (DDI_SUCCESS); 25325cf1a30Sjl139090 } 25425cf1a30Sjl139090 25525cf1a30Sjl139090 /* 25625cf1a30Sjl139090 * okm_detach - Module's detach routine. 25725cf1a30Sjl139090 * 25825cf1a30Sjl139090 * Description: Cleans up the module's state structures and any other 25925cf1a30Sjl139090 * relevant data. 26025cf1a30Sjl139090 */ 26125cf1a30Sjl139090 int 26225cf1a30Sjl139090 okm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 26325cf1a30Sjl139090 { 26425cf1a30Sjl139090 okms_t *okmsp; 26525cf1a30Sjl139090 26625cf1a30Sjl139090 if (cmd != DDI_DETACH) { 26725cf1a30Sjl139090 return (DDI_FAILURE); 26825cf1a30Sjl139090 } 26925cf1a30Sjl139090 27025cf1a30Sjl139090 if ((okmsp = ddi_get_driver_private(dip)) == NULL) { 27125cf1a30Sjl139090 return (DDI_FAILURE); 27225cf1a30Sjl139090 } 27325cf1a30Sjl139090 27425cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 27525cf1a30Sjl139090 /* 27625cf1a30Sjl139090 * Check if the mailbox is still in use. 27725cf1a30Sjl139090 */ 27825cf1a30Sjl139090 if (okmsp->km_state & OKM_MB_INITED) { 27925cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 28025cf1a30Sjl139090 cmn_err(CE_WARN, "Detach failure: Mailbox in use"); 28125cf1a30Sjl139090 return (DDI_FAILURE); 28225cf1a30Sjl139090 } 28325cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 28425cf1a30Sjl139090 okm_cleanup(okmsp); 28525cf1a30Sjl139090 ddi_set_driver_private(dip, NULL); 28625cf1a30Sjl139090 return (DDI_SUCCESS); 28725cf1a30Sjl139090 } 28825cf1a30Sjl139090 28925cf1a30Sjl139090 /* 29025cf1a30Sjl139090 * okm_info - Module's info routine. 29125cf1a30Sjl139090 */ 29225cf1a30Sjl139090 /* ARGSUSED */ 29325cf1a30Sjl139090 int 29425cf1a30Sjl139090 okm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 29525cf1a30Sjl139090 { 2966074f19fSZach Kissel okms_t *okmsp = &okms_global; 29725cf1a30Sjl139090 minor_t minor; 29825cf1a30Sjl139090 int ret = DDI_FAILURE; 29925cf1a30Sjl139090 30025cf1a30Sjl139090 switch (infocmd) { 30125cf1a30Sjl139090 case DDI_INFO_DEVT2DEVINFO: 3026074f19fSZach Kissel /* 3036074f19fSZach Kissel * We have the case here where the minor number 3046074f19fSZach Kissel * is the same as the instance number. So, just 3056074f19fSZach Kissel * make sure we have the right minor node in our 3066074f19fSZach Kissel * global state. If we don't, set the result to NULL. 3076074f19fSZach Kissel */ 30825cf1a30Sjl139090 minor = getminor((dev_t)arg); 3096074f19fSZach Kissel if (okmsp->km_inst != minor) { 31025cf1a30Sjl139090 *result = NULL; 31125cf1a30Sjl139090 } else { 31225cf1a30Sjl139090 *result = okmsp->km_dip; 31325cf1a30Sjl139090 ret = DDI_SUCCESS; 31425cf1a30Sjl139090 } 31525cf1a30Sjl139090 break; 31625cf1a30Sjl139090 31725cf1a30Sjl139090 case DDI_INFO_DEVT2INSTANCE: 31825cf1a30Sjl139090 minor = getminor((dev_t)arg); 31925cf1a30Sjl139090 *result = (void *)(uintptr_t)minor; 32025cf1a30Sjl139090 ret = DDI_SUCCESS; 32125cf1a30Sjl139090 32225cf1a30Sjl139090 default: 32325cf1a30Sjl139090 break; 32425cf1a30Sjl139090 } 32525cf1a30Sjl139090 return (ret); 32625cf1a30Sjl139090 } 32725cf1a30Sjl139090 32825cf1a30Sjl139090 /* 32925cf1a30Sjl139090 * okm_open - Device open routine. 33025cf1a30Sjl139090 * 33125cf1a30Sjl139090 * Description: Initializes the mailbox and waits until the mailbox 33225cf1a30Sjl139090 * gets connected. Only one open at a time is supported. 33325cf1a30Sjl139090 */ 33425cf1a30Sjl139090 /*ARGSUSED*/ 33525cf1a30Sjl139090 int 33625cf1a30Sjl139090 okm_open(dev_t *devp, int flag, int otyp, struct cred *cred) 33725cf1a30Sjl139090 { 33825cf1a30Sjl139090 okms_t *okmsp = &okms_global; 33925cf1a30Sjl139090 int ret = 0; 34025cf1a30Sjl139090 34125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_open: called\n")); 34225cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 34325cf1a30Sjl139090 if (okmsp->km_state & OKM_OPENED) { 34425cf1a30Sjl139090 /* Only one open supported */ 34525cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 34625cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_open: already opened\n")); 34725cf1a30Sjl139090 return (EBUSY); 34825cf1a30Sjl139090 } 34925cf1a30Sjl139090 okmsp->km_state |= OKM_OPENED; 35025cf1a30Sjl139090 ret = block_until_ready(okmsp); 35125cf1a30Sjl139090 if (ret != 0) { 35225cf1a30Sjl139090 okmsp->km_state &= ~OKM_OPENED; 35325cf1a30Sjl139090 } 35425cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 35525cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_open: ret=%d\n", ret)); 35625cf1a30Sjl139090 return (ret); 35725cf1a30Sjl139090 } 35825cf1a30Sjl139090 35925cf1a30Sjl139090 /* 36025cf1a30Sjl139090 * block_until_ready - Function to wait until the mailbox is ready to use. 36125cf1a30Sjl139090 * 36225cf1a30Sjl139090 * Description: It initializes the mailbox and waits for the mailbox 36325cf1a30Sjl139090 * state to transition to connected. 36425cf1a30Sjl139090 */ 36525cf1a30Sjl139090 int 36625cf1a30Sjl139090 block_until_ready(okms_t *okmsp) 36725cf1a30Sjl139090 { 36825cf1a30Sjl139090 int ret = 0; 36925cf1a30Sjl139090 37025cf1a30Sjl139090 DPRINTF(DBG_DRV, ("block_until_ready: called\n")); 37125cf1a30Sjl139090 ASSERT(MUTEX_HELD(&okmsp->km_lock)); 37225cf1a30Sjl139090 37325cf1a30Sjl139090 if (okmsp->km_state & OKM_MB_DISC) { 37425cf1a30Sjl139090 DPRINTF(DBG_DRV, ("block_until_ready: closing the mailbox\n")); 37525cf1a30Sjl139090 okm_mbox_fini(okmsp); 37625cf1a30Sjl139090 } 37725cf1a30Sjl139090 if (okmsp->km_state & OKM_MB_CONN) { 37825cf1a30Sjl139090 DPRINTF(DBG_DRV, ("block_until_ready: mailbox connected\n")); 37925cf1a30Sjl139090 return (0); 38025cf1a30Sjl139090 } 38125cf1a30Sjl139090 /* 38225cf1a30Sjl139090 * Initialize mailbox. 38325cf1a30Sjl139090 */ 38425cf1a30Sjl139090 if ((ret = okm_mbox_init(okmsp)) != 0) { 38525cf1a30Sjl139090 DPRINTF(DBG_MBOX, 38625cf1a30Sjl139090 ("block_until_ready: mailbox init failed ret=%d\n", ret)); 38725cf1a30Sjl139090 return (ret); 38825cf1a30Sjl139090 } 38925cf1a30Sjl139090 DPRINTF(DBG_DRV, ("block_until_ready: ret=%d", ret)); 39025cf1a30Sjl139090 return (ret); 39125cf1a30Sjl139090 } 39225cf1a30Sjl139090 39325cf1a30Sjl139090 /* 39425cf1a30Sjl139090 * okm_close - Device close routine. 39525cf1a30Sjl139090 * 39625cf1a30Sjl139090 * Description: Closes the mailbox. 39725cf1a30Sjl139090 */ 39825cf1a30Sjl139090 /*ARGSUSED*/ 39925cf1a30Sjl139090 int 40025cf1a30Sjl139090 okm_close(dev_t dev, int flag, int otyp, struct cred *cred) 40125cf1a30Sjl139090 { 40225cf1a30Sjl139090 okms_t *okmsp = &okms_global; 40325cf1a30Sjl139090 40425cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_close: called\n")); 40525cf1a30Sjl139090 /* Close the lower layer first */ 40625cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 40725cf1a30Sjl139090 okm_mbox_fini(okmsp); 40825cf1a30Sjl139090 okmsp->km_state = 0; 40925cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 41025cf1a30Sjl139090 return (0); 41125cf1a30Sjl139090 } 41225cf1a30Sjl139090 41325cf1a30Sjl139090 41425cf1a30Sjl139090 /* 41525cf1a30Sjl139090 * okm_ioctl - Device ioctl routine. 41625cf1a30Sjl139090 * 41725cf1a30Sjl139090 * Description: Processes ioctls from the daemon. 41825cf1a30Sjl139090 */ 41925cf1a30Sjl139090 /*ARGSUSED*/ 42025cf1a30Sjl139090 int 42125cf1a30Sjl139090 okm_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cred, int *rvalp) 42225cf1a30Sjl139090 { 42325cf1a30Sjl139090 okms_t *okmsp = &okms_global; 42425cf1a30Sjl139090 sckm_ioctl_getreq_t ireq; 42525cf1a30Sjl139090 sckm_ioctl_status_t istatus; 42625cf1a30Sjl139090 int ret = 0; 42725cf1a30Sjl139090 42825cf1a30Sjl139090 switch (cmd) { 42925cf1a30Sjl139090 case SCKM_IOCTL_GETREQ: 43025cf1a30Sjl139090 43125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_ioctl: GETREQ\n")); 43225cf1a30Sjl139090 if (okm_copyin_ioctl_getreq(data, &ireq, flag)) { 43325cf1a30Sjl139090 return (EFAULT); 43425cf1a30Sjl139090 } 43525cf1a30Sjl139090 43625cf1a30Sjl139090 ret = okm_get_req(okmsp, &ireq, data, flag); 43725cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_ioctl: GETREQ ret=%d\n", ret)); 43825cf1a30Sjl139090 break; 43925cf1a30Sjl139090 44025cf1a30Sjl139090 case SCKM_IOCTL_STATUS: 44125cf1a30Sjl139090 44225cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_ioctl: STATUS\n")); 44325cf1a30Sjl139090 if (ddi_copyin((caddr_t)data, &istatus, 44425cf1a30Sjl139090 sizeof (sckm_ioctl_status_t), flag)) { 44525cf1a30Sjl139090 return (EFAULT); 44625cf1a30Sjl139090 } 44725cf1a30Sjl139090 ret = okm_process_status(okmsp, &istatus); 44825cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_ioctl: STATUS ret=%d\n", ret)); 44925cf1a30Sjl139090 break; 45025cf1a30Sjl139090 45125cf1a30Sjl139090 default: 45225cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_ioctl: UNKNOWN ioctl\n")); 45325cf1a30Sjl139090 ret = EINVAL; 45425cf1a30Sjl139090 } 45525cf1a30Sjl139090 return (ret); 45625cf1a30Sjl139090 } 45725cf1a30Sjl139090 45825cf1a30Sjl139090 /* 45925cf1a30Sjl139090 * okm_get_req - Get a request from the mailbox. 46025cf1a30Sjl139090 * 46125cf1a30Sjl139090 * Description: It blocks until a message is received, then processes 46225cf1a30Sjl139090 * the message and returns it to the requestor. 46325cf1a30Sjl139090 */ 46425cf1a30Sjl139090 int 46525cf1a30Sjl139090 okm_get_req(okms_t *okmsp, sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag) 46625cf1a30Sjl139090 { 46725cf1a30Sjl139090 okm_req_hdr_t *reqp; 46825cf1a30Sjl139090 caddr_t msgbuf; 46925cf1a30Sjl139090 uint32_t len; 47025cf1a30Sjl139090 int ret; 47125cf1a30Sjl139090 47225cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_getreq: called\n")); 47325cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 47425cf1a30Sjl139090 if ((ret = block_until_ready(okmsp)) != 0) { 47525cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 47625cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_getreq: failed ret=%d\n", ret)); 47725cf1a30Sjl139090 return (ret); 47825cf1a30Sjl139090 } 47925cf1a30Sjl139090 48025cf1a30Sjl139090 if (okmsp->km_reqp != NULL) { 48125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_getreq: req cached\n")); 48225cf1a30Sjl139090 reqp = okmsp->km_reqp; 48325cf1a30Sjl139090 len = okmsp->km_reqlen; 48425cf1a30Sjl139090 okmsp->km_reqp = NULL; 48525cf1a30Sjl139090 okmsp->km_reqlen = 0; 48625cf1a30Sjl139090 } else { 48725cf1a30Sjl139090 retry: 48825cf1a30Sjl139090 while (OKM_MBOX_READY(okmsp) && 48925cf1a30Sjl139090 ((ret = scf_mb_canget(okmsp->km_target, 49025cf1a30Sjl139090 okmsp->km_key, &len)) != 0)) { 49125cf1a30Sjl139090 if (ret != ENOMSG) { 49225cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_getreq: Unknown " 49325cf1a30Sjl139090 "mbox failure=%d\n", ret)); 49425cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 49525cf1a30Sjl139090 return (EIO); 49625cf1a30Sjl139090 } 49725cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_getreq: waiting for mesg\n")); 49825cf1a30Sjl139090 if (cv_wait_sig(&okmsp->km_wait, 49925cf1a30Sjl139090 &okmsp->km_lock) <= 0) { 50025cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 50125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_getreq:interrupted\n")); 50225cf1a30Sjl139090 return (EINTR); 50325cf1a30Sjl139090 } 50425cf1a30Sjl139090 } 50525cf1a30Sjl139090 if (!OKM_MBOX_READY(okmsp)) { 50625cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 50725cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_getreq: mailbox not ready\n")); 50825cf1a30Sjl139090 return (EIO); 50925cf1a30Sjl139090 } 51025cf1a30Sjl139090 ASSERT(len != 0); 51125cf1a30Sjl139090 msgbuf = kmem_alloc(len, KM_SLEEP); 51225cf1a30Sjl139090 okmsp->km_sg_rcv.msc_dptr = msgbuf; 51325cf1a30Sjl139090 okmsp->km_sg_rcv.msc_len = len; 51425cf1a30Sjl139090 51525cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_getreq: getmsg\n")); 51625cf1a30Sjl139090 ret = scf_mb_getmsg(okmsp->km_target, okmsp->km_key, len, 1, 51725cf1a30Sjl139090 &okmsp->km_sg_rcv, 0); 51825cf1a30Sjl139090 if (ret == ENOMSG || ret == EMSGSIZE) { 51925cf1a30Sjl139090 kmem_free(msgbuf, len); 52025cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_getreq: nomsg ret=%d\n", ret)); 52125cf1a30Sjl139090 goto retry; 52225cf1a30Sjl139090 } else if (ret != 0) { 52325cf1a30Sjl139090 kmem_free(msgbuf, len); 52425cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 52525cf1a30Sjl139090 DPRINTF(DBG_WARN, 52625cf1a30Sjl139090 ("okm_getreq: Unknown mbox failure=%d\n", ret)); 52725cf1a30Sjl139090 return (EIO); 52825cf1a30Sjl139090 } 52925cf1a30Sjl139090 53025cf1a30Sjl139090 /* check message length */ 53125cf1a30Sjl139090 if (len < sizeof (okm_req_hdr_t)) { 53225cf1a30Sjl139090 /* protocol error, drop message */ 53325cf1a30Sjl139090 kmem_free(msgbuf, len); 53425cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 53525cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_getreq: Bad message\n")); 53625cf1a30Sjl139090 return (EBADMSG); 53725cf1a30Sjl139090 } 53825cf1a30Sjl139090 53925cf1a30Sjl139090 reqp = (okm_req_hdr_t *)msgbuf; 54025cf1a30Sjl139090 reqp->krq_version = ntohl(reqp->krq_version); 54125cf1a30Sjl139090 reqp->krq_transid = ntohl(reqp->krq_transid); 54225cf1a30Sjl139090 reqp->krq_cmd = ntohl(reqp->krq_cmd); 54325cf1a30Sjl139090 reqp->krq_reserved = ntohl(reqp->krq_reserved); 54425cf1a30Sjl139090 54525cf1a30Sjl139090 /* check version of the message received */ 54625cf1a30Sjl139090 if (reqp->krq_version != OKM_PROTOCOL_VERSION) { 547*07d06da5SSurya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid, 54825cf1a30Sjl139090 OKM_ERR_VERSION, 0, 0); 54925cf1a30Sjl139090 kmem_free(msgbuf, len); 55025cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 55125cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_getreq: Unknown version=%d\n", 55225cf1a30Sjl139090 reqp->krq_version)); 55325cf1a30Sjl139090 return (EBADMSG); 55425cf1a30Sjl139090 } 55525cf1a30Sjl139090 } 55625cf1a30Sjl139090 55725cf1a30Sjl139090 /* process message */ 55825cf1a30Sjl139090 ret = okm_process_req(okmsp, reqp, len, ireqp, data, flag); 55925cf1a30Sjl139090 if (okmsp->km_reqp == NULL) { 56025cf1a30Sjl139090 /* 56125cf1a30Sjl139090 * The message is not saved, so free the buffer. 56225cf1a30Sjl139090 */ 56325cf1a30Sjl139090 kmem_free(reqp, len); 56425cf1a30Sjl139090 } 56525cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 56625cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_getreq: ret=%d\n", ret)); 56725cf1a30Sjl139090 return (ret); 56825cf1a30Sjl139090 } 56925cf1a30Sjl139090 57025cf1a30Sjl139090 57125cf1a30Sjl139090 /* 57225cf1a30Sjl139090 * okm_process_req - Process the request. 57325cf1a30Sjl139090 * 57425cf1a30Sjl139090 * Description: Validate the request and then give the request to the 57525cf1a30Sjl139090 * daemon. 57625cf1a30Sjl139090 */ 57725cf1a30Sjl139090 int 57825cf1a30Sjl139090 okm_process_req(okms_t *okmsp, okm_req_hdr_t *reqp, uint32_t len, 57925cf1a30Sjl139090 sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag) 58025cf1a30Sjl139090 { 58125cf1a30Sjl139090 void *req_datap = (void *)(((char *)reqp) + sizeof (okm_req_hdr_t)); 58225cf1a30Sjl139090 int sadb_msglen = len - sizeof (okm_req_hdr_t); 58325cf1a30Sjl139090 58425cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_req: called\n")); 58525cf1a30Sjl139090 DUMP_REQ(reqp, len); 58625cf1a30Sjl139090 58725cf1a30Sjl139090 switch (reqp->krq_cmd) { 58825cf1a30Sjl139090 case OKM_MSG_SADB: 58925cf1a30Sjl139090 /* sanity check request */ 59025cf1a30Sjl139090 if (sadb_msglen <= 0) { 591*07d06da5SSurya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid, 59225cf1a30Sjl139090 OKM_ERR_SADB_MSG, 0, 0); 59325cf1a30Sjl139090 DPRINTF(DBG_WARN, ("okm_process_req: bad message\n")); 59425cf1a30Sjl139090 return (EBADMSG); 59525cf1a30Sjl139090 } 59625cf1a30Sjl139090 59725cf1a30Sjl139090 /* 59825cf1a30Sjl139090 * Save the message, prior to giving it to the daemon. 59925cf1a30Sjl139090 */ 60025cf1a30Sjl139090 okmsp->km_reqp = reqp; 60125cf1a30Sjl139090 okmsp->km_reqlen = len; 60225cf1a30Sjl139090 60325cf1a30Sjl139090 if (ireqp->buf_len < len) { 60425cf1a30Sjl139090 DPRINTF(DBG_WARN, 60525cf1a30Sjl139090 ("okm_process_req: not enough space\n")); 60625cf1a30Sjl139090 return (ENOSPC); 60725cf1a30Sjl139090 } 60825cf1a30Sjl139090 60925cf1a30Sjl139090 ireqp->transid = reqp->krq_transid; 61025cf1a30Sjl139090 ireqp->type = SCKM_IOCTL_REQ_SADB; 61125cf1a30Sjl139090 if (ddi_copyout(req_datap, ireqp->buf, sadb_msglen, flag)) { 61225cf1a30Sjl139090 DPRINTF(DBG_WARN, 61325cf1a30Sjl139090 ("okm_process_req: copyout failed\n")); 61425cf1a30Sjl139090 return (EFAULT); 61525cf1a30Sjl139090 } 61625cf1a30Sjl139090 ireqp->buf_len = sadb_msglen; 61725cf1a30Sjl139090 if (okm_copyout_ioctl_getreq(ireqp, data, flag)) { 61825cf1a30Sjl139090 DPRINTF(DBG_WARN, 61925cf1a30Sjl139090 ("okm_process_req: copyout failed\n")); 62025cf1a30Sjl139090 return (EFAULT); 62125cf1a30Sjl139090 } 62225cf1a30Sjl139090 break; 62325cf1a30Sjl139090 62425cf1a30Sjl139090 default: 62525cf1a30Sjl139090 cmn_err(CE_WARN, "Unknown cmd 0x%x received", reqp->krq_cmd); 62625cf1a30Sjl139090 /* 62725cf1a30Sjl139090 * Received an unknown command, send corresponding 62825cf1a30Sjl139090 * error message. 62925cf1a30Sjl139090 */ 630*07d06da5SSurya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid, 631*07d06da5SSurya Prakki OKM_ERR_BAD_CMD, 0, 0); 63225cf1a30Sjl139090 return (EBADMSG); 63325cf1a30Sjl139090 } 63425cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_req: ret=0\n")); 63525cf1a30Sjl139090 return (0); 63625cf1a30Sjl139090 } 63725cf1a30Sjl139090 63825cf1a30Sjl139090 /* 63925cf1a30Sjl139090 * okm_process_status - Process the status from the daemon. 64025cf1a30Sjl139090 * 64125cf1a30Sjl139090 * Description: Processes the status received from the daemon and sends 64225cf1a30Sjl139090 * corresponding message to the SP. 64325cf1a30Sjl139090 */ 64425cf1a30Sjl139090 int 64525cf1a30Sjl139090 okm_process_status(okms_t *okmsp, sckm_ioctl_status_t *ireply) 64625cf1a30Sjl139090 { 64725cf1a30Sjl139090 uint32_t status; 64825cf1a30Sjl139090 uint32_t sadb_msg_errno = 0; 64925cf1a30Sjl139090 uint32_t sadb_msg_version = 0; 65025cf1a30Sjl139090 okm_req_hdr_t *reqp = okmsp->km_reqp; 65125cf1a30Sjl139090 int ret; 65225cf1a30Sjl139090 65325cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: called\n")); 65425cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 65525cf1a30Sjl139090 if ((ret = block_until_ready(okmsp)) != 0) { 65625cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 65725cf1a30Sjl139090 DPRINTF(DBG_WARN, 65825cf1a30Sjl139090 ("okm_process_status: Unknown failure=%d\n", ret)); 65925cf1a30Sjl139090 return (ret); 66025cf1a30Sjl139090 } 66125cf1a30Sjl139090 66225cf1a30Sjl139090 /* fail if no status is expected, or if it does not match */ 66325cf1a30Sjl139090 if (!okmsp->km_reqp || (reqp->krq_transid != ireply->transid)) { 66425cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 66525cf1a30Sjl139090 DPRINTF(DBG_WARN, 66625cf1a30Sjl139090 ("okm_process_status: req/transid mismatch\n")); 66725cf1a30Sjl139090 return (EINVAL); 66825cf1a30Sjl139090 } 66925cf1a30Sjl139090 67025cf1a30Sjl139090 switch (ireply->status) { 67125cf1a30Sjl139090 case SCKM_IOCTL_STAT_SUCCESS: 67225cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: SUCCESS\n")); 67325cf1a30Sjl139090 status = OKM_SUCCESS; 67425cf1a30Sjl139090 break; 67525cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_PFKEY: 67625cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: PFKEY ERROR\n")); 67725cf1a30Sjl139090 status = OKM_ERR_SADB_PFKEY; 67825cf1a30Sjl139090 sadb_msg_errno = ireply->sadb_msg_errno; 67925cf1a30Sjl139090 break; 68025cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_REQ: 68125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: REQ ERROR\n")); 68225cf1a30Sjl139090 status = OKM_ERR_DAEMON; 68325cf1a30Sjl139090 break; 68425cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_VERSION: 68525cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: SADB VERSION ERROR\n")); 68625cf1a30Sjl139090 status = OKM_ERR_SADB_VERSION; 68725cf1a30Sjl139090 sadb_msg_version = ireply->sadb_msg_version; 68825cf1a30Sjl139090 break; 68925cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_TIMEOUT: 69025cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: TIMEOUT ERR\n")); 69125cf1a30Sjl139090 status = OKM_ERR_SADB_TIMEOUT; 69225cf1a30Sjl139090 break; 69325cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_OTHER: 69425cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: OTHER ERR\n")); 69525cf1a30Sjl139090 status = OKM_ERR_DAEMON; 69625cf1a30Sjl139090 break; 69725cf1a30Sjl139090 case SCKM_IOCTL_STAT_ERR_SADB_TYPE: 69825cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: SADB TYPE ERR\n")); 69925cf1a30Sjl139090 status = OKM_ERR_SADB_BAD_TYPE; 70025cf1a30Sjl139090 break; 70125cf1a30Sjl139090 default: 70225cf1a30Sjl139090 cmn_err(CE_WARN, "SCKM daemon returned invalid status %d\n", 70325cf1a30Sjl139090 ireply->status); 70425cf1a30Sjl139090 status = OKM_ERR_DAEMON; 70525cf1a30Sjl139090 } 70625cf1a30Sjl139090 ret = okm_send_reply(okmsp, ireply->transid, status, 70725cf1a30Sjl139090 sadb_msg_errno, sadb_msg_version); 70825cf1a30Sjl139090 /* 70925cf1a30Sjl139090 * Clean up the cached request now. 71025cf1a30Sjl139090 */ 71125cf1a30Sjl139090 if (ret == 0) { 71225cf1a30Sjl139090 kmem_free(okmsp->km_reqp, okmsp->km_reqlen); 71325cf1a30Sjl139090 okmsp->km_reqp = NULL; 71425cf1a30Sjl139090 okmsp->km_reqlen = 0; 71525cf1a30Sjl139090 } 71625cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 71725cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_process_status: ret=%d\n", ret)); 71825cf1a30Sjl139090 return (ret); 71925cf1a30Sjl139090 } 72025cf1a30Sjl139090 72125cf1a30Sjl139090 /* 72225cf1a30Sjl139090 * okm_copyin_ioctl_getreq - copy-in the ioctl request from the daemon. 72325cf1a30Sjl139090 */ 72425cf1a30Sjl139090 72525cf1a30Sjl139090 static int 72625cf1a30Sjl139090 okm_copyin_ioctl_getreq(intptr_t userarg, sckm_ioctl_getreq_t *driverarg, 72725cf1a30Sjl139090 int flag) 72825cf1a30Sjl139090 { 72925cf1a30Sjl139090 #ifdef _MULTI_DATAMODEL 73025cf1a30Sjl139090 switch (ddi_model_convert_from(flag & FMODELS)) { 73125cf1a30Sjl139090 case DDI_MODEL_ILP32: { 73225cf1a30Sjl139090 sckm_ioctl_getreq32_t driverarg32; 73325cf1a30Sjl139090 if (ddi_copyin((caddr_t)userarg, &driverarg32, 73425cf1a30Sjl139090 sizeof (sckm_ioctl_getreq32_t), flag)) { 73525cf1a30Sjl139090 return (EFAULT); 73625cf1a30Sjl139090 } 73725cf1a30Sjl139090 driverarg->transid = driverarg32.transid; 73825cf1a30Sjl139090 driverarg->type = driverarg32.type; 73925cf1a30Sjl139090 driverarg->buf = (caddr_t)(uintptr_t)driverarg32.buf; 74025cf1a30Sjl139090 driverarg->buf_len = driverarg32.buf_len; 74125cf1a30Sjl139090 break; 74225cf1a30Sjl139090 } 74325cf1a30Sjl139090 case DDI_MODEL_NONE: { 74425cf1a30Sjl139090 if (ddi_copyin((caddr_t)userarg, &driverarg, 74525cf1a30Sjl139090 sizeof (sckm_ioctl_getreq_t), flag)) { 74625cf1a30Sjl139090 return (EFAULT); 74725cf1a30Sjl139090 } 74825cf1a30Sjl139090 break; 74925cf1a30Sjl139090 } 75025cf1a30Sjl139090 } 75125cf1a30Sjl139090 #else /* ! _MULTI_DATAMODEL */ 75225cf1a30Sjl139090 if (ddi_copyin((caddr_t)userarg, &driverarg, 75325cf1a30Sjl139090 sizeof (sckm_ioctl_getreq_t), flag)) { 75425cf1a30Sjl139090 return (EFAULT); 75525cf1a30Sjl139090 } 75625cf1a30Sjl139090 #endif /* _MULTI_DATAMODEL */ 75725cf1a30Sjl139090 return (0); 75825cf1a30Sjl139090 } 75925cf1a30Sjl139090 76025cf1a30Sjl139090 76125cf1a30Sjl139090 /* 76225cf1a30Sjl139090 * okm_copyout_ioctl_getreq - copy-out the request to the daemon. 76325cf1a30Sjl139090 */ 76425cf1a30Sjl139090 static int 76525cf1a30Sjl139090 okm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg, 76625cf1a30Sjl139090 int flag) 76725cf1a30Sjl139090 { 76825cf1a30Sjl139090 #ifdef _MULTI_DATAMODEL 76925cf1a30Sjl139090 switch (ddi_model_convert_from(flag & FMODELS)) { 77025cf1a30Sjl139090 case DDI_MODEL_ILP32: { 77125cf1a30Sjl139090 sckm_ioctl_getreq32_t driverarg32; 77225cf1a30Sjl139090 driverarg32.transid = driverarg->transid; 77325cf1a30Sjl139090 driverarg32.type = driverarg->type; 77425cf1a30Sjl139090 driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf; 77525cf1a30Sjl139090 driverarg32.buf_len = driverarg->buf_len; 77625cf1a30Sjl139090 if (ddi_copyout(&driverarg32, (caddr_t)userarg, 77725cf1a30Sjl139090 sizeof (sckm_ioctl_getreq32_t), flag)) { 77825cf1a30Sjl139090 return (EFAULT); 77925cf1a30Sjl139090 } 78025cf1a30Sjl139090 break; 78125cf1a30Sjl139090 } 78225cf1a30Sjl139090 case DDI_MODEL_NONE: 78325cf1a30Sjl139090 if (ddi_copyout(driverarg, (caddr_t)userarg, 78425cf1a30Sjl139090 sizeof (sckm_ioctl_getreq_t), flag)) { 78525cf1a30Sjl139090 return (EFAULT); 78625cf1a30Sjl139090 } 78725cf1a30Sjl139090 break; 78825cf1a30Sjl139090 } 78925cf1a30Sjl139090 #else /* ! _MULTI_DATAMODEL */ 79025cf1a30Sjl139090 if (ddi_copyout(driverarg, (caddr_t)userarg, 79125cf1a30Sjl139090 sizeof (sckm_ioctl_getreq_t), flag)) { 79225cf1a30Sjl139090 return (EFAULT); 79325cf1a30Sjl139090 } 79425cf1a30Sjl139090 #endif /* _MULTI_DATAMODEL */ 79525cf1a30Sjl139090 return (0); 79625cf1a30Sjl139090 } 79725cf1a30Sjl139090 79825cf1a30Sjl139090 /* 79925cf1a30Sjl139090 * okm_cleanup - Cleanup routine. 80025cf1a30Sjl139090 */ 80125cf1a30Sjl139090 static void 80225cf1a30Sjl139090 okm_cleanup(okms_t *okmsp) 80325cf1a30Sjl139090 { 80425cf1a30Sjl139090 80525cf1a30Sjl139090 ASSERT(okmsp != NULL); 80625cf1a30Sjl139090 if (okmsp->km_clean & OKM_CLEAN_NODE) { 80725cf1a30Sjl139090 ddi_remove_minor_node(okmsp->km_dip, NULL); 80825cf1a30Sjl139090 } 80925cf1a30Sjl139090 if (okmsp->km_clean & OKM_CLEAN_LOCK) 81025cf1a30Sjl139090 mutex_destroy(&okmsp->km_lock); 81125cf1a30Sjl139090 if (okmsp->km_clean & OKM_CLEAN_CV) 81225cf1a30Sjl139090 cv_destroy(&okmsp->km_wait); 81325cf1a30Sjl139090 if (okmsp->km_reqp != NULL) { 81425cf1a30Sjl139090 kmem_free(okmsp->km_reqp, okmsp->km_reqlen); 81525cf1a30Sjl139090 okmsp->km_reqp = NULL; 81625cf1a30Sjl139090 okmsp->km_reqlen = 0; 81725cf1a30Sjl139090 } 81825cf1a30Sjl139090 ddi_set_driver_private(okmsp->km_dip, NULL); 81925cf1a30Sjl139090 } 82025cf1a30Sjl139090 82125cf1a30Sjl139090 /* 82225cf1a30Sjl139090 * okm_mbox_init - Mailbox specific initialization. 82325cf1a30Sjl139090 */ 82425cf1a30Sjl139090 static int 82525cf1a30Sjl139090 okm_mbox_init(okms_t *okmsp) 82625cf1a30Sjl139090 { 82725cf1a30Sjl139090 int ret; 82825cf1a30Sjl139090 clock_t tout; 82925cf1a30Sjl139090 83025cf1a30Sjl139090 ASSERT(MUTEX_HELD(&okmsp->km_lock)); 83125cf1a30Sjl139090 okmsp->km_target = OKM_TARGET_ID; 83225cf1a30Sjl139090 okmsp->km_key = DKMD_KEY; 83325cf1a30Sjl139090 okmsp->km_state &= ~OKM_MB_INITED; 83425cf1a30Sjl139090 83525cf1a30Sjl139090 /* Iterate until mailbox gets connected */ 83625cf1a30Sjl139090 while (!(okmsp->km_state & OKM_MB_CONN)) { 83725cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_init: calling mb_init\n")); 83825cf1a30Sjl139090 ret = scf_mb_init(okmsp->km_target, okmsp->km_key, 83925cf1a30Sjl139090 okm_event_handler, (void *)okmsp); 84025cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_init: mb_init ret=%d\n", ret)); 84125cf1a30Sjl139090 842030f3a8fSraghuram if (ret != 0) { 843030f3a8fSraghuram DPRINTF(DBG_MBOX, 844030f3a8fSraghuram ("okm_mbox_init: failed ret =%d\n", ret)); 845030f3a8fSraghuram DTRACE_PROBE1(okm_mbox_fail, int, ret); 846030f3a8fSraghuram } else { 84725cf1a30Sjl139090 okmsp->km_state |= OKM_MB_INITED; 84825cf1a30Sjl139090 84925cf1a30Sjl139090 /* Block until the mailbox is ready to communicate. */ 85025cf1a30Sjl139090 while (!(okmsp->km_state & 85125cf1a30Sjl139090 (OKM_MB_CONN | OKM_MB_DISC))) { 85225cf1a30Sjl139090 85325cf1a30Sjl139090 if (cv_wait_sig(&okmsp->km_wait, 85425cf1a30Sjl139090 &okmsp->km_lock) <= 0) { 85525cf1a30Sjl139090 /* interrupted */ 85625cf1a30Sjl139090 ret = EINTR; 85725cf1a30Sjl139090 break; 85825cf1a30Sjl139090 } 85925cf1a30Sjl139090 } 86025cf1a30Sjl139090 } 86125cf1a30Sjl139090 86225cf1a30Sjl139090 if ((ret != 0) || (okmsp->km_state & OKM_MB_DISC)) { 86325cf1a30Sjl139090 864030f3a8fSraghuram if (okmsp->km_state & OKM_MB_INITED) { 865030f3a8fSraghuram (void) scf_mb_fini(okmsp->km_target, 866030f3a8fSraghuram okmsp->km_key); 867030f3a8fSraghuram } 868030f3a8fSraghuram if (okmsp->km_state & OKM_MB_DISC) { 86925cf1a30Sjl139090 DPRINTF(DBG_WARN, 87025cf1a30Sjl139090 ("okm_mbox_init: mbox DISC_ERROR\n")); 871030f3a8fSraghuram DTRACE_PROBE1(okm_mbox_fail, 872030f3a8fSraghuram int, OKM_MB_DISC); 873030f3a8fSraghuram } 874030f3a8fSraghuram 875030f3a8fSraghuram okmsp->km_state &= ~(OKM_MB_INITED | OKM_MB_DISC | 876030f3a8fSraghuram OKM_MB_CONN); 877030f3a8fSraghuram 878030f3a8fSraghuram if (ret == EINTR) { 879030f3a8fSraghuram return (ret); 880030f3a8fSraghuram } 88125cf1a30Sjl139090 88225cf1a30Sjl139090 /* 88325cf1a30Sjl139090 * If there was failure, then wait for 88425cf1a30Sjl139090 * OKM_MB_TOUT secs and retry again. 88525cf1a30Sjl139090 */ 88625cf1a30Sjl139090 88725cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_init: waiting...\n")); 888d3d50737SRafael Vanoni tout = drv_usectohz(OKM_MB_TOUT); 889d3d50737SRafael Vanoni ret = cv_reltimedwait_sig(&okmsp->km_wait, 890d3d50737SRafael Vanoni &okmsp->km_lock, tout, TR_CLOCK_TICK); 89125cf1a30Sjl139090 if (ret == 0) { 89225cf1a30Sjl139090 /* if interrupted, return immediately. */ 89325cf1a30Sjl139090 DPRINTF(DBG_MBOX, 89425cf1a30Sjl139090 ("okm_mbox_init: interrupted\n")); 89525cf1a30Sjl139090 return (EINTR); 89625cf1a30Sjl139090 } 89725cf1a30Sjl139090 } 89825cf1a30Sjl139090 } 89925cf1a30Sjl139090 90025cf1a30Sjl139090 ret = scf_mb_ctrl(okmsp->km_target, okmsp->km_key, 90125cf1a30Sjl139090 SCF_MBOP_MAXMSGSIZE, &okmsp->km_maxsz); 90225cf1a30Sjl139090 90325cf1a30Sjl139090 /* 90425cf1a30Sjl139090 * The max msg size should be at least the size of reply 90525cf1a30Sjl139090 * we need to send. 90625cf1a30Sjl139090 */ 90725cf1a30Sjl139090 if ((ret == 0) && (okmsp->km_maxsz < sizeof (okm_rep_hdr_t))) { 90825cf1a30Sjl139090 cmn_err(CE_WARN, "Max message size expected >= %ld " 90925cf1a30Sjl139090 "but found %d\n", sizeof (okm_rep_hdr_t), okmsp->km_maxsz); 91025cf1a30Sjl139090 ret = EIO; 91125cf1a30Sjl139090 } 91225cf1a30Sjl139090 if (ret != 0) { 91325cf1a30Sjl139090 okmsp->km_state &= ~OKM_MB_INITED; 91425cf1a30Sjl139090 (void) scf_mb_fini(okmsp->km_target, okmsp->km_key); 91525cf1a30Sjl139090 } 91625cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_init: mb_init ret=%d\n", ret)); 91725cf1a30Sjl139090 return (ret); 91825cf1a30Sjl139090 } 91925cf1a30Sjl139090 92025cf1a30Sjl139090 /* 92125cf1a30Sjl139090 * okm_mbox_fini - Mailbox de-initialization. 92225cf1a30Sjl139090 */ 92325cf1a30Sjl139090 static void 92425cf1a30Sjl139090 okm_mbox_fini(okms_t *okmsp) 92525cf1a30Sjl139090 { 92625cf1a30Sjl139090 int ret = 0; 92725cf1a30Sjl139090 92825cf1a30Sjl139090 ASSERT(MUTEX_HELD(&okmsp->km_lock)); 92925cf1a30Sjl139090 if (okmsp->km_state & OKM_MB_INITED) { 93025cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_fini: calling mb_fini\n")); 93125cf1a30Sjl139090 ret = scf_mb_fini(okmsp->km_target, okmsp->km_key); 93225cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_mbox_fini: mb_fini ret=%d\n", ret)); 93325cf1a30Sjl139090 if (ret != 0) { 93425cf1a30Sjl139090 cmn_err(CE_WARN, 93525cf1a30Sjl139090 "Failed to close the Mailbox error=%d", ret); 93625cf1a30Sjl139090 } 93725cf1a30Sjl139090 okmsp->km_state &= ~(OKM_MB_INITED | OKM_MB_CONN | OKM_MB_DISC); 93825cf1a30Sjl139090 } 93925cf1a30Sjl139090 } 94025cf1a30Sjl139090 94125cf1a30Sjl139090 /* 94225cf1a30Sjl139090 * okm_event_handler - Mailbox event handler. 94325cf1a30Sjl139090 * 94425cf1a30Sjl139090 * Description: Implements a state machine to handle all the mailbox 94525cf1a30Sjl139090 * events. For each event, it sets the appropriate state 94625cf1a30Sjl139090 * flag and wakes up the threads waiting for that event. 94725cf1a30Sjl139090 */ 94825cf1a30Sjl139090 void 94925cf1a30Sjl139090 okm_event_handler(scf_event_t event, void *arg) 95025cf1a30Sjl139090 { 95125cf1a30Sjl139090 okms_t *okmsp = (okms_t *)arg; 95225cf1a30Sjl139090 95325cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_event_handler: called\n")); 95425cf1a30Sjl139090 ASSERT(okmsp != NULL); 95525cf1a30Sjl139090 mutex_enter(&okmsp->km_lock); 95625cf1a30Sjl139090 if (!(okmsp->km_state & OKM_MB_INITED)) { 95725cf1a30Sjl139090 /* 95825cf1a30Sjl139090 * Ignore all events if the state flag indicates that the 95925cf1a30Sjl139090 * mailbox not initialized, this may happen during the close. 96025cf1a30Sjl139090 */ 96125cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 96225cf1a30Sjl139090 DPRINTF(DBG_MBOX, 96325cf1a30Sjl139090 ("okm_event_handler: event=0x%X - mailbox not inited \n", 96425cf1a30Sjl139090 event)); 96525cf1a30Sjl139090 return; 96625cf1a30Sjl139090 } 96725cf1a30Sjl139090 switch (event) { 96825cf1a30Sjl139090 case SCF_MB_CONN_OK: 96925cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_event_handler: Event CONN_OK\n")); 97025cf1a30Sjl139090 /* 97125cf1a30Sjl139090 * Now the mailbox is ready to use, lets wake up 97225cf1a30Sjl139090 * any one waiting for this event. 97325cf1a30Sjl139090 */ 97425cf1a30Sjl139090 okmsp->km_state |= OKM_MB_CONN; 97525cf1a30Sjl139090 cv_broadcast(&okmsp->km_wait); 97625cf1a30Sjl139090 break; 97725cf1a30Sjl139090 97825cf1a30Sjl139090 case SCF_MB_MSG_DATA: 97925cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_event_handler: Event MSG_DATA\n")); 98025cf1a30Sjl139090 /* 98125cf1a30Sjl139090 * A message is available in the mailbox, 98225cf1a30Sjl139090 * wakeup if any one is ready to read the message. 98325cf1a30Sjl139090 */ 98425cf1a30Sjl139090 if (OKM_MBOX_READY(okmsp)) { 98525cf1a30Sjl139090 cv_broadcast(&okmsp->km_wait); 98625cf1a30Sjl139090 } 98725cf1a30Sjl139090 break; 98825cf1a30Sjl139090 98925cf1a30Sjl139090 case SCF_MB_SPACE: 99025cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_event_handler: Event MB_SPACE\n")); 99125cf1a30Sjl139090 /* 99225cf1a30Sjl139090 * Now the mailbox is ready to transmit, lets 99325cf1a30Sjl139090 * wakeup if any one is waiting to write. 99425cf1a30Sjl139090 */ 99525cf1a30Sjl139090 if (OKM_MBOX_READY(okmsp)) { 99625cf1a30Sjl139090 cv_broadcast(&okmsp->km_wait); 99725cf1a30Sjl139090 } 99825cf1a30Sjl139090 break; 99925cf1a30Sjl139090 case SCF_MB_DISC_ERROR: 100025cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_event_handler: Event DISC_ERROR\n")); 100125cf1a30Sjl139090 okmsp->km_state &= ~OKM_MB_CONN; 100225cf1a30Sjl139090 okmsp->km_state |= OKM_MB_DISC; 100325cf1a30Sjl139090 cv_broadcast(&okmsp->km_wait); 100425cf1a30Sjl139090 break; 100525cf1a30Sjl139090 default: 100625cf1a30Sjl139090 cmn_err(CE_WARN, "Unexpected event received\n"); 100725cf1a30Sjl139090 } 100825cf1a30Sjl139090 mutex_exit(&okmsp->km_lock); 100925cf1a30Sjl139090 } 101025cf1a30Sjl139090 101125cf1a30Sjl139090 /* 101225cf1a30Sjl139090 * okm_send_reply - Send a mailbox reply message. 101325cf1a30Sjl139090 */ 101425cf1a30Sjl139090 int 101525cf1a30Sjl139090 okm_send_reply(okms_t *okmsp, uint32_t transid, 101625cf1a30Sjl139090 uint32_t status, uint32_t sadb_err, uint32_t sadb_ver) 101725cf1a30Sjl139090 { 101825cf1a30Sjl139090 okm_rep_hdr_t reply; 101925cf1a30Sjl139090 int ret = EIO; 102025cf1a30Sjl139090 102125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_send_reply: called\n")); 102225cf1a30Sjl139090 ASSERT(MUTEX_HELD(&okmsp->km_lock)); 102325cf1a30Sjl139090 reply.krp_version = htonl(OKM_PROTOCOL_VERSION); 102425cf1a30Sjl139090 reply.krp_transid = htonl(transid); 102525cf1a30Sjl139090 reply.krp_status = htonl(status); 102625cf1a30Sjl139090 reply.krp_sadb_errno = htonl(sadb_err); 102725cf1a30Sjl139090 reply.krp_sadb_version = htonl(sadb_ver); 102825cf1a30Sjl139090 okmsp->km_sg_tx.msc_dptr = (caddr_t)&reply; 102925cf1a30Sjl139090 okmsp->km_sg_tx.msc_len = sizeof (reply); 103025cf1a30Sjl139090 DUMP_REPLY(&reply); 103125cf1a30Sjl139090 103225cf1a30Sjl139090 while (OKM_MBOX_READY(okmsp)) { 103325cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_send_reply: sending reply\n")); 103425cf1a30Sjl139090 ret = scf_mb_putmsg(okmsp->km_target, okmsp->km_key, 103525cf1a30Sjl139090 sizeof (reply), 1, &okmsp->km_sg_tx, 0); 103625cf1a30Sjl139090 DPRINTF(DBG_MBOX, ("okm_send_reply: putmsg ret=%d\n", ret)); 103725cf1a30Sjl139090 if (ret == EBUSY || ret == ENOSPC) { 103825cf1a30Sjl139090 /* mailbox is busy, poll/retry */ 103925cf1a30Sjl139090 if (cv_timedwait_sig(&okmsp->km_wait, 104025cf1a30Sjl139090 &okmsp->km_lock, okm_timeout_val(ret)) == 0) { 104125cf1a30Sjl139090 /* interrupted */ 104225cf1a30Sjl139090 ret = EINTR; 104325cf1a30Sjl139090 DPRINTF(DBG_DRV, 104425cf1a30Sjl139090 ("okm_send_reply: interrupted\n")); 104525cf1a30Sjl139090 break; 104625cf1a30Sjl139090 } 104725cf1a30Sjl139090 } else { 104825cf1a30Sjl139090 break; 104925cf1a30Sjl139090 } 105025cf1a30Sjl139090 } 105125cf1a30Sjl139090 DPRINTF(DBG_DRV, ("okm_send_reply: ret=%d\n", ret)); 105225cf1a30Sjl139090 return (ret); 105325cf1a30Sjl139090 } 105425cf1a30Sjl139090 105525cf1a30Sjl139090 /* 105625cf1a30Sjl139090 * okm_timeout_val -- Return appropriate timeout value. 105725cf1a30Sjl139090 * 105825cf1a30Sjl139090 * A small timeout value is returned for EBUSY as the mailbox busy 105925cf1a30Sjl139090 * condition may go away sooner and we are expected to poll. 106025cf1a30Sjl139090 * 106125cf1a30Sjl139090 * A larger timeout value is returned for ENOSPC case, as the condition 106225cf1a30Sjl139090 * depends on the peer to release buffer space. 106325cf1a30Sjl139090 * NOTE: there will also be an event(SCF_MB_SPACE) but a timeout is 106425cf1a30Sjl139090 * used for reliability purposes. 106525cf1a30Sjl139090 */ 106625cf1a30Sjl139090 static clock_t 106725cf1a30Sjl139090 okm_timeout_val(int error) 106825cf1a30Sjl139090 { 106925cf1a30Sjl139090 clock_t tval; 107025cf1a30Sjl139090 107125cf1a30Sjl139090 ASSERT(error == EBUSY || error == ENOSPC); 107225cf1a30Sjl139090 107325cf1a30Sjl139090 if (error == EBUSY) { 107425cf1a30Sjl139090 tval = OKM_SM_TOUT; 107525cf1a30Sjl139090 } else { 107625cf1a30Sjl139090 tval = OKM_LG_TOUT; 107725cf1a30Sjl139090 } 107825cf1a30Sjl139090 return (drv_usectohz(tval)); 107925cf1a30Sjl139090 } 108025cf1a30Sjl139090 108125cf1a30Sjl139090 #ifdef DEBUG 108225cf1a30Sjl139090 static void 108325cf1a30Sjl139090 okm_print_req(okm_req_hdr_t *reqp, uint32_t len) 108425cf1a30Sjl139090 { 108525cf1a30Sjl139090 uint8_t *datap = (uint8_t *)(((char *)reqp) + sizeof (okm_req_hdr_t)); 108625cf1a30Sjl139090 int msglen = len - sizeof (okm_req_hdr_t); 108725cf1a30Sjl139090 int i, j; 108825cf1a30Sjl139090 #define BYTES_PER_LINE 20 108925cf1a30Sjl139090 char bytestr[BYTES_PER_LINE * 3 + 1]; 109025cf1a30Sjl139090 109125cf1a30Sjl139090 if (!(okm_debug & DBG_MESG)) 109225cf1a30Sjl139090 return; 109325cf1a30Sjl139090 printf("OKM: Request ver=%d transid=%d cmd=%s\n", 109425cf1a30Sjl139090 reqp->krq_version, reqp->krq_transid, 109525cf1a30Sjl139090 ((reqp->krq_cmd == OKM_MSG_SADB) ? "MSG_SADB" : "UNKNOWN")); 109625cf1a30Sjl139090 for (i = 0; i < msglen; ) { 109725cf1a30Sjl139090 for (j = 0; (j < BYTES_PER_LINE) && (i < msglen); j++, i++) { 1098*07d06da5SSurya Prakki (void) sprintf(&bytestr[j * 3], "%02X ", datap[i]); 109925cf1a30Sjl139090 } 110025cf1a30Sjl139090 if (j != 0) { 110125cf1a30Sjl139090 printf("\t%s\n", bytestr); 110225cf1a30Sjl139090 } 110325cf1a30Sjl139090 } 110425cf1a30Sjl139090 } 110525cf1a30Sjl139090 110625cf1a30Sjl139090 static void 110725cf1a30Sjl139090 okm_print_rep(okm_rep_hdr_t *repp) 110825cf1a30Sjl139090 { 110925cf1a30Sjl139090 if (!(okm_debug & DBG_MESG)) 111025cf1a30Sjl139090 return; 111125cf1a30Sjl139090 printf("OKM: Reply Ver=%d Transid=%d Status=%d ", 111225cf1a30Sjl139090 repp->krp_version, repp->krp_transid, repp->krp_status); 111325cf1a30Sjl139090 printf("Sadb_errno=%d Sadb_ver=%d\n", repp->krp_sadb_errno, 111425cf1a30Sjl139090 repp->krp_sadb_version); 111525cf1a30Sjl139090 } 111625cf1a30Sjl139090 #endif 1117