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 <stddef.h> 30*dbed73cbSSangeeta Misra #include <sys/types.h> 31*dbed73cbSSangeeta Misra #include <sys/socket.h> 32*dbed73cbSSangeeta Misra #include <sys/list.h> 33*dbed73cbSSangeeta Misra #include <assert.h> 34*dbed73cbSSangeeta Misra #include <errno.h> 35*dbed73cbSSangeeta Misra #include <libilb.h> 36*dbed73cbSSangeeta Misra #include <net/if.h> 37*dbed73cbSSangeeta Misra #include <inet/ilb.h> 38*dbed73cbSSangeeta Misra #include <netinet/in.h> 39*dbed73cbSSangeeta Misra #include <arpa/inet.h> 40*dbed73cbSSangeeta Misra #include "libilb_impl.h" 41*dbed73cbSSangeeta Misra #include "ilbd.h" 42*dbed73cbSSangeeta Misra 43*dbed73cbSSangeeta Misra typedef enum { 44*dbed73cbSSangeeta Misra not_searched, 45*dbed73cbSSangeeta Misra stop_found, 46*dbed73cbSSangeeta Misra cont_search, 47*dbed73cbSSangeeta Misra fail_search 48*dbed73cbSSangeeta Misra } srch_ind_t; 49*dbed73cbSSangeeta Misra 50*dbed73cbSSangeeta Misra static list_t ilbd_sg_hlist; 51*dbed73cbSSangeeta Misra 52*dbed73cbSSangeeta Misra static ilb_status_t i_delete_srv(ilbd_sg_t *, ilbd_srv_t *, int); 53*dbed73cbSSangeeta Misra static void i_ilbd_free_srvID(ilbd_sg_t *, int32_t); 54*dbed73cbSSangeeta Misra 55*dbed73cbSSangeeta Misra /* Last parameter to pass to i_find_srv(), specifying the matching mode */ 56*dbed73cbSSangeeta Misra #define MODE_ADDR 1 57*dbed73cbSSangeeta Misra #define MODE_SRVID 2 58*dbed73cbSSangeeta Misra 59*dbed73cbSSangeeta Misra static ilbd_srv_t *i_find_srv(list_t *, ilb_sg_srv_t *, int); 60*dbed73cbSSangeeta Misra 61*dbed73cbSSangeeta Misra void 62*dbed73cbSSangeeta Misra i_setup_sg_hlist(void) 63*dbed73cbSSangeeta Misra { 64*dbed73cbSSangeeta Misra list_create(&ilbd_sg_hlist, sizeof (ilbd_sg_t), 65*dbed73cbSSangeeta Misra offsetof(ilbd_sg_t, isg_link)); 66*dbed73cbSSangeeta Misra } 67*dbed73cbSSangeeta Misra 68*dbed73cbSSangeeta Misra /* 69*dbed73cbSSangeeta Misra * allocate storage for a daemon-internal server group, init counters 70*dbed73cbSSangeeta Misra */ 71*dbed73cbSSangeeta Misra static ilbd_sg_t * 72*dbed73cbSSangeeta Misra i_ilbd_alloc_sg(char *name) 73*dbed73cbSSangeeta Misra { 74*dbed73cbSSangeeta Misra ilbd_sg_t *d_sg; 75*dbed73cbSSangeeta Misra 76*dbed73cbSSangeeta Misra d_sg = calloc(sizeof (*d_sg), 1); 77*dbed73cbSSangeeta Misra if (d_sg == NULL) 78*dbed73cbSSangeeta Misra goto out; 79*dbed73cbSSangeeta Misra 80*dbed73cbSSangeeta Misra (void) strlcpy(d_sg->isg_name, name, sizeof (d_sg->isg_name)); 81*dbed73cbSSangeeta Misra 82*dbed73cbSSangeeta Misra list_create(&d_sg->isg_srvlist, sizeof (ilbd_srv_t), 83*dbed73cbSSangeeta Misra offsetof(ilbd_srv_t, isv_srv_link)); 84*dbed73cbSSangeeta Misra list_create(&d_sg->isg_rulelist, sizeof (ilbd_rule_t), 85*dbed73cbSSangeeta Misra offsetof(ilbd_rule_t, irl_sglink)); 86*dbed73cbSSangeeta Misra 87*dbed73cbSSangeeta Misra list_insert_tail(&ilbd_sg_hlist, d_sg); 88*dbed73cbSSangeeta Misra out: 89*dbed73cbSSangeeta Misra return (d_sg); 90*dbed73cbSSangeeta Misra } 91*dbed73cbSSangeeta Misra 92*dbed73cbSSangeeta Misra static ilb_status_t 93*dbed73cbSSangeeta Misra i_ilbd_save_sg(ilbd_sg_t *d_sg, ilbd_scf_cmd_t scf_cmd, const char *prop_name, 94*dbed73cbSSangeeta Misra char *valstr) 95*dbed73cbSSangeeta Misra { 96*dbed73cbSSangeeta Misra switch (scf_cmd) { 97*dbed73cbSSangeeta Misra case ILBD_SCF_CREATE: 98*dbed73cbSSangeeta Misra return (ilbd_create_pg(ILBD_SCF_SG, (void *)d_sg)); 99*dbed73cbSSangeeta Misra case ILBD_SCF_DESTROY: 100*dbed73cbSSangeeta Misra return (ilbd_destroy_pg(ILBD_SCF_SG, d_sg->isg_name)); 101*dbed73cbSSangeeta Misra case ILBD_SCF_ENABLE_DISABLE: 102*dbed73cbSSangeeta Misra if (prop_name == NULL) 103*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 104*dbed73cbSSangeeta Misra return (ilbd_change_prop(ILBD_SCF_SG, d_sg->isg_name, 105*dbed73cbSSangeeta Misra prop_name, valstr)); 106*dbed73cbSSangeeta Misra default: 107*dbed73cbSSangeeta Misra logdebug("i_ilbd_save_sg: invalid scf cmd %d", scf_cmd); 108*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 109*dbed73cbSSangeeta Misra } 110*dbed73cbSSangeeta Misra } 111*dbed73cbSSangeeta Misra 112*dbed73cbSSangeeta Misra ilb_status_t 113*dbed73cbSSangeeta Misra i_attach_rule2sg(ilbd_sg_t *sg, ilbd_rule_t *irl) 114*dbed73cbSSangeeta Misra { 115*dbed73cbSSangeeta Misra /* assert: the same rule is attached to any sg only once */ 116*dbed73cbSSangeeta Misra list_insert_tail(&sg->isg_rulelist, irl); 117*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 118*dbed73cbSSangeeta Misra } 119*dbed73cbSSangeeta Misra 120*dbed73cbSSangeeta Misra static void 121*dbed73cbSSangeeta Misra i_ilbd_free_sg(ilbd_sg_t *sg) 122*dbed73cbSSangeeta Misra { 123*dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv; 124*dbed73cbSSangeeta Misra 125*dbed73cbSSangeeta Misra if (sg == NULL) 126*dbed73cbSSangeeta Misra return; 127*dbed73cbSSangeeta Misra list_remove(&ilbd_sg_hlist, sg); 128*dbed73cbSSangeeta Misra while ((tmp_srv = list_remove_tail(&sg->isg_srvlist)) != NULL) { 129*dbed73cbSSangeeta Misra i_ilbd_free_srvID(sg, tmp_srv->isv_id); 130*dbed73cbSSangeeta Misra free(tmp_srv); 131*dbed73cbSSangeeta Misra sg->isg_srvcount--; 132*dbed73cbSSangeeta Misra } 133*dbed73cbSSangeeta Misra free(sg); 134*dbed73cbSSangeeta Misra } 135*dbed73cbSSangeeta Misra 136*dbed73cbSSangeeta Misra ilbd_sg_t * 137*dbed73cbSSangeeta Misra i_find_sg_byname(const char *name) 138*dbed73cbSSangeeta Misra { 139*dbed73cbSSangeeta Misra ilbd_sg_t *sg; 140*dbed73cbSSangeeta Misra 141*dbed73cbSSangeeta Misra /* find position of sg in list */ 142*dbed73cbSSangeeta Misra for (sg = list_head(&ilbd_sg_hlist); sg != NULL; 143*dbed73cbSSangeeta Misra sg = list_next(&ilbd_sg_hlist, sg)) { 144*dbed73cbSSangeeta Misra if (strncmp(sg->isg_name, name, sizeof (sg->isg_name)) == 0) 145*dbed73cbSSangeeta Misra return (sg); 146*dbed73cbSSangeeta Misra } 147*dbed73cbSSangeeta Misra return (sg); 148*dbed73cbSSangeeta Misra } 149*dbed73cbSSangeeta Misra 150*dbed73cbSSangeeta Misra /* 151*dbed73cbSSangeeta Misra * Generates an audit record for enable-server, disable-server, remove-server 152*dbed73cbSSangeeta Misra * delete-servergroup, create-servergroup and add-server subcommands. 153*dbed73cbSSangeeta Misra */ 154*dbed73cbSSangeeta Misra static void 155*dbed73cbSSangeeta Misra ilbd_audit_server_event(audit_sg_event_data_t *data, 156*dbed73cbSSangeeta Misra ilbd_cmd_t cmd, ilb_status_t rc, ucred_t *ucredp) 157*dbed73cbSSangeeta Misra { 158*dbed73cbSSangeeta Misra adt_session_data_t *ah; 159*dbed73cbSSangeeta Misra adt_event_data_t *event; 160*dbed73cbSSangeeta Misra au_event_t flag; 161*dbed73cbSSangeeta Misra int audit_error; 162*dbed73cbSSangeeta Misra 163*dbed73cbSSangeeta Misra if ((ucredp == NULL) && ((cmd == ILBD_ADD_SERVER_TO_GROUP) || 164*dbed73cbSSangeeta Misra (cmd == ILBD_CREATE_SERVERGROUP))) { 165*dbed73cbSSangeeta Misra /* 166*dbed73cbSSangeeta Misra * We came here from the path where ilbd is 167*dbed73cbSSangeeta Misra * incorporating the ILB configuration from 168*dbed73cbSSangeeta Misra * SCF. In that case, we skip auditing 169*dbed73cbSSangeeta Misra */ 170*dbed73cbSSangeeta Misra return; 171*dbed73cbSSangeeta Misra } 172*dbed73cbSSangeeta Misra 173*dbed73cbSSangeeta Misra if (adt_start_session(&ah, NULL, 0) != 0) { 174*dbed73cbSSangeeta Misra logerr("ilbd_audit_server_event: adt_start_session failed"); 175*dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 176*dbed73cbSSangeeta Misra } 177*dbed73cbSSangeeta Misra 178*dbed73cbSSangeeta Misra if (adt_set_from_ucred(ah, ucredp, ADT_NEW) != 0) { 179*dbed73cbSSangeeta Misra (void) adt_end_session(ah); 180*dbed73cbSSangeeta Misra logerr("ilbd_audit_server_event: adt_set_from_ucred failed"); 181*dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 182*dbed73cbSSangeeta Misra } 183*dbed73cbSSangeeta Misra 184*dbed73cbSSangeeta Misra if (cmd == ILBD_ENABLE_SERVER) 185*dbed73cbSSangeeta Misra flag = ADT_ilb_enable_server; 186*dbed73cbSSangeeta Misra else if (cmd == ILBD_DISABLE_SERVER) 187*dbed73cbSSangeeta Misra flag = ADT_ilb_disable_server; 188*dbed73cbSSangeeta Misra else if (cmd == ILBD_REM_SERVER_FROM_GROUP) 189*dbed73cbSSangeeta Misra flag = ADT_ilb_remove_server; 190*dbed73cbSSangeeta Misra else if (cmd == ILBD_ADD_SERVER_TO_GROUP) 191*dbed73cbSSangeeta Misra flag = ADT_ilb_add_server; 192*dbed73cbSSangeeta Misra else if (cmd == ILBD_CREATE_SERVERGROUP) 193*dbed73cbSSangeeta Misra flag = ADT_ilb_create_servergroup; 194*dbed73cbSSangeeta Misra else if (cmd == ILBD_DESTROY_SERVERGROUP) 195*dbed73cbSSangeeta Misra flag = ADT_ilb_delete_servergroup; 196*dbed73cbSSangeeta Misra 197*dbed73cbSSangeeta Misra if ((event = adt_alloc_event(ah, flag)) == NULL) { 198*dbed73cbSSangeeta Misra logerr("ilbd_audit_server_event: adt_alloc_event failed"); 199*dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 200*dbed73cbSSangeeta Misra } 201*dbed73cbSSangeeta Misra (void) memset((char *)event, 0, sizeof (adt_event_data_t)); 202*dbed73cbSSangeeta Misra 203*dbed73cbSSangeeta Misra switch (cmd) { 204*dbed73cbSSangeeta Misra case ILBD_ENABLE_SERVER: 205*dbed73cbSSangeeta Misra event->adt_ilb_enable_server.auth_used = 206*dbed73cbSSangeeta Misra NET_ILB_ENABLE_AUTH; 207*dbed73cbSSangeeta Misra event->adt_ilb_enable_server.server_id = 208*dbed73cbSSangeeta Misra data->ed_serverid; 209*dbed73cbSSangeeta Misra event->adt_ilb_enable_server.server_ipaddress = 210*dbed73cbSSangeeta Misra data->ed_server_address; 211*dbed73cbSSangeeta Misra break; 212*dbed73cbSSangeeta Misra case ILBD_DISABLE_SERVER: 213*dbed73cbSSangeeta Misra event->adt_ilb_disable_server.auth_used = 214*dbed73cbSSangeeta Misra NET_ILB_ENABLE_AUTH; 215*dbed73cbSSangeeta Misra event->adt_ilb_disable_server.server_id = 216*dbed73cbSSangeeta Misra data->ed_serverid; 217*dbed73cbSSangeeta Misra event->adt_ilb_disable_server.server_ipaddress = 218*dbed73cbSSangeeta Misra data->ed_server_address; 219*dbed73cbSSangeeta Misra break; 220*dbed73cbSSangeeta Misra case ILBD_REM_SERVER_FROM_GROUP: 221*dbed73cbSSangeeta Misra event->adt_ilb_remove_server.auth_used = 222*dbed73cbSSangeeta Misra NET_ILB_CONFIG_AUTH; 223*dbed73cbSSangeeta Misra event->adt_ilb_remove_server.server_id = 224*dbed73cbSSangeeta Misra data->ed_serverid; 225*dbed73cbSSangeeta Misra event->adt_ilb_remove_server.server_group = data->ed_sgroup; 226*dbed73cbSSangeeta Misra event->adt_ilb_remove_server.server_ipaddress = 227*dbed73cbSSangeeta Misra data->ed_server_address; 228*dbed73cbSSangeeta Misra break; 229*dbed73cbSSangeeta Misra case ILBD_CREATE_SERVERGROUP: 230*dbed73cbSSangeeta Misra event->adt_ilb_create_servergroup.auth_used = 231*dbed73cbSSangeeta Misra NET_ILB_CONFIG_AUTH; 232*dbed73cbSSangeeta Misra event->adt_ilb_create_servergroup.server_group = 233*dbed73cbSSangeeta Misra data->ed_sgroup; 234*dbed73cbSSangeeta Misra break; 235*dbed73cbSSangeeta Misra case ILBD_ADD_SERVER_TO_GROUP: 236*dbed73cbSSangeeta Misra event->adt_ilb_add_server.auth_used = 237*dbed73cbSSangeeta Misra NET_ILB_CONFIG_AUTH; 238*dbed73cbSSangeeta Misra event->adt_ilb_add_server.server_ipaddress = 239*dbed73cbSSangeeta Misra data->ed_server_address; 240*dbed73cbSSangeeta Misra event->adt_ilb_add_server.server_id = 241*dbed73cbSSangeeta Misra data->ed_serverid; 242*dbed73cbSSangeeta Misra event->adt_ilb_add_server.server_group = 243*dbed73cbSSangeeta Misra data->ed_sgroup; 244*dbed73cbSSangeeta Misra event->adt_ilb_add_server.server_minport = 245*dbed73cbSSangeeta Misra ntohs(data->ed_minport); 246*dbed73cbSSangeeta Misra event->adt_ilb_add_server.server_maxport = 247*dbed73cbSSangeeta Misra ntohs(data->ed_maxport); 248*dbed73cbSSangeeta Misra break; 249*dbed73cbSSangeeta Misra case ILBD_DESTROY_SERVERGROUP: 250*dbed73cbSSangeeta Misra event->adt_ilb_delete_servergroup.auth_used = 251*dbed73cbSSangeeta Misra NET_ILB_CONFIG_AUTH; 252*dbed73cbSSangeeta Misra event->adt_ilb_delete_servergroup.server_group = 253*dbed73cbSSangeeta Misra data->ed_sgroup; 254*dbed73cbSSangeeta Misra break; 255*dbed73cbSSangeeta Misra } 256*dbed73cbSSangeeta Misra 257*dbed73cbSSangeeta Misra /* Fill in success/failure */ 258*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) { 259*dbed73cbSSangeeta Misra if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { 260*dbed73cbSSangeeta Misra logerr("ilbd_audit_server_event:" 261*dbed73cbSSangeeta Misra " adt_put_event failed"); 262*dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 263*dbed73cbSSangeeta Misra } 264*dbed73cbSSangeeta Misra } else { 265*dbed73cbSSangeeta Misra audit_error = ilberror2auditerror(rc); 266*dbed73cbSSangeeta Misra if (adt_put_event(event, ADT_FAILURE, audit_error) != 0) { 267*dbed73cbSSangeeta Misra logerr("ilbd_audit_server_event:" 268*dbed73cbSSangeeta Misra " adt_put_event failed"); 269*dbed73cbSSangeeta Misra exit(EXIT_FAILURE); 270*dbed73cbSSangeeta Misra } 271*dbed73cbSSangeeta Misra } 272*dbed73cbSSangeeta Misra adt_free_event(event); 273*dbed73cbSSangeeta Misra (void) adt_end_session(ah); 274*dbed73cbSSangeeta Misra } 275*dbed73cbSSangeeta Misra 276*dbed73cbSSangeeta Misra ilb_status_t 277*dbed73cbSSangeeta Misra ilbd_destroy_sg(const char *sg_name, const struct passwd *ps, 278*dbed73cbSSangeeta Misra ucred_t *ucredp) 279*dbed73cbSSangeeta Misra { 280*dbed73cbSSangeeta Misra ilb_status_t rc; 281*dbed73cbSSangeeta Misra ilbd_sg_t *tmp_sg; 282*dbed73cbSSangeeta Misra audit_sg_event_data_t audit_sg_data; 283*dbed73cbSSangeeta Misra 284*dbed73cbSSangeeta Misra (void) memset(&audit_sg_data, 0, sizeof (audit_sg_event_data_t)); 285*dbed73cbSSangeeta Misra audit_sg_data.ed_sgroup = (char *)sg_name; 286*dbed73cbSSangeeta Misra 287*dbed73cbSSangeeta Misra rc = ilbd_check_client_config_auth(ps); 288*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 289*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 290*dbed73cbSSangeeta Misra ILBD_DESTROY_SERVERGROUP, rc, ucredp); 291*dbed73cbSSangeeta Misra return (rc); 292*dbed73cbSSangeeta Misra } 293*dbed73cbSSangeeta Misra 294*dbed73cbSSangeeta Misra tmp_sg = i_find_sg_byname(sg_name); 295*dbed73cbSSangeeta Misra if (tmp_sg == NULL) { 296*dbed73cbSSangeeta Misra logdebug("ilbd_destroy_sg: cannot find specified server" 297*dbed73cbSSangeeta Misra " group %s", sg_name); 298*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 299*dbed73cbSSangeeta Misra ILBD_DESTROY_SERVERGROUP, ILB_STATUS_SGUNAVAIL, ucredp); 300*dbed73cbSSangeeta Misra return (ILB_STATUS_SGUNAVAIL); 301*dbed73cbSSangeeta Misra } 302*dbed73cbSSangeeta Misra 303*dbed73cbSSangeeta Misra /* 304*dbed73cbSSangeeta Misra * we only destroy SGs that don't have any rules associated with 305*dbed73cbSSangeeta Misra * them anymore. 306*dbed73cbSSangeeta Misra */ 307*dbed73cbSSangeeta Misra if (list_head(&tmp_sg->isg_rulelist) != NULL) { 308*dbed73cbSSangeeta Misra logdebug("ilbd_destroy_sg: server group %s has rules" 309*dbed73cbSSangeeta Misra " associated with it and thus cannot be" 310*dbed73cbSSangeeta Misra " removed", tmp_sg->isg_name); 311*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 312*dbed73cbSSangeeta Misra ILBD_DESTROY_SERVERGROUP, ILB_STATUS_SGINUSE, ucredp); 313*dbed73cbSSangeeta Misra return (ILB_STATUS_SGINUSE); 314*dbed73cbSSangeeta Misra } 315*dbed73cbSSangeeta Misra 316*dbed73cbSSangeeta Misra if (ps != NULL) { 317*dbed73cbSSangeeta Misra rc = i_ilbd_save_sg(tmp_sg, ILBD_SCF_DESTROY, NULL, NULL); 318*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 319*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 320*dbed73cbSSangeeta Misra ILBD_DESTROY_SERVERGROUP, rc, ucredp); 321*dbed73cbSSangeeta Misra return (rc); 322*dbed73cbSSangeeta Misra } 323*dbed73cbSSangeeta Misra } 324*dbed73cbSSangeeta Misra i_ilbd_free_sg(tmp_sg); 325*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, ILBD_DESTROY_SERVERGROUP, 326*dbed73cbSSangeeta Misra rc, ucredp); 327*dbed73cbSSangeeta Misra return (rc); 328*dbed73cbSSangeeta Misra } 329*dbed73cbSSangeeta Misra 330*dbed73cbSSangeeta Misra /* ARGSUSED */ 331*dbed73cbSSangeeta Misra /* 332*dbed73cbSSangeeta Misra * Parameter ev_port is not used but has to have for read persistent configure 333*dbed73cbSSangeeta Misra * ilbd_create_sg(), ilbd_create_hc() and ilbd_create_rule() are callbacks 334*dbed73cbSSangeeta Misra * for ilbd_scf_instance_walk_pg() which requires the same signature. 335*dbed73cbSSangeeta Misra */ 336*dbed73cbSSangeeta Misra ilb_status_t 337*dbed73cbSSangeeta Misra ilbd_create_sg(ilb_sg_info_t *sg, int ev_port, const struct passwd *ps, 338*dbed73cbSSangeeta Misra ucred_t *ucredp) 339*dbed73cbSSangeeta Misra { 340*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 341*dbed73cbSSangeeta Misra ilbd_sg_t *d_sg; 342*dbed73cbSSangeeta Misra audit_sg_event_data_t audit_sg_data; 343*dbed73cbSSangeeta Misra 344*dbed73cbSSangeeta Misra (void) memset(&audit_sg_data, 0, sizeof (audit_sg_event_data_t)); 345*dbed73cbSSangeeta Misra audit_sg_data.ed_sgroup = sg->sg_name; 346*dbed73cbSSangeeta Misra 347*dbed73cbSSangeeta Misra if (ps != NULL) { 348*dbed73cbSSangeeta Misra rc = ilbd_check_client_config_auth(ps); 349*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 350*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 351*dbed73cbSSangeeta Misra ILBD_CREATE_SERVERGROUP, rc, ucredp); 352*dbed73cbSSangeeta Misra return (rc); 353*dbed73cbSSangeeta Misra } 354*dbed73cbSSangeeta Misra } 355*dbed73cbSSangeeta Misra 356*dbed73cbSSangeeta Misra if (i_find_sg_byname(sg->sg_name) != NULL) { 357*dbed73cbSSangeeta Misra logdebug("ilbd_create_sg: server group %s already exists", 358*dbed73cbSSangeeta Misra sg->sg_name); 359*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 360*dbed73cbSSangeeta Misra ILBD_CREATE_SERVERGROUP, ILB_STATUS_SGEXISTS, ucredp); 361*dbed73cbSSangeeta Misra return (ILB_STATUS_SGEXISTS); 362*dbed73cbSSangeeta Misra } 363*dbed73cbSSangeeta Misra 364*dbed73cbSSangeeta Misra d_sg = i_ilbd_alloc_sg(sg->sg_name); 365*dbed73cbSSangeeta Misra if (d_sg == NULL) { 366*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 367*dbed73cbSSangeeta Misra ILBD_CREATE_SERVERGROUP, ILB_STATUS_ENOMEM, ucredp); 368*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 369*dbed73cbSSangeeta Misra } 370*dbed73cbSSangeeta Misra 371*dbed73cbSSangeeta Misra /* 372*dbed73cbSSangeeta Misra * we've successfully created the sg in memory. Before we can 373*dbed73cbSSangeeta Misra * return "success", we need to reflect this in persistent 374*dbed73cbSSangeeta Misra * storage 375*dbed73cbSSangeeta Misra */ 376*dbed73cbSSangeeta Misra if (ps != NULL) { 377*dbed73cbSSangeeta Misra rc = i_ilbd_save_sg(d_sg, ILBD_SCF_CREATE, NULL, NULL); 378*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 379*dbed73cbSSangeeta Misra i_ilbd_free_sg(d_sg); 380*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 381*dbed73cbSSangeeta Misra ILBD_CREATE_SERVERGROUP, rc, ucredp); 382*dbed73cbSSangeeta Misra return (rc); 383*dbed73cbSSangeeta Misra } 384*dbed73cbSSangeeta Misra } 385*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 386*dbed73cbSSangeeta Misra ILBD_CREATE_SERVERGROUP, rc, ucredp); 387*dbed73cbSSangeeta Misra return (rc); 388*dbed73cbSSangeeta Misra } 389*dbed73cbSSangeeta Misra 390*dbed73cbSSangeeta Misra /* 391*dbed73cbSSangeeta Misra * This function checks whether tsrv should/can be inserted before lsrv 392*dbed73cbSSangeeta Misra * and does so if possible. 393*dbed73cbSSangeeta Misra * We keep the list in sorted order so we don't have to search it 394*dbed73cbSSangeeta Misra * in its entirety for overlap every time we insert a new server. 395*dbed73cbSSangeeta Misra * Return code: 396*dbed73cbSSangeeta Misra * stop_found: don't continue searching because we found a place 397*dbed73cbSSangeeta Misra * cont_search: continue with next element in the list 398*dbed73cbSSangeeta Misra * fail_search: search failed (caller translates to ILB_STATUS_EEXIST) 399*dbed73cbSSangeeta Misra */ 400*dbed73cbSSangeeta Misra static srch_ind_t 401*dbed73cbSSangeeta Misra i_test_and_insert(ilbd_srv_t *tsrv, ilbd_srv_t *lsrv, list_t *srvlist) 402*dbed73cbSSangeeta Misra { 403*dbed73cbSSangeeta Misra struct in6_addr *t1, *l1; 404*dbed73cbSSangeeta Misra int fnd; 405*dbed73cbSSangeeta Misra 406*dbed73cbSSangeeta Misra t1 = &tsrv->isv_addr; 407*dbed73cbSSangeeta Misra l1 = &lsrv->isv_addr; 408*dbed73cbSSangeeta Misra 409*dbed73cbSSangeeta Misra if ((fnd = ilb_cmp_in6_addr(t1, l1, NULL)) == 1) 410*dbed73cbSSangeeta Misra return (cont_search); /* search can continue */ 411*dbed73cbSSangeeta Misra 412*dbed73cbSSangeeta Misra if (fnd == 0) { 413*dbed73cbSSangeeta Misra logdebug("i_test_and_insert: specified server already exists"); 414*dbed73cbSSangeeta Misra return (fail_search); 415*dbed73cbSSangeeta Misra } 416*dbed73cbSSangeeta Misra /* the list is kept in ascending order */ 417*dbed73cbSSangeeta Misra list_insert_before(srvlist, lsrv, tsrv); 418*dbed73cbSSangeeta Misra return (stop_found); 419*dbed73cbSSangeeta Misra } 420*dbed73cbSSangeeta Misra 421*dbed73cbSSangeeta Misra 422*dbed73cbSSangeeta Misra /* 423*dbed73cbSSangeeta Misra * copy a server description [ip1,ip2,port1,port2,srvID,flags] 424*dbed73cbSSangeeta Misra */ 425*dbed73cbSSangeeta Misra #define COPY_SERVER(src, dest) \ 426*dbed73cbSSangeeta Misra (dest)->sgs_addr = (src)->sgs_addr; \ 427*dbed73cbSSangeeta Misra (dest)->sgs_minport = (src)->sgs_minport; \ 428*dbed73cbSSangeeta Misra (dest)->sgs_maxport = (src)->sgs_maxport; \ 429*dbed73cbSSangeeta Misra (dest)->sgs_id = (src)->sgs_id; \ 430*dbed73cbSSangeeta Misra (void) strlcpy((dest)->sgs_srvID, (src)->sgs_srvID, \ 431*dbed73cbSSangeeta Misra sizeof ((dest)->sgs_srvID)); \ 432*dbed73cbSSangeeta Misra (dest)->sgs_flags = (src)->sgs_flags 433*dbed73cbSSangeeta Misra 434*dbed73cbSSangeeta Misra static ilb_status_t 435*dbed73cbSSangeeta Misra i_add_srv2sg(ilbd_sg_t *dsg, ilb_sg_srv_t *srv, ilbd_srv_t **ret_srv) 436*dbed73cbSSangeeta Misra { 437*dbed73cbSSangeeta Misra ilb_sg_srv_t *n_sg_srv; 438*dbed73cbSSangeeta Misra list_t *srvlist; 439*dbed73cbSSangeeta Misra srch_ind_t search = not_searched; 440*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 441*dbed73cbSSangeeta Misra ilbd_srv_t *nsrv, *lsrv; 442*dbed73cbSSangeeta Misra in_port_t h_minport, h_maxport; 443*dbed73cbSSangeeta Misra 444*dbed73cbSSangeeta Misra nsrv = calloc(sizeof (*nsrv), 1); 445*dbed73cbSSangeeta Misra if (nsrv == NULL) 446*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 447*dbed73cbSSangeeta Misra n_sg_srv = &nsrv->isv_srv; 448*dbed73cbSSangeeta Misra COPY_SERVER(srv, n_sg_srv); 449*dbed73cbSSangeeta Misra 450*dbed73cbSSangeeta Misra /* 451*dbed73cbSSangeeta Misra * port info is in network byte order - we need host byte order 452*dbed73cbSSangeeta Misra * for comparisons purposes 453*dbed73cbSSangeeta Misra */ 454*dbed73cbSSangeeta Misra h_minport = ntohs(n_sg_srv->sgs_minport); 455*dbed73cbSSangeeta Misra h_maxport = ntohs(n_sg_srv->sgs_maxport); 456*dbed73cbSSangeeta Misra if (h_minport != 0 && h_minport > h_maxport) 457*dbed73cbSSangeeta Misra n_sg_srv->sgs_maxport = n_sg_srv->sgs_minport; 458*dbed73cbSSangeeta Misra 459*dbed73cbSSangeeta Misra srvlist = &dsg->isg_srvlist; 460*dbed73cbSSangeeta Misra 461*dbed73cbSSangeeta Misra lsrv = list_head(srvlist); 462*dbed73cbSSangeeta Misra if (lsrv == NULL) { 463*dbed73cbSSangeeta Misra list_insert_head(srvlist, nsrv); 464*dbed73cbSSangeeta Misra } else { 465*dbed73cbSSangeeta Misra while (lsrv != NULL) { 466*dbed73cbSSangeeta Misra search = i_test_and_insert(nsrv, lsrv, 467*dbed73cbSSangeeta Misra srvlist); 468*dbed73cbSSangeeta Misra 469*dbed73cbSSangeeta Misra if (search != cont_search) 470*dbed73cbSSangeeta Misra break; 471*dbed73cbSSangeeta Misra lsrv = list_next(srvlist, lsrv); 472*dbed73cbSSangeeta Misra 473*dbed73cbSSangeeta Misra /* if reaches the end of list, insert to the tail */ 474*dbed73cbSSangeeta Misra if (search == cont_search && lsrv == NULL) 475*dbed73cbSSangeeta Misra list_insert_tail(srvlist, nsrv); 476*dbed73cbSSangeeta Misra } 477*dbed73cbSSangeeta Misra if (search == fail_search) 478*dbed73cbSSangeeta Misra rc = ILB_STATUS_EEXIST; 479*dbed73cbSSangeeta Misra } 480*dbed73cbSSangeeta Misra 481*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) { 482*dbed73cbSSangeeta Misra dsg->isg_srvcount++; 483*dbed73cbSSangeeta Misra *ret_srv = nsrv; 484*dbed73cbSSangeeta Misra } else { 485*dbed73cbSSangeeta Misra free(nsrv); 486*dbed73cbSSangeeta Misra } 487*dbed73cbSSangeeta Misra 488*dbed73cbSSangeeta Misra return (rc); 489*dbed73cbSSangeeta Misra } 490*dbed73cbSSangeeta Misra 491*dbed73cbSSangeeta Misra /* 492*dbed73cbSSangeeta Misra * Allocate a server ID. The algorithm is simple. Just check the ID array 493*dbed73cbSSangeeta Misra * of the server group and find an unused ID. If *set_id is given, it 494*dbed73cbSSangeeta Misra * means that the ID is already allocated and the ID array needs to be 495*dbed73cbSSangeeta Misra * updated. This is the case when ilbd reads from the persistent 496*dbed73cbSSangeeta Misra * configuration. 497*dbed73cbSSangeeta Misra */ 498*dbed73cbSSangeeta Misra static int32_t 499*dbed73cbSSangeeta Misra i_ilbd_alloc_srvID(ilbd_sg_t *sg, int32_t *set_id) 500*dbed73cbSSangeeta Misra { 501*dbed73cbSSangeeta Misra int32_t id; 502*dbed73cbSSangeeta Misra int32_t i; 503*dbed73cbSSangeeta Misra 504*dbed73cbSSangeeta Misra /* The server ID is already allocated, just update the ID array. */ 505*dbed73cbSSangeeta Misra if (set_id != NULL) { 506*dbed73cbSSangeeta Misra assert(sg->isg_id_arr[*set_id] == 0); 507*dbed73cbSSangeeta Misra sg->isg_id_arr[*set_id] = 1; 508*dbed73cbSSangeeta Misra return (*set_id); 509*dbed73cbSSangeeta Misra } 510*dbed73cbSSangeeta Misra 511*dbed73cbSSangeeta Misra /* if we're "full up", give back something invalid */ 512*dbed73cbSSangeeta Misra if (sg->isg_srvcount == MAX_SRVCOUNT) 513*dbed73cbSSangeeta Misra return (BAD_SRVID); 514*dbed73cbSSangeeta Misra 515*dbed73cbSSangeeta Misra i = sg->isg_max_id; 516*dbed73cbSSangeeta Misra for (id = 0; id < MAX_SRVCOUNT; id++) { 517*dbed73cbSSangeeta Misra if (sg->isg_id_arr[(id + i) % MAX_SRVCOUNT] == 0) 518*dbed73cbSSangeeta Misra break; 519*dbed73cbSSangeeta Misra } 520*dbed73cbSSangeeta Misra 521*dbed73cbSSangeeta Misra sg->isg_max_id = (id + i) % MAX_SRVCOUNT; 522*dbed73cbSSangeeta Misra sg->isg_id_arr[sg->isg_max_id] = 1; 523*dbed73cbSSangeeta Misra return (sg->isg_max_id); 524*dbed73cbSSangeeta Misra } 525*dbed73cbSSangeeta Misra 526*dbed73cbSSangeeta Misra /* 527*dbed73cbSSangeeta Misra * Free a server ID by updating the server group's ID array. 528*dbed73cbSSangeeta Misra */ 529*dbed73cbSSangeeta Misra static void 530*dbed73cbSSangeeta Misra i_ilbd_free_srvID(ilbd_sg_t *sg, int32_t id) 531*dbed73cbSSangeeta Misra { 532*dbed73cbSSangeeta Misra assert(sg->isg_id_arr[id] == 1); 533*dbed73cbSSangeeta Misra sg->isg_id_arr[id] = 0; 534*dbed73cbSSangeeta Misra } 535*dbed73cbSSangeeta Misra 536*dbed73cbSSangeeta Misra /* 537*dbed73cbSSangeeta Misra * This function is called by ilbd_add_server_to_group() and 538*dbed73cbSSangeeta Misra * ilb_remove_server_group() to create a audit record for a 539*dbed73cbSSangeeta Misra * failed servicing of add-server/remove-server command 540*dbed73cbSSangeeta Misra */ 541*dbed73cbSSangeeta Misra static void 542*dbed73cbSSangeeta Misra fill_audit_record(ilb_sg_info_t *sg, audit_sg_event_data_t *audit_sg_data, 543*dbed73cbSSangeeta Misra ilbd_cmd_t cmd, ilb_status_t rc, ucred_t *ucredp) 544*dbed73cbSSangeeta Misra { 545*dbed73cbSSangeeta Misra ilb_sg_srv_t *tsrv; 546*dbed73cbSSangeeta Misra int i; 547*dbed73cbSSangeeta Misra 548*dbed73cbSSangeeta Misra for (i = 0; i < sg->sg_srvcount; i++) { 549*dbed73cbSSangeeta Misra tsrv = &sg->sg_servers[i]; 550*dbed73cbSSangeeta Misra if (cmd == ILBD_ADD_SERVER_TO_GROUP) { 551*dbed73cbSSangeeta Misra char addrstr_buf[INET6_ADDRSTRLEN]; 552*dbed73cbSSangeeta Misra 553*dbed73cbSSangeeta Misra audit_sg_data->ed_serverid = NULL; 554*dbed73cbSSangeeta Misra ilbd_addr2str(&tsrv->sgs_addr, addrstr_buf, 555*dbed73cbSSangeeta Misra sizeof (addrstr_buf)); 556*dbed73cbSSangeeta Misra audit_sg_data->ed_server_address = addrstr_buf; 557*dbed73cbSSangeeta Misra audit_sg_data->ed_minport = tsrv->sgs_minport; 558*dbed73cbSSangeeta Misra audit_sg_data->ed_maxport = tsrv->sgs_maxport; 559*dbed73cbSSangeeta Misra audit_sg_data->ed_sgroup = sg->sg_name; 560*dbed73cbSSangeeta Misra } else if (cmd == ILBD_REM_SERVER_FROM_GROUP) { 561*dbed73cbSSangeeta Misra audit_sg_data->ed_serverid = tsrv->sgs_srvID; 562*dbed73cbSSangeeta Misra audit_sg_data->ed_sgroup = sg->sg_name; 563*dbed73cbSSangeeta Misra audit_sg_data->ed_server_address = NULL; 564*dbed73cbSSangeeta Misra audit_sg_data->ed_minport = 0; 565*dbed73cbSSangeeta Misra audit_sg_data->ed_maxport = 0; 566*dbed73cbSSangeeta Misra } 567*dbed73cbSSangeeta Misra ilbd_audit_server_event(audit_sg_data, cmd, rc, ucredp); 568*dbed73cbSSangeeta Misra } 569*dbed73cbSSangeeta Misra } 570*dbed73cbSSangeeta Misra 571*dbed73cbSSangeeta Misra /* 572*dbed73cbSSangeeta Misra * the name(s) of the server(s) are encoded in the sg. 573*dbed73cbSSangeeta Misra */ 574*dbed73cbSSangeeta Misra ilb_status_t 575*dbed73cbSSangeeta Misra ilbd_add_server_to_group(ilb_sg_info_t *sg_info, int ev_port, 576*dbed73cbSSangeeta Misra const struct passwd *ps, ucred_t *ucredp) 577*dbed73cbSSangeeta Misra { 578*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 579*dbed73cbSSangeeta Misra ilbd_sg_t *tmp_sg; 580*dbed73cbSSangeeta Misra int i, j; 581*dbed73cbSSangeeta Misra int32_t new_id = BAD_SRVID; 582*dbed73cbSSangeeta Misra int32_t af = AF_UNSPEC; 583*dbed73cbSSangeeta Misra ilbd_srv_t *nsrv; 584*dbed73cbSSangeeta Misra ilb_sg_srv_t *srv; 585*dbed73cbSSangeeta Misra audit_sg_event_data_t audit_sg_data; 586*dbed73cbSSangeeta Misra char addrstr_buf[INET6_ADDRSTRLEN]; 587*dbed73cbSSangeeta Misra 588*dbed73cbSSangeeta Misra if (ps != NULL) { 589*dbed73cbSSangeeta Misra rc = ilbd_check_client_config_auth(ps); 590*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 591*dbed73cbSSangeeta Misra fill_audit_record(sg_info, &audit_sg_data, 592*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 593*dbed73cbSSangeeta Misra return (rc); 594*dbed73cbSSangeeta Misra } 595*dbed73cbSSangeeta Misra } 596*dbed73cbSSangeeta Misra 597*dbed73cbSSangeeta Misra tmp_sg = i_find_sg_byname(sg_info->sg_name); 598*dbed73cbSSangeeta Misra if (tmp_sg == NULL) { 599*dbed73cbSSangeeta Misra logdebug("ilbd_add_server_to_group: server" 600*dbed73cbSSangeeta Misra " group %s does not exist", sg_info->sg_name); 601*dbed73cbSSangeeta Misra fill_audit_record(sg_info, &audit_sg_data, 602*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, ILB_STATUS_ENOENT, ucredp); 603*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 604*dbed73cbSSangeeta Misra } 605*dbed73cbSSangeeta Misra 606*dbed73cbSSangeeta Misra /* 607*dbed73cbSSangeeta Misra * we do the dance with address family below to make sure only 608*dbed73cbSSangeeta Misra * IP addresses in the same AF get into an SG; the first one to get 609*dbed73cbSSangeeta Misra * in sets the "tone" 610*dbed73cbSSangeeta Misra * if this is the first server to join a group, check whether 611*dbed73cbSSangeeta Misra * there's no mismatch with any *rules* already attached 612*dbed73cbSSangeeta Misra */ 613*dbed73cbSSangeeta Misra if (tmp_sg->isg_srvcount > 0) { 614*dbed73cbSSangeeta Misra ilbd_srv_t *tsrv = list_head(&tmp_sg->isg_srvlist); 615*dbed73cbSSangeeta Misra 616*dbed73cbSSangeeta Misra af = GET_AF(&tsrv->isv_addr); 617*dbed73cbSSangeeta Misra } else { 618*dbed73cbSSangeeta Misra ilbd_rule_t *irl = list_head(&tmp_sg->isg_rulelist); 619*dbed73cbSSangeeta Misra 620*dbed73cbSSangeeta Misra if (irl != NULL) 621*dbed73cbSSangeeta Misra af = GET_AF(&irl->irl_vip); 622*dbed73cbSSangeeta Misra } 623*dbed73cbSSangeeta Misra 624*dbed73cbSSangeeta Misra for (i = 0; i < sg_info->sg_srvcount; i++) { 625*dbed73cbSSangeeta Misra srv = &sg_info->sg_servers[i]; 626*dbed73cbSSangeeta Misra 627*dbed73cbSSangeeta Misra (void) memset(&audit_sg_data, 0, sizeof (audit_sg_data)); 628*dbed73cbSSangeeta Misra ilbd_addr2str(&srv->sgs_addr, addrstr_buf, 629*dbed73cbSSangeeta Misra sizeof (addrstr_buf)); 630*dbed73cbSSangeeta Misra audit_sg_data.ed_server_address = addrstr_buf; 631*dbed73cbSSangeeta Misra audit_sg_data.ed_minport = srv->sgs_minport; 632*dbed73cbSSangeeta Misra audit_sg_data.ed_maxport = srv->sgs_maxport; 633*dbed73cbSSangeeta Misra audit_sg_data.ed_sgroup = sg_info->sg_name; 634*dbed73cbSSangeeta Misra 635*dbed73cbSSangeeta Misra /* only test if we have sth to test against */ 636*dbed73cbSSangeeta Misra if (af != AF_UNSPEC) { 637*dbed73cbSSangeeta Misra int32_t sgs_af = GET_AF(&srv->sgs_addr); 638*dbed73cbSSangeeta Misra 639*dbed73cbSSangeeta Misra if (af != sgs_af) { 640*dbed73cbSSangeeta Misra logdebug("address family mismatch with previous" 641*dbed73cbSSangeeta Misra " hosts in servergroup or with rule"); 642*dbed73cbSSangeeta Misra rc = ILB_STATUS_MISMATCHH; 643*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 644*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 645*dbed73cbSSangeeta Misra goto rollback; 646*dbed73cbSSangeeta Misra } 647*dbed73cbSSangeeta Misra } 648*dbed73cbSSangeeta Misra 649*dbed73cbSSangeeta Misra /* 650*dbed73cbSSangeeta Misra * PS: NULL means daemon is loading configure from scf. 651*dbed73cbSSangeeta Misra * ServerID is already assigned, just update the ID array. 652*dbed73cbSSangeeta Misra */ 653*dbed73cbSSangeeta Misra if (ps != NULL) { 654*dbed73cbSSangeeta Misra new_id = i_ilbd_alloc_srvID(tmp_sg, NULL); 655*dbed73cbSSangeeta Misra if (new_id == BAD_SRVID) { 656*dbed73cbSSangeeta Misra logdebug("ilbd_add_server_to_group: server" 657*dbed73cbSSangeeta Misra "group %s is full, no more servers" 658*dbed73cbSSangeeta Misra " can be added", sg_info->sg_name); 659*dbed73cbSSangeeta Misra rc = ILB_STATUS_SGFULL; 660*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 661*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 662*dbed73cbSSangeeta Misra goto rollback; 663*dbed73cbSSangeeta Misra } 664*dbed73cbSSangeeta Misra srv->sgs_id = new_id; 665*dbed73cbSSangeeta Misra } else { 666*dbed73cbSSangeeta Misra new_id = i_ilbd_alloc_srvID(tmp_sg, &srv->sgs_id); 667*dbed73cbSSangeeta Misra } 668*dbed73cbSSangeeta Misra 669*dbed73cbSSangeeta Misra /* 670*dbed73cbSSangeeta Misra * here we implement the requirement that server IDs start 671*dbed73cbSSangeeta Misra * with a character that is not legal in hostnames - in our 672*dbed73cbSSangeeta Misra * case, a "_" (underscore). 673*dbed73cbSSangeeta Misra */ 674*dbed73cbSSangeeta Misra (void) snprintf(srv->sgs_srvID, 675*dbed73cbSSangeeta Misra sizeof (srv->sgs_srvID), "%c%s.%d", ILB_SRVID_PREFIX, 676*dbed73cbSSangeeta Misra tmp_sg->isg_name, srv->sgs_id); 677*dbed73cbSSangeeta Misra audit_sg_data.ed_serverid = srv->sgs_srvID; 678*dbed73cbSSangeeta Misra 679*dbed73cbSSangeeta Misra /* 680*dbed73cbSSangeeta Misra * Before we update the kernel rules by adding the server, 681*dbed73cbSSangeeta Misra * we need to make checks and fail if any of the 682*dbed73cbSSangeeta Misra * following is true: 683*dbed73cbSSangeeta Misra * 684*dbed73cbSSangeeta Misra * o if the server has single port and the servergroup 685*dbed73cbSSangeeta Misra * is associated to a DSR rule with a port range 686*dbed73cbSSangeeta Misra * o if the server has a port range and the servergroup 687*dbed73cbSSangeeta Misra * is associated to a DSR rule with a port range and 688*dbed73cbSSangeeta Misra * the rule's min and max port does not exactly 689*dbed73cbSSangeeta Misra * match that of the server's. 690*dbed73cbSSangeeta Misra * o if the the server has a port range and the servergroup 691*dbed73cbSSangeeta Misra * is associated to a NAT/Half-NAT rule with a port range 692*dbed73cbSSangeeta Misra * and the rule's port range size does not match that 693*dbed73cbSSangeeta Misra * of the server's. 694*dbed73cbSSangeeta Misra * o if the rule has a fixed hc port, check that this port 695*dbed73cbSSangeeta Misra * is valid in the server's port specification. 696*dbed73cbSSangeeta Misra */ 697*dbed73cbSSangeeta Misra rc = i_check_srv2rules(&tmp_sg->isg_rulelist, srv); 698*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 699*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 700*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 701*dbed73cbSSangeeta Misra goto rollback; 702*dbed73cbSSangeeta Misra } 703*dbed73cbSSangeeta Misra 704*dbed73cbSSangeeta Misra if ((rc = i_add_srv2sg(tmp_sg, srv, &nsrv)) != ILB_STATUS_OK) { 705*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 706*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 707*dbed73cbSSangeeta Misra goto rollback; 708*dbed73cbSSangeeta Misra } 709*dbed73cbSSangeeta Misra 710*dbed73cbSSangeeta Misra rc = i_add_srv2krules(&tmp_sg->isg_rulelist, &nsrv->isv_srv, 711*dbed73cbSSangeeta Misra ev_port); 712*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 713*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 714*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 715*dbed73cbSSangeeta Misra /* 716*dbed73cbSSangeeta Misra * The failure may be due to the serverid being on 717*dbed73cbSSangeeta Misra * hold in kernel for connection draining. But ilbd 718*dbed73cbSSangeeta Misra * has no way of knowing that. So we are freeing up 719*dbed73cbSSangeeta Misra * the serverid, and may run into the risk of 720*dbed73cbSSangeeta Misra * having this failure again, if we choose this 721*dbed73cbSSangeeta Misra * serverid when processing the next add-server 722*dbed73cbSSangeeta Misra * command for this servergroup, while connection 723*dbed73cbSSangeeta Misra * draining is underway. We assume that the user 724*dbed73cbSSangeeta Misra * will read the man page after he/she encounters 725*dbed73cbSSangeeta Misra * this failure, and learn to not add any server 726*dbed73cbSSangeeta Misra * to the servergroup until connection draining of 727*dbed73cbSSangeeta Misra * all servers in the servergroup is complete. 728*dbed73cbSSangeeta Misra * XXX Need to revisit this when connection draining 729*dbed73cbSSangeeta Misra * is reworked 730*dbed73cbSSangeeta Misra */ 731*dbed73cbSSangeeta Misra list_remove(&tmp_sg->isg_srvlist, nsrv); 732*dbed73cbSSangeeta Misra i_ilbd_free_srvID(tmp_sg, nsrv->isv_id); 733*dbed73cbSSangeeta Misra free(nsrv); 734*dbed73cbSSangeeta Misra tmp_sg->isg_srvcount--; 735*dbed73cbSSangeeta Misra goto rollback; 736*dbed73cbSSangeeta Misra } 737*dbed73cbSSangeeta Misra if (ps != NULL) { 738*dbed73cbSSangeeta Misra rc = ilbd_scf_add_srv(tmp_sg, nsrv); 739*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 740*dbed73cbSSangeeta Misra /* 741*dbed73cbSSangeeta Misra * The following should not fail since the 742*dbed73cbSSangeeta Misra * server is just added. Just in case, we 743*dbed73cbSSangeeta Misra * pass in -1 as the event port to avoid 744*dbed73cbSSangeeta Misra * roll back in i_rem_srv_frm_krules() called 745*dbed73cbSSangeeta Misra * by i_delete_srv(). 746*dbed73cbSSangeeta Misra */ 747*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 748*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 749*dbed73cbSSangeeta Misra (void) i_delete_srv(tmp_sg, nsrv, -1); 750*dbed73cbSSangeeta Misra break; 751*dbed73cbSSangeeta Misra } 752*dbed73cbSSangeeta Misra } 753*dbed73cbSSangeeta Misra } 754*dbed73cbSSangeeta Misra 755*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) { 756*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 757*dbed73cbSSangeeta Misra ILBD_ADD_SERVER_TO_GROUP, rc, ucredp); 758*dbed73cbSSangeeta Misra return (rc); 759*dbed73cbSSangeeta Misra } 760*dbed73cbSSangeeta Misra 761*dbed73cbSSangeeta Misra rollback: 762*dbed73cbSSangeeta Misra /* 763*dbed73cbSSangeeta Misra * If ilbd is initializing based on the SCF data and something fails, 764*dbed73cbSSangeeta Misra * the only choice is to transition the service to maintanence mode... 765*dbed73cbSSangeeta Misra */ 766*dbed73cbSSangeeta Misra if (ps == NULL) { 767*dbed73cbSSangeeta Misra logerr("%s: failure during initialization -" 768*dbed73cbSSangeeta Misra " entering maintenance mode", __func__); 769*dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 770*dbed73cbSSangeeta Misra return (rc); 771*dbed73cbSSangeeta Misra } 772*dbed73cbSSangeeta Misra 773*dbed73cbSSangeeta Misra /* 774*dbed73cbSSangeeta Misra * we need to roll back all servers previous to the one 775*dbed73cbSSangeeta Misra * that just caused the failure 776*dbed73cbSSangeeta Misra */ 777*dbed73cbSSangeeta Misra for (j = i-1; j >= 0; j--) { 778*dbed73cbSSangeeta Misra srv = &sg_info->sg_servers[j]; 779*dbed73cbSSangeeta Misra 780*dbed73cbSSangeeta Misra /* We should be able to find those servers just added. */ 781*dbed73cbSSangeeta Misra nsrv = i_find_srv(&tmp_sg->isg_srvlist, srv, MODE_SRVID); 782*dbed73cbSSangeeta Misra assert(nsrv != NULL); 783*dbed73cbSSangeeta Misra (void) i_delete_srv(tmp_sg, nsrv, -1); 784*dbed73cbSSangeeta Misra } 785*dbed73cbSSangeeta Misra return (rc); 786*dbed73cbSSangeeta Misra } 787*dbed73cbSSangeeta Misra 788*dbed73cbSSangeeta Misra static srch_ind_t 789*dbed73cbSSangeeta Misra i_match_srvID(ilb_sg_srv_t *sg_srv, ilbd_srv_t *lsrv) 790*dbed73cbSSangeeta Misra { 791*dbed73cbSSangeeta Misra if (strncmp(sg_srv->sgs_srvID, lsrv->isv_srvID, 792*dbed73cbSSangeeta Misra sizeof (sg_srv->sgs_srvID)) == 0) { 793*dbed73cbSSangeeta Misra return (stop_found); 794*dbed73cbSSangeeta Misra } 795*dbed73cbSSangeeta Misra return (cont_search); 796*dbed73cbSSangeeta Misra } 797*dbed73cbSSangeeta Misra 798*dbed73cbSSangeeta Misra /* 799*dbed73cbSSangeeta Misra * Sanity check on a rule's port specification against all the servers' 800*dbed73cbSSangeeta Misra * specification in its associated server group. 801*dbed73cbSSangeeta Misra * 802*dbed73cbSSangeeta Misra * 1. If the health check's probe port (hcport) is specified. 803*dbed73cbSSangeeta Misra * - if server port range is specified, check if hcport is inside 804*dbed73cbSSangeeta Misra * the range 805*dbed73cbSSangeeta Misra * - if no server port is specified (meaning the port range is the same as 806*dbed73cbSSangeeta Misra * the rule's port range), check if hcport is inside the rule's range. 807*dbed73cbSSangeeta Misra * 808*dbed73cbSSangeeta Misra * 2. If a server has no port specification, there is no conflict. 809*dbed73cbSSangeeta Misra * 810*dbed73cbSSangeeta Misra * 3. If the rule's load balance mode is DSR, a server port specification must 811*dbed73cbSSangeeta Misra * be exactly the same as the rule's. 812*dbed73cbSSangeeta Misra * 813*dbed73cbSSangeeta Misra * 4. In other modes (NAT and half-NAT), the server's port range must be 814*dbed73cbSSangeeta Misra * the same as the rule's, unless it is doing port collapsing (the server's 815*dbed73cbSSangeeta Misra * port range is only 1). 816*dbed73cbSSangeeta Misra */ 817*dbed73cbSSangeeta Misra ilb_status_t 818*dbed73cbSSangeeta Misra ilbd_sg_check_rule_port(ilbd_sg_t *sg, ilb_rule_info_t *rl) 819*dbed73cbSSangeeta Misra { 820*dbed73cbSSangeeta Misra ilbd_srv_t *srv; 821*dbed73cbSSangeeta Misra in_port_t r_minport, r_maxport; 822*dbed73cbSSangeeta Misra 823*dbed73cbSSangeeta Misra /* Don't allow adding a rule to a sg with no server, for now... */ 824*dbed73cbSSangeeta Misra if (sg->isg_srvcount == 0) 825*dbed73cbSSangeeta Misra return (ILB_STATUS_SGEMPTY); 826*dbed73cbSSangeeta Misra 827*dbed73cbSSangeeta Misra r_minport = ntohs(rl->rl_minport); 828*dbed73cbSSangeeta Misra r_maxport = ntohs(rl->rl_maxport); 829*dbed73cbSSangeeta Misra 830*dbed73cbSSangeeta Misra for (srv = list_head(&sg->isg_srvlist); srv != NULL; 831*dbed73cbSSangeeta Misra srv = list_next(&sg->isg_srvlist, srv)) { 832*dbed73cbSSangeeta Misra in_port_t srv_minport, srv_maxport; 833*dbed73cbSSangeeta Misra int range; 834*dbed73cbSSangeeta Misra 835*dbed73cbSSangeeta Misra srv_minport = ntohs(srv->isv_minport); 836*dbed73cbSSangeeta Misra srv_maxport = ntohs(srv->isv_maxport); 837*dbed73cbSSangeeta Misra range = srv_maxport - srv_minport; 838*dbed73cbSSangeeta Misra 839*dbed73cbSSangeeta Misra /* 840*dbed73cbSSangeeta Misra * If the rule has a specific probe port, check if that port is 841*dbed73cbSSangeeta Misra * valid in all the servers' port specification. 842*dbed73cbSSangeeta Misra */ 843*dbed73cbSSangeeta Misra if (rl->rl_hcpflag == ILB_HCI_PROBE_FIX) { 844*dbed73cbSSangeeta Misra in_port_t hcport = ntohs(rl->rl_hcport); 845*dbed73cbSSangeeta Misra 846*dbed73cbSSangeeta Misra /* No server port specified. */ 847*dbed73cbSSangeeta Misra if (srv_minport == 0) { 848*dbed73cbSSangeeta Misra if (hcport > r_maxport || hcport < r_minport) { 849*dbed73cbSSangeeta Misra return (ILB_STATUS_BADSG); 850*dbed73cbSSangeeta Misra } 851*dbed73cbSSangeeta Misra } else { 852*dbed73cbSSangeeta Misra if (hcport > srv_maxport || 853*dbed73cbSSangeeta Misra hcport < srv_minport) { 854*dbed73cbSSangeeta Misra return (ILB_STATUS_BADSG); 855*dbed73cbSSangeeta Misra } 856*dbed73cbSSangeeta Misra } 857*dbed73cbSSangeeta Misra } 858*dbed73cbSSangeeta Misra 859*dbed73cbSSangeeta Misra /* 860*dbed73cbSSangeeta Misra * There is no server port specification, so there cannot be 861*dbed73cbSSangeeta Misra * any conflict. 862*dbed73cbSSangeeta Misra */ 863*dbed73cbSSangeeta Misra if (srv_minport == 0) 864*dbed73cbSSangeeta Misra continue; 865*dbed73cbSSangeeta Misra 866*dbed73cbSSangeeta Misra if (rl->rl_topo == ILB_TOPO_DSR) { 867*dbed73cbSSangeeta Misra if (r_minport != srv_minport || 868*dbed73cbSSangeeta Misra r_maxport != srv_maxport) { 869*dbed73cbSSangeeta Misra return (ILB_STATUS_BADSG); 870*dbed73cbSSangeeta Misra } 871*dbed73cbSSangeeta Misra } else { 872*dbed73cbSSangeeta Misra if ((range != r_maxport - r_minport) && range != 0) 873*dbed73cbSSangeeta Misra return (ILB_STATUS_BADSG); 874*dbed73cbSSangeeta Misra } 875*dbed73cbSSangeeta Misra } 876*dbed73cbSSangeeta Misra 877*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 878*dbed73cbSSangeeta Misra } 879*dbed73cbSSangeeta Misra 880*dbed73cbSSangeeta Misra static srch_ind_t 881*dbed73cbSSangeeta Misra i_match_srvIP(ilb_sg_srv_t *sg_srv, ilbd_srv_t *lsrv) 882*dbed73cbSSangeeta Misra { 883*dbed73cbSSangeeta Misra if (IN6_ARE_ADDR_EQUAL(&sg_srv->sgs_addr, &lsrv->isv_addr)) 884*dbed73cbSSangeeta Misra return (stop_found); 885*dbed73cbSSangeeta Misra return (cont_search); 886*dbed73cbSSangeeta Misra } 887*dbed73cbSSangeeta Misra 888*dbed73cbSSangeeta Misra static ilbd_srv_t * 889*dbed73cbSSangeeta Misra i_find_srv(list_t *srvlist, ilb_sg_srv_t *sg_srv, int cmpmode) 890*dbed73cbSSangeeta Misra { 891*dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv; 892*dbed73cbSSangeeta Misra srch_ind_t srch_res = cont_search; 893*dbed73cbSSangeeta Misra 894*dbed73cbSSangeeta Misra for (tmp_srv = list_head(srvlist); tmp_srv != NULL; 895*dbed73cbSSangeeta Misra tmp_srv = list_next(srvlist, tmp_srv)) { 896*dbed73cbSSangeeta Misra switch (cmpmode) { 897*dbed73cbSSangeeta Misra case MODE_ADDR: 898*dbed73cbSSangeeta Misra srch_res = i_match_srvIP(sg_srv, tmp_srv); 899*dbed73cbSSangeeta Misra break; 900*dbed73cbSSangeeta Misra case MODE_SRVID: 901*dbed73cbSSangeeta Misra srch_res = i_match_srvID(sg_srv, tmp_srv); 902*dbed73cbSSangeeta Misra break; 903*dbed73cbSSangeeta Misra } 904*dbed73cbSSangeeta Misra if (srch_res == stop_found) 905*dbed73cbSSangeeta Misra break; 906*dbed73cbSSangeeta Misra } 907*dbed73cbSSangeeta Misra 908*dbed73cbSSangeeta Misra if (srch_res == stop_found) 909*dbed73cbSSangeeta Misra return (tmp_srv); 910*dbed73cbSSangeeta Misra return (NULL); 911*dbed73cbSSangeeta Misra } 912*dbed73cbSSangeeta Misra 913*dbed73cbSSangeeta Misra static ilb_status_t 914*dbed73cbSSangeeta Misra i_delete_srv(ilbd_sg_t *sg, ilbd_srv_t *srv, int ev_port) 915*dbed73cbSSangeeta Misra { 916*dbed73cbSSangeeta Misra ilb_status_t rc; 917*dbed73cbSSangeeta Misra 918*dbed73cbSSangeeta Misra rc = i_rem_srv_frm_krules(&sg->isg_rulelist, &srv->isv_srv, ev_port); 919*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 920*dbed73cbSSangeeta Misra return (rc); 921*dbed73cbSSangeeta Misra list_remove(&sg->isg_srvlist, srv); 922*dbed73cbSSangeeta Misra i_ilbd_free_srvID(sg, srv->isv_id); 923*dbed73cbSSangeeta Misra free(srv); 924*dbed73cbSSangeeta Misra sg->isg_srvcount--; 925*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 926*dbed73cbSSangeeta Misra } 927*dbed73cbSSangeeta Misra 928*dbed73cbSSangeeta Misra /* 929*dbed73cbSSangeeta Misra * some people argue that returning anything here is 930*dbed73cbSSangeeta Misra * useless - what *do* you do if you can't remove/destroy 931*dbed73cbSSangeeta Misra * something anyway? 932*dbed73cbSSangeeta Misra */ 933*dbed73cbSSangeeta Misra ilb_status_t 934*dbed73cbSSangeeta Misra ilbd_rem_server_from_group(ilb_sg_info_t *sg_info, int ev_port, 935*dbed73cbSSangeeta Misra const struct passwd *ps, ucred_t *ucredp) 936*dbed73cbSSangeeta Misra { 937*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 938*dbed73cbSSangeeta Misra ilbd_sg_t *tmp_sg; 939*dbed73cbSSangeeta Misra ilbd_srv_t *srv, tmp_srv; 940*dbed73cbSSangeeta Misra ilb_sg_srv_t *tsrv; 941*dbed73cbSSangeeta Misra audit_sg_event_data_t audit_sg_data; 942*dbed73cbSSangeeta Misra char addrstr_buf[INET6_ADDRSTRLEN]; 943*dbed73cbSSangeeta Misra 944*dbed73cbSSangeeta Misra rc = ilbd_check_client_config_auth(ps); 945*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 946*dbed73cbSSangeeta Misra fill_audit_record(sg_info, &audit_sg_data, 947*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, rc, ucredp); 948*dbed73cbSSangeeta Misra return (rc); 949*dbed73cbSSangeeta Misra } 950*dbed73cbSSangeeta Misra 951*dbed73cbSSangeeta Misra tmp_sg = i_find_sg_byname(sg_info->sg_name); 952*dbed73cbSSangeeta Misra if (tmp_sg == NULL) { 953*dbed73cbSSangeeta Misra logdebug("%s: server group %s\n does not exist", __func__, 954*dbed73cbSSangeeta Misra sg_info->sg_name); 955*dbed73cbSSangeeta Misra fill_audit_record(sg_info, &audit_sg_data, 956*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, ILB_STATUS_SGUNAVAIL, ucredp); 957*dbed73cbSSangeeta Misra return (ILB_STATUS_SGUNAVAIL); 958*dbed73cbSSangeeta Misra } 959*dbed73cbSSangeeta Misra tsrv = &sg_info->sg_servers[0]; 960*dbed73cbSSangeeta Misra audit_sg_data.ed_serverid = tsrv->sgs_srvID; 961*dbed73cbSSangeeta Misra audit_sg_data.ed_sgroup = sg_info->sg_name; 962*dbed73cbSSangeeta Misra audit_sg_data.ed_server_address = NULL; 963*dbed73cbSSangeeta Misra 964*dbed73cbSSangeeta Misra assert(sg_info->sg_srvcount == 1); 965*dbed73cbSSangeeta Misra srv = i_find_srv(&tmp_sg->isg_srvlist, &sg_info->sg_servers[0], 966*dbed73cbSSangeeta Misra MODE_SRVID); 967*dbed73cbSSangeeta Misra if (srv == NULL) { 968*dbed73cbSSangeeta Misra logdebug("%s: cannot find server in server group %s", __func__, 969*dbed73cbSSangeeta Misra sg_info->sg_name); 970*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 971*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, ILB_STATUS_SRVUNAVAIL, ucredp); 972*dbed73cbSSangeeta Misra return (ILB_STATUS_SRVUNAVAIL); 973*dbed73cbSSangeeta Misra } 974*dbed73cbSSangeeta Misra tsrv = &srv->isv_srv; 975*dbed73cbSSangeeta Misra ilbd_addr2str(&tsrv->sgs_addr, addrstr_buf, 976*dbed73cbSSangeeta Misra sizeof (addrstr_buf)); 977*dbed73cbSSangeeta Misra audit_sg_data.ed_server_address = addrstr_buf; 978*dbed73cbSSangeeta Misra /* 979*dbed73cbSSangeeta Misra * i_delete_srv frees srv, therefore we need to save 980*dbed73cbSSangeeta Misra * this information for ilbd_scf_del_srv 981*dbed73cbSSangeeta Misra */ 982*dbed73cbSSangeeta Misra (void) memcpy(&tmp_srv, srv, sizeof (tmp_srv)); 983*dbed73cbSSangeeta Misra 984*dbed73cbSSangeeta Misra rc = i_delete_srv(tmp_sg, srv, ev_port); 985*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 986*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 987*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, rc, ucredp); 988*dbed73cbSSangeeta Misra return (rc); 989*dbed73cbSSangeeta Misra } 990*dbed73cbSSangeeta Misra 991*dbed73cbSSangeeta Misra if (ps != NULL) { 992*dbed73cbSSangeeta Misra if ((rc = ilbd_scf_del_srv(tmp_sg, &tmp_srv)) != 993*dbed73cbSSangeeta Misra ILB_STATUS_OK) { 994*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 995*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, rc, ucredp); 996*dbed73cbSSangeeta Misra logerr("%s: SCF update failed - entering maintenance" 997*dbed73cbSSangeeta Misra " mode", __func__); 998*dbed73cbSSangeeta Misra (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE); 999*dbed73cbSSangeeta Misra } 1000*dbed73cbSSangeeta Misra } 1001*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1002*dbed73cbSSangeeta Misra ILBD_REM_SERVER_FROM_GROUP, rc, ucredp); 1003*dbed73cbSSangeeta Misra return (rc); 1004*dbed73cbSSangeeta Misra } 1005*dbed73cbSSangeeta Misra 1006*dbed73cbSSangeeta Misra ilb_status_t 1007*dbed73cbSSangeeta Misra ilbd_retrieve_names(ilbd_cmd_t cmd, uint32_t *rbuf, size_t *rbufsz) 1008*dbed73cbSSangeeta Misra { 1009*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 1010*dbed73cbSSangeeta Misra ilbd_namelist_t *nlist; 1011*dbed73cbSSangeeta Misra size_t tmp_rbufsz; 1012*dbed73cbSSangeeta Misra 1013*dbed73cbSSangeeta Misra tmp_rbufsz = *rbufsz; 1014*dbed73cbSSangeeta Misra /* Set up the reply buffer. rbufsz will be set to the new size. */ 1015*dbed73cbSSangeeta Misra ilbd_reply_ok(rbuf, rbufsz); 1016*dbed73cbSSangeeta Misra 1017*dbed73cbSSangeeta Misra /* Calculate how much space is left for holding name info. */ 1018*dbed73cbSSangeeta Misra *rbufsz += sizeof (ilbd_namelist_t); 1019*dbed73cbSSangeeta Misra tmp_rbufsz -= *rbufsz; 1020*dbed73cbSSangeeta Misra 1021*dbed73cbSSangeeta Misra nlist = (ilbd_namelist_t *)&((ilb_comm_t *)rbuf)->ic_data; 1022*dbed73cbSSangeeta Misra nlist->ilbl_count = 0; 1023*dbed73cbSSangeeta Misra 1024*dbed73cbSSangeeta Misra switch (cmd) { 1025*dbed73cbSSangeeta Misra case ILBD_RETRIEVE_SG_NAMES: { 1026*dbed73cbSSangeeta Misra ilbd_sg_t *sg; 1027*dbed73cbSSangeeta Misra 1028*dbed73cbSSangeeta Misra for (sg = list_head(&ilbd_sg_hlist); 1029*dbed73cbSSangeeta Misra sg != NULL && tmp_rbufsz >= sizeof (ilbd_name_t); 1030*dbed73cbSSangeeta Misra sg = list_next(&ilbd_sg_hlist, sg), 1031*dbed73cbSSangeeta Misra tmp_rbufsz -= sizeof (ilbd_name_t)) { 1032*dbed73cbSSangeeta Misra (void) strlcpy(nlist->ilbl_name[nlist->ilbl_count++], 1033*dbed73cbSSangeeta Misra sg->isg_name, sizeof (ilbd_name_t)); 1034*dbed73cbSSangeeta Misra } 1035*dbed73cbSSangeeta Misra break; 1036*dbed73cbSSangeeta Misra } 1037*dbed73cbSSangeeta Misra case ILBD_RETRIEVE_RULE_NAMES: { 1038*dbed73cbSSangeeta Misra ilbd_rule_t *irl; 1039*dbed73cbSSangeeta Misra extern list_t ilbd_rule_hlist; 1040*dbed73cbSSangeeta Misra 1041*dbed73cbSSangeeta Misra for (irl = list_head(&ilbd_rule_hlist); 1042*dbed73cbSSangeeta Misra irl != NULL && tmp_rbufsz >= sizeof (ilbd_name_t); 1043*dbed73cbSSangeeta Misra irl = list_next(&ilbd_rule_hlist, irl), 1044*dbed73cbSSangeeta Misra tmp_rbufsz -= sizeof (ilbd_name_t)) { 1045*dbed73cbSSangeeta Misra (void) strlcpy(nlist->ilbl_name[nlist->ilbl_count++], 1046*dbed73cbSSangeeta Misra irl->irl_name, sizeof (ilbd_name_t)); 1047*dbed73cbSSangeeta Misra } 1048*dbed73cbSSangeeta Misra break; 1049*dbed73cbSSangeeta Misra } 1050*dbed73cbSSangeeta Misra case ILBD_RETRIEVE_HC_NAMES: { 1051*dbed73cbSSangeeta Misra extern list_t ilbd_hc_list; 1052*dbed73cbSSangeeta Misra ilbd_hc_t *hc; 1053*dbed73cbSSangeeta Misra 1054*dbed73cbSSangeeta Misra for (hc = list_head(&ilbd_hc_list); 1055*dbed73cbSSangeeta Misra hc != NULL && tmp_rbufsz >= sizeof (ilbd_name_t); 1056*dbed73cbSSangeeta Misra hc = list_next(&ilbd_hc_list, hc)) { 1057*dbed73cbSSangeeta Misra (void) strlcpy(nlist->ilbl_name[nlist->ilbl_count++], 1058*dbed73cbSSangeeta Misra hc->ihc_name, sizeof (ilbd_name_t)); 1059*dbed73cbSSangeeta Misra } 1060*dbed73cbSSangeeta Misra break; 1061*dbed73cbSSangeeta Misra } 1062*dbed73cbSSangeeta Misra default: 1063*dbed73cbSSangeeta Misra logdebug("ilbd_retrieve_names: unknown command"); 1064*dbed73cbSSangeeta Misra return (ILB_STATUS_INVAL_CMD); 1065*dbed73cbSSangeeta Misra } 1066*dbed73cbSSangeeta Misra 1067*dbed73cbSSangeeta Misra *rbufsz += nlist->ilbl_count * sizeof (ilbd_name_t); 1068*dbed73cbSSangeeta Misra return (rc); 1069*dbed73cbSSangeeta Misra } 1070*dbed73cbSSangeeta Misra 1071*dbed73cbSSangeeta Misra ilb_status_t 1072*dbed73cbSSangeeta Misra ilbd_retrieve_sg_hosts(const char *sg_name, uint32_t *rbuf, size_t *rbufsz) 1073*dbed73cbSSangeeta Misra { 1074*dbed73cbSSangeeta Misra ilbd_sg_t *dsg; 1075*dbed73cbSSangeeta Misra ilbd_srv_t *dsrv; 1076*dbed73cbSSangeeta Misra list_t *srvlist; 1077*dbed73cbSSangeeta Misra ilb_sg_info_t *sg_info; 1078*dbed73cbSSangeeta Misra size_t tmp_rbufsz; 1079*dbed73cbSSangeeta Misra 1080*dbed73cbSSangeeta Misra dsg = i_find_sg_byname(sg_name); 1081*dbed73cbSSangeeta Misra if (dsg == NULL) { 1082*dbed73cbSSangeeta Misra logdebug("ilbd_retrieve_sg_hosts: server group" 1083*dbed73cbSSangeeta Misra " %s not found", sg_name); 1084*dbed73cbSSangeeta Misra return (ILB_STATUS_SGUNAVAIL); 1085*dbed73cbSSangeeta Misra } 1086*dbed73cbSSangeeta Misra 1087*dbed73cbSSangeeta Misra srvlist = &dsg->isg_srvlist; 1088*dbed73cbSSangeeta Misra dsrv = list_head(srvlist); 1089*dbed73cbSSangeeta Misra 1090*dbed73cbSSangeeta Misra tmp_rbufsz = *rbufsz; 1091*dbed73cbSSangeeta Misra ilbd_reply_ok(rbuf, rbufsz); 1092*dbed73cbSSangeeta Misra 1093*dbed73cbSSangeeta Misra /* Calculate the size to hold all the hosts info. */ 1094*dbed73cbSSangeeta Misra *rbufsz += sizeof (ilb_sg_info_t); 1095*dbed73cbSSangeeta Misra tmp_rbufsz -= *rbufsz; 1096*dbed73cbSSangeeta Misra 1097*dbed73cbSSangeeta Misra sg_info = (ilb_sg_info_t *)&((ilb_comm_t *)rbuf)->ic_data; 1098*dbed73cbSSangeeta Misra (void) strlcpy(sg_info->sg_name, sg_name, sizeof (sg_info->sg_name)); 1099*dbed73cbSSangeeta Misra sg_info->sg_srvcount = 0; 1100*dbed73cbSSangeeta Misra 1101*dbed73cbSSangeeta Misra while (dsrv != NULL && tmp_rbufsz >= sizeof (ilb_sg_srv_t)) { 1102*dbed73cbSSangeeta Misra sg_info->sg_servers[sg_info->sg_srvcount++] = dsrv->isv_srv; 1103*dbed73cbSSangeeta Misra dsrv = list_next(srvlist, dsrv); 1104*dbed73cbSSangeeta Misra tmp_rbufsz -= sizeof (ilb_sg_srv_t); 1105*dbed73cbSSangeeta Misra } 1106*dbed73cbSSangeeta Misra *rbufsz += sg_info->sg_srvcount * sizeof (ilb_sg_srv_t); 1107*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1108*dbed73cbSSangeeta Misra } 1109*dbed73cbSSangeeta Misra 1110*dbed73cbSSangeeta Misra /* 1111*dbed73cbSSangeeta Misra * this mapping function works on the assumption that HC only is 1112*dbed73cbSSangeeta Misra * active when a server is enabled. 1113*dbed73cbSSangeeta Misra */ 1114*dbed73cbSSangeeta Misra static ilb_cmd_t 1115*dbed73cbSSangeeta Misra i_srvcmd_d2k(ilbd_srv_status_ind_t dcmd) 1116*dbed73cbSSangeeta Misra { 1117*dbed73cbSSangeeta Misra ilb_cmd_t cmd; 1118*dbed73cbSSangeeta Misra 1119*dbed73cbSSangeeta Misra switch (dcmd) { 1120*dbed73cbSSangeeta Misra case stat_enable_server: 1121*dbed73cbSSangeeta Misra case stat_declare_srv_alive: 1122*dbed73cbSSangeeta Misra cmd = ILB_ENABLE_SERVERS; 1123*dbed73cbSSangeeta Misra break; 1124*dbed73cbSSangeeta Misra case stat_disable_server: 1125*dbed73cbSSangeeta Misra case stat_declare_srv_dead: 1126*dbed73cbSSangeeta Misra cmd = ILB_DISABLE_SERVERS; 1127*dbed73cbSSangeeta Misra break; 1128*dbed73cbSSangeeta Misra } 1129*dbed73cbSSangeeta Misra 1130*dbed73cbSSangeeta Misra return (cmd); 1131*dbed73cbSSangeeta Misra } 1132*dbed73cbSSangeeta Misra 1133*dbed73cbSSangeeta Misra ilb_status_t 1134*dbed73cbSSangeeta Misra ilbd_k_Xable_server(const struct in6_addr *addr, const char *rlname, 1135*dbed73cbSSangeeta Misra ilbd_srv_status_ind_t cmd) 1136*dbed73cbSSangeeta Misra { 1137*dbed73cbSSangeeta Misra ilb_status_t rc; 1138*dbed73cbSSangeeta Misra ilb_servers_cmd_t kcmd; 1139*dbed73cbSSangeeta Misra int e; 1140*dbed73cbSSangeeta Misra 1141*dbed73cbSSangeeta Misra kcmd.cmd = i_srvcmd_d2k(cmd); 1142*dbed73cbSSangeeta Misra (void) strlcpy(kcmd.name, rlname, sizeof (kcmd.name)); 1143*dbed73cbSSangeeta Misra kcmd.num_servers = 1; 1144*dbed73cbSSangeeta Misra 1145*dbed73cbSSangeeta Misra kcmd.servers[0].addr = *addr; 1146*dbed73cbSSangeeta Misra kcmd.servers[0].err = 0; 1147*dbed73cbSSangeeta Misra 1148*dbed73cbSSangeeta Misra rc = do_ioctl(&kcmd, 0); 1149*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 1150*dbed73cbSSangeeta Misra return (rc); 1151*dbed73cbSSangeeta Misra 1152*dbed73cbSSangeeta Misra if ((e = kcmd.servers[0].err) != 0) { 1153*dbed73cbSSangeeta Misra logdebug("ilbd_k_Xable_server: error %s occurred", 1154*dbed73cbSSangeeta Misra strerror(e)); 1155*dbed73cbSSangeeta Misra return (ilb_map_errno2ilbstat(e)); 1156*dbed73cbSSangeeta Misra } 1157*dbed73cbSSangeeta Misra 1158*dbed73cbSSangeeta Misra return (rc); 1159*dbed73cbSSangeeta Misra } 1160*dbed73cbSSangeeta Misra 1161*dbed73cbSSangeeta Misra #define IS_SRV_ENABLED(s) ILB_IS_SRV_ENABLED((s)->sgs_flags) 1162*dbed73cbSSangeeta Misra #define IS_SRV_DISABLED(s) (!(IS_SRV_ENABLED(s))) 1163*dbed73cbSSangeeta Misra 1164*dbed73cbSSangeeta Misra #define SET_SRV_ENABLED(s) ILB_SET_ENABLED((s)->sgs_flags) 1165*dbed73cbSSangeeta Misra #define SET_SRV_DISABLED(s) ILB_SET_DISABLED((s)->sgs_flags) 1166*dbed73cbSSangeeta Misra 1167*dbed73cbSSangeeta Misra static ilb_status_t 1168*dbed73cbSSangeeta Misra ilbd_Xable_server(ilb_sg_info_t *sg, const struct passwd *ps, 1169*dbed73cbSSangeeta Misra ilbd_srv_status_ind_t cmd, ucred_t *ucredp) 1170*dbed73cbSSangeeta Misra { 1171*dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK; 1172*dbed73cbSSangeeta Misra ilbd_sg_t *isg; 1173*dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv; 1174*dbed73cbSSangeeta Misra ilb_sg_srv_t *srv; 1175*dbed73cbSSangeeta Misra ilbd_rule_t *irl; 1176*dbed73cbSSangeeta Misra char *dot; 1177*dbed73cbSSangeeta Misra int scf_name_len = ILBD_MAX_NAME_LEN; 1178*dbed73cbSSangeeta Misra int scf_val_len = ILBD_MAX_VALUE_LEN; 1179*dbed73cbSSangeeta Misra char prop_name[scf_name_len]; 1180*dbed73cbSSangeeta Misra ilb_ip_addr_t ipaddr; 1181*dbed73cbSSangeeta Misra void *addrptr; 1182*dbed73cbSSangeeta Misra char ipstr[INET6_ADDRSTRLEN], valstr[scf_val_len]; 1183*dbed73cbSSangeeta Misra int ipver, vallen; 1184*dbed73cbSSangeeta Misra char sgname[ILB_NAMESZ]; 1185*dbed73cbSSangeeta Misra uint32_t nflags; 1186*dbed73cbSSangeeta Misra ilbd_srv_status_ind_t u_cmd; 1187*dbed73cbSSangeeta Misra audit_sg_event_data_t audit_sg_data; 1188*dbed73cbSSangeeta Misra char addrstr_buf[INET6_ADDRSTRLEN]; 1189*dbed73cbSSangeeta Misra 1190*dbed73cbSSangeeta Misra (void) memset(&audit_sg_data, 0, sizeof (audit_sg_data)); 1191*dbed73cbSSangeeta Misra 1192*dbed73cbSSangeeta Misra /* we currently only implement a "list" of one */ 1193*dbed73cbSSangeeta Misra assert(sg->sg_srvcount == 1); 1194*dbed73cbSSangeeta Misra 1195*dbed73cbSSangeeta Misra srv = &sg->sg_servers[0]; 1196*dbed73cbSSangeeta Misra audit_sg_data.ed_serverid = srv->sgs_srvID; 1197*dbed73cbSSangeeta Misra audit_sg_data.ed_server_address = NULL; 1198*dbed73cbSSangeeta Misra 1199*dbed73cbSSangeeta Misra rc = ilbd_check_client_enable_auth(ps); 1200*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 1201*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1202*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, rc, ucredp); 1203*dbed73cbSSangeeta Misra return (rc); 1204*dbed73cbSSangeeta Misra } 1205*dbed73cbSSangeeta Misra 1206*dbed73cbSSangeeta Misra if (srv->sgs_srvID[0] != ILB_SRVID_PREFIX) { 1207*dbed73cbSSangeeta Misra switch (cmd) { 1208*dbed73cbSSangeeta Misra case stat_disable_server: 1209*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1210*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, 1211*dbed73cbSSangeeta Misra ILB_STATUS_EINVAL, ucredp); 1212*dbed73cbSSangeeta Misra break; 1213*dbed73cbSSangeeta Misra case stat_enable_server: 1214*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1215*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, 1216*dbed73cbSSangeeta Misra ILB_STATUS_EINVAL, ucredp); 1217*dbed73cbSSangeeta Misra break; 1218*dbed73cbSSangeeta Misra } 1219*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1220*dbed73cbSSangeeta Misra } 1221*dbed73cbSSangeeta Misra 1222*dbed73cbSSangeeta Misra /* 1223*dbed73cbSSangeeta Misra * the following asserts that serverIDs are constructed 1224*dbed73cbSSangeeta Misra * along the pattern "_"<SG name>"."<number> 1225*dbed73cbSSangeeta Misra * so we look for the final "." to recreate the SG name. 1226*dbed73cbSSangeeta Misra */ 1227*dbed73cbSSangeeta Misra (void) strlcpy(sgname, srv->sgs_srvID + 1, sizeof (sgname)); 1228*dbed73cbSSangeeta Misra dot = strrchr(sgname, (int)'.'); 1229*dbed73cbSSangeeta Misra if (dot == NULL) { 1230*dbed73cbSSangeeta Misra switch (cmd) { 1231*dbed73cbSSangeeta Misra case stat_disable_server: 1232*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1233*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, 1234*dbed73cbSSangeeta Misra ILB_STATUS_EINVAL, ucredp); 1235*dbed73cbSSangeeta Misra break; 1236*dbed73cbSSangeeta Misra case stat_enable_server: 1237*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1238*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, 1239*dbed73cbSSangeeta Misra ILB_STATUS_EINVAL, ucredp); 1240*dbed73cbSSangeeta Misra break; 1241*dbed73cbSSangeeta Misra } 1242*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 1243*dbed73cbSSangeeta Misra } 1244*dbed73cbSSangeeta Misra 1245*dbed73cbSSangeeta Misra /* make the non-sg_name part "invisible" */ 1246*dbed73cbSSangeeta Misra *dot = '\0'; 1247*dbed73cbSSangeeta Misra isg = i_find_sg_byname(sgname); 1248*dbed73cbSSangeeta Misra if (isg == NULL) { 1249*dbed73cbSSangeeta Misra switch (cmd) { 1250*dbed73cbSSangeeta Misra case stat_disable_server: 1251*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1252*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, 1253*dbed73cbSSangeeta Misra ILB_STATUS_ENOENT, ucredp); 1254*dbed73cbSSangeeta Misra break; 1255*dbed73cbSSangeeta Misra case stat_enable_server: 1256*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1257*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, 1258*dbed73cbSSangeeta Misra ILB_STATUS_ENOENT, ucredp); 1259*dbed73cbSSangeeta Misra break; 1260*dbed73cbSSangeeta Misra } 1261*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 1262*dbed73cbSSangeeta Misra } 1263*dbed73cbSSangeeta Misra 1264*dbed73cbSSangeeta Misra tmp_srv = i_find_srv(&isg->isg_srvlist, srv, MODE_SRVID); 1265*dbed73cbSSangeeta Misra if (tmp_srv == NULL) { 1266*dbed73cbSSangeeta Misra switch (cmd) { 1267*dbed73cbSSangeeta Misra case stat_disable_server: 1268*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1269*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, 1270*dbed73cbSSangeeta Misra ILB_STATUS_ENOENT, ucredp); 1271*dbed73cbSSangeeta Misra break; 1272*dbed73cbSSangeeta Misra case stat_enable_server: 1273*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1274*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, 1275*dbed73cbSSangeeta Misra ILB_STATUS_ENOENT, ucredp); 1276*dbed73cbSSangeeta Misra break; 1277*dbed73cbSSangeeta Misra } 1278*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 1279*dbed73cbSSangeeta Misra } 1280*dbed73cbSSangeeta Misra 1281*dbed73cbSSangeeta Misra /* 1282*dbed73cbSSangeeta Misra * if server's servergroup is not associated with 1283*dbed73cbSSangeeta Misra * a rule, do not enable it. 1284*dbed73cbSSangeeta Misra */ 1285*dbed73cbSSangeeta Misra irl = list_head(&isg->isg_rulelist); 1286*dbed73cbSSangeeta Misra if (irl == NULL) { 1287*dbed73cbSSangeeta Misra switch (cmd) { 1288*dbed73cbSSangeeta Misra case stat_disable_server: 1289*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1290*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, 1291*dbed73cbSSangeeta Misra ILB_STATUS_INVAL_ENBSRVR, ucredp); 1292*dbed73cbSSangeeta Misra break; 1293*dbed73cbSSangeeta Misra case stat_enable_server: 1294*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1295*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, 1296*dbed73cbSSangeeta Misra ILB_STATUS_INVAL_ENBSRVR, ucredp); 1297*dbed73cbSSangeeta Misra break; 1298*dbed73cbSSangeeta Misra } 1299*dbed73cbSSangeeta Misra return (ILB_STATUS_INVAL_ENBSRVR); 1300*dbed73cbSSangeeta Misra } 1301*dbed73cbSSangeeta Misra /* Fill in the server IP address for audit record */ 1302*dbed73cbSSangeeta Misra ilbd_addr2str(&tmp_srv->isv_addr, addrstr_buf, 1303*dbed73cbSSangeeta Misra sizeof (addrstr_buf)); 1304*dbed73cbSSangeeta Misra audit_sg_data.ed_server_address = addrstr_buf; 1305*dbed73cbSSangeeta Misra 1306*dbed73cbSSangeeta Misra /* 1307*dbed73cbSSangeeta Misra * We have found the server in memory, perform the following 1308*dbed73cbSSangeeta Misra * tasks. 1309*dbed73cbSSangeeta Misra * 1310*dbed73cbSSangeeta Misra * 1. For every rule associated with this SG, 1311*dbed73cbSSangeeta Misra * - tell the kernel 1312*dbed73cbSSangeeta Misra * - tell the hc 1313*dbed73cbSSangeeta Misra * 2. Update our internal state and persistent configuration 1314*dbed73cbSSangeeta Misra * if the new state is not the same as the old one. 1315*dbed73cbSSangeeta Misra */ 1316*dbed73cbSSangeeta Misra /* 1. */ 1317*dbed73cbSSangeeta Misra for (; irl != NULL; irl = list_next(&isg->isg_rulelist, irl)) { 1318*dbed73cbSSangeeta Misra rc = ilbd_k_Xable_server(&tmp_srv->isv_addr, 1319*dbed73cbSSangeeta Misra irl->irl_name, cmd); 1320*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 1321*dbed73cbSSangeeta Misra switch (cmd) { 1322*dbed73cbSSangeeta Misra case stat_disable_server: 1323*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1324*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, rc, ucredp); 1325*dbed73cbSSangeeta Misra break; 1326*dbed73cbSSangeeta Misra case stat_enable_server: 1327*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1328*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, rc, ucredp); 1329*dbed73cbSSangeeta Misra break; 1330*dbed73cbSSangeeta Misra } 1331*dbed73cbSSangeeta Misra goto rollback_rules; 1332*dbed73cbSSangeeta Misra } 1333*dbed73cbSSangeeta Misra if (!RULE_HAS_HC(irl)) 1334*dbed73cbSSangeeta Misra continue; 1335*dbed73cbSSangeeta Misra 1336*dbed73cbSSangeeta Misra if (cmd == stat_disable_server) { 1337*dbed73cbSSangeeta Misra rc = ilbd_hc_disable_server(irl, 1338*dbed73cbSSangeeta Misra &tmp_srv->isv_srv); 1339*dbed73cbSSangeeta Misra } else { 1340*dbed73cbSSangeeta Misra assert(cmd == stat_enable_server); 1341*dbed73cbSSangeeta Misra rc = ilbd_hc_enable_server(irl, 1342*dbed73cbSSangeeta Misra &tmp_srv->isv_srv); 1343*dbed73cbSSangeeta Misra } 1344*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) { 1345*dbed73cbSSangeeta Misra logdebug("ilbd_Xable_server: cannot toggle srv " 1346*dbed73cbSSangeeta Misra "timer, rc =%d, srv =%s%d\n", rc, 1347*dbed73cbSSangeeta Misra tmp_srv->isv_srvID, 1348*dbed73cbSSangeeta Misra tmp_srv->isv_id); 1349*dbed73cbSSangeeta Misra } 1350*dbed73cbSSangeeta Misra } 1351*dbed73cbSSangeeta Misra 1352*dbed73cbSSangeeta Misra /* 2. */ 1353*dbed73cbSSangeeta Misra if ((cmd == stat_disable_server && 1354*dbed73cbSSangeeta Misra IS_SRV_DISABLED(&tmp_srv->isv_srv)) || 1355*dbed73cbSSangeeta Misra (cmd == stat_enable_server && 1356*dbed73cbSSangeeta Misra IS_SRV_ENABLED(&tmp_srv->isv_srv))) { 1357*dbed73cbSSangeeta Misra switch (cmd) { 1358*dbed73cbSSangeeta Misra case stat_disable_server: 1359*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1360*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, ILB_STATUS_OK, ucredp); 1361*dbed73cbSSangeeta Misra break; 1362*dbed73cbSSangeeta Misra case stat_enable_server: 1363*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1364*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, ILB_STATUS_OK, ucredp); 1365*dbed73cbSSangeeta Misra break; 1366*dbed73cbSSangeeta Misra } 1367*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1368*dbed73cbSSangeeta Misra } 1369*dbed73cbSSangeeta Misra 1370*dbed73cbSSangeeta Misra nflags = tmp_srv->isv_flags; 1371*dbed73cbSSangeeta Misra if (cmd == stat_enable_server) 1372*dbed73cbSSangeeta Misra ILB_SET_ENABLED(nflags); 1373*dbed73cbSSangeeta Misra else 1374*dbed73cbSSangeeta Misra ILB_SET_DISABLED(nflags); 1375*dbed73cbSSangeeta Misra 1376*dbed73cbSSangeeta Misra IP_COPY_IMPL_2_CLI(&tmp_srv->isv_addr, &ipaddr); 1377*dbed73cbSSangeeta Misra ipver = GET_AF(&tmp_srv->isv_addr); 1378*dbed73cbSSangeeta Misra vallen = (ipver == AF_INET) ? INET_ADDRSTRLEN : 1379*dbed73cbSSangeeta Misra INET6_ADDRSTRLEN; 1380*dbed73cbSSangeeta Misra addrptr = (ipver == AF_INET) ? (void *)&ipaddr.ia_v4 : 1381*dbed73cbSSangeeta Misra (void *)&ipaddr.ia_v6; 1382*dbed73cbSSangeeta Misra if (inet_ntop(ipver, addrptr, ipstr, vallen) == NULL) { 1383*dbed73cbSSangeeta Misra logerr("ilbd_Xable_server: failed transfer ip addr to" 1384*dbed73cbSSangeeta Misra " str"); 1385*dbed73cbSSangeeta Misra if (errno == ENOSPC) 1386*dbed73cbSSangeeta Misra rc = ILB_STATUS_ENOMEM; 1387*dbed73cbSSangeeta Misra else 1388*dbed73cbSSangeeta Misra rc = ILB_STATUS_GENERIC; 1389*dbed73cbSSangeeta Misra switch (cmd) { 1390*dbed73cbSSangeeta Misra case stat_disable_server: 1391*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1392*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, rc, ucredp); 1393*dbed73cbSSangeeta Misra break; 1394*dbed73cbSSangeeta Misra case stat_enable_server: 1395*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1396*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, rc, ucredp); 1397*dbed73cbSSangeeta Misra break; 1398*dbed73cbSSangeeta Misra } 1399*dbed73cbSSangeeta Misra goto rollback_rules; 1400*dbed73cbSSangeeta Misra } 1401*dbed73cbSSangeeta Misra 1402*dbed73cbSSangeeta Misra (void) snprintf(valstr, sizeof (valstr), "%s;%d;%d-%d;%d", 1403*dbed73cbSSangeeta Misra ipstr, ipver, 1404*dbed73cbSSangeeta Misra ntohs(tmp_srv->isv_minport), 1405*dbed73cbSSangeeta Misra ntohs(tmp_srv->isv_maxport), nflags); 1406*dbed73cbSSangeeta Misra (void) snprintf(prop_name, sizeof (prop_name), "server%d", 1407*dbed73cbSSangeeta Misra tmp_srv->isv_id); 1408*dbed73cbSSangeeta Misra 1409*dbed73cbSSangeeta Misra switch (cmd) { 1410*dbed73cbSSangeeta Misra case stat_disable_server: 1411*dbed73cbSSangeeta Misra rc = i_ilbd_save_sg(isg, ILBD_SCF_ENABLE_DISABLE, 1412*dbed73cbSSangeeta Misra prop_name, valstr); 1413*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) 1414*dbed73cbSSangeeta Misra SET_SRV_DISABLED(&tmp_srv->isv_srv); 1415*dbed73cbSSangeeta Misra break; 1416*dbed73cbSSangeeta Misra case stat_enable_server: 1417*dbed73cbSSangeeta Misra rc = i_ilbd_save_sg(isg, ILBD_SCF_ENABLE_DISABLE, 1418*dbed73cbSSangeeta Misra prop_name, valstr); 1419*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) 1420*dbed73cbSSangeeta Misra SET_SRV_ENABLED(&tmp_srv->isv_srv); 1421*dbed73cbSSangeeta Misra break; 1422*dbed73cbSSangeeta Misra } 1423*dbed73cbSSangeeta Misra if (rc == ILB_STATUS_OK) { 1424*dbed73cbSSangeeta Misra switch (cmd) { 1425*dbed73cbSSangeeta Misra case stat_disable_server: 1426*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1427*dbed73cbSSangeeta Misra ILBD_DISABLE_SERVER, ILB_STATUS_OK, ucredp); 1428*dbed73cbSSangeeta Misra break; 1429*dbed73cbSSangeeta Misra case stat_enable_server: 1430*dbed73cbSSangeeta Misra ilbd_audit_server_event(&audit_sg_data, 1431*dbed73cbSSangeeta Misra ILBD_ENABLE_SERVER, ILB_STATUS_OK, ucredp); 1432*dbed73cbSSangeeta Misra break; 1433*dbed73cbSSangeeta Misra } 1434*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1435*dbed73cbSSangeeta Misra } 1436*dbed73cbSSangeeta Misra 1437*dbed73cbSSangeeta Misra rollback_rules: 1438*dbed73cbSSangeeta Misra if (cmd == stat_disable_server) 1439*dbed73cbSSangeeta Misra u_cmd = stat_enable_server; 1440*dbed73cbSSangeeta Misra else 1441*dbed73cbSSangeeta Misra u_cmd = stat_disable_server; 1442*dbed73cbSSangeeta Misra 1443*dbed73cbSSangeeta Misra if (irl == NULL) 1444*dbed73cbSSangeeta Misra irl = list_tail(&isg->isg_rulelist); 1445*dbed73cbSSangeeta Misra else 1446*dbed73cbSSangeeta Misra irl = list_prev(&isg->isg_rulelist, irl); 1447*dbed73cbSSangeeta Misra 1448*dbed73cbSSangeeta Misra for (; irl != NULL; irl = list_prev(&isg->isg_rulelist, irl)) { 1449*dbed73cbSSangeeta Misra (void) ilbd_k_Xable_server(&tmp_srv->isv_addr, 1450*dbed73cbSSangeeta Misra irl->irl_name, u_cmd); 1451*dbed73cbSSangeeta Misra if (!RULE_HAS_HC(irl)) 1452*dbed73cbSSangeeta Misra continue; 1453*dbed73cbSSangeeta Misra 1454*dbed73cbSSangeeta Misra if (u_cmd == stat_disable_server) 1455*dbed73cbSSangeeta Misra (void) ilbd_hc_disable_server(irl, &tmp_srv->isv_srv); 1456*dbed73cbSSangeeta Misra else 1457*dbed73cbSSangeeta Misra (void) ilbd_hc_enable_server(irl, &tmp_srv->isv_srv); 1458*dbed73cbSSangeeta Misra } 1459*dbed73cbSSangeeta Misra 1460*dbed73cbSSangeeta Misra return (rc); 1461*dbed73cbSSangeeta Misra } 1462*dbed73cbSSangeeta Misra 1463*dbed73cbSSangeeta Misra ilb_status_t 1464*dbed73cbSSangeeta Misra ilbd_disable_server(ilb_sg_info_t *sg, const struct passwd *ps, 1465*dbed73cbSSangeeta Misra ucred_t *ucredp) 1466*dbed73cbSSangeeta Misra { 1467*dbed73cbSSangeeta Misra return (ilbd_Xable_server(sg, ps, stat_disable_server, ucredp)); 1468*dbed73cbSSangeeta Misra } 1469*dbed73cbSSangeeta Misra 1470*dbed73cbSSangeeta Misra ilb_status_t 1471*dbed73cbSSangeeta Misra ilbd_enable_server(ilb_sg_info_t *sg, const struct passwd *ps, 1472*dbed73cbSSangeeta Misra ucred_t *ucredp) 1473*dbed73cbSSangeeta Misra { 1474*dbed73cbSSangeeta Misra return (ilbd_Xable_server(sg, ps, stat_enable_server, ucredp)); 1475*dbed73cbSSangeeta Misra } 1476*dbed73cbSSangeeta Misra 1477*dbed73cbSSangeeta Misra /* 1478*dbed73cbSSangeeta Misra * fill in the srvID for the given IP address in the 0th server 1479*dbed73cbSSangeeta Misra */ 1480*dbed73cbSSangeeta Misra ilb_status_t 1481*dbed73cbSSangeeta Misra ilbd_address_to_srvID(ilb_sg_info_t *sg, uint32_t *rbuf, size_t *rbufsz) 1482*dbed73cbSSangeeta Misra { 1483*dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv; 1484*dbed73cbSSangeeta Misra ilb_sg_srv_t *tsrv; 1485*dbed73cbSSangeeta Misra ilbd_sg_t *tmp_sg; 1486*dbed73cbSSangeeta Misra 1487*dbed73cbSSangeeta Misra ilbd_reply_ok(rbuf, rbufsz); 1488*dbed73cbSSangeeta Misra tsrv = (ilb_sg_srv_t *)&((ilb_comm_t *)rbuf)->ic_data; 1489*dbed73cbSSangeeta Misra *rbufsz += sizeof (ilb_sg_srv_t); 1490*dbed73cbSSangeeta Misra 1491*dbed73cbSSangeeta Misra tmp_sg = i_find_sg_byname(sg->sg_name); 1492*dbed73cbSSangeeta Misra if (tmp_sg == NULL) 1493*dbed73cbSSangeeta Misra return (ILB_STATUS_SGUNAVAIL); 1494*dbed73cbSSangeeta Misra tsrv->sgs_addr = sg->sg_servers[0].sgs_addr; 1495*dbed73cbSSangeeta Misra 1496*dbed73cbSSangeeta Misra tmp_srv = i_find_srv(&tmp_sg->isg_srvlist, tsrv, MODE_ADDR); 1497*dbed73cbSSangeeta Misra if (tmp_srv == NULL) 1498*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 1499*dbed73cbSSangeeta Misra 1500*dbed73cbSSangeeta Misra (void) strlcpy(tsrv->sgs_srvID, tmp_srv->isv_srvID, 1501*dbed73cbSSangeeta Misra sizeof (tsrv->sgs_srvID)); 1502*dbed73cbSSangeeta Misra 1503*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1504*dbed73cbSSangeeta Misra } 1505*dbed73cbSSangeeta Misra 1506*dbed73cbSSangeeta Misra /* 1507*dbed73cbSSangeeta Misra * fill in the address for the given serverID in the 0th server 1508*dbed73cbSSangeeta Misra */ 1509*dbed73cbSSangeeta Misra ilb_status_t 1510*dbed73cbSSangeeta Misra ilbd_srvID_to_address(ilb_sg_info_t *sg, uint32_t *rbuf, size_t *rbufsz) 1511*dbed73cbSSangeeta Misra { 1512*dbed73cbSSangeeta Misra ilbd_srv_t *tmp_srv; 1513*dbed73cbSSangeeta Misra ilb_sg_srv_t *tsrv; 1514*dbed73cbSSangeeta Misra ilbd_sg_t *tmp_sg; 1515*dbed73cbSSangeeta Misra 1516*dbed73cbSSangeeta Misra ilbd_reply_ok(rbuf, rbufsz); 1517*dbed73cbSSangeeta Misra tsrv = (ilb_sg_srv_t *)&((ilb_comm_t *)rbuf)->ic_data; 1518*dbed73cbSSangeeta Misra 1519*dbed73cbSSangeeta Misra tmp_sg = i_find_sg_byname(sg->sg_name); 1520*dbed73cbSSangeeta Misra if (tmp_sg == NULL) 1521*dbed73cbSSangeeta Misra return (ILB_STATUS_SGUNAVAIL); 1522*dbed73cbSSangeeta Misra (void) strlcpy(tsrv->sgs_srvID, sg->sg_servers[0].sgs_srvID, 1523*dbed73cbSSangeeta Misra sizeof (tsrv->sgs_srvID)); 1524*dbed73cbSSangeeta Misra 1525*dbed73cbSSangeeta Misra tmp_srv = i_find_srv(&tmp_sg->isg_srvlist, tsrv, MODE_SRVID); 1526*dbed73cbSSangeeta Misra if (tmp_srv == NULL) 1527*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOENT); 1528*dbed73cbSSangeeta Misra 1529*dbed73cbSSangeeta Misra tsrv->sgs_addr = tmp_srv->isv_addr; 1530*dbed73cbSSangeeta Misra *rbufsz += sizeof (ilb_sg_srv_t); 1531*dbed73cbSSangeeta Misra 1532*dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1533*dbed73cbSSangeeta Misra } 1534*dbed73cbSSangeeta Misra 1535*dbed73cbSSangeeta Misra void 1536*dbed73cbSSangeeta Misra ilbd_addr2str(struct in6_addr *ipaddr, char *addrstr_buf, size_t sz) 1537*dbed73cbSSangeeta Misra { 1538*dbed73cbSSangeeta Misra ilb_ip_addr_t ilb_ip; 1539*dbed73cbSSangeeta Misra 1540*dbed73cbSSangeeta Misra IP_COPY_IMPL_2_CLI(ipaddr, &ilb_ip); 1541*dbed73cbSSangeeta Misra addr2str(ilb_ip, addrstr_buf, sz); 1542*dbed73cbSSangeeta Misra } 1543*dbed73cbSSangeeta Misra 1544*dbed73cbSSangeeta Misra /* Convert ip address to a address string */ 1545*dbed73cbSSangeeta Misra void 1546*dbed73cbSSangeeta Misra addr2str(ilb_ip_addr_t ip, char *buf, size_t sz) 1547*dbed73cbSSangeeta Misra { 1548*dbed73cbSSangeeta Misra 1549*dbed73cbSSangeeta Misra switch (ip.ia_af) { 1550*dbed73cbSSangeeta Misra case AF_INET: 1551*dbed73cbSSangeeta Misra if ((uint32_t *)&(ip).ia_v4 == 0) 1552*dbed73cbSSangeeta Misra buf[0] = '\0'; 1553*dbed73cbSSangeeta Misra else 1554*dbed73cbSSangeeta Misra (void) inet_ntop(AF_INET, (void *)&(ip).ia_v4, buf, sz); 1555*dbed73cbSSangeeta Misra break; 1556*dbed73cbSSangeeta Misra case AF_INET6: 1557*dbed73cbSSangeeta Misra if (IN6_IS_ADDR_UNSPECIFIED(&(ip).ia_v6)) { 1558*dbed73cbSSangeeta Misra buf[0] = '\0'; 1559*dbed73cbSSangeeta Misra break; 1560*dbed73cbSSangeeta Misra } 1561*dbed73cbSSangeeta Misra (void) inet_ntop(ip.ia_af, (void *)&(ip).ia_v6, buf, sz); 1562*dbed73cbSSangeeta Misra break; 1563*dbed73cbSSangeeta Misra default: buf[0] = '\0'; 1564*dbed73cbSSangeeta Misra } 1565*dbed73cbSSangeeta Misra } 1566*dbed73cbSSangeeta Misra 1567*dbed73cbSSangeeta Misra /* 1568*dbed73cbSSangeeta Misra * Map ilb_status errors to similar errno values from errno.h or 1569*dbed73cbSSangeeta Misra * adt_event.h to be used for audit record 1570*dbed73cbSSangeeta Misra */ 1571*dbed73cbSSangeeta Misra int 1572*dbed73cbSSangeeta Misra ilberror2auditerror(ilb_status_t rc) 1573*dbed73cbSSangeeta Misra { 1574*dbed73cbSSangeeta Misra int audit_error; 1575*dbed73cbSSangeeta Misra 1576*dbed73cbSSangeeta Misra switch (rc) { 1577*dbed73cbSSangeeta Misra case ILB_STATUS_CFGAUTH: 1578*dbed73cbSSangeeta Misra audit_error = ADT_FAIL_VALUE_AUTH; 1579*dbed73cbSSangeeta Misra break; 1580*dbed73cbSSangeeta Misra case ILB_STATUS_ENOMEM: 1581*dbed73cbSSangeeta Misra audit_error = ENOMEM; 1582*dbed73cbSSangeeta Misra break; 1583*dbed73cbSSangeeta Misra case ILB_STATUS_ENOENT: 1584*dbed73cbSSangeeta Misra case ILB_STATUS_ENOHCINFO: 1585*dbed73cbSSangeeta Misra case ILB_STATUS_INVAL_HCTESTTYPE: 1586*dbed73cbSSangeeta Misra case ILB_STATUS_INVAL_CMD: 1587*dbed73cbSSangeeta Misra case ILB_STATUS_DUP_RULE: 1588*dbed73cbSSangeeta Misra case ILB_STATUS_ENORULE: 1589*dbed73cbSSangeeta Misra case ILB_STATUS_SGUNAVAIL: 1590*dbed73cbSSangeeta Misra audit_error = ENOENT; 1591*dbed73cbSSangeeta Misra break; 1592*dbed73cbSSangeeta Misra case ILB_STATUS_EINVAL: 1593*dbed73cbSSangeeta Misra case ILB_STATUS_MISMATCHSG: 1594*dbed73cbSSangeeta Misra case ILB_STATUS_MISMATCHH: 1595*dbed73cbSSangeeta Misra case ILB_STATUS_BADSG: 1596*dbed73cbSSangeeta Misra case ILB_STATUS_INVAL_SRVR: 1597*dbed73cbSSangeeta Misra case ILB_STATUS_INVAL_ENBSRVR: 1598*dbed73cbSSangeeta Misra case ILB_STATUS_BADPORT: 1599*dbed73cbSSangeeta Misra audit_error = EINVAL; 1600*dbed73cbSSangeeta Misra break; 1601*dbed73cbSSangeeta Misra case ILB_STATUS_EEXIST: 1602*dbed73cbSSangeeta Misra case ILB_STATUS_SGEXISTS: 1603*dbed73cbSSangeeta Misra audit_error = EEXIST; 1604*dbed73cbSSangeeta Misra break; 1605*dbed73cbSSangeeta Misra case ILB_STATUS_EWOULDBLOCK: 1606*dbed73cbSSangeeta Misra audit_error = EWOULDBLOCK; 1607*dbed73cbSSangeeta Misra break; 1608*dbed73cbSSangeeta Misra case ILB_STATUS_INPROGRESS: 1609*dbed73cbSSangeeta Misra audit_error = EINPROGRESS; 1610*dbed73cbSSangeeta Misra break; 1611*dbed73cbSSangeeta Misra case ILB_STATUS_INTERNAL: 1612*dbed73cbSSangeeta Misra case ILB_STATUS_CALLBACK: 1613*dbed73cbSSangeeta Misra case ILB_STATUS_PERMIT: 1614*dbed73cbSSangeeta Misra case ILB_STATUS_RULE_NO_HC: 1615*dbed73cbSSangeeta Misra audit_error = ADT_FAIL_VALUE_PROGRAM; 1616*dbed73cbSSangeeta Misra break; 1617*dbed73cbSSangeeta Misra case ILB_STATUS_SOCKET: 1618*dbed73cbSSangeeta Misra audit_error = ENOTSOCK; 1619*dbed73cbSSangeeta Misra break; 1620*dbed73cbSSangeeta Misra case ILB_STATUS_READ: 1621*dbed73cbSSangeeta Misra case ILB_STATUS_WRITE: 1622*dbed73cbSSangeeta Misra audit_error = ENOTCONN; 1623*dbed73cbSSangeeta Misra break; 1624*dbed73cbSSangeeta Misra case ILB_STATUS_SGINUSE: 1625*dbed73cbSSangeeta Misra audit_error = EADDRINUSE; 1626*dbed73cbSSangeeta Misra break; 1627*dbed73cbSSangeeta Misra case ILB_STATUS_SEND: 1628*dbed73cbSSangeeta Misra audit_error = ECOMM; 1629*dbed73cbSSangeeta Misra break; 1630*dbed73cbSSangeeta Misra case ILB_STATUS_SGFULL: 1631*dbed73cbSSangeeta Misra audit_error = EOVERFLOW; 1632*dbed73cbSSangeeta Misra break; 1633*dbed73cbSSangeeta Misra case ILB_STATUS_NAMETOOLONG: 1634*dbed73cbSSangeeta Misra audit_error = ENAMETOOLONG; 1635*dbed73cbSSangeeta Misra break; 1636*dbed73cbSSangeeta Misra case ILB_STATUS_SRVUNAVAIL: 1637*dbed73cbSSangeeta Misra audit_error = EHOSTUNREACH; 1638*dbed73cbSSangeeta Misra break; 1639*dbed73cbSSangeeta Misra default: 1640*dbed73cbSSangeeta Misra audit_error = ADT_FAIL_VALUE_UNKNOWN; 1641*dbed73cbSSangeeta Misra break; 1642*dbed73cbSSangeeta Misra } 1643*dbed73cbSSangeeta Misra return (audit_error); 1644*dbed73cbSSangeeta Misra } 1645