1*dbed73cbSSangeeta Misra /* 2*dbed73cbSSangeeta Misra * CDDL HEADER START 3*dbed73cbSSangeeta Misra * 4*dbed73cbSSangeeta Misra * The contents of this file are subject to the terms of the 5*dbed73cbSSangeeta Misra * Common Development and Distribution License (the "License"). 6*dbed73cbSSangeeta Misra * You may not use this file except in compliance with the License. 7*dbed73cbSSangeeta Misra * 8*dbed73cbSSangeeta Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*dbed73cbSSangeeta Misra * or http://www.opensolaris.org/os/licensing. 10*dbed73cbSSangeeta Misra * See the License for the specific language governing permissions 11*dbed73cbSSangeeta Misra * and limitations under the License. 12*dbed73cbSSangeeta Misra * 13*dbed73cbSSangeeta Misra * When distributing Covered Code, include this CDDL HEADER in each 14*dbed73cbSSangeeta Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*dbed73cbSSangeeta Misra * If applicable, add the following below this CDDL HEADER, with the 16*dbed73cbSSangeeta Misra * fields enclosed by brackets "[]" replaced with your own identifying 17*dbed73cbSSangeeta Misra * information: Portions Copyright [yyyy] [name of copyright owner] 18*dbed73cbSSangeeta Misra * 19*dbed73cbSSangeeta Misra * CDDL HEADER END 20*dbed73cbSSangeeta Misra */ 21*dbed73cbSSangeeta Misra 22*dbed73cbSSangeeta Misra /* 23*dbed73cbSSangeeta Misra * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*dbed73cbSSangeeta Misra * Use is subject to license terms. 25*dbed73cbSSangeeta Misra */ 26*dbed73cbSSangeeta Misra 27*dbed73cbSSangeeta Misra #include <stdlib.h> 28*dbed73cbSSangeeta Misra #include <strings.h> 29*dbed73cbSSangeeta Misra #include <sys/types.h> 30*dbed73cbSSangeeta Misra #include <sys/socket.h> 31*dbed73cbSSangeeta Misra #include <netinet/in.h> 32*dbed73cbSSangeeta Misra #include <stddef.h> 33*dbed73cbSSangeeta Misra #include <libilb_impl.h> 34*dbed73cbSSangeeta Misra #include <libilb.h> 35*dbed73cbSSangeeta Misra 36*dbed73cbSSangeeta Misra /* 37*dbed73cbSSangeeta Misra * Create a health check, returning a health check handle upon success. 38*dbed73cbSSangeeta Misra * Health check created will be recorded in persistent datastore. 39*dbed73cbSSangeeta Misra */ 40*dbed73cbSSangeeta Misra ilb_status_t 41*dbed73cbSSangeeta Misra ilb_create_hc(ilb_handle_t h, const ilb_hc_info_t *hc) 42*dbed73cbSSangeeta Misra { 43*dbed73cbSSangeeta Misra ilb_status_t rc; 44*dbed73cbSSangeeta Misra ilb_comm_t *ic; 45*dbed73cbSSangeeta Misra size_t ic_sz; 46*dbed73cbSSangeeta Misra 47*dbed73cbSSangeeta Misra if (h == ILB_INVALID_HANDLE || hc == NULL || *hc->hci_name == '\0' || 48*dbed73cbSSangeeta Misra hc->hci_timeout < 0 || hc->hci_count < 0 || 49*dbed73cbSSangeeta Misra hc->hci_interval <= hc->hci_timeout * hc->hci_count) 50*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 51*dbed73cbSSangeeta Misra 52*dbed73cbSSangeeta Misra if ((ic = i_ilb_alloc_req(ILBD_CREATE_HC, &ic_sz)) == NULL) 53*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 54*dbed73cbSSangeeta Misra 55*dbed73cbSSangeeta Misra (void) memcpy(&ic->ic_data, hc, sizeof (ilb_hc_info_t)); 56*dbed73cbSSangeeta Misra 57*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz); 58*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 59*dbed73cbSSangeeta Misra goto out; 60*dbed73cbSSangeeta Misra 61*dbed73cbSSangeeta Misra if (ic->ic_cmd != ILBD_CMD_OK) 62*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&ic->ic_data; 63*dbed73cbSSangeeta Misra 64*dbed73cbSSangeeta Misra out: 65*dbed73cbSSangeeta Misra free(ic); 66*dbed73cbSSangeeta Misra return (rc); 67*dbed73cbSSangeeta Misra } 68*dbed73cbSSangeeta Misra 69*dbed73cbSSangeeta Misra /* 70*dbed73cbSSangeeta Misra * Given a health check handle, destroy the corresponding health check. 71*dbed73cbSSangeeta Misra * Persistent datastore will be updated as well. 72*dbed73cbSSangeeta Misra */ 73*dbed73cbSSangeeta Misra ilb_status_t 74*dbed73cbSSangeeta Misra ilb_destroy_hc(ilb_handle_t h, const char *hcname) 75*dbed73cbSSangeeta Misra { 76*dbed73cbSSangeeta Misra ilb_status_t rc; 77*dbed73cbSSangeeta Misra ilb_comm_t *ic; 78*dbed73cbSSangeeta Misra size_t ic_sz; 79*dbed73cbSSangeeta Misra 80*dbed73cbSSangeeta Misra if (h == ILB_INVALID_HANDLE || hcname == NULL || *hcname == '\0') 81*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 82*dbed73cbSSangeeta Misra 83*dbed73cbSSangeeta Misra if ((ic = i_ilb_alloc_req(ILBD_DESTROY_HC, &ic_sz)) == NULL) 84*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 85*dbed73cbSSangeeta Misra 86*dbed73cbSSangeeta Misra (void) strlcpy((char *)&ic->ic_data, hcname, sizeof (ilbd_name_t)); 87*dbed73cbSSangeeta Misra 88*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz); 89*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 90*dbed73cbSSangeeta Misra goto out; 91*dbed73cbSSangeeta Misra 92*dbed73cbSSangeeta Misra if (ic->ic_cmd != ILBD_CMD_OK) 93*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&ic->ic_data; 94*dbed73cbSSangeeta Misra 95*dbed73cbSSangeeta Misra out: 96*dbed73cbSSangeeta Misra free(ic); 97*dbed73cbSSangeeta Misra return (rc); 98*dbed73cbSSangeeta Misra } 99*dbed73cbSSangeeta Misra 100*dbed73cbSSangeeta Misra /* 101*dbed73cbSSangeeta Misra * Given a health check name, get hc info associated with this handle 102*dbed73cbSSangeeta Misra */ 103*dbed73cbSSangeeta Misra ilb_status_t 104*dbed73cbSSangeeta Misra ilb_get_hc_info(ilb_handle_t h, const char *name, ilb_hc_info_t *hcp) 105*dbed73cbSSangeeta Misra { 106*dbed73cbSSangeeta Misra ilb_status_t rc; 107*dbed73cbSSangeeta Misra ilb_comm_t *ic, *rbuf; 108*dbed73cbSSangeeta Misra size_t ic_sz, rbufsz; 109*dbed73cbSSangeeta Misra 110*dbed73cbSSangeeta Misra if (h == ILB_INVALID_HANDLE || name == NULL || hcp == NULL) 111*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 112*dbed73cbSSangeeta Misra 113*dbed73cbSSangeeta Misra if ((ic = i_ilb_alloc_req(ILBD_GET_HC_INFO, &ic_sz)) == NULL) 114*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 115*dbed73cbSSangeeta Misra rbufsz = sizeof (ilb_comm_t) + sizeof (ilb_hc_info_t); 116*dbed73cbSSangeeta Misra if ((rbuf = malloc(rbufsz)) == NULL) { 117*dbed73cbSSangeeta Misra free(ic); 118*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 119*dbed73cbSSangeeta Misra } 120*dbed73cbSSangeeta Misra 121*dbed73cbSSangeeta Misra (void) strlcpy((char *)&ic->ic_data, name, sizeof (ilbd_name_t)); 122*dbed73cbSSangeeta Misra 123*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, ic, ic_sz, rbuf, &rbufsz); 124*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 125*dbed73cbSSangeeta Misra goto out; 126*dbed73cbSSangeeta Misra 127*dbed73cbSSangeeta Misra if (rbuf->ic_cmd != ILBD_CMD_OK) { 128*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&rbuf->ic_data; 129*dbed73cbSSangeeta Misra goto out; 130*dbed73cbSSangeeta Misra } 131*dbed73cbSSangeeta Misra (void) memcpy(hcp, &rbuf->ic_data, sizeof (*hcp)); 132*dbed73cbSSangeeta Misra 133*dbed73cbSSangeeta Misra out: 134*dbed73cbSSangeeta Misra free(ic); 135*dbed73cbSSangeeta Misra free(rbuf); 136*dbed73cbSSangeeta Misra return (rc); 137*dbed73cbSSangeeta Misra } 138*dbed73cbSSangeeta Misra 139*dbed73cbSSangeeta Misra /* 140*dbed73cbSSangeeta Misra * Walk through all health checks, will need if we implement list-hc 141*dbed73cbSSangeeta Misra */ 142*dbed73cbSSangeeta Misra ilb_status_t 143*dbed73cbSSangeeta Misra ilb_walk_hc(ilb_handle_t h, hc_walkerfunc_t func, void *arg) 144*dbed73cbSSangeeta Misra { 145*dbed73cbSSangeeta Misra ilb_status_t rc; 146*dbed73cbSSangeeta Misra ilb_hc_info_t hc_info; 147*dbed73cbSSangeeta Misra ilbd_namelist_t *hc_names; 148*dbed73cbSSangeeta Misra ilb_comm_t ic, *rbuf; 149*dbed73cbSSangeeta Misra size_t rbufsz; 150*dbed73cbSSangeeta Misra int i; 151*dbed73cbSSangeeta Misra 152*dbed73cbSSangeeta Misra rbufsz = ILBD_MSG_SIZE; 153*dbed73cbSSangeeta Misra if ((rbuf = malloc(rbufsz)) == NULL) 154*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 155*dbed73cbSSangeeta Misra ic.ic_cmd = ILBD_RETRIEVE_HC_NAMES; 156*dbed73cbSSangeeta Misra 157*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, &ic, sizeof (ic), rbuf, &rbufsz); 158*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 159*dbed73cbSSangeeta Misra goto out; 160*dbed73cbSSangeeta Misra if (rbuf->ic_cmd != ILBD_CMD_OK) { 161*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&rbuf->ic_data; 162*dbed73cbSSangeeta Misra goto out; 163*dbed73cbSSangeeta Misra } 164*dbed73cbSSangeeta Misra 165*dbed73cbSSangeeta Misra hc_names = (ilbd_namelist_t *)&rbuf->ic_data; 166*dbed73cbSSangeeta Misra for (i = 0; i < hc_names->ilbl_count; i++) { 167*dbed73cbSSangeeta Misra rc = ilb_get_hc_info(h, hc_names->ilbl_name[i], &hc_info); 168*dbed73cbSSangeeta Misra /* 169*dbed73cbSSangeeta Misra * Since getting the list of hc names and getting the info 170*dbed73cbSSangeeta Misra * of each of them are not atomic, some hc objects may have 171*dbed73cbSSangeeta Misra * been deleted. If this is the case, just skip them. 172*dbed73cbSSangeeta Misra */ 173*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_ENOENT) { 174*dbed73cbSSangeeta Misra rc = ILB_STATUS_OK; 175*dbed73cbSSangeeta Misra continue; 176*dbed73cbSSangeeta Misra } else if (rc != ILB_STATUS_OK) { 177*dbed73cbSSangeeta Misra break; 178*dbed73cbSSangeeta Misra } 179*dbed73cbSSangeeta Misra rc = func(h, &hc_info, arg); 180*dbed73cbSSangeeta Misra } 181*dbed73cbSSangeeta Misra 182*dbed73cbSSangeeta Misra out: 183*dbed73cbSSangeeta Misra free(rbuf); 184*dbed73cbSSangeeta Misra return (rc); 185*dbed73cbSSangeeta Misra } 186*dbed73cbSSangeeta Misra 187*dbed73cbSSangeeta Misra static ilb_status_t 188*dbed73cbSSangeeta Misra ilb_get_hc_srvs(ilb_handle_t h, const char *rulename, ilb_comm_t **rbuf, 189*dbed73cbSSangeeta Misra size_t *rbufsz) 190*dbed73cbSSangeeta Misra { 191*dbed73cbSSangeeta Misra ilb_status_t rc; 192*dbed73cbSSangeeta Misra ilb_comm_t *ic, *tmp_rbuf; 193*dbed73cbSSangeeta Misra size_t ic_sz; 194*dbed73cbSSangeeta Misra 195*dbed73cbSSangeeta Misra if ((ic = i_ilb_alloc_req(ILBD_GET_HC_SRVS, &ic_sz)) == NULL) 196*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 197*dbed73cbSSangeeta Misra *rbufsz = ILBD_MSG_SIZE; 198*dbed73cbSSangeeta Misra if ((tmp_rbuf = malloc(*rbufsz)) == NULL) { 199*dbed73cbSSangeeta Misra free(ic); 200*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 201*dbed73cbSSangeeta Misra } 202*dbed73cbSSangeeta Misra 203*dbed73cbSSangeeta Misra (void) strlcpy((char *)&ic->ic_data, rulename, 204*dbed73cbSSangeeta Misra sizeof (ilbd_name_t)); 205*dbed73cbSSangeeta Misra 206*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, ic, ic_sz, tmp_rbuf, rbufsz); 207*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 208*dbed73cbSSangeeta Misra goto out; 209*dbed73cbSSangeeta Misra 210*dbed73cbSSangeeta Misra if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) { 211*dbed73cbSSangeeta Misra *rbuf = tmp_rbuf; 212*dbed73cbSSangeeta Misra return (rc); 213*dbed73cbSSangeeta Misra } 214*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&tmp_rbuf->ic_data; 215*dbed73cbSSangeeta Misra out: 216*dbed73cbSSangeeta Misra free(ic); 217*dbed73cbSSangeeta Misra free(tmp_rbuf); 218*dbed73cbSSangeeta Misra *rbuf = NULL; 219*dbed73cbSSangeeta Misra return (rc); 220*dbed73cbSSangeeta Misra } 221*dbed73cbSSangeeta Misra 222*dbed73cbSSangeeta Misra ilb_status_t 223*dbed73cbSSangeeta Misra ilb_walk_hc_srvs(ilb_handle_t h, hc_srvwalkerfunc_t fn, const char *rulename, 224*dbed73cbSSangeeta Misra void *arg) 225*dbed73cbSSangeeta Misra { 226*dbed73cbSSangeeta Misra ilb_status_t rc; 227*dbed73cbSSangeeta Misra ilb_hc_rule_srv_t *srvs; 228*dbed73cbSSangeeta Misra int i, j; 229*dbed73cbSSangeeta Misra ilb_comm_t *rbuf; 230*dbed73cbSSangeeta Misra size_t rbufsz; 231*dbed73cbSSangeeta Misra 232*dbed73cbSSangeeta Misra if (rulename != NULL) { 233*dbed73cbSSangeeta Misra rc = ilb_get_hc_srvs(h, rulename, &rbuf, &rbufsz); 234*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 235*dbed73cbSSangeeta Misra return (rc); 236*dbed73cbSSangeeta Misra srvs = (ilb_hc_rule_srv_t *)&rbuf->ic_data; 237*dbed73cbSSangeeta Misra for (i = 0; i < srvs->rs_num_srvs; i++) { 238*dbed73cbSSangeeta Misra rc = fn(h, &srvs->rs_srvs[i], arg); 239*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 240*dbed73cbSSangeeta Misra break; 241*dbed73cbSSangeeta Misra } 242*dbed73cbSSangeeta Misra free(rbuf); 243*dbed73cbSSangeeta Misra } else { 244*dbed73cbSSangeeta Misra ilbd_namelist_t *names; 245*dbed73cbSSangeeta Misra ilb_comm_t *srv_rbuf; 246*dbed73cbSSangeeta Misra size_t srv_rbufsz; 247*dbed73cbSSangeeta Misra 248*dbed73cbSSangeeta Misra rc = i_ilb_retrieve_rule_names(h, &rbuf, &rbufsz); 249*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 250*dbed73cbSSangeeta Misra return (rc); 251*dbed73cbSSangeeta Misra names = (ilbd_namelist_t *)&rbuf->ic_data; 252*dbed73cbSSangeeta Misra 253*dbed73cbSSangeeta Misra for (i = 0; i < names->ilbl_count; i++) { 254*dbed73cbSSangeeta Misra rc = ilb_get_hc_srvs(h, names->ilbl_name[i], 255*dbed73cbSSangeeta Misra &srv_rbuf, &srv_rbufsz); 256*dbed73cbSSangeeta Misra 257*dbed73cbSSangeeta Misra /* Not all rules have HC, so reset the error to OK. */ 258*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_RULE_NO_HC) { 259*dbed73cbSSangeeta Misra rc = ILB_STATUS_OK; 260*dbed73cbSSangeeta Misra continue; 261*dbed73cbSSangeeta Misra } else if (rc != ILB_STATUS_OK) { 262*dbed73cbSSangeeta Misra break; 263*dbed73cbSSangeeta Misra } 264*dbed73cbSSangeeta Misra 265*dbed73cbSSangeeta Misra srvs = (ilb_hc_rule_srv_t *)&srv_rbuf->ic_data; 266*dbed73cbSSangeeta Misra for (j = 0; j < srvs->rs_num_srvs; j++) { 267*dbed73cbSSangeeta Misra rc = fn(h, &srvs->rs_srvs[j], arg); 268*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 269*dbed73cbSSangeeta Misra break; 270*dbed73cbSSangeeta Misra } 271*dbed73cbSSangeeta Misra free(srv_rbuf); 272*dbed73cbSSangeeta Misra } 273*dbed73cbSSangeeta Misra free(rbuf); 274*dbed73cbSSangeeta Misra } 275*dbed73cbSSangeeta Misra return (rc); 276*dbed73cbSSangeeta Misra } 277