1dbed73cbSSangeeta Misra /* 2dbed73cbSSangeeta Misra * CDDL HEADER START 3dbed73cbSSangeeta Misra * 4dbed73cbSSangeeta Misra * The contents of this file are subject to the terms of the 5dbed73cbSSangeeta Misra * Common Development and Distribution License (the "License"). 6dbed73cbSSangeeta Misra * You may not use this file except in compliance with the License. 7dbed73cbSSangeeta Misra * 8dbed73cbSSangeeta Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9dbed73cbSSangeeta Misra * or http://www.opensolaris.org/os/licensing. 10dbed73cbSSangeeta Misra * See the License for the specific language governing permissions 11dbed73cbSSangeeta Misra * and limitations under the License. 12dbed73cbSSangeeta Misra * 13dbed73cbSSangeeta Misra * When distributing Covered Code, include this CDDL HEADER in each 14dbed73cbSSangeeta Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15dbed73cbSSangeeta Misra * If applicable, add the following below this CDDL HEADER, with the 16dbed73cbSSangeeta Misra * fields enclosed by brackets "[]" replaced with your own identifying 17dbed73cbSSangeeta Misra * information: Portions Copyright [yyyy] [name of copyright owner] 18dbed73cbSSangeeta Misra * 19dbed73cbSSangeeta Misra * CDDL HEADER END 20dbed73cbSSangeeta Misra */ 21dbed73cbSSangeeta Misra 22dbed73cbSSangeeta Misra /* 23*3ae6a67dSSangeeta Misra * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24dbed73cbSSangeeta Misra */ 25dbed73cbSSangeeta Misra 26dbed73cbSSangeeta Misra #include <stdlib.h> 27dbed73cbSSangeeta Misra #include <stdio.h> 28dbed73cbSSangeeta Misra #include <strings.h> 29dbed73cbSSangeeta Misra #include <sys/types.h> 30dbed73cbSSangeeta Misra #include <sys/socket.h> 31dbed73cbSSangeeta Misra #include <netinet/in.h> 32dbed73cbSSangeeta Misra #include <arpa/inet.h> 33dbed73cbSSangeeta Misra #include <sys/list.h> 34dbed73cbSSangeeta Misra #include <libilb.h> 35dbed73cbSSangeeta Misra #include <assert.h> 36dbed73cbSSangeeta Misra #include <libscf.h> 37dbed73cbSSangeeta Misra #include "libilb_impl.h" 38dbed73cbSSangeeta Misra #include "ilbd.h" 39dbed73cbSSangeeta Misra 40dbed73cbSSangeeta Misra #define ILBD_PG_NAME_RULE "rule_" 41dbed73cbSSangeeta Misra #define ILBD_PG_NAME_SG "sg_" 42dbed73cbSSangeeta Misra #define ILBD_PG_NAME_HC "hc_" 43dbed73cbSSangeeta Misra #define ILBD_SVC_FMRI "svc:/network/loadbalancer/ilb" 44dbed73cbSSangeeta Misra #define ILBD_INST_NAME "default" 45dbed73cbSSangeeta Misra 46dbed73cbSSangeeta Misra typedef enum { 47dbed73cbSSangeeta Misra ILBD_RULE_STATUS, 48dbed73cbSSangeeta Misra ILBD_RULE_VIP, 49dbed73cbSSangeeta Misra ILBD_RULE_PROTO, 50dbed73cbSSangeeta Misra ILBD_RULE_PORT, 51dbed73cbSSangeeta Misra ILBD_RULE_ALGO, 52dbed73cbSSangeeta Misra ILBD_RULE_TOPO, 53dbed73cbSSangeeta Misra ILBD_RULE_NAT_STR, 54dbed73cbSSangeeta Misra ILBD_RULE_NAT_END, 55dbed73cbSSangeeta Misra ILBD_RULE_STI_MASK, 56dbed73cbSSangeeta Misra ILBD_RULE_SGNAME, 57dbed73cbSSangeeta Misra ILBD_RULE_HCNAME, 58dbed73cbSSangeeta Misra ILBD_RULE_HCPORT, 59dbed73cbSSangeeta Misra ILBD_RULE_HCPFLAG, 60dbed73cbSSangeeta Misra ILBD_RULE_DRAINTIME, 61dbed73cbSSangeeta Misra ILBD_RULE_NAT_TO, 62dbed73cbSSangeeta Misra ILBD_RULE_PERS_TO, 63dbed73cbSSangeeta Misra 64dbed73cbSSangeeta Misra ILBD_SG_SERVER, 65dbed73cbSSangeeta Misra 66dbed73cbSSangeeta Misra ILBD_HC_TEST, 67dbed73cbSSangeeta Misra ILBD_HC_TIMEOUT, 68dbed73cbSSangeeta Misra ILBD_HC_INTERVAL, 69dbed73cbSSangeeta Misra ILBD_HC_DEF_PING, 70dbed73cbSSangeeta Misra ILBD_HC_COUNT, 71dbed73cbSSangeeta Misra 72dbed73cbSSangeeta Misra ILBD_VAR_INVALID 73dbed73cbSSangeeta Misra } ilbd_var_type_t; 74dbed73cbSSangeeta Misra 75dbed73cbSSangeeta Misra typedef struct prop_tbl_entry { 76dbed73cbSSangeeta Misra ilbd_var_type_t val_type; 77dbed73cbSSangeeta Misra const char *scf_propname; 78dbed73cbSSangeeta Misra scf_type_t scf_proptype; 79dbed73cbSSangeeta Misra } prop_tbl_entry_t; 80dbed73cbSSangeeta Misra 81dbed73cbSSangeeta Misra /* 82dbed73cbSSangeeta Misra * this table contains a map of all SCF properties, including rules, 83dbed73cbSSangeeta Misra * servergroups and health checks. The place to add new property needs to be 84dbed73cbSSangeeta Misra * watched carefully. When new properties are added, corresponding *VAR_NUM 85dbed73cbSSangeeta Misra * needs to be adjusted to reflect the correct index of the table 86dbed73cbSSangeeta Misra */ 87dbed73cbSSangeeta Misra prop_tbl_entry_t prop_tbl[] = { 88dbed73cbSSangeeta Misra /* entried for rule */ 89dbed73cbSSangeeta Misra {ILBD_RULE_STATUS, "status", SCF_TYPE_BOOLEAN}, 90dbed73cbSSangeeta Misra /* SCF_TYPE_NET_ADDR_V4 or SCF_TYPE_NET_ADDR_V6 */ 91dbed73cbSSangeeta Misra {ILBD_RULE_VIP, "vip", SCF_TYPE_INVALID}, 92dbed73cbSSangeeta Misra {ILBD_RULE_PROTO, "protocol", SCF_TYPE_ASTRING}, 93dbed73cbSSangeeta Misra {ILBD_RULE_PORT, "port", SCF_TYPE_ASTRING}, 94dbed73cbSSangeeta Misra {ILBD_RULE_ALGO, "ilb-algo", SCF_TYPE_ASTRING}, 95dbed73cbSSangeeta Misra {ILBD_RULE_TOPO, "ilb-type", SCF_TYPE_ASTRING}, 96dbed73cbSSangeeta Misra {ILBD_RULE_NAT_STR, "ilb-nat-start", SCF_TYPE_INVALID}, 97dbed73cbSSangeeta Misra {ILBD_RULE_NAT_END, "ilb-nat-end", SCF_TYPE_INVALID}, 98dbed73cbSSangeeta Misra {ILBD_RULE_STI_MASK, "ilb-sti-mask", SCF_TYPE_INVALID}, 99dbed73cbSSangeeta Misra {ILBD_RULE_SGNAME, "servergroup", SCF_TYPE_ASTRING}, 100dbed73cbSSangeeta Misra {ILBD_RULE_HCNAME, "healthcheck", SCF_TYPE_ASTRING}, 101dbed73cbSSangeeta Misra {ILBD_RULE_HCPORT, "hc-port", SCF_TYPE_INTEGER}, 102dbed73cbSSangeeta Misra {ILBD_RULE_HCPFLAG, "hcp-flag", SCF_TYPE_INTEGER}, 103dbed73cbSSangeeta Misra {ILBD_RULE_DRAINTIME, "drain-time", SCF_TYPE_INTEGER}, 104dbed73cbSSangeeta Misra {ILBD_RULE_NAT_TO, "nat-timeout", SCF_TYPE_INTEGER}, 105dbed73cbSSangeeta Misra {ILBD_RULE_PERS_TO, "pers-timeout", SCF_TYPE_INTEGER}, 106dbed73cbSSangeeta Misra /* add new rule related prop here */ 107dbed73cbSSangeeta Misra /* entries for sg */ 108dbed73cbSSangeeta Misra {ILBD_SG_SERVER, "server", SCF_TYPE_ASTRING}, 109dbed73cbSSangeeta Misra /* add new sg related prop here */ 110dbed73cbSSangeeta Misra /* entries for hc */ 111dbed73cbSSangeeta Misra {ILBD_HC_TEST, "test", SCF_TYPE_ASTRING}, 112dbed73cbSSangeeta Misra {ILBD_HC_TIMEOUT, "timeout", SCF_TYPE_INTEGER}, 113dbed73cbSSangeeta Misra {ILBD_HC_INTERVAL, "interval", SCF_TYPE_INTEGER}, 114dbed73cbSSangeeta Misra {ILBD_HC_DEF_PING, "ping", SCF_TYPE_BOOLEAN}, 115dbed73cbSSangeeta Misra /* add new hc related prop here */ 116dbed73cbSSangeeta Misra {ILBD_HC_COUNT, "count", SCF_TYPE_INTEGER} 117dbed73cbSSangeeta Misra }; 118dbed73cbSSangeeta Misra 119dbed73cbSSangeeta Misra #define ILBD_PROP_VAR_NUM (ILBD_HC_COUNT + 1) 120dbed73cbSSangeeta Misra #define ILBD_RULE_VAR_NUM (ILBD_SG_SERVER) 121dbed73cbSSangeeta Misra #define ILBD_SG_VAR_NUM (ILBD_HC_TEST - ILBD_SG_SERVER) 122dbed73cbSSangeeta Misra #define ILBD_HC_VAR_NUM (ILBD_PROP_VAR_NUM - ILBD_HC_TEST) 123dbed73cbSSangeeta Misra 124dbed73cbSSangeeta Misra static ilb_status_t ilbd_scf_set_prop(scf_propertygroup_t *, const char *, 125dbed73cbSSangeeta Misra scf_type_t, scf_value_t *); 126dbed73cbSSangeeta Misra static ilb_status_t ilbd_scf_retrieve_pg(const char *, scf_propertygroup_t **, 127dbed73cbSSangeeta Misra boolean_t); 128dbed73cbSSangeeta Misra static ilb_status_t ilbd_scf_delete_pg(scf_propertygroup_t *); 129dbed73cbSSangeeta Misra static ilb_status_t ilbd_scf_get_prop_val(scf_propertygroup_t *, const char *, 130dbed73cbSSangeeta Misra scf_value_t **); 131dbed73cbSSangeeta Misra 132dbed73cbSSangeeta Misra #define MIN(a, b) ((a) < (b) ? (a) : (b)) 133dbed73cbSSangeeta Misra 134dbed73cbSSangeeta Misra int 135dbed73cbSSangeeta Misra ilbd_scf_limit(int type) 136dbed73cbSSangeeta Misra { 137dbed73cbSSangeeta Misra return (MIN(scf_limit(type), 120)); 138dbed73cbSSangeeta Misra } 139dbed73cbSSangeeta Misra 140dbed73cbSSangeeta Misra /* 141dbed73cbSSangeeta Misra * Translate libscf error to libilb status 142dbed73cbSSangeeta Misra */ 143dbed73cbSSangeeta Misra ilb_status_t 144dbed73cbSSangeeta Misra ilbd_scf_err_to_ilb_err() 145dbed73cbSSangeeta Misra { 146dbed73cbSSangeeta Misra switch (scf_error()) { 147dbed73cbSSangeeta Misra case SCF_ERROR_NONE: 148dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 149dbed73cbSSangeeta Misra case SCF_ERROR_HANDLE_MISMATCH: 150dbed73cbSSangeeta Misra case SCF_ERROR_HANDLE_DESTROYED: 151dbed73cbSSangeeta Misra case SCF_ERROR_VERSION_MISMATCH: 152dbed73cbSSangeeta Misra case SCF_ERROR_NOT_BOUND: 153dbed73cbSSangeeta Misra case SCF_ERROR_CONSTRAINT_VIOLATED: 154dbed73cbSSangeeta Misra case SCF_ERROR_NOT_SET: 155dbed73cbSSangeeta Misra case SCF_ERROR_TYPE_MISMATCH: 156dbed73cbSSangeeta Misra case SCF_ERROR_INVALID_ARGUMENT: 157dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 158dbed73cbSSangeeta Misra case SCF_ERROR_NO_MEMORY: 159dbed73cbSSangeeta Misra case SCF_ERROR_NO_RESOURCES: 160dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 161dbed73cbSSangeeta Misra case SCF_ERROR_NOT_FOUND: 162dbed73cbSSangeeta Misra case SCF_ERROR_DELETED: 163dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 164dbed73cbSSangeeta Misra case SCF_ERROR_EXISTS: 165dbed73cbSSangeeta Misra return (ILB_STATUS_EEXIST); 166dbed73cbSSangeeta Misra case SCF_ERROR_PERMISSION_DENIED: 167dbed73cbSSangeeta Misra return (ILB_STATUS_PERMIT); 168dbed73cbSSangeeta Misra case SCF_ERROR_CALLBACK_FAILED: 169dbed73cbSSangeeta Misra return (ILB_STATUS_CALLBACK); 170dbed73cbSSangeeta Misra case SCF_ERROR_IN_USE: 171dbed73cbSSangeeta Misra return (ILB_STATUS_INUSE); 172dbed73cbSSangeeta Misra default: 173dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 174dbed73cbSSangeeta Misra } 175dbed73cbSSangeeta Misra } 176dbed73cbSSangeeta Misra 177dbed73cbSSangeeta Misra static void 178dbed73cbSSangeeta Misra ilbd_name_to_scfpgname(ilbd_scf_pg_type_t pg_type, const char *pgname, 179dbed73cbSSangeeta Misra char *scf_pgname) 180dbed73cbSSangeeta Misra { 181dbed73cbSSangeeta Misra switch (pg_type) { 182dbed73cbSSangeeta Misra case ILBD_SCF_RULE: 183dbed73cbSSangeeta Misra (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN, 184dbed73cbSSangeeta Misra ILBD_PG_NAME_RULE "%s", pgname); 185dbed73cbSSangeeta Misra return; 186dbed73cbSSangeeta Misra case ILBD_SCF_SG: 187dbed73cbSSangeeta Misra (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN, 188dbed73cbSSangeeta Misra ILBD_PG_NAME_SG "%s", pgname); 189dbed73cbSSangeeta Misra return; 190dbed73cbSSangeeta Misra case ILBD_SCF_HC: 191dbed73cbSSangeeta Misra (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN, 192dbed73cbSSangeeta Misra ILBD_PG_NAME_HC "%s", pgname); 193dbed73cbSSangeeta Misra return; 194dbed73cbSSangeeta Misra /* Should not happen. Log it and put ILB service in maintenance. */ 195dbed73cbSSangeeta Misra default: 196dbed73cbSSangeeta Misra logerr("ilbd_name_to_scfpgname: invalid pg type %d for pg %s", 197dbed73cbSSangeeta Misra pg_type, pgname); 198dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 199dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 200dbed73cbSSangeeta Misra return; 201dbed73cbSSangeeta Misra } 202dbed73cbSSangeeta Misra } 203dbed73cbSSangeeta Misra 204dbed73cbSSangeeta Misra static void 205dbed73cbSSangeeta Misra ilbd_scf_destroy(scf_handle_t *h, scf_service_t *s, scf_instance_t *inst, 206dbed73cbSSangeeta Misra scf_propertygroup_t *pg) 207dbed73cbSSangeeta Misra { 208dbed73cbSSangeeta Misra if (pg != NULL) 209dbed73cbSSangeeta Misra scf_pg_destroy(pg); 210dbed73cbSSangeeta Misra if (inst != NULL) 211dbed73cbSSangeeta Misra scf_instance_destroy(inst); 212dbed73cbSSangeeta Misra if (s != NULL) 213dbed73cbSSangeeta Misra scf_service_destroy(s); 214dbed73cbSSangeeta Misra if (h != NULL) 215dbed73cbSSangeeta Misra scf_handle_destroy(h); 216dbed73cbSSangeeta Misra } 217dbed73cbSSangeeta Misra 218dbed73cbSSangeeta Misra 219dbed73cbSSangeeta Misra static ilb_status_t 220dbed73cbSSangeeta Misra ilbd_scf_get_inst(scf_handle_t **h, scf_service_t **svc, scf_instance_t **inst) 221dbed73cbSSangeeta Misra { 222dbed73cbSSangeeta Misra if ((*h = scf_handle_create(SCF_VERSION)) == NULL) 223dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 224dbed73cbSSangeeta Misra 225dbed73cbSSangeeta Misra if (scf_handle_bind(*h) != 0) { 226dbed73cbSSangeeta Misra ilbd_scf_destroy(*h, NULL, NULL, NULL); 227dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 228dbed73cbSSangeeta Misra } 229dbed73cbSSangeeta Misra 230dbed73cbSSangeeta Misra if ((*svc = scf_service_create(*h)) == NULL) { 231dbed73cbSSangeeta Misra ilbd_scf_destroy(*h, NULL, NULL, NULL); 232dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 233dbed73cbSSangeeta Misra } 234dbed73cbSSangeeta Misra 235dbed73cbSSangeeta Misra if (scf_handle_decode_fmri(*h, ILBD_SVC_FMRI, NULL, *svc, NULL, NULL, 236dbed73cbSSangeeta Misra NULL, SCF_DECODE_FMRI_EXACT) != 0) { 237dbed73cbSSangeeta Misra ilbd_scf_destroy(*h, *svc, NULL, NULL); 238dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 239dbed73cbSSangeeta Misra } 240dbed73cbSSangeeta Misra 241dbed73cbSSangeeta Misra if ((*inst = scf_instance_create(*h)) == NULL) { 242dbed73cbSSangeeta Misra ilbd_scf_destroy(*h, *svc, NULL, NULL); 243dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 244dbed73cbSSangeeta Misra } 245dbed73cbSSangeeta Misra 246dbed73cbSSangeeta Misra if (scf_service_get_instance(*svc, ILBD_INST_NAME, *inst) != 0) { 247dbed73cbSSangeeta Misra ilbd_scf_destroy(*h, *svc, *inst, NULL); 248dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 249dbed73cbSSangeeta Misra } 250dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 251dbed73cbSSangeeta Misra } 252dbed73cbSSangeeta Misra 253dbed73cbSSangeeta Misra /* 254dbed73cbSSangeeta Misra * If create is set, create a new prop group, destroy the old one if exists. 255dbed73cbSSangeeta Misra * If create not set, try to find the prop group with given name. 256dbed73cbSSangeeta Misra * The created or found entry is returned as *pg. 257dbed73cbSSangeeta Misra * Caller frees *pg and its handle scf_pg_handle(pg) 258dbed73cbSSangeeta Misra */ 259dbed73cbSSangeeta Misra static ilb_status_t 260dbed73cbSSangeeta Misra ilbd_scf_retrieve_pg(const char *pgname, scf_propertygroup_t **pg, 261dbed73cbSSangeeta Misra boolean_t create) 262dbed73cbSSangeeta Misra { 263dbed73cbSSangeeta Misra scf_instance_t *inst; 264dbed73cbSSangeeta Misra scf_handle_t *h; 265dbed73cbSSangeeta Misra scf_service_t *svc; 266dbed73cbSSangeeta Misra ilb_status_t ret; 267dbed73cbSSangeeta Misra 268dbed73cbSSangeeta Misra ret = ilbd_scf_get_inst(&h, &svc, &inst); 269dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 270dbed73cbSSangeeta Misra return (ret); 271dbed73cbSSangeeta Misra 272dbed73cbSSangeeta Misra *pg = scf_pg_create(h); 273dbed73cbSSangeeta Misra if (*pg == NULL) 274dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 275dbed73cbSSangeeta Misra 276dbed73cbSSangeeta Misra if (scf_instance_get_pg(inst, pgname, *pg) != 0) { 277dbed73cbSSangeeta Misra if (scf_error() != SCF_ERROR_NOT_FOUND || 278dbed73cbSSangeeta Misra (scf_error() == SCF_ERROR_NOT_FOUND && (!create))) { 279dbed73cbSSangeeta Misra ilbd_scf_destroy(h, svc, inst, *pg); 280dbed73cbSSangeeta Misra *pg = NULL; 281dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 282dbed73cbSSangeeta Misra } 283dbed73cbSSangeeta Misra } else { 284dbed73cbSSangeeta Misra /* 285dbed73cbSSangeeta Misra * Found pg, don't want to create, return EEXIST. Note that 286dbed73cbSSangeeta Misra * h cannot be destroyed here since the caller needs to use it. 287dbed73cbSSangeeta Misra * The caller gets it by calling scf_pg_handle(). 288dbed73cbSSangeeta Misra */ 289dbed73cbSSangeeta Misra if (!create) { 290dbed73cbSSangeeta Misra ilbd_scf_destroy(NULL, svc, inst, NULL); 291dbed73cbSSangeeta Misra return (ILB_STATUS_EEXIST); 292dbed73cbSSangeeta Misra } 293dbed73cbSSangeeta Misra /* found pg, need to create, destroy the existing one */ 294dbed73cbSSangeeta Misra else 295dbed73cbSSangeeta Misra (void) ilbd_scf_delete_pg(*pg); 296dbed73cbSSangeeta Misra } 297dbed73cbSSangeeta Misra 298dbed73cbSSangeeta Misra if (create) { 299dbed73cbSSangeeta Misra if (scf_instance_add_pg(inst, pgname, 300dbed73cbSSangeeta Misra SCF_GROUP_APPLICATION, 0, *pg) != 0) { 301dbed73cbSSangeeta Misra ilbd_scf_destroy(h, svc, inst, *pg); 302dbed73cbSSangeeta Misra *pg = NULL; 303dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 304dbed73cbSSangeeta Misra } 305dbed73cbSSangeeta Misra } 306dbed73cbSSangeeta Misra 307dbed73cbSSangeeta Misra /* 308dbed73cbSSangeeta Misra * Note that handle cannot be destroyed here, caller sometimes needs 309dbed73cbSSangeeta Misra * to use it. It gets the handle by calling scf_pg_handle(). 310dbed73cbSSangeeta Misra */ 311dbed73cbSSangeeta Misra ilbd_scf_destroy(NULL, svc, inst, NULL); 312dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 313dbed73cbSSangeeta Misra } 314dbed73cbSSangeeta Misra 315dbed73cbSSangeeta Misra struct algo_tbl_entry { 316dbed73cbSSangeeta Misra ilb_algo_t algo_type; 317dbed73cbSSangeeta Misra const char *algo_str; 318dbed73cbSSangeeta Misra } algo_tbl[] = { 319dbed73cbSSangeeta Misra {ILB_ALG_ROUNDROBIN, "ROUNDROBIN"}, 320dbed73cbSSangeeta Misra {ILB_ALG_HASH_IP, "HASH-IP"}, 321dbed73cbSSangeeta Misra {ILB_ALG_HASH_IP_SPORT, "HASH-IP-PORT"}, 322dbed73cbSSangeeta Misra {ILB_ALG_HASH_IP_VIP, "HASH-IP-VIP"} 323dbed73cbSSangeeta Misra }; 324dbed73cbSSangeeta Misra 325dbed73cbSSangeeta Misra #define ILBD_ALGO_TBL_SIZE (sizeof (algo_tbl) / \ 326dbed73cbSSangeeta Misra sizeof (*algo_tbl)) 327dbed73cbSSangeeta Misra 328dbed73cbSSangeeta Misra void 329dbed73cbSSangeeta Misra ilbd_algo_to_str(ilb_algo_t algo_type, char *valstr) 330dbed73cbSSangeeta Misra { 331dbed73cbSSangeeta Misra int i; 332dbed73cbSSangeeta Misra 333dbed73cbSSangeeta Misra for (i = 0; i < ILBD_ALGO_TBL_SIZE; i++) { 334dbed73cbSSangeeta Misra if (algo_type == algo_tbl[i].algo_type) { 335dbed73cbSSangeeta Misra (void) strlcpy(valstr, algo_tbl[i].algo_str, 336dbed73cbSSangeeta Misra ILBD_MAX_VALUE_LEN); 337dbed73cbSSangeeta Misra return; 338dbed73cbSSangeeta Misra } 339dbed73cbSSangeeta Misra } 340dbed73cbSSangeeta Misra logerr("ilbd_algo_to_str: algo not found"); 341dbed73cbSSangeeta Misra } 342dbed73cbSSangeeta Misra 343dbed73cbSSangeeta Misra static void 344dbed73cbSSangeeta Misra ilbd_scf_str_to_algo(ilb_algo_t *algo_type, char *valstr) 345dbed73cbSSangeeta Misra { 346dbed73cbSSangeeta Misra int i; 347dbed73cbSSangeeta Misra 348dbed73cbSSangeeta Misra for (i = 0; i < ILBD_ALGO_TBL_SIZE; i++) { 349dbed73cbSSangeeta Misra if (strcmp(valstr, algo_tbl[i].algo_str) == 0) { 350dbed73cbSSangeeta Misra *algo_type = algo_tbl[i].algo_type; 351dbed73cbSSangeeta Misra return; 352dbed73cbSSangeeta Misra } 353dbed73cbSSangeeta Misra } 354dbed73cbSSangeeta Misra logerr("ilbd_scf_str_to_algo: algo not found"); 355dbed73cbSSangeeta Misra } 356dbed73cbSSangeeta Misra 357dbed73cbSSangeeta Misra struct topo_tbl_entry { 358dbed73cbSSangeeta Misra ilb_topo_t topo_type; 359dbed73cbSSangeeta Misra const char *topo_str; 360dbed73cbSSangeeta Misra } topo_tbl[] = { 361dbed73cbSSangeeta Misra {ILB_TOPO_DSR, "DSR"}, 362dbed73cbSSangeeta Misra {ILB_TOPO_NAT, "NAT"}, 363dbed73cbSSangeeta Misra {ILB_TOPO_HALF_NAT, "HALF-NAT"} 364dbed73cbSSangeeta Misra }; 365dbed73cbSSangeeta Misra 366dbed73cbSSangeeta Misra #define ILBD_TOPO_TBL_SIZE (sizeof (topo_tbl) / \ 367dbed73cbSSangeeta Misra sizeof (*topo_tbl)) 368dbed73cbSSangeeta Misra 369dbed73cbSSangeeta Misra void 370dbed73cbSSangeeta Misra ilbd_topo_to_str(ilb_topo_t topo_type, char *valstr) 371dbed73cbSSangeeta Misra { 372dbed73cbSSangeeta Misra int i; 373dbed73cbSSangeeta Misra 374dbed73cbSSangeeta Misra for (i = 0; i < ILBD_TOPO_TBL_SIZE; i++) { 375dbed73cbSSangeeta Misra if (topo_type == topo_tbl[i].topo_type) { 376dbed73cbSSangeeta Misra (void) strlcpy(valstr, topo_tbl[i].topo_str, 377dbed73cbSSangeeta Misra ILBD_MAX_VALUE_LEN); 378dbed73cbSSangeeta Misra return; 379dbed73cbSSangeeta Misra } 380dbed73cbSSangeeta Misra } 381dbed73cbSSangeeta Misra logerr("ilbd_scf_topo_to_str: topo not found"); 382dbed73cbSSangeeta Misra } 383dbed73cbSSangeeta Misra 384dbed73cbSSangeeta Misra static void 385dbed73cbSSangeeta Misra ilbd_scf_str_to_topo(ilb_topo_t *topo_type, char *valstr) 386dbed73cbSSangeeta Misra { 387dbed73cbSSangeeta Misra int i; 388dbed73cbSSangeeta Misra 389dbed73cbSSangeeta Misra for (i = 0; i < ILBD_TOPO_TBL_SIZE; i++) { 390dbed73cbSSangeeta Misra if (strcmp(valstr, topo_tbl[i].topo_str) == 0) { 391dbed73cbSSangeeta Misra *topo_type = topo_tbl[i].topo_type; 392dbed73cbSSangeeta Misra return; 393dbed73cbSSangeeta Misra } 394dbed73cbSSangeeta Misra } 395dbed73cbSSangeeta Misra logerr("ilbd_scf_str_to_topo: topo not found"); 396dbed73cbSSangeeta Misra } 397dbed73cbSSangeeta Misra 398dbed73cbSSangeeta Misra static void 399dbed73cbSSangeeta Misra ilbd_get_svr_field(char *valstr, struct in6_addr *sgs_addr, 400dbed73cbSSangeeta Misra int32_t *min_port, int32_t *max_port, int32_t *sgs_flags) 401dbed73cbSSangeeta Misra { 402dbed73cbSSangeeta Misra char *ipaddr, *ipverstr, *portstr, *flagstr; 403dbed73cbSSangeeta Misra int ip_ver; 404dbed73cbSSangeeta Misra ilb_ip_addr_t temp_ip; 405dbed73cbSSangeeta Misra void *addrptr; 406dbed73cbSSangeeta Misra char *max_portstr; 407dbed73cbSSangeeta Misra 408dbed73cbSSangeeta Misra ipaddr = strtok(valstr, ";"); 409dbed73cbSSangeeta Misra ipverstr = strtok(NULL, ";"); 410dbed73cbSSangeeta Misra portstr = strtok(NULL, ";"); 411dbed73cbSSangeeta Misra flagstr = strtok(NULL, ";"); 412dbed73cbSSangeeta Misra 413dbed73cbSSangeeta Misra if (ipaddr == NULL || ipverstr == NULL || portstr == NULL || 414dbed73cbSSangeeta Misra flagstr == NULL) { 415dbed73cbSSangeeta Misra logerr("%s: invalid server fields", __func__); 416dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 417dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 418dbed73cbSSangeeta Misra } 419dbed73cbSSangeeta Misra ip_ver = atoi(ipverstr); 420dbed73cbSSangeeta Misra addrptr = (ip_ver == AF_INET) ? (void *)&temp_ip.ia_v4 : 421dbed73cbSSangeeta Misra (void *)&temp_ip.ia_v6; 422dbed73cbSSangeeta Misra if (inet_pton(ip_ver, ipaddr, addrptr) == NULL) { 423dbed73cbSSangeeta Misra logerr("ilbd_get_svr_field: inet_pton failed"); 424dbed73cbSSangeeta Misra return; 425dbed73cbSSangeeta Misra } 426dbed73cbSSangeeta Misra 427dbed73cbSSangeeta Misra if (ip_ver == AF_INET) { 428dbed73cbSSangeeta Misra IN6_INADDR_TO_V4MAPPED(&(temp_ip.ia_v4), sgs_addr); 429dbed73cbSSangeeta Misra } else { 430dbed73cbSSangeeta Misra (void) memcpy(sgs_addr, &(temp_ip.ia_v6), 431dbed73cbSSangeeta Misra sizeof (struct in6_addr)); 432dbed73cbSSangeeta Misra } 433dbed73cbSSangeeta Misra 434dbed73cbSSangeeta Misra *sgs_flags = atoi(flagstr); 435dbed73cbSSangeeta Misra *min_port = atoi(strtok(portstr, "-")); 436dbed73cbSSangeeta Misra *min_port = ntohs(*min_port); 437dbed73cbSSangeeta Misra max_portstr = strtok(NULL, "-"); 438dbed73cbSSangeeta Misra if (max_portstr != NULL) { 439dbed73cbSSangeeta Misra *max_port = atoi(max_portstr); 440dbed73cbSSangeeta Misra *max_port = ntohs(*max_port); 441dbed73cbSSangeeta Misra } 442dbed73cbSSangeeta Misra } 443dbed73cbSSangeeta Misra 444dbed73cbSSangeeta Misra /* 445dbed73cbSSangeeta Misra * Convert the info of a server to its SCF string value representation. 446dbed73cbSSangeeta Misra * Argument value is assumed to be of size ILBD_MAX_VALUE_LEN. 447dbed73cbSSangeeta Misra */ 448dbed73cbSSangeeta Misra static void 449dbed73cbSSangeeta Misra ilbd_srv_scf_val(ilbd_srv_t *srv, char *value) 450dbed73cbSSangeeta Misra { 451dbed73cbSSangeeta Misra char ipstr[INET6_ADDRSTRLEN]; 452dbed73cbSSangeeta Misra int ipver; 453dbed73cbSSangeeta Misra 454dbed73cbSSangeeta Misra if (GET_AF(&srv->isv_addr) == AF_INET) { 455dbed73cbSSangeeta Misra struct in_addr v4_addr; 456dbed73cbSSangeeta Misra 457dbed73cbSSangeeta Misra IN6_V4MAPPED_TO_INADDR(&srv->isv_addr, &v4_addr); 458dbed73cbSSangeeta Misra (void) inet_ntop(AF_INET, &v4_addr, ipstr, sizeof (ipstr)); 459dbed73cbSSangeeta Misra ipver = AF_INET; 460dbed73cbSSangeeta Misra } else { 461dbed73cbSSangeeta Misra (void) inet_ntop(AF_INET6, &srv->isv_addr, ipstr, 462dbed73cbSSangeeta Misra sizeof (ipstr)); 463dbed73cbSSangeeta Misra ipver = AF_INET6; 464dbed73cbSSangeeta Misra } 465dbed73cbSSangeeta Misra (void) snprintf(value, ILBD_MAX_VALUE_LEN, "%s;%d;%d-%d;%d", 466dbed73cbSSangeeta Misra ipstr, ipver, ntohs(srv->isv_minport), ntohs(srv->isv_maxport), 467dbed73cbSSangeeta Misra srv->isv_flags); 468dbed73cbSSangeeta Misra } 469dbed73cbSSangeeta Misra 470dbed73cbSSangeeta Misra /* get the "ip:port:status" str of the #num server in the servergroup */ 471dbed73cbSSangeeta Misra ilb_status_t 472dbed73cbSSangeeta Misra ilbd_get_svr_info(ilbd_sg_t *sg, int num, char *valstr, char *svrname) 473dbed73cbSSangeeta Misra { 474dbed73cbSSangeeta Misra int i; 475dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv = NULL; 476dbed73cbSSangeeta Misra 477dbed73cbSSangeeta Misra tmp_srv = list_head(&sg->isg_srvlist); 478dbed73cbSSangeeta Misra if (tmp_srv == NULL) 479dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 480dbed73cbSSangeeta Misra 481dbed73cbSSangeeta Misra for (i = 0; i < num; i++) 482dbed73cbSSangeeta Misra tmp_srv = list_next(&sg->isg_srvlist, tmp_srv); 483dbed73cbSSangeeta Misra 484dbed73cbSSangeeta Misra assert(tmp_srv != NULL); 485dbed73cbSSangeeta Misra if (valstr != NULL) 486dbed73cbSSangeeta Misra ilbd_srv_scf_val(tmp_srv, valstr); 487dbed73cbSSangeeta Misra 488dbed73cbSSangeeta Misra if (svrname != NULL) { 489dbed73cbSSangeeta Misra (void) snprintf(svrname, ILBD_MAX_NAME_LEN, "server%d", 490dbed73cbSSangeeta Misra tmp_srv->isv_id); 491dbed73cbSSangeeta Misra } 492dbed73cbSSangeeta Misra 493dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 494dbed73cbSSangeeta Misra } 495dbed73cbSSangeeta Misra 496dbed73cbSSangeeta Misra /* convert a struct in6_addr to valstr */ 497dbed73cbSSangeeta Misra ilb_status_t 498dbed73cbSSangeeta Misra ilbd_scf_ip_to_str(uint16_t ipversion, struct in6_addr *addr, 499dbed73cbSSangeeta Misra scf_type_t *scftype, char *valstr) 500dbed73cbSSangeeta Misra { 501dbed73cbSSangeeta Misra size_t vallen; 502dbed73cbSSangeeta Misra ilb_ip_addr_t ipaddr; 503dbed73cbSSangeeta Misra void *addrptr; 504dbed73cbSSangeeta Misra 505dbed73cbSSangeeta Misra vallen = (ipversion == AF_INET) ? INET_ADDRSTRLEN : 506dbed73cbSSangeeta Misra INET6_ADDRSTRLEN; 507dbed73cbSSangeeta Misra if (scftype != NULL) 508dbed73cbSSangeeta Misra *scftype = (ipversion == AF_INET) ? SCF_TYPE_NET_ADDR_V4 : 509dbed73cbSSangeeta Misra SCF_TYPE_NET_ADDR_V6; 510dbed73cbSSangeeta Misra 511dbed73cbSSangeeta Misra IP_COPY_IMPL_2_CLI(addr, &ipaddr); 512dbed73cbSSangeeta Misra addrptr = (ipversion == AF_INET) ? 513dbed73cbSSangeeta Misra (void *)&ipaddr.ia_v4 : (void *)&ipaddr.ia_v6; 514dbed73cbSSangeeta Misra (void) inet_ntop(ipversion, (void *)addrptr, valstr, vallen); 515dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 516dbed73cbSSangeeta Misra } 517dbed73cbSSangeeta Misra 518dbed73cbSSangeeta Misra /* 519dbed73cbSSangeeta Misra * This function takes a ilbd internal data struct and translate its value to 520dbed73cbSSangeeta Misra * scf value. The data struct is passed in within "data". 521dbed73cbSSangeeta Misra * Upon successful return, the scf val will be stored in "val" and the scf type 522dbed73cbSSangeeta Misra * will be returned in "scftype" if scftype != NULL, the number of values 523dbed73cbSSangeeta Misra * translated will be in "numval" 524dbed73cbSSangeeta Misra * If it failed, no data will be written to SCF 525dbed73cbSSangeeta Misra */ 526dbed73cbSSangeeta Misra static ilb_status_t 527dbed73cbSSangeeta Misra ilbd_data_to_scfval(ilbd_scf_pg_type_t pg_type, ilbd_var_type_t type, 528dbed73cbSSangeeta Misra scf_handle_t *h, void *data, scf_value_t ***val, scf_type_t *scftype, 529dbed73cbSSangeeta Misra int *numval) 530dbed73cbSSangeeta Misra { 531dbed73cbSSangeeta Misra scf_value_t *v, **varray = NULL; 532dbed73cbSSangeeta Misra int ret = ILB_STATUS_OK; 533dbed73cbSSangeeta Misra int i; 534dbed73cbSSangeeta Misra int scf_val_len = ILBD_MAX_VALUE_LEN; 535*3ae6a67dSSangeeta Misra char *valstr = NULL; 536dbed73cbSSangeeta Misra int valint; 537dbed73cbSSangeeta Misra uint8_t valbool = 0; 538dbed73cbSSangeeta Misra ilbd_rule_t *r_ent = NULL; 539dbed73cbSSangeeta Misra ilbd_sg_t *s_ent = NULL; 540dbed73cbSSangeeta Misra ilbd_hc_t *h_ent = NULL; 541dbed73cbSSangeeta Misra 542dbed73cbSSangeeta Misra switch (pg_type) { 543dbed73cbSSangeeta Misra case ILBD_SCF_RULE: 544dbed73cbSSangeeta Misra r_ent = (ilbd_rule_t *)data; 545dbed73cbSSangeeta Misra break; 546dbed73cbSSangeeta Misra case ILBD_SCF_SG: 547dbed73cbSSangeeta Misra s_ent = (ilbd_sg_t *)data; 548dbed73cbSSangeeta Misra break; 549dbed73cbSSangeeta Misra case ILBD_SCF_HC: 550dbed73cbSSangeeta Misra h_ent = (ilbd_hc_t *)data; 551dbed73cbSSangeeta Misra break; 552dbed73cbSSangeeta Misra } 553dbed73cbSSangeeta Misra 554dbed73cbSSangeeta Misra v = scf_value_create(h); 555dbed73cbSSangeeta Misra if (v == NULL) 556dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 557dbed73cbSSangeeta Misra 558*3ae6a67dSSangeeta Misra if ((valstr = malloc(scf_val_len)) == NULL) 559*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 560dbed73cbSSangeeta Misra switch (type) { 561dbed73cbSSangeeta Misra case ILBD_RULE_STATUS: 562dbed73cbSSangeeta Misra valbool = r_ent->irl_flags & ILB_FLAGS_RULE_ENABLED; 563dbed73cbSSangeeta Misra break; 564dbed73cbSSangeeta Misra case ILBD_RULE_VIP: 565dbed73cbSSangeeta Misra ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion, &r_ent->irl_vip, 566dbed73cbSSangeeta Misra scftype, valstr); 567dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 568*3ae6a67dSSangeeta Misra free(valstr); 569dbed73cbSSangeeta Misra scf_value_destroy(v); 570dbed73cbSSangeeta Misra return (ret); 571dbed73cbSSangeeta Misra } 572dbed73cbSSangeeta Misra break; 573dbed73cbSSangeeta Misra case ILBD_RULE_PROTO: { 574dbed73cbSSangeeta Misra struct protoent *protoent; 575dbed73cbSSangeeta Misra 576dbed73cbSSangeeta Misra protoent = getprotobynumber(r_ent->irl_proto); 577*3ae6a67dSSangeeta Misra (void) strlcpy(valstr, protoent->p_name, scf_val_len); 578dbed73cbSSangeeta Misra break; 579dbed73cbSSangeeta Misra } 580dbed73cbSSangeeta Misra case ILBD_RULE_PORT: 581*3ae6a67dSSangeeta Misra (void) snprintf(valstr, scf_val_len, "%d-%d", 582dbed73cbSSangeeta Misra r_ent->irl_minport, r_ent->irl_maxport); 583dbed73cbSSangeeta Misra break; 584dbed73cbSSangeeta Misra case ILBD_RULE_ALGO: 585dbed73cbSSangeeta Misra ilbd_algo_to_str(r_ent->irl_algo, valstr); 586dbed73cbSSangeeta Misra break; 587dbed73cbSSangeeta Misra case ILBD_RULE_TOPO: 588dbed73cbSSangeeta Misra ilbd_topo_to_str(r_ent->irl_topo, valstr); 589dbed73cbSSangeeta Misra break; 590dbed73cbSSangeeta Misra case ILBD_RULE_NAT_STR: 591dbed73cbSSangeeta Misra ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion, 592dbed73cbSSangeeta Misra &r_ent->irl_nat_src_start, scftype, valstr); 593dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 594*3ae6a67dSSangeeta Misra free(valstr); 595dbed73cbSSangeeta Misra scf_value_destroy(v); 596dbed73cbSSangeeta Misra return (ret); 597dbed73cbSSangeeta Misra } 598dbed73cbSSangeeta Misra break; 599dbed73cbSSangeeta Misra case ILBD_RULE_NAT_END: 600dbed73cbSSangeeta Misra ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion, 601dbed73cbSSangeeta Misra &r_ent->irl_nat_src_end, scftype, valstr); 602dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 603*3ae6a67dSSangeeta Misra free(valstr); 604dbed73cbSSangeeta Misra scf_value_destroy(v); 605dbed73cbSSangeeta Misra return (ret); 606dbed73cbSSangeeta Misra } 607dbed73cbSSangeeta Misra break; 608dbed73cbSSangeeta Misra case ILBD_RULE_STI_MASK: 609dbed73cbSSangeeta Misra ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion, 610dbed73cbSSangeeta Misra &r_ent->irl_stickymask, scftype, valstr); 611dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 612*3ae6a67dSSangeeta Misra free(valstr); 613dbed73cbSSangeeta Misra scf_value_destroy(v); 614dbed73cbSSangeeta Misra return (ret); 615dbed73cbSSangeeta Misra } 616dbed73cbSSangeeta Misra break; 617dbed73cbSSangeeta Misra case ILBD_RULE_SGNAME: 618*3ae6a67dSSangeeta Misra (void) strlcpy(valstr, r_ent->irl_sgname, scf_val_len); 619dbed73cbSSangeeta Misra break; 620dbed73cbSSangeeta Misra case ILBD_RULE_HCNAME: 621dbed73cbSSangeeta Misra if (r_ent->irl_hcname[0] != '\0') 622dbed73cbSSangeeta Misra (void) strlcpy(valstr, r_ent->irl_hcname, 623*3ae6a67dSSangeeta Misra scf_val_len); 624dbed73cbSSangeeta Misra else 625dbed73cbSSangeeta Misra bzero(valstr, ILBD_MAX_VALUE_LEN); 626dbed73cbSSangeeta Misra break; 627dbed73cbSSangeeta Misra case ILBD_RULE_HCPORT: 628dbed73cbSSangeeta Misra valint = r_ent->irl_hcport; 629dbed73cbSSangeeta Misra break; 630dbed73cbSSangeeta Misra case ILBD_RULE_HCPFLAG: 631dbed73cbSSangeeta Misra valint = r_ent->irl_hcpflag; 632dbed73cbSSangeeta Misra break; 633dbed73cbSSangeeta Misra case ILBD_RULE_DRAINTIME: 634dbed73cbSSangeeta Misra valint = r_ent->irl_conndrain; 635dbed73cbSSangeeta Misra break; 636dbed73cbSSangeeta Misra case ILBD_RULE_NAT_TO: 637dbed73cbSSangeeta Misra valint = r_ent->irl_nat_timeout; 638dbed73cbSSangeeta Misra break; 639dbed73cbSSangeeta Misra case ILBD_RULE_PERS_TO: 640dbed73cbSSangeeta Misra valint = r_ent->irl_sticky_timeout; 641dbed73cbSSangeeta Misra break; 642dbed73cbSSangeeta Misra 643dbed73cbSSangeeta Misra case ILBD_SG_SERVER: 644dbed73cbSSangeeta Misra if (s_ent->isg_srvcount == 0) { 645dbed73cbSSangeeta Misra (void) strlcpy(valstr, "EMPTY_SERVERGROUP", 646*3ae6a67dSSangeeta Misra scf_val_len); 647dbed73cbSSangeeta Misra break; 648dbed73cbSSangeeta Misra } 649dbed73cbSSangeeta Misra 650dbed73cbSSangeeta Misra varray = calloc(sizeof (*varray), s_ent->isg_srvcount); 651dbed73cbSSangeeta Misra if (varray == NULL) { 652dbed73cbSSangeeta Misra scf_value_destroy(v); 653*3ae6a67dSSangeeta Misra free(valstr); 654dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 655dbed73cbSSangeeta Misra } 656dbed73cbSSangeeta Misra 657dbed73cbSSangeeta Misra for (i = 0; i < s_ent->isg_srvcount; i++) { 658dbed73cbSSangeeta Misra if (v == NULL) { 659dbed73cbSSangeeta Misra for (i--; i >= 0; i--) 660dbed73cbSSangeeta Misra scf_value_destroy(varray[i]); 661*3ae6a67dSSangeeta Misra free(valstr); 662dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 663dbed73cbSSangeeta Misra } 664dbed73cbSSangeeta Misra 665dbed73cbSSangeeta Misra ret = ilbd_get_svr_info(s_ent, i, valstr, NULL); 666dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 667dbed73cbSSangeeta Misra scf_value_destroy(v); 668dbed73cbSSangeeta Misra for (i--; i >= 0; i--) 669dbed73cbSSangeeta Misra scf_value_destroy(varray[i]); 670*3ae6a67dSSangeeta Misra free(valstr); 671dbed73cbSSangeeta Misra free(varray); 672dbed73cbSSangeeta Misra return (ret); 673dbed73cbSSangeeta Misra } 674dbed73cbSSangeeta Misra (void) scf_value_set_astring(v, valstr); 675dbed73cbSSangeeta Misra varray[i] = v; 676dbed73cbSSangeeta Misra v = scf_value_create(h); 677dbed73cbSSangeeta Misra } 678dbed73cbSSangeeta Misra /* the last 'v' we created will go unused, so drop it */ 679dbed73cbSSangeeta Misra scf_value_destroy(v); 680dbed73cbSSangeeta Misra *numval = s_ent->isg_srvcount; 681dbed73cbSSangeeta Misra *val = varray; 682*3ae6a67dSSangeeta Misra free(valstr); 683dbed73cbSSangeeta Misra return (ret); 684dbed73cbSSangeeta Misra case ILBD_HC_TEST: 685*3ae6a67dSSangeeta Misra (void) strlcpy(valstr, h_ent->ihc_test, scf_val_len); 686dbed73cbSSangeeta Misra break; 687dbed73cbSSangeeta Misra case ILBD_HC_TIMEOUT: 688dbed73cbSSangeeta Misra valint = h_ent->ihc_timeout; 689dbed73cbSSangeeta Misra break; 690dbed73cbSSangeeta Misra case ILBD_HC_INTERVAL: 691dbed73cbSSangeeta Misra valint = h_ent->ihc_interval; 692dbed73cbSSangeeta Misra break; 693dbed73cbSSangeeta Misra case ILBD_HC_DEF_PING: 694dbed73cbSSangeeta Misra valbool = h_ent->ihc_def_ping; 695dbed73cbSSangeeta Misra break; 696dbed73cbSSangeeta Misra case ILBD_HC_COUNT: 697dbed73cbSSangeeta Misra valint = h_ent->ihc_count; 698dbed73cbSSangeeta Misra break; 699dbed73cbSSangeeta Misra } 700dbed73cbSSangeeta Misra 701dbed73cbSSangeeta Misra switch (*scftype) { 702dbed73cbSSangeeta Misra case SCF_TYPE_BOOLEAN: 703dbed73cbSSangeeta Misra scf_value_set_boolean(v, valbool); 704dbed73cbSSangeeta Misra break; 705dbed73cbSSangeeta Misra case SCF_TYPE_ASTRING: 706dbed73cbSSangeeta Misra (void) scf_value_set_astring(v, valstr); 707dbed73cbSSangeeta Misra break; 708dbed73cbSSangeeta Misra case SCF_TYPE_INTEGER: 709dbed73cbSSangeeta Misra scf_value_set_integer(v, valint); 710dbed73cbSSangeeta Misra break; 711dbed73cbSSangeeta Misra case SCF_TYPE_NET_ADDR_V4: 712dbed73cbSSangeeta Misra (void) scf_value_set_from_string(v, SCF_TYPE_NET_ADDR_V4, 713dbed73cbSSangeeta Misra valstr); 714dbed73cbSSangeeta Misra break; 715dbed73cbSSangeeta Misra case SCF_TYPE_NET_ADDR_V6: 716dbed73cbSSangeeta Misra (void) scf_value_set_from_string(v, SCF_TYPE_NET_ADDR_V6, 717dbed73cbSSangeeta Misra valstr); 718dbed73cbSSangeeta Misra break; 719dbed73cbSSangeeta Misra } 720*3ae6a67dSSangeeta Misra free(valstr); 721dbed73cbSSangeeta Misra 722dbed73cbSSangeeta Misra varray = calloc(1, sizeof (*varray)); 723dbed73cbSSangeeta Misra if (varray == NULL) { 724dbed73cbSSangeeta Misra scf_value_destroy(v); 725dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 726dbed73cbSSangeeta Misra } 727dbed73cbSSangeeta Misra varray[0] = v; 728dbed73cbSSangeeta Misra *val = varray; 729dbed73cbSSangeeta Misra *numval = 1; 730dbed73cbSSangeeta Misra return (ret); 731dbed73cbSSangeeta Misra } 732dbed73cbSSangeeta Misra 733dbed73cbSSangeeta Misra /* 734dbed73cbSSangeeta Misra * create a scf property group 735dbed73cbSSangeeta Misra */ 736dbed73cbSSangeeta Misra ilb_status_t 737dbed73cbSSangeeta Misra ilbd_create_pg(ilbd_scf_pg_type_t pg_type, void *data) 738dbed73cbSSangeeta Misra { 739dbed73cbSSangeeta Misra ilb_status_t ret; 740dbed73cbSSangeeta Misra char *pgname; 741dbed73cbSSangeeta Misra scf_propertygroup_t *pg = NULL; 742dbed73cbSSangeeta Misra scf_value_t **val; 743dbed73cbSSangeeta Misra scf_handle_t *h; 744dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 745*3ae6a67dSSangeeta Misra char *scfpgbuf; /* property group name or group type */ 746dbed73cbSSangeeta Misra int i, i_st, i_end; 747dbed73cbSSangeeta Misra 748dbed73cbSSangeeta Misra switch (pg_type) { 749dbed73cbSSangeeta Misra case ILBD_SCF_RULE: { 750dbed73cbSSangeeta Misra ilbd_rule_t *r_ent = (ilbd_rule_t *)data; 751dbed73cbSSangeeta Misra 752dbed73cbSSangeeta Misra pgname = r_ent->irl_name; 753dbed73cbSSangeeta Misra i_st = 0; 754dbed73cbSSangeeta Misra i_end = ILBD_RULE_VAR_NUM; 755dbed73cbSSangeeta Misra break; 756dbed73cbSSangeeta Misra } 757dbed73cbSSangeeta Misra case ILBD_SCF_SG: { 758dbed73cbSSangeeta Misra ilbd_sg_t *s_ent = (ilbd_sg_t *)data; 759dbed73cbSSangeeta Misra 760dbed73cbSSangeeta Misra pgname = s_ent->isg_name; 761dbed73cbSSangeeta Misra i_st = ILBD_RULE_VAR_NUM; 762dbed73cbSSangeeta Misra i_end = ILBD_RULE_VAR_NUM + ILBD_SG_VAR_NUM; 763dbed73cbSSangeeta Misra break; 764dbed73cbSSangeeta Misra } 765dbed73cbSSangeeta Misra case ILBD_SCF_HC: { 766dbed73cbSSangeeta Misra ilbd_hc_t *h_ent = (ilbd_hc_t *)data; 767dbed73cbSSangeeta Misra 768dbed73cbSSangeeta Misra pgname = h_ent->ihc_name; 769dbed73cbSSangeeta Misra i_st = ILBD_RULE_VAR_NUM + ILBD_SG_VAR_NUM; 770dbed73cbSSangeeta Misra i_end = ILBD_PROP_VAR_NUM; 771dbed73cbSSangeeta Misra break; 772dbed73cbSSangeeta Misra } 773dbed73cbSSangeeta Misra default: 774dbed73cbSSangeeta Misra logdebug("ilbd_create_pg: invalid pg type %d for pg %s", 775dbed73cbSSangeeta Misra pg_type, pgname); 776dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 777dbed73cbSSangeeta Misra } 778*3ae6a67dSSangeeta Misra if ((scfpgbuf = malloc(scf_name_len)) == NULL) 779*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 780dbed73cbSSangeeta Misra 781*3ae6a67dSSangeeta Misra ilbd_name_to_scfpgname(pg_type, pgname, scfpgbuf); 782dbed73cbSSangeeta Misra 783*3ae6a67dSSangeeta Misra ret = ilbd_scf_retrieve_pg(scfpgbuf, &pg, B_TRUE); 784*3ae6a67dSSangeeta Misra if (ret != ILB_STATUS_OK) { 785*3ae6a67dSSangeeta Misra free(scfpgbuf); 786dbed73cbSSangeeta Misra return (ret); 787*3ae6a67dSSangeeta Misra } 788dbed73cbSSangeeta Misra h = scf_pg_handle(pg); 789dbed73cbSSangeeta Misra 790dbed73cbSSangeeta Misra /* fill in props */ 791dbed73cbSSangeeta Misra for (i = i_st; i < i_end; i++) { 792dbed73cbSSangeeta Misra int num, j; 793dbed73cbSSangeeta Misra scf_type_t scftype = prop_tbl[i].scf_proptype; 794dbed73cbSSangeeta Misra 795dbed73cbSSangeeta Misra ret = ilbd_data_to_scfval(pg_type, prop_tbl[i].val_type, h, 796dbed73cbSSangeeta Misra data, &val, &scftype, &num); 797dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 798dbed73cbSSangeeta Misra goto done; 799dbed73cbSSangeeta Misra 800dbed73cbSSangeeta Misra for (j = 0; j < num; j++) { 801dbed73cbSSangeeta Misra if (pg_type == ILBD_SCF_SG) { 802dbed73cbSSangeeta Misra ret = ilbd_get_svr_info(data, j, NULL, 803*3ae6a67dSSangeeta Misra scfpgbuf); 804dbed73cbSSangeeta Misra if (ret == ILB_STATUS_ENOENT) { 805*3ae6a67dSSangeeta Misra (void) strlcpy(scfpgbuf, 806*3ae6a67dSSangeeta Misra "EMPTY_SERVER", scf_name_len); 807dbed73cbSSangeeta Misra } 808*3ae6a67dSSangeeta Misra ret = ilbd_scf_set_prop(pg, scfpgbuf, 809dbed73cbSSangeeta Misra scftype, val[j]); 810dbed73cbSSangeeta Misra } else { 811dbed73cbSSangeeta Misra ret = ilbd_scf_set_prop(pg, 812dbed73cbSSangeeta Misra prop_tbl[i].scf_propname, scftype, val[j]); 813dbed73cbSSangeeta Misra } 814dbed73cbSSangeeta Misra scf_value_destroy(val[j]); 815dbed73cbSSangeeta Misra } 816dbed73cbSSangeeta Misra free(val); 817dbed73cbSSangeeta Misra } 818dbed73cbSSangeeta Misra 819dbed73cbSSangeeta Misra done: 820*3ae6a67dSSangeeta Misra free(scfpgbuf); 821dbed73cbSSangeeta Misra ilbd_scf_destroy(h, NULL, NULL, pg); 822dbed73cbSSangeeta Misra return (ret); 823dbed73cbSSangeeta Misra } 824dbed73cbSSangeeta Misra 825dbed73cbSSangeeta Misra /* 826dbed73cbSSangeeta Misra * destroy a scf property group 827dbed73cbSSangeeta Misra */ 828dbed73cbSSangeeta Misra static ilb_status_t 829dbed73cbSSangeeta Misra ilbd_scf_delete_pg(scf_propertygroup_t *pg) 830dbed73cbSSangeeta Misra { 831dbed73cbSSangeeta Misra if (scf_pg_delete(pg) != 0) 832dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 833dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 834dbed73cbSSangeeta Misra } 835dbed73cbSSangeeta Misra 836dbed73cbSSangeeta Misra /* sg can have same name as rule */ 837dbed73cbSSangeeta Misra ilb_status_t 838dbed73cbSSangeeta Misra ilbd_destroy_pg(ilbd_scf_pg_type_t pg_t, const char *pgname) 839dbed73cbSSangeeta Misra { 840dbed73cbSSangeeta Misra ilb_status_t ret; 841dbed73cbSSangeeta Misra scf_propertygroup_t *pg; 842dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 843*3ae6a67dSSangeeta Misra char *scfname; 844dbed73cbSSangeeta Misra 845*3ae6a67dSSangeeta Misra if ((scfname = malloc(scf_name_len)) == NULL) 846*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 847dbed73cbSSangeeta Misra ilbd_name_to_scfpgname(pg_t, pgname, scfname); 848dbed73cbSSangeeta Misra 849dbed73cbSSangeeta Misra ret = ilbd_scf_retrieve_pg(scfname, &pg, B_FALSE); 850*3ae6a67dSSangeeta Misra free(scfname); 851dbed73cbSSangeeta Misra if (ret != ILB_STATUS_EEXIST) 852dbed73cbSSangeeta Misra return (ret); 853dbed73cbSSangeeta Misra ret = ilbd_scf_delete_pg(pg); 854dbed73cbSSangeeta Misra ilbd_scf_destroy(scf_pg_handle(pg), NULL, NULL, pg); 855dbed73cbSSangeeta Misra return (ret); 856dbed73cbSSangeeta Misra } 857dbed73cbSSangeeta Misra 858dbed73cbSSangeeta Misra /* 859dbed73cbSSangeeta Misra * Set named property to scf value specified. If property is new, 860dbed73cbSSangeeta Misra * create it. 861dbed73cbSSangeeta Misra */ 862dbed73cbSSangeeta Misra static ilb_status_t 863dbed73cbSSangeeta Misra ilbd_scf_set_prop(scf_propertygroup_t *pg, const char *propname, 864dbed73cbSSangeeta Misra scf_type_t proptype, scf_value_t *val) 865dbed73cbSSangeeta Misra { 866dbed73cbSSangeeta Misra scf_handle_t *h = NULL; 867dbed73cbSSangeeta Misra scf_property_t *prop = NULL; 868dbed73cbSSangeeta Misra scf_value_t *oldval = NULL; 869dbed73cbSSangeeta Misra scf_transaction_t *tx = NULL; 870dbed73cbSSangeeta Misra scf_transaction_entry_t *ent = NULL; 871dbed73cbSSangeeta Misra boolean_t new = B_FALSE; 872dbed73cbSSangeeta Misra ilb_status_t ret = ILB_STATUS_OK; 873dbed73cbSSangeeta Misra int commit_ret; 874dbed73cbSSangeeta Misra 875dbed73cbSSangeeta Misra h = scf_pg_handle(pg); 876dbed73cbSSangeeta Misra if (h == NULL || propname == NULL) 877dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 878dbed73cbSSangeeta Misra 879dbed73cbSSangeeta Misra ret = ilbd_scf_get_prop_val(pg, propname, &oldval); 880dbed73cbSSangeeta Misra if (oldval != NULL) 881dbed73cbSSangeeta Misra scf_value_destroy(oldval); 882dbed73cbSSangeeta Misra if (ret == ILB_STATUS_ENOENT) 883dbed73cbSSangeeta Misra new = B_TRUE; 884dbed73cbSSangeeta Misra else if (ret != ILB_STATUS_OK) 885dbed73cbSSangeeta Misra return (ret); 886dbed73cbSSangeeta Misra 887dbed73cbSSangeeta Misra if ((prop = scf_property_create(h)) == NULL) 888dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 889dbed73cbSSangeeta Misra if ((tx = scf_transaction_create(h)) == NULL || 890dbed73cbSSangeeta Misra (ent = scf_entry_create(h)) == NULL) { 891dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 892dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: create scf transaction failed\n"); 893dbed73cbSSangeeta Misra goto out; 894dbed73cbSSangeeta Misra } 895dbed73cbSSangeeta Misra 896dbed73cbSSangeeta Misra if (scf_transaction_start(tx, pg) == -1) { 897dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 898dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: start scf transaction failed\n"); 899dbed73cbSSangeeta Misra goto out; 900dbed73cbSSangeeta Misra } 901dbed73cbSSangeeta Misra 902dbed73cbSSangeeta Misra if (new) { 903dbed73cbSSangeeta Misra if (scf_transaction_property_new(tx, ent, propname, 904dbed73cbSSangeeta Misra proptype) == -1) { 905dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 906dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: create scf prop failed\n"); 907dbed73cbSSangeeta Misra goto out; 908dbed73cbSSangeeta Misra } 909dbed73cbSSangeeta Misra } else { 910dbed73cbSSangeeta Misra if (scf_transaction_property_change(tx, ent, propname, proptype) 911dbed73cbSSangeeta Misra == -1) { 912dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 913dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: change scf prop failed\n"); 914dbed73cbSSangeeta Misra goto out; 915dbed73cbSSangeeta Misra } 916dbed73cbSSangeeta Misra } 917dbed73cbSSangeeta Misra 918dbed73cbSSangeeta Misra if (scf_entry_add_value(ent, val) != 0) { 919dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: add scf entry failed\n"); 920dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 921dbed73cbSSangeeta Misra goto out; 922dbed73cbSSangeeta Misra } 923dbed73cbSSangeeta Misra 924dbed73cbSSangeeta Misra commit_ret = scf_transaction_commit(tx); 925dbed73cbSSangeeta Misra switch (commit_ret) { 926dbed73cbSSangeeta Misra case 1: 927dbed73cbSSangeeta Misra ret = ILB_STATUS_OK; 928dbed73cbSSangeeta Misra /* update pg here, so subsequent property setting succeeds */ 929dbed73cbSSangeeta Misra (void) scf_pg_update(pg); 930dbed73cbSSangeeta Misra break; 931dbed73cbSSangeeta Misra case 0: 932dbed73cbSSangeeta Misra /* transaction failed due to not having most recent pg */ 933dbed73cbSSangeeta Misra ret = ILB_STATUS_INUSE; 934dbed73cbSSangeeta Misra break; 935dbed73cbSSangeeta Misra default: 936dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 937dbed73cbSSangeeta Misra break; 938dbed73cbSSangeeta Misra } 939dbed73cbSSangeeta Misra out: 940dbed73cbSSangeeta Misra if (tx != NULL) 941dbed73cbSSangeeta Misra scf_transaction_destroy(tx); 942dbed73cbSSangeeta Misra if (ent != NULL) 943dbed73cbSSangeeta Misra scf_entry_destroy(ent); 944dbed73cbSSangeeta Misra if (prop != NULL) 945dbed73cbSSangeeta Misra scf_property_destroy(prop); 946dbed73cbSSangeeta Misra 947dbed73cbSSangeeta Misra return (ret); 948dbed73cbSSangeeta Misra } 949dbed73cbSSangeeta Misra 950dbed73cbSSangeeta Misra /* 951dbed73cbSSangeeta Misra * get a prop's scf val 952dbed73cbSSangeeta Misra */ 953dbed73cbSSangeeta Misra static ilb_status_t 954dbed73cbSSangeeta Misra ilbd_scf_get_prop_val(scf_propertygroup_t *pg, const char *propname, 955dbed73cbSSangeeta Misra scf_value_t **val) 956dbed73cbSSangeeta Misra { 957dbed73cbSSangeeta Misra scf_handle_t *h = NULL; 958dbed73cbSSangeeta Misra scf_property_t *prop = NULL; 959dbed73cbSSangeeta Misra scf_value_t *value = NULL; 960dbed73cbSSangeeta Misra ilb_status_t ret = ILB_STATUS_OK; 961dbed73cbSSangeeta Misra 962dbed73cbSSangeeta Misra h = scf_pg_handle(pg); 963dbed73cbSSangeeta Misra if (h == NULL || propname == NULL) 964dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 965dbed73cbSSangeeta Misra 966dbed73cbSSangeeta Misra if ((prop = scf_property_create(h)) == NULL) 967dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 968dbed73cbSSangeeta Misra 969dbed73cbSSangeeta Misra if (scf_pg_get_property(pg, propname, prop) != 0) { 970dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 971dbed73cbSSangeeta Misra goto out; 972dbed73cbSSangeeta Misra } 973dbed73cbSSangeeta Misra 974dbed73cbSSangeeta Misra if ((value = scf_value_create(h)) == NULL) { 975dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 976dbed73cbSSangeeta Misra goto out; 977dbed73cbSSangeeta Misra } 978dbed73cbSSangeeta Misra 979dbed73cbSSangeeta Misra if (scf_property_get_value(prop, value) != 0) { 980dbed73cbSSangeeta Misra scf_value_destroy(value); 981dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 982dbed73cbSSangeeta Misra goto out; 983dbed73cbSSangeeta Misra } 984dbed73cbSSangeeta Misra 985dbed73cbSSangeeta Misra *val = value; 986dbed73cbSSangeeta Misra out: 987dbed73cbSSangeeta Misra if (prop != NULL) 988dbed73cbSSangeeta Misra scf_property_destroy(prop); 989dbed73cbSSangeeta Misra 990dbed73cbSSangeeta Misra return (ret); 991dbed73cbSSangeeta Misra } 992dbed73cbSSangeeta Misra 993dbed73cbSSangeeta Misra typedef struct ilbd_data 994dbed73cbSSangeeta Misra { 995dbed73cbSSangeeta Misra union { 996dbed73cbSSangeeta Misra ilb_sg_info_t *sg_info; 997dbed73cbSSangeeta Misra ilb_hc_info_t *hc_info; 998dbed73cbSSangeeta Misra ilb_rule_info_t *rule_info; 999dbed73cbSSangeeta Misra } data; 1000dbed73cbSSangeeta Misra ilbd_scf_pg_type_t pg_type; /* type of data */ 1001dbed73cbSSangeeta Misra #define sg_data data.sg_info 1002dbed73cbSSangeeta Misra #define hc_data data.hc_info 1003dbed73cbSSangeeta Misra #define rule_data data.rule_info 1004dbed73cbSSangeeta Misra } ilbd_data_t; 1005dbed73cbSSangeeta Misra 1006dbed73cbSSangeeta Misra void 1007dbed73cbSSangeeta Misra ilbd_scf_str_to_ip(int ipversion, char *ipstr, struct in6_addr *addr) 1008dbed73cbSSangeeta Misra { 1009dbed73cbSSangeeta Misra ilb_ip_addr_t ipaddr; 1010dbed73cbSSangeeta Misra void *addrptr; 1011dbed73cbSSangeeta Misra 1012dbed73cbSSangeeta Misra addrptr = (ipversion == AF_INET) ? 1013dbed73cbSSangeeta Misra (void *)&ipaddr.ia_v4 : (void *)&ipaddr.ia_v6; 1014dbed73cbSSangeeta Misra (void) inet_pton(ipversion, ipstr, addrptr); 1015dbed73cbSSangeeta Misra if (ipversion == AF_INET) { 1016dbed73cbSSangeeta Misra IN6_INADDR_TO_V4MAPPED(&(ipaddr.ia_v4), addr); 1017dbed73cbSSangeeta Misra } else { 1018dbed73cbSSangeeta Misra (void) memcpy(addr, &(ipaddr.ia_v6), 1019dbed73cbSSangeeta Misra sizeof (struct in6_addr)); 1020dbed73cbSSangeeta Misra } 1021dbed73cbSSangeeta Misra } 1022dbed73cbSSangeeta Misra 1023dbed73cbSSangeeta Misra /* 1024dbed73cbSSangeeta Misra * This function takes a scf value and writes it to the correct field of the 1025dbed73cbSSangeeta Misra * corresponding data struct. 1026dbed73cbSSangeeta Misra */ 1027dbed73cbSSangeeta Misra static ilb_status_t 1028dbed73cbSSangeeta Misra ilbd_scfval_to_data(const char *propname, ilbd_var_type_t ilb_type, 1029dbed73cbSSangeeta Misra scf_value_t *val, ilbd_data_t *ilb_data) 1030dbed73cbSSangeeta Misra { 1031dbed73cbSSangeeta Misra 1032dbed73cbSSangeeta Misra scf_type_t scf_type = scf_value_type(val); 1033dbed73cbSSangeeta Misra ilbd_scf_pg_type_t pg_type = ilb_data->pg_type; 1034dbed73cbSSangeeta Misra int ret = 0; 1035dbed73cbSSangeeta Misra ilb_rule_info_t *r_ent = NULL; 1036dbed73cbSSangeeta Misra ilb_sg_info_t *s_ent = NULL; 1037dbed73cbSSangeeta Misra ilb_hc_info_t *h_ent = NULL; 1038dbed73cbSSangeeta Misra char ipstr[INET6_ADDRSTRLEN]; 1039*3ae6a67dSSangeeta Misra char *valstr; 1040dbed73cbSSangeeta Misra int64_t valint; 1041dbed73cbSSangeeta Misra uint8_t valbool; 1042dbed73cbSSangeeta Misra int ipversion; 1043dbed73cbSSangeeta Misra 1044dbed73cbSSangeeta Misra switch (pg_type) { 1045dbed73cbSSangeeta Misra case ILBD_SCF_RULE: 1046dbed73cbSSangeeta Misra r_ent = ilb_data->rule_data; 1047dbed73cbSSangeeta Misra break; 1048dbed73cbSSangeeta Misra case ILBD_SCF_HC: 1049dbed73cbSSangeeta Misra h_ent = ilb_data->hc_data; 1050dbed73cbSSangeeta Misra break; 1051dbed73cbSSangeeta Misra case ILBD_SCF_SG: 1052dbed73cbSSangeeta Misra s_ent = ilb_data->sg_data; 1053dbed73cbSSangeeta Misra break; 1054dbed73cbSSangeeta Misra } 1055dbed73cbSSangeeta Misra 1056dbed73cbSSangeeta Misra /* get scf value out */ 1057*3ae6a67dSSangeeta Misra if ((valstr = malloc(ILBD_MAX_VALUE_LEN)) == NULL) 1058*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 1059dbed73cbSSangeeta Misra switch (scf_type) { 1060dbed73cbSSangeeta Misra case SCF_TYPE_NET_ADDR_V4: 1061dbed73cbSSangeeta Misra if (scf_value_get_as_string_typed(val, 1062*3ae6a67dSSangeeta Misra SCF_TYPE_NET_ADDR_V4, ipstr, INET_ADDRSTRLEN) < 0) { 1063*3ae6a67dSSangeeta Misra free(valstr); 1064dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1065*3ae6a67dSSangeeta Misra } 1066dbed73cbSSangeeta Misra ipversion = AF_INET; 1067dbed73cbSSangeeta Misra break; 1068dbed73cbSSangeeta Misra case SCF_TYPE_NET_ADDR_V6: 1069dbed73cbSSangeeta Misra if (scf_value_get_as_string_typed(val, 1070*3ae6a67dSSangeeta Misra SCF_TYPE_NET_ADDR_V6, ipstr, 1071*3ae6a67dSSangeeta Misra INET6_ADDRSTRLEN) < 0) { 1072*3ae6a67dSSangeeta Misra free(valstr); 1073dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1074*3ae6a67dSSangeeta Misra } 1075dbed73cbSSangeeta Misra ipversion = AF_INET6; 1076dbed73cbSSangeeta Misra break; 1077dbed73cbSSangeeta Misra case SCF_TYPE_BOOLEAN: 1078*3ae6a67dSSangeeta Misra if (scf_value_get_boolean(val, &valbool) < 0) { 1079*3ae6a67dSSangeeta Misra free(valstr); 1080dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1081*3ae6a67dSSangeeta Misra } 1082dbed73cbSSangeeta Misra break; 1083dbed73cbSSangeeta Misra case SCF_TYPE_ASTRING: 1084*3ae6a67dSSangeeta Misra if (scf_value_get_astring(val, valstr, 1085*3ae6a67dSSangeeta Misra ILBD_MAX_VALUE_LEN) < 0) { 1086*3ae6a67dSSangeeta Misra free(valstr); 1087dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1088*3ae6a67dSSangeeta Misra } 1089dbed73cbSSangeeta Misra break; 1090dbed73cbSSangeeta Misra case SCF_TYPE_INTEGER: 1091*3ae6a67dSSangeeta Misra if (scf_value_get_integer(val, &valint) < 0) { 1092*3ae6a67dSSangeeta Misra free(valstr); 1093dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1094*3ae6a67dSSangeeta Misra } 1095dbed73cbSSangeeta Misra break; 1096dbed73cbSSangeeta Misra default: 1097*3ae6a67dSSangeeta Misra free(valstr); 1098dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1099dbed73cbSSangeeta Misra } 1100dbed73cbSSangeeta Misra 1101dbed73cbSSangeeta Misra ret = ILB_STATUS_OK; 1102dbed73cbSSangeeta Misra switch (ilb_type) { 1103dbed73cbSSangeeta Misra case ILBD_RULE_STATUS: 1104dbed73cbSSangeeta Misra if (valbool) 1105dbed73cbSSangeeta Misra r_ent->rl_flags |= ILB_FLAGS_RULE_ENABLED; 1106dbed73cbSSangeeta Misra break; 1107dbed73cbSSangeeta Misra case ILBD_RULE_VIP: 1108dbed73cbSSangeeta Misra r_ent->rl_ipversion = ipversion; 1109dbed73cbSSangeeta Misra ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_vip); 1110dbed73cbSSangeeta Misra break; 1111dbed73cbSSangeeta Misra case ILBD_RULE_PROTO: { 1112dbed73cbSSangeeta Misra struct protoent *protoent; 1113dbed73cbSSangeeta Misra 1114dbed73cbSSangeeta Misra protoent = getprotobyname(valstr); 1115dbed73cbSSangeeta Misra r_ent->rl_proto = protoent->p_proto; 1116dbed73cbSSangeeta Misra break; 1117dbed73cbSSangeeta Misra } 1118dbed73cbSSangeeta Misra case ILBD_RULE_PORT: { 1119dbed73cbSSangeeta Misra char *token1, *token2; 1120dbed73cbSSangeeta Misra 1121dbed73cbSSangeeta Misra token1 = strtok(valstr, "-"); 1122dbed73cbSSangeeta Misra token2 = strtok(NULL, "-"); 1123dbed73cbSSangeeta Misra r_ent->rl_minport = atoi(token1); 1124dbed73cbSSangeeta Misra r_ent->rl_maxport = atoi(token2); 1125dbed73cbSSangeeta Misra break; 1126dbed73cbSSangeeta Misra } 1127dbed73cbSSangeeta Misra case ILBD_RULE_ALGO: 1128dbed73cbSSangeeta Misra ilbd_scf_str_to_algo(&(r_ent->rl_algo), valstr); 1129dbed73cbSSangeeta Misra break; 1130dbed73cbSSangeeta Misra case ILBD_RULE_TOPO: 1131dbed73cbSSangeeta Misra ilbd_scf_str_to_topo(&(r_ent->rl_topo), valstr); 1132dbed73cbSSangeeta Misra break; 1133dbed73cbSSangeeta Misra case ILBD_RULE_NAT_STR: 1134dbed73cbSSangeeta Misra ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_nat_src_start); 1135dbed73cbSSangeeta Misra break; 1136dbed73cbSSangeeta Misra case ILBD_RULE_NAT_END: 1137dbed73cbSSangeeta Misra ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_nat_src_end); 1138dbed73cbSSangeeta Misra break; 1139dbed73cbSSangeeta Misra case ILBD_RULE_STI_MASK: 1140dbed73cbSSangeeta Misra ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_stickymask); 1141dbed73cbSSangeeta Misra if (ipversion == AF_INET) { 1142dbed73cbSSangeeta Misra if (!IN6_IS_ADDR_V4MAPPED_ANY(&r_ent->rl_stickymask)) 1143dbed73cbSSangeeta Misra r_ent->rl_flags |= ILB_FLAGS_RULE_STICKY; 1144dbed73cbSSangeeta Misra } else { 1145dbed73cbSSangeeta Misra if (!IN6_IS_ADDR_UNSPECIFIED(&r_ent->rl_stickymask)) 1146dbed73cbSSangeeta Misra r_ent->rl_flags |= ILB_FLAGS_RULE_STICKY; 1147dbed73cbSSangeeta Misra } 1148dbed73cbSSangeeta Misra break; 1149dbed73cbSSangeeta Misra case ILBD_RULE_SGNAME: 1150dbed73cbSSangeeta Misra (void) strlcpy(r_ent->rl_sgname, valstr, 1151dbed73cbSSangeeta Misra sizeof (r_ent->rl_sgname)); 1152dbed73cbSSangeeta Misra break; 1153dbed73cbSSangeeta Misra case ILBD_RULE_HCNAME: 1154dbed73cbSSangeeta Misra (void) strlcpy(r_ent->rl_hcname, valstr, 1155dbed73cbSSangeeta Misra sizeof (r_ent->rl_hcname)); 1156dbed73cbSSangeeta Misra break; 1157dbed73cbSSangeeta Misra case ILBD_RULE_HCPORT: 1158dbed73cbSSangeeta Misra r_ent->rl_hcport = valint; 1159dbed73cbSSangeeta Misra break; 1160dbed73cbSSangeeta Misra case ILBD_RULE_HCPFLAG: 1161dbed73cbSSangeeta Misra r_ent->rl_hcpflag = valint; 1162dbed73cbSSangeeta Misra break; 1163dbed73cbSSangeeta Misra case ILBD_RULE_DRAINTIME: 1164dbed73cbSSangeeta Misra r_ent->rl_conndrain = valint; 1165dbed73cbSSangeeta Misra break; 1166dbed73cbSSangeeta Misra case ILBD_RULE_NAT_TO: 1167dbed73cbSSangeeta Misra r_ent->rl_nat_timeout = valint; 1168dbed73cbSSangeeta Misra break; 1169dbed73cbSSangeeta Misra case ILBD_RULE_PERS_TO: 1170dbed73cbSSangeeta Misra r_ent->rl_sticky_timeout = valint; 1171dbed73cbSSangeeta Misra break; 1172dbed73cbSSangeeta Misra 1173dbed73cbSSangeeta Misra case ILBD_SG_SERVER: { 1174dbed73cbSSangeeta Misra int svr_cnt = s_ent->sg_srvcount; 1175dbed73cbSSangeeta Misra 1176dbed73cbSSangeeta Misra /* found a new server, increase the svr count of this sg */ 1177dbed73cbSSangeeta Misra s_ent->sg_srvcount++; 1178dbed73cbSSangeeta Misra 1179dbed73cbSSangeeta Misra /* 1180dbed73cbSSangeeta Misra * valstr contains information of one server in the servergroup 1181dbed73cbSSangeeta Misra * valstr is in the format of "ip:minport-maxport:enable" 1182dbed73cbSSangeeta Misra */ 1183dbed73cbSSangeeta Misra s_ent = realloc(s_ent, sizeof (ilb_sg_info_t) + 1184dbed73cbSSangeeta Misra s_ent->sg_srvcount * sizeof (ilb_sg_srv_t)); 1185dbed73cbSSangeeta Misra 1186dbed73cbSSangeeta Misra /* sgs_srvID is the sg name, leave it blank */ 1187dbed73cbSSangeeta Misra /* 1188dbed73cbSSangeeta Misra * sgs_id is the digit in propname, propname is in a format of 1189dbed73cbSSangeeta Misra * "server" + the digital serverID. We get the serverID by 1190dbed73cbSSangeeta Misra * reading from the 7th char of propname. 1191dbed73cbSSangeeta Misra */ 1192dbed73cbSSangeeta Misra s_ent->sg_servers[svr_cnt].sgs_id = atoi(&propname[6]); 1193dbed73cbSSangeeta Misra 1194dbed73cbSSangeeta Misra ilbd_get_svr_field(valstr, 1195dbed73cbSSangeeta Misra &s_ent->sg_servers[svr_cnt].sgs_addr, 1196dbed73cbSSangeeta Misra &s_ent->sg_servers[svr_cnt].sgs_minport, 1197dbed73cbSSangeeta Misra &s_ent->sg_servers[svr_cnt].sgs_maxport, 1198dbed73cbSSangeeta Misra &s_ent->sg_servers[svr_cnt].sgs_flags); 1199dbed73cbSSangeeta Misra ilb_data->sg_data = s_ent; 1200dbed73cbSSangeeta Misra 1201dbed73cbSSangeeta Misra break; 1202dbed73cbSSangeeta Misra } 1203dbed73cbSSangeeta Misra case ILBD_HC_TEST: 1204dbed73cbSSangeeta Misra (void) strlcpy(h_ent->hci_test, valstr, 1205dbed73cbSSangeeta Misra sizeof (h_ent->hci_test)); 1206dbed73cbSSangeeta Misra break; 1207dbed73cbSSangeeta Misra case ILBD_HC_TIMEOUT: 1208dbed73cbSSangeeta Misra h_ent->hci_timeout = valint; 1209dbed73cbSSangeeta Misra break; 1210dbed73cbSSangeeta Misra case ILBD_HC_INTERVAL: 1211dbed73cbSSangeeta Misra h_ent->hci_interval = valint; 1212dbed73cbSSangeeta Misra break; 1213dbed73cbSSangeeta Misra case ILBD_HC_DEF_PING: 1214dbed73cbSSangeeta Misra h_ent->hci_def_ping = valbool; 1215dbed73cbSSangeeta Misra break; 1216dbed73cbSSangeeta Misra case ILBD_HC_COUNT: 1217dbed73cbSSangeeta Misra h_ent->hci_count = valint; 1218dbed73cbSSangeeta Misra break; 1219dbed73cbSSangeeta Misra case ILBD_VAR_INVALID: 1220dbed73cbSSangeeta Misra /* 1221dbed73cbSSangeeta Misra * An empty server group is represented by an invalid 1222dbed73cbSSangeeta Misra * SCF property. So when loading a server group, this 1223dbed73cbSSangeeta Misra * case can be hit. But it should happen only for this 1224dbed73cbSSangeeta Misra * single case. So if it happens in another case, move 1225dbed73cbSSangeeta Misra * the service into maintenance mode. 1226dbed73cbSSangeeta Misra */ 1227dbed73cbSSangeeta Misra if (pg_type != ILBD_SCF_SG || scf_type != SCF_TYPE_ASTRING) { 1228dbed73cbSSangeeta Misra logerr("%s: invalid ilb type", __func__); 1229dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 1230dbed73cbSSangeeta Misra } else { 1231dbed73cbSSangeeta Misra logdebug("%s: invalid ilb type", __func__); 1232dbed73cbSSangeeta Misra } 1233dbed73cbSSangeeta Misra break; 1234dbed73cbSSangeeta Misra } 1235dbed73cbSSangeeta Misra 1236*3ae6a67dSSangeeta Misra free(valstr); 1237dbed73cbSSangeeta Misra return (ret); 1238dbed73cbSSangeeta Misra } 1239dbed73cbSSangeeta Misra 1240dbed73cbSSangeeta Misra static ilbd_var_type_t 1241dbed73cbSSangeeta Misra ilbd_name_to_valtype(const char *prop_name) 1242dbed73cbSSangeeta Misra { 1243dbed73cbSSangeeta Misra int i; 1244dbed73cbSSangeeta Misra 1245dbed73cbSSangeeta Misra for (i = 0; i < ILBD_PROP_VAR_NUM; i++) 1246dbed73cbSSangeeta Misra if (strncmp(prop_name, prop_tbl[i].scf_propname, 1247dbed73cbSSangeeta Misra strlen(prop_tbl[i].scf_propname)) == 0) 1248dbed73cbSSangeeta Misra return (prop_tbl[i].val_type); 1249dbed73cbSSangeeta Misra 1250dbed73cbSSangeeta Misra logdebug("ilbd_name_to_valtype: couldn't find prop %s", prop_name); 1251dbed73cbSSangeeta Misra return (ILBD_VAR_INVALID); 1252dbed73cbSSangeeta Misra } 1253dbed73cbSSangeeta Misra 1254dbed73cbSSangeeta Misra /* callback for pg_walk_prop, arg is ilbd_data_t */ 1255dbed73cbSSangeeta Misra static ilb_status_t 1256dbed73cbSSangeeta Misra ilbd_scf_load_prop(scf_propertygroup_t *pg, const char *prop_name, void *arg) 1257dbed73cbSSangeeta Misra { 1258dbed73cbSSangeeta Misra scf_handle_t *h; 1259dbed73cbSSangeeta Misra scf_value_t *val; 1260dbed73cbSSangeeta Misra ilb_status_t ret; 1261dbed73cbSSangeeta Misra ilbd_data_t *ilb_data = (ilbd_data_t *)arg; 1262dbed73cbSSangeeta Misra ilbd_var_type_t val_type = ilbd_name_to_valtype(prop_name); 1263dbed73cbSSangeeta Misra 1264dbed73cbSSangeeta Misra h = scf_pg_handle(pg); 1265dbed73cbSSangeeta Misra if (h == NULL) 1266dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1267dbed73cbSSangeeta Misra 1268dbed73cbSSangeeta Misra ret = ilbd_scf_get_prop_val(pg, prop_name, &val); 1269dbed73cbSSangeeta Misra if (ret == ILB_STATUS_ENOENT) 1270dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1271dbed73cbSSangeeta Misra else if (ret != ILB_STATUS_OK) 1272dbed73cbSSangeeta Misra return (ret); 1273dbed73cbSSangeeta Misra 1274dbed73cbSSangeeta Misra /* 1275dbed73cbSSangeeta Misra * Load value to ilb_data. 1276dbed73cbSSangeeta Misra */ 1277dbed73cbSSangeeta Misra ret = ilbd_scfval_to_data(prop_name, val_type, val, ilb_data); 1278dbed73cbSSangeeta Misra 1279dbed73cbSSangeeta Misra out: 1280dbed73cbSSangeeta Misra if (val != NULL) 1281dbed73cbSSangeeta Misra scf_value_destroy(val); 1282dbed73cbSSangeeta Misra 1283dbed73cbSSangeeta Misra return (ret); 1284dbed73cbSSangeeta Misra } 1285dbed73cbSSangeeta Misra 1286dbed73cbSSangeeta Misra /* 1287dbed73cbSSangeeta Misra * walk properties in one prop group, arg is ilbd_data 1288dbed73cbSSangeeta Misra * cb is ilbd_scf_load_prop() 1289dbed73cbSSangeeta Misra */ 1290dbed73cbSSangeeta Misra static ilb_status_t 1291dbed73cbSSangeeta Misra ilbd_scf_pg_walk_props(scf_propertygroup_t *pg, 1292dbed73cbSSangeeta Misra ilb_status_t (*cb)(scf_propertygroup_t *, const char *, void *), 1293dbed73cbSSangeeta Misra void *arg) 1294dbed73cbSSangeeta Misra { 1295dbed73cbSSangeeta Misra scf_handle_t *h; 1296dbed73cbSSangeeta Misra scf_iter_t *propiter; 1297dbed73cbSSangeeta Misra scf_property_t *prop; 1298dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 1299*3ae6a67dSSangeeta Misra char *prop_name = NULL; 1300dbed73cbSSangeeta Misra ilb_status_t ret = ILB_STATUS_OK; 1301dbed73cbSSangeeta Misra int scf_ret = -1; 1302dbed73cbSSangeeta Misra 1303dbed73cbSSangeeta Misra h = scf_pg_handle(pg); 1304dbed73cbSSangeeta Misra if (h == NULL) 1305dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1306dbed73cbSSangeeta Misra 1307dbed73cbSSangeeta Misra prop = scf_property_create(h); 1308dbed73cbSSangeeta Misra propiter = scf_iter_create(h); 1309dbed73cbSSangeeta Misra if (prop == NULL || propiter == NULL) 1310dbed73cbSSangeeta Misra goto out; 1311dbed73cbSSangeeta Misra 1312dbed73cbSSangeeta Misra if (scf_iter_pg_properties(propiter, pg) != 0) 1313dbed73cbSSangeeta Misra goto out; 1314dbed73cbSSangeeta Misra 1315*3ae6a67dSSangeeta Misra if ((prop_name = malloc(scf_name_len)) == NULL) { 1316*3ae6a67dSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1317*3ae6a67dSSangeeta Misra goto out; 1318*3ae6a67dSSangeeta Misra } 1319dbed73cbSSangeeta Misra while ((scf_ret = scf_iter_next_property(propiter, prop)) == 1) { 1320*3ae6a67dSSangeeta Misra if (scf_property_get_name(prop, prop_name, scf_name_len) 1321dbed73cbSSangeeta Misra < 0) { 1322dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1323dbed73cbSSangeeta Misra goto out; 1324dbed73cbSSangeeta Misra } 1325dbed73cbSSangeeta Misra ret = cb(pg, prop_name, arg); 1326dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1327dbed73cbSSangeeta Misra break; 1328dbed73cbSSangeeta Misra } 1329dbed73cbSSangeeta Misra out: 1330*3ae6a67dSSangeeta Misra if (prop_name != NULL) 1331*3ae6a67dSSangeeta Misra free(prop_name); 1332dbed73cbSSangeeta Misra if (scf_ret == -1) 1333dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1334dbed73cbSSangeeta Misra if (prop != NULL) 1335dbed73cbSSangeeta Misra scf_property_destroy(prop); 1336dbed73cbSSangeeta Misra if (propiter != NULL) 1337dbed73cbSSangeeta Misra scf_iter_destroy(propiter); 1338dbed73cbSSangeeta Misra 1339dbed73cbSSangeeta Misra return (ret); 1340dbed73cbSSangeeta Misra } 1341dbed73cbSSangeeta Misra 1342dbed73cbSSangeeta Misra /* cbs are libd_create_X */ 1343dbed73cbSSangeeta Misra static ilb_status_t 1344dbed73cbSSangeeta Misra ilbd_scf_instance_walk_pg(scf_instance_t *inst, 1345dbed73cbSSangeeta Misra ilbd_scf_pg_type_t pg_type, 1346dbed73cbSSangeeta Misra ilb_status_t (*cb)(void *, int, struct passwd *, ucred_t *), 1347dbed73cbSSangeeta Misra void *arg1, void *arg2) 1348dbed73cbSSangeeta Misra { 1349dbed73cbSSangeeta Misra int scf_ret; 1350dbed73cbSSangeeta Misra ilb_status_t ret; 1351dbed73cbSSangeeta Misra scf_handle_t *h; 1352dbed73cbSSangeeta Misra scf_iter_t *pgiter; 1353dbed73cbSSangeeta Misra scf_propertygroup_t *newpg; 1354dbed73cbSSangeeta Misra int port = *((int *)arg1); 1355*3ae6a67dSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 1356*3ae6a67dSSangeeta Misra char *pg_name = NULL; 1357dbed73cbSSangeeta Misra 1358dbed73cbSSangeeta Misra if (inst == NULL) 1359dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1360dbed73cbSSangeeta Misra 1361dbed73cbSSangeeta Misra h = scf_instance_handle(inst); 1362dbed73cbSSangeeta Misra if (h == NULL) 1363dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1364dbed73cbSSangeeta Misra 1365dbed73cbSSangeeta Misra if ((newpg = scf_pg_create(h)) == NULL) 1366dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 1367dbed73cbSSangeeta Misra 1368dbed73cbSSangeeta Misra if ((pgiter = scf_iter_create(h)) == NULL) { 1369dbed73cbSSangeeta Misra scf_pg_destroy(newpg); 1370dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 1371dbed73cbSSangeeta Misra } 1372dbed73cbSSangeeta Misra 1373dbed73cbSSangeeta Misra if ((scf_ret = scf_iter_instance_pgs(pgiter, inst)) < 0) 1374dbed73cbSSangeeta Misra goto out; 1375dbed73cbSSangeeta Misra 1376*3ae6a67dSSangeeta Misra if ((pg_name = malloc(scf_name_len)) == NULL) { 1377*3ae6a67dSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1378*3ae6a67dSSangeeta Misra goto out; 1379*3ae6a67dSSangeeta Misra } 1380dbed73cbSSangeeta Misra while ((scf_ret = scf_iter_next_pg(pgiter, newpg)) > 0) { 1381dbed73cbSSangeeta Misra ilbd_data_t data; 1382dbed73cbSSangeeta Misra 1383*3ae6a67dSSangeeta Misra if (scf_pg_get_name(newpg, pg_name, scf_name_len) < 0) { 1384dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1385dbed73cbSSangeeta Misra goto out; 1386dbed73cbSSangeeta Misra } 1387dbed73cbSSangeeta Misra 1388dbed73cbSSangeeta Misra /* 1389dbed73cbSSangeeta Misra * if pg name indicates it's a ilb configuration, walk its prop 1390dbed73cbSSangeeta Misra */ 1391dbed73cbSSangeeta Misra data.pg_type = pg_type; 1392dbed73cbSSangeeta Misra data.hc_data = NULL; 1393dbed73cbSSangeeta Misra data.sg_data = NULL; 1394dbed73cbSSangeeta Misra data.rule_data = NULL; 1395dbed73cbSSangeeta Misra 1396dbed73cbSSangeeta Misra switch (pg_type) { 1397dbed73cbSSangeeta Misra case ILBD_SCF_RULE: 1398dbed73cbSSangeeta Misra if (strncmp(ILBD_PG_NAME_RULE, pg_name, 1399dbed73cbSSangeeta Misra strlen(ILBD_PG_NAME_RULE)) == 0) { 1400dbed73cbSSangeeta Misra data.rule_data = calloc(1, 1401dbed73cbSSangeeta Misra sizeof (ilb_rule_info_t)); 1402dbed73cbSSangeeta Misra if (data.rule_data == NULL) { 1403dbed73cbSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1404dbed73cbSSangeeta Misra goto out; 1405dbed73cbSSangeeta Misra } 1406dbed73cbSSangeeta Misra ret = ilbd_scf_pg_walk_props(newpg, 1407dbed73cbSSangeeta Misra ilbd_scf_load_prop, &data); 1408dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1409dbed73cbSSangeeta Misra goto out; 1410dbed73cbSSangeeta Misra assert(data.rule_data != NULL); 1411dbed73cbSSangeeta Misra /* set rule name */ 1412dbed73cbSSangeeta Misra (void) strlcpy(data.rule_data->rl_name, 1413dbed73cbSSangeeta Misra &pg_name[strlen(ILBD_PG_NAME_RULE)], 1414dbed73cbSSangeeta Misra sizeof (data.rule_data->rl_name)); 1415dbed73cbSSangeeta Misra 1416dbed73cbSSangeeta Misra ret = cb(data.rule_data, port, arg2, NULL); 1417dbed73cbSSangeeta Misra free(data.rule_data); 1418dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1419dbed73cbSSangeeta Misra goto out; 1420dbed73cbSSangeeta Misra } 1421dbed73cbSSangeeta Misra break; 1422dbed73cbSSangeeta Misra case ILBD_SCF_SG: 1423dbed73cbSSangeeta Misra if (strncmp(ILBD_PG_NAME_SG, pg_name, 1424dbed73cbSSangeeta Misra strlen(ILBD_PG_NAME_SG)) == 0) { 1425dbed73cbSSangeeta Misra data.sg_data = calloc(1, 1426dbed73cbSSangeeta Misra sizeof (ilb_sg_info_t)); 1427*3ae6a67dSSangeeta Misra if (data.sg_data == NULL) { 1428*3ae6a67dSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1429*3ae6a67dSSangeeta Misra goto out; 1430*3ae6a67dSSangeeta Misra } 1431dbed73cbSSangeeta Misra ret = ilbd_scf_pg_walk_props(newpg, 1432dbed73cbSSangeeta Misra ilbd_scf_load_prop, &data); 1433dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 1434dbed73cbSSangeeta Misra free(data.sg_data); 1435dbed73cbSSangeeta Misra goto out; 1436dbed73cbSSangeeta Misra } 1437dbed73cbSSangeeta Misra assert(data.sg_data != NULL); 1438dbed73cbSSangeeta Misra /* set sg name */ 1439dbed73cbSSangeeta Misra (void) strlcpy(data.sg_data->sg_name, 1440dbed73cbSSangeeta Misra &pg_name[strlen(ILBD_PG_NAME_SG)], 1441dbed73cbSSangeeta Misra sizeof (data.sg_data->sg_name)); 1442dbed73cbSSangeeta Misra ret = cb(data.sg_data, port, arg2, NULL); 1443dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 1444dbed73cbSSangeeta Misra free(data.sg_data); 1445dbed73cbSSangeeta Misra goto out; 1446dbed73cbSSangeeta Misra } 1447dbed73cbSSangeeta Misra /* 1448dbed73cbSSangeeta Misra * create a servergroup is two-step operation. 1449dbed73cbSSangeeta Misra * 1. create an empty servergroup. 1450dbed73cbSSangeeta Misra * 2. add server(s) to the group. 1451dbed73cbSSangeeta Misra * 1452dbed73cbSSangeeta Misra * since we are here from: 1453dbed73cbSSangeeta Misra * main_loop()->ilbd_read_config()-> 1454dbed73cbSSangeeta Misra * ilbd_walk_sg_pgs() 1455dbed73cbSSangeeta Misra * there is no cli to send. So in this 1456dbed73cbSSangeeta Misra * path auditing will skip the 1457dbed73cbSSangeeta Misra * adt_set_from_ucred() check 1458dbed73cbSSangeeta Misra */ 1459dbed73cbSSangeeta Misra if (data.sg_data->sg_srvcount > 0) { 1460dbed73cbSSangeeta Misra ret = ilbd_add_server_to_group( 1461dbed73cbSSangeeta Misra data.sg_data, port, NULL, NULL); 1462dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) { 1463dbed73cbSSangeeta Misra free(data.sg_data); 1464dbed73cbSSangeeta Misra goto out; 1465dbed73cbSSangeeta Misra } 1466dbed73cbSSangeeta Misra free(data.sg_data); 1467dbed73cbSSangeeta Misra } 1468dbed73cbSSangeeta Misra } 1469dbed73cbSSangeeta Misra break; 1470dbed73cbSSangeeta Misra case ILBD_SCF_HC: 1471dbed73cbSSangeeta Misra if (strncmp(ILBD_PG_NAME_HC, pg_name, 1472dbed73cbSSangeeta Misra strlen(ILBD_PG_NAME_HC)) == 0) { 1473dbed73cbSSangeeta Misra data.hc_data = calloc(1, 1474dbed73cbSSangeeta Misra sizeof (ilb_hc_info_t)); 1475*3ae6a67dSSangeeta Misra if (data.hc_data == NULL) { 1476*3ae6a67dSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1477*3ae6a67dSSangeeta Misra goto out; 1478*3ae6a67dSSangeeta Misra } 1479dbed73cbSSangeeta Misra ret = ilbd_scf_pg_walk_props(newpg, 1480dbed73cbSSangeeta Misra ilbd_scf_load_prop, &data); 1481dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1482dbed73cbSSangeeta Misra goto out; 1483dbed73cbSSangeeta Misra assert(data.hc_data != NULL); 1484dbed73cbSSangeeta Misra /* set hc name */ 1485dbed73cbSSangeeta Misra (void) strlcpy(data.hc_data->hci_name, 1486dbed73cbSSangeeta Misra &pg_name[strlen(ILBD_PG_NAME_HC)], 1487dbed73cbSSangeeta Misra sizeof (data.hc_data->hci_name)); 1488dbed73cbSSangeeta Misra ret = cb(data.hc_data, port, arg2, NULL); 1489dbed73cbSSangeeta Misra free(data.hc_data); 1490dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1491dbed73cbSSangeeta Misra goto out; 1492dbed73cbSSangeeta Misra } 1493dbed73cbSSangeeta Misra break; 1494dbed73cbSSangeeta Misra } 1495dbed73cbSSangeeta Misra } 1496dbed73cbSSangeeta Misra 1497dbed73cbSSangeeta Misra out: 1498*3ae6a67dSSangeeta Misra if (pg_name != NULL) 1499*3ae6a67dSSangeeta Misra free(pg_name); 1500dbed73cbSSangeeta Misra if (scf_ret < 0) 1501dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1502dbed73cbSSangeeta Misra scf_pg_destroy(newpg); 1503dbed73cbSSangeeta Misra scf_iter_destroy(pgiter); 1504dbed73cbSSangeeta Misra return (ret); 1505dbed73cbSSangeeta Misra } 1506dbed73cbSSangeeta Misra 1507dbed73cbSSangeeta Misra typedef ilb_status_t (*ilbd_scf_walker_fn)(void *, int, struct passwd *, 1508dbed73cbSSangeeta Misra ucred_t *); 1509dbed73cbSSangeeta Misra 1510dbed73cbSSangeeta Misra ilb_status_t 1511dbed73cbSSangeeta Misra ilbd_walk_rule_pgs(ilb_status_t (*func)(ilb_rule_info_t *, int, 1512dbed73cbSSangeeta Misra const struct passwd *, ucred_t *), void *arg1, void *arg2) 1513dbed73cbSSangeeta Misra { 1514dbed73cbSSangeeta Misra scf_instance_t *inst; 1515dbed73cbSSangeeta Misra scf_handle_t *h; 1516dbed73cbSSangeeta Misra scf_service_t *svc; 1517dbed73cbSSangeeta Misra ilb_status_t ret; 1518dbed73cbSSangeeta Misra 1519dbed73cbSSangeeta Misra ret = ilbd_scf_get_inst(&h, &svc, &inst); 1520dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1521dbed73cbSSangeeta Misra return (ret); 1522dbed73cbSSangeeta Misra 1523dbed73cbSSangeeta Misra /* get rule prop group, transfer it to ilb_lrule_info_t */ 1524dbed73cbSSangeeta Misra ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_RULE, 1525dbed73cbSSangeeta Misra (ilbd_scf_walker_fn)func, arg1, arg2); 1526dbed73cbSSangeeta Misra ilbd_scf_destroy(h, svc, inst, NULL); 1527dbed73cbSSangeeta Misra return (ret); 1528dbed73cbSSangeeta Misra } 1529dbed73cbSSangeeta Misra 1530dbed73cbSSangeeta Misra ilb_status_t 1531dbed73cbSSangeeta Misra ilbd_walk_sg_pgs(ilb_status_t (*func)(ilb_sg_info_t *, int, 1532dbed73cbSSangeeta Misra const struct passwd *, ucred_t *), void *arg1, void *arg2) 1533dbed73cbSSangeeta Misra { 1534dbed73cbSSangeeta Misra scf_instance_t *inst; 1535dbed73cbSSangeeta Misra scf_handle_t *h; 1536dbed73cbSSangeeta Misra scf_service_t *svc; 1537dbed73cbSSangeeta Misra ilb_status_t ret; 1538dbed73cbSSangeeta Misra 1539dbed73cbSSangeeta Misra ret = ilbd_scf_get_inst(&h, &svc, &inst); 1540dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1541dbed73cbSSangeeta Misra return (ret); 1542dbed73cbSSangeeta Misra 1543dbed73cbSSangeeta Misra ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_SG, 1544dbed73cbSSangeeta Misra (ilbd_scf_walker_fn)func, arg1, arg2); 1545dbed73cbSSangeeta Misra ilbd_scf_destroy(h, svc, inst, NULL); 1546dbed73cbSSangeeta Misra return (ret); 1547dbed73cbSSangeeta Misra } 1548dbed73cbSSangeeta Misra 1549dbed73cbSSangeeta Misra ilb_status_t 1550dbed73cbSSangeeta Misra ilbd_walk_hc_pgs(ilb_status_t (*func)(const ilb_hc_info_t *, int, 1551dbed73cbSSangeeta Misra const struct passwd *, ucred_t *), void *arg1, void *arg2) 1552dbed73cbSSangeeta Misra { 1553dbed73cbSSangeeta Misra scf_instance_t *inst; 1554dbed73cbSSangeeta Misra scf_handle_t *h; 1555dbed73cbSSangeeta Misra scf_service_t *svc; 1556dbed73cbSSangeeta Misra ilb_status_t ret; 1557dbed73cbSSangeeta Misra 1558dbed73cbSSangeeta Misra ret = ilbd_scf_get_inst(&h, &svc, &inst); 1559dbed73cbSSangeeta Misra if (ret != ILB_STATUS_OK) 1560dbed73cbSSangeeta Misra return (ret); 1561dbed73cbSSangeeta Misra 1562dbed73cbSSangeeta Misra ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_HC, 1563dbed73cbSSangeeta Misra (ilbd_scf_walker_fn)func, arg1, arg2); 1564dbed73cbSSangeeta Misra ilbd_scf_destroy(h, svc, inst, NULL); 1565dbed73cbSSangeeta Misra return (ret); 1566dbed73cbSSangeeta Misra } 1567dbed73cbSSangeeta Misra 1568dbed73cbSSangeeta Misra ilb_status_t 1569dbed73cbSSangeeta Misra ilbd_change_prop(ilbd_scf_pg_type_t pg_type, const char *pg_name, 1570dbed73cbSSangeeta Misra const char *prop_name, void *new_val) 1571dbed73cbSSangeeta Misra { 1572dbed73cbSSangeeta Misra int ret; 1573dbed73cbSSangeeta Misra scf_propertygroup_t *scfpg = NULL; 1574*3ae6a67dSSangeeta Misra char *scf_pgname = NULL; 1575dbed73cbSSangeeta Misra scf_type_t scftype; 1576dbed73cbSSangeeta Misra scf_value_t *scfval; 1577dbed73cbSSangeeta Misra scf_handle_t *h; 1578dbed73cbSSangeeta Misra 1579*3ae6a67dSSangeeta Misra if ((scf_pgname = malloc(ILBD_MAX_NAME_LEN)) == NULL) 1580*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 1581dbed73cbSSangeeta Misra ilbd_name_to_scfpgname(pg_type, pg_name, scf_pgname); 1582dbed73cbSSangeeta Misra ret = ilbd_scf_retrieve_pg(scf_pgname, &scfpg, B_FALSE); 1583*3ae6a67dSSangeeta Misra free(scf_pgname); 1584*3ae6a67dSSangeeta Misra 1585dbed73cbSSangeeta Misra if (ret != ILB_STATUS_EEXIST) 1586dbed73cbSSangeeta Misra return (ret); 1587dbed73cbSSangeeta Misra 1588dbed73cbSSangeeta Misra assert(scfpg != NULL); 1589dbed73cbSSangeeta Misra 1590dbed73cbSSangeeta Misra h = scf_pg_handle(scfpg); 1591dbed73cbSSangeeta Misra if (h == NULL) { 1592dbed73cbSSangeeta Misra ret = ILB_STATUS_EINVAL; 1593dbed73cbSSangeeta Misra goto done; 1594dbed73cbSSangeeta Misra } 1595dbed73cbSSangeeta Misra 1596dbed73cbSSangeeta Misra if ((scfval = scf_value_create(h)) == NULL) { 1597dbed73cbSSangeeta Misra ret = ILB_STATUS_ENOMEM; 1598dbed73cbSSangeeta Misra goto done; 1599dbed73cbSSangeeta Misra } 1600dbed73cbSSangeeta Misra 1601dbed73cbSSangeeta Misra if (pg_type == ILBD_SCF_RULE) { 1602dbed73cbSSangeeta Misra scftype = SCF_TYPE_BOOLEAN; 1603dbed73cbSSangeeta Misra scf_value_set_boolean(scfval, *(boolean_t *)new_val); 1604dbed73cbSSangeeta Misra } else if (pg_type == ILBD_SCF_SG) { 1605dbed73cbSSangeeta Misra scftype = SCF_TYPE_ASTRING; 1606dbed73cbSSangeeta Misra (void) scf_value_set_astring(scfval, (char *)new_val); 1607dbed73cbSSangeeta Misra } 1608dbed73cbSSangeeta Misra ret = ilbd_scf_set_prop(scfpg, prop_name, scftype, scfval); 1609dbed73cbSSangeeta Misra 1610dbed73cbSSangeeta Misra done: 1611dbed73cbSSangeeta Misra if (scf_pg_handle(scfpg) != NULL) 1612dbed73cbSSangeeta Misra scf_handle_destroy(scf_pg_handle(scfpg)); 1613dbed73cbSSangeeta Misra if (scfpg != NULL) 1614dbed73cbSSangeeta Misra scf_pg_destroy(scfpg); 1615dbed73cbSSangeeta Misra if (scfval != NULL) 1616dbed73cbSSangeeta Misra scf_value_destroy(scfval); 1617dbed73cbSSangeeta Misra return (ret); 1618dbed73cbSSangeeta Misra } 1619dbed73cbSSangeeta Misra 1620dbed73cbSSangeeta Misra /* 1621dbed73cbSSangeeta Misra * Update the persistent configuration with a new server, srv, added to a 1622dbed73cbSSangeeta Misra * server group, sg. 1623dbed73cbSSangeeta Misra */ 1624dbed73cbSSangeeta Misra ilb_status_t 1625dbed73cbSSangeeta Misra ilbd_scf_add_srv(ilbd_sg_t *sg, ilbd_srv_t *srv) 1626dbed73cbSSangeeta Misra { 1627dbed73cbSSangeeta Misra scf_propertygroup_t *pg; 1628dbed73cbSSangeeta Misra scf_handle_t *h; 1629dbed73cbSSangeeta Misra scf_value_t *val; 1630dbed73cbSSangeeta Misra ilb_status_t ret; 1631dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 1632*3ae6a67dSSangeeta Misra char *buf = NULL; 1633*3ae6a67dSSangeeta Misra 1634*3ae6a67dSSangeeta Misra if ((buf = malloc(scf_name_len)) == NULL) 1635*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 1636dbed73cbSSangeeta Misra 1637dbed73cbSSangeeta Misra ilbd_name_to_scfpgname(ILBD_SCF_SG, sg->isg_name, buf); 1638dbed73cbSSangeeta Misra ret = ilbd_scf_retrieve_pg(buf, &pg, B_FALSE); 1639dbed73cbSSangeeta Misra /* 1640dbed73cbSSangeeta Misra * The server group does not exist in persistent storage. This 1641dbed73cbSSangeeta Misra * cannot happen. Should probably transition the service to 1642dbed73cbSSangeeta Misra * maintenance since it should be there. 1643dbed73cbSSangeeta Misra */ 1644dbed73cbSSangeeta Misra if (ret != ILB_STATUS_EEXIST) { 1645dbed73cbSSangeeta Misra logerr("ilbd_scf_add_srv: SCF update failed - entering" 1646dbed73cbSSangeeta Misra " maintenance mode"); 1647dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 1648*3ae6a67dSSangeeta Misra free(buf); 1649dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1650dbed73cbSSangeeta Misra } 1651dbed73cbSSangeeta Misra 1652dbed73cbSSangeeta Misra if ((h = scf_pg_handle(pg)) == NULL) { 1653dbed73cbSSangeeta Misra ilbd_scf_destroy(NULL, NULL, NULL, pg); 1654*3ae6a67dSSangeeta Misra free(buf); 1655dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 1656dbed73cbSSangeeta Misra } 1657dbed73cbSSangeeta Misra 1658dbed73cbSSangeeta Misra if ((val = scf_value_create(h)) == NULL) { 1659dbed73cbSSangeeta Misra ilbd_scf_destroy(h, NULL, NULL, pg); 1660*3ae6a67dSSangeeta Misra free(buf); 1661dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 1662dbed73cbSSangeeta Misra } 1663dbed73cbSSangeeta Misra ilbd_srv_scf_val(srv, buf); 1664dbed73cbSSangeeta Misra (void) scf_value_set_astring(val, buf); 1665dbed73cbSSangeeta Misra 1666*3ae6a67dSSangeeta Misra (void) snprintf(buf, scf_name_len, "server%d", srv->isv_id); 1667*3ae6a67dSSangeeta Misra ret = ilbd_scf_set_prop(pg, buf, SCF_TYPE_ASTRING, val); 1668*3ae6a67dSSangeeta Misra free(buf); 1669dbed73cbSSangeeta Misra ilbd_scf_destroy(h, NULL, NULL, pg); 1670dbed73cbSSangeeta Misra scf_value_destroy(val); 1671dbed73cbSSangeeta Misra 1672dbed73cbSSangeeta Misra return (ret); 1673dbed73cbSSangeeta Misra } 1674dbed73cbSSangeeta Misra 1675dbed73cbSSangeeta Misra /* 1676dbed73cbSSangeeta Misra * Delete a server, srv, of a server group, sg, from the persistent 1677dbed73cbSSangeeta Misra * configuration. 1678dbed73cbSSangeeta Misra */ 1679dbed73cbSSangeeta Misra ilb_status_t 1680dbed73cbSSangeeta Misra ilbd_scf_del_srv(ilbd_sg_t *sg, ilbd_srv_t *srv) 1681dbed73cbSSangeeta Misra { 1682dbed73cbSSangeeta Misra ilb_status_t ret; 1683dbed73cbSSangeeta Misra scf_propertygroup_t *pg; 1684dbed73cbSSangeeta Misra scf_handle_t *h; 1685dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 1686*3ae6a67dSSangeeta Misra char *buf; 1687dbed73cbSSangeeta Misra scf_transaction_t *tx = NULL; 1688dbed73cbSSangeeta Misra scf_transaction_entry_t *entry = NULL; 1689dbed73cbSSangeeta Misra 1690*3ae6a67dSSangeeta Misra if ((buf = malloc(scf_name_len)) == NULL) 1691*3ae6a67dSSangeeta Misra return (ILB_STATUS_ENOMEM); 1692dbed73cbSSangeeta Misra ilbd_name_to_scfpgname(ILBD_SCF_SG, sg->isg_name, buf); 1693dbed73cbSSangeeta Misra ret = ilbd_scf_retrieve_pg(buf, &pg, B_FALSE); 1694dbed73cbSSangeeta Misra /* 1695dbed73cbSSangeeta Misra * The server group does not exist in persistent storage. This 1696dbed73cbSSangeeta Misra * cannot happen. THe caller of this function puts service in 1697dbed73cbSSangeeta Misra * maintenance mode. 1698dbed73cbSSangeeta Misra */ 1699*3ae6a67dSSangeeta Misra if (ret != ILB_STATUS_EEXIST) { 1700*3ae6a67dSSangeeta Misra free(buf); 1701dbed73cbSSangeeta Misra return (ILB_STATUS_INTERNAL); 1702*3ae6a67dSSangeeta Misra } 1703dbed73cbSSangeeta Misra ret = ILB_STATUS_OK; 1704dbed73cbSSangeeta Misra 1705dbed73cbSSangeeta Misra if ((h = scf_pg_handle(pg)) == NULL) { 1706dbed73cbSSangeeta Misra logdebug("ilbd_scf_del_srv: scf_pg_handle: %s\n", 1707dbed73cbSSangeeta Misra scf_strerror(scf_error())); 1708dbed73cbSSangeeta Misra ilbd_scf_destroy(NULL, NULL, NULL, pg); 1709*3ae6a67dSSangeeta Misra free(buf); 1710dbed73cbSSangeeta Misra return (ilbd_scf_err_to_ilb_err()); 1711dbed73cbSSangeeta Misra } 1712dbed73cbSSangeeta Misra 1713dbed73cbSSangeeta Misra if ((tx = scf_transaction_create(h)) == NULL || 1714dbed73cbSSangeeta Misra (entry = scf_entry_create(h)) == NULL) { 1715dbed73cbSSangeeta Misra logdebug("ilbd_scf_del_srv: create scf transaction failed: " 1716dbed73cbSSangeeta Misra "%s\n", scf_strerror(scf_error())); 1717dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1718dbed73cbSSangeeta Misra goto out; 1719dbed73cbSSangeeta Misra } 1720dbed73cbSSangeeta Misra 1721*3ae6a67dSSangeeta Misra (void) snprintf(buf, scf_name_len, "server%d", srv->isv_id); 1722dbed73cbSSangeeta Misra 1723dbed73cbSSangeeta Misra if (scf_transaction_start(tx, pg) == -1) { 1724dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: start scf transaction failed: " 1725dbed73cbSSangeeta Misra "%s\n", scf_strerror(scf_error())); 1726dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1727dbed73cbSSangeeta Misra goto out; 1728dbed73cbSSangeeta Misra } 1729dbed73cbSSangeeta Misra if (scf_transaction_property_delete(tx, entry, buf) == -1) { 1730dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: delete property failed: %s\n", 1731dbed73cbSSangeeta Misra scf_strerror(scf_error())); 1732dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1733dbed73cbSSangeeta Misra goto out; 1734dbed73cbSSangeeta Misra } 1735dbed73cbSSangeeta Misra if (scf_transaction_commit(tx) != 1) { 1736dbed73cbSSangeeta Misra logdebug("ilbd_scf_set_prop: commit transaction failed: %s\n", 1737dbed73cbSSangeeta Misra scf_strerror(scf_error())); 1738dbed73cbSSangeeta Misra ret = ilbd_scf_err_to_ilb_err(); 1739dbed73cbSSangeeta Misra } 1740dbed73cbSSangeeta Misra 1741dbed73cbSSangeeta Misra out: 1742*3ae6a67dSSangeeta Misra free(buf); 1743dbed73cbSSangeeta Misra if (entry != NULL) 1744dbed73cbSSangeeta Misra scf_entry_destroy(entry); 1745dbed73cbSSangeeta Misra if (tx != NULL) 1746dbed73cbSSangeeta Misra scf_transaction_destroy(tx); 1747dbed73cbSSangeeta Misra ilbd_scf_destroy(h, NULL, NULL, pg); 1748dbed73cbSSangeeta Misra 1749dbed73cbSSangeeta Misra return (ret); 1750dbed73cbSSangeeta Misra } 1751