110946SSangeeta.Misra@Sun.COM /*
210946SSangeeta.Misra@Sun.COM * CDDL HEADER START
310946SSangeeta.Misra@Sun.COM *
410946SSangeeta.Misra@Sun.COM * The contents of this file are subject to the terms of the
510946SSangeeta.Misra@Sun.COM * Common Development and Distribution License (the "License").
610946SSangeeta.Misra@Sun.COM * You may not use this file except in compliance with the License.
710946SSangeeta.Misra@Sun.COM *
810946SSangeeta.Misra@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910946SSangeeta.Misra@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010946SSangeeta.Misra@Sun.COM * See the License for the specific language governing permissions
1110946SSangeeta.Misra@Sun.COM * and limitations under the License.
1210946SSangeeta.Misra@Sun.COM *
1310946SSangeeta.Misra@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410946SSangeeta.Misra@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510946SSangeeta.Misra@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610946SSangeeta.Misra@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710946SSangeeta.Misra@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810946SSangeeta.Misra@Sun.COM *
1910946SSangeeta.Misra@Sun.COM * CDDL HEADER END
2010946SSangeeta.Misra@Sun.COM */
2110946SSangeeta.Misra@Sun.COM
2210946SSangeeta.Misra@Sun.COM /*
23*12857SSangeeta.Misra@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410946SSangeeta.Misra@Sun.COM */
2510946SSangeeta.Misra@Sun.COM
2610946SSangeeta.Misra@Sun.COM #include <stdlib.h>
2710946SSangeeta.Misra@Sun.COM #include <stdio.h>
2810946SSangeeta.Misra@Sun.COM #include <strings.h>
2910946SSangeeta.Misra@Sun.COM #include <sys/types.h>
3010946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
3110946SSangeeta.Misra@Sun.COM #include <netinet/in.h>
3210946SSangeeta.Misra@Sun.COM #include <arpa/inet.h>
3310946SSangeeta.Misra@Sun.COM #include <sys/list.h>
3410946SSangeeta.Misra@Sun.COM #include <libilb.h>
3510946SSangeeta.Misra@Sun.COM #include <assert.h>
3610946SSangeeta.Misra@Sun.COM #include <libscf.h>
3710946SSangeeta.Misra@Sun.COM #include "libilb_impl.h"
3810946SSangeeta.Misra@Sun.COM #include "ilbd.h"
3910946SSangeeta.Misra@Sun.COM
4010946SSangeeta.Misra@Sun.COM #define ILBD_PG_NAME_RULE "rule_"
4110946SSangeeta.Misra@Sun.COM #define ILBD_PG_NAME_SG "sg_"
4210946SSangeeta.Misra@Sun.COM #define ILBD_PG_NAME_HC "hc_"
4310946SSangeeta.Misra@Sun.COM #define ILBD_SVC_FMRI "svc:/network/loadbalancer/ilb"
4410946SSangeeta.Misra@Sun.COM #define ILBD_INST_NAME "default"
4510946SSangeeta.Misra@Sun.COM
4610946SSangeeta.Misra@Sun.COM typedef enum {
4710946SSangeeta.Misra@Sun.COM ILBD_RULE_STATUS,
4810946SSangeeta.Misra@Sun.COM ILBD_RULE_VIP,
4910946SSangeeta.Misra@Sun.COM ILBD_RULE_PROTO,
5010946SSangeeta.Misra@Sun.COM ILBD_RULE_PORT,
5110946SSangeeta.Misra@Sun.COM ILBD_RULE_ALGO,
5210946SSangeeta.Misra@Sun.COM ILBD_RULE_TOPO,
5310946SSangeeta.Misra@Sun.COM ILBD_RULE_NAT_STR,
5410946SSangeeta.Misra@Sun.COM ILBD_RULE_NAT_END,
5510946SSangeeta.Misra@Sun.COM ILBD_RULE_STI_MASK,
5610946SSangeeta.Misra@Sun.COM ILBD_RULE_SGNAME,
5710946SSangeeta.Misra@Sun.COM ILBD_RULE_HCNAME,
5810946SSangeeta.Misra@Sun.COM ILBD_RULE_HCPORT,
5910946SSangeeta.Misra@Sun.COM ILBD_RULE_HCPFLAG,
6010946SSangeeta.Misra@Sun.COM ILBD_RULE_DRAINTIME,
6110946SSangeeta.Misra@Sun.COM ILBD_RULE_NAT_TO,
6210946SSangeeta.Misra@Sun.COM ILBD_RULE_PERS_TO,
6310946SSangeeta.Misra@Sun.COM
6410946SSangeeta.Misra@Sun.COM ILBD_SG_SERVER,
6510946SSangeeta.Misra@Sun.COM
6610946SSangeeta.Misra@Sun.COM ILBD_HC_TEST,
6710946SSangeeta.Misra@Sun.COM ILBD_HC_TIMEOUT,
6810946SSangeeta.Misra@Sun.COM ILBD_HC_INTERVAL,
6910946SSangeeta.Misra@Sun.COM ILBD_HC_DEF_PING,
7010946SSangeeta.Misra@Sun.COM ILBD_HC_COUNT,
7110946SSangeeta.Misra@Sun.COM
7210946SSangeeta.Misra@Sun.COM ILBD_VAR_INVALID
7310946SSangeeta.Misra@Sun.COM } ilbd_var_type_t;
7410946SSangeeta.Misra@Sun.COM
7510946SSangeeta.Misra@Sun.COM typedef struct prop_tbl_entry {
7610946SSangeeta.Misra@Sun.COM ilbd_var_type_t val_type;
7710946SSangeeta.Misra@Sun.COM const char *scf_propname;
7810946SSangeeta.Misra@Sun.COM scf_type_t scf_proptype;
7910946SSangeeta.Misra@Sun.COM } prop_tbl_entry_t;
8010946SSangeeta.Misra@Sun.COM
8110946SSangeeta.Misra@Sun.COM /*
8210946SSangeeta.Misra@Sun.COM * this table contains a map of all SCF properties, including rules,
8310946SSangeeta.Misra@Sun.COM * servergroups and health checks. The place to add new property needs to be
8410946SSangeeta.Misra@Sun.COM * watched carefully. When new properties are added, corresponding *VAR_NUM
8510946SSangeeta.Misra@Sun.COM * needs to be adjusted to reflect the correct index of the table
8610946SSangeeta.Misra@Sun.COM */
8710946SSangeeta.Misra@Sun.COM prop_tbl_entry_t prop_tbl[] = {
8810946SSangeeta.Misra@Sun.COM /* entried for rule */
8910946SSangeeta.Misra@Sun.COM {ILBD_RULE_STATUS, "status", SCF_TYPE_BOOLEAN},
9010946SSangeeta.Misra@Sun.COM /* SCF_TYPE_NET_ADDR_V4 or SCF_TYPE_NET_ADDR_V6 */
9110946SSangeeta.Misra@Sun.COM {ILBD_RULE_VIP, "vip", SCF_TYPE_INVALID},
9210946SSangeeta.Misra@Sun.COM {ILBD_RULE_PROTO, "protocol", SCF_TYPE_ASTRING},
9310946SSangeeta.Misra@Sun.COM {ILBD_RULE_PORT, "port", SCF_TYPE_ASTRING},
9410946SSangeeta.Misra@Sun.COM {ILBD_RULE_ALGO, "ilb-algo", SCF_TYPE_ASTRING},
9510946SSangeeta.Misra@Sun.COM {ILBD_RULE_TOPO, "ilb-type", SCF_TYPE_ASTRING},
9610946SSangeeta.Misra@Sun.COM {ILBD_RULE_NAT_STR, "ilb-nat-start", SCF_TYPE_INVALID},
9710946SSangeeta.Misra@Sun.COM {ILBD_RULE_NAT_END, "ilb-nat-end", SCF_TYPE_INVALID},
9810946SSangeeta.Misra@Sun.COM {ILBD_RULE_STI_MASK, "ilb-sti-mask", SCF_TYPE_INVALID},
9910946SSangeeta.Misra@Sun.COM {ILBD_RULE_SGNAME, "servergroup", SCF_TYPE_ASTRING},
10010946SSangeeta.Misra@Sun.COM {ILBD_RULE_HCNAME, "healthcheck", SCF_TYPE_ASTRING},
10110946SSangeeta.Misra@Sun.COM {ILBD_RULE_HCPORT, "hc-port", SCF_TYPE_INTEGER},
10210946SSangeeta.Misra@Sun.COM {ILBD_RULE_HCPFLAG, "hcp-flag", SCF_TYPE_INTEGER},
10310946SSangeeta.Misra@Sun.COM {ILBD_RULE_DRAINTIME, "drain-time", SCF_TYPE_INTEGER},
10410946SSangeeta.Misra@Sun.COM {ILBD_RULE_NAT_TO, "nat-timeout", SCF_TYPE_INTEGER},
10510946SSangeeta.Misra@Sun.COM {ILBD_RULE_PERS_TO, "pers-timeout", SCF_TYPE_INTEGER},
10610946SSangeeta.Misra@Sun.COM /* add new rule related prop here */
10710946SSangeeta.Misra@Sun.COM /* entries for sg */
10810946SSangeeta.Misra@Sun.COM {ILBD_SG_SERVER, "server", SCF_TYPE_ASTRING},
10910946SSangeeta.Misra@Sun.COM /* add new sg related prop here */
11010946SSangeeta.Misra@Sun.COM /* entries for hc */
11110946SSangeeta.Misra@Sun.COM {ILBD_HC_TEST, "test", SCF_TYPE_ASTRING},
11210946SSangeeta.Misra@Sun.COM {ILBD_HC_TIMEOUT, "timeout", SCF_TYPE_INTEGER},
11310946SSangeeta.Misra@Sun.COM {ILBD_HC_INTERVAL, "interval", SCF_TYPE_INTEGER},
11410946SSangeeta.Misra@Sun.COM {ILBD_HC_DEF_PING, "ping", SCF_TYPE_BOOLEAN},
11510946SSangeeta.Misra@Sun.COM /* add new hc related prop here */
11610946SSangeeta.Misra@Sun.COM {ILBD_HC_COUNT, "count", SCF_TYPE_INTEGER}
11710946SSangeeta.Misra@Sun.COM };
11810946SSangeeta.Misra@Sun.COM
11910946SSangeeta.Misra@Sun.COM #define ILBD_PROP_VAR_NUM (ILBD_HC_COUNT + 1)
12010946SSangeeta.Misra@Sun.COM #define ILBD_RULE_VAR_NUM (ILBD_SG_SERVER)
12110946SSangeeta.Misra@Sun.COM #define ILBD_SG_VAR_NUM (ILBD_HC_TEST - ILBD_SG_SERVER)
12210946SSangeeta.Misra@Sun.COM #define ILBD_HC_VAR_NUM (ILBD_PROP_VAR_NUM - ILBD_HC_TEST)
12310946SSangeeta.Misra@Sun.COM
12410946SSangeeta.Misra@Sun.COM static ilb_status_t ilbd_scf_set_prop(scf_propertygroup_t *, const char *,
12510946SSangeeta.Misra@Sun.COM scf_type_t, scf_value_t *);
12610946SSangeeta.Misra@Sun.COM static ilb_status_t ilbd_scf_retrieve_pg(const char *, scf_propertygroup_t **,
12710946SSangeeta.Misra@Sun.COM boolean_t);
12810946SSangeeta.Misra@Sun.COM static ilb_status_t ilbd_scf_delete_pg(scf_propertygroup_t *);
12910946SSangeeta.Misra@Sun.COM static ilb_status_t ilbd_scf_get_prop_val(scf_propertygroup_t *, const char *,
13010946SSangeeta.Misra@Sun.COM scf_value_t **);
13110946SSangeeta.Misra@Sun.COM
13210946SSangeeta.Misra@Sun.COM #define MIN(a, b) ((a) < (b) ? (a) : (b))
13310946SSangeeta.Misra@Sun.COM
13410946SSangeeta.Misra@Sun.COM int
ilbd_scf_limit(int type)13510946SSangeeta.Misra@Sun.COM ilbd_scf_limit(int type)
13610946SSangeeta.Misra@Sun.COM {
13710946SSangeeta.Misra@Sun.COM return (MIN(scf_limit(type), 120));
13810946SSangeeta.Misra@Sun.COM }
13910946SSangeeta.Misra@Sun.COM
14010946SSangeeta.Misra@Sun.COM /*
14110946SSangeeta.Misra@Sun.COM * Translate libscf error to libilb status
14210946SSangeeta.Misra@Sun.COM */
14310946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_scf_err_to_ilb_err()14410946SSangeeta.Misra@Sun.COM ilbd_scf_err_to_ilb_err()
14510946SSangeeta.Misra@Sun.COM {
14610946SSangeeta.Misra@Sun.COM switch (scf_error()) {
14710946SSangeeta.Misra@Sun.COM case SCF_ERROR_NONE:
14810946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
14910946SSangeeta.Misra@Sun.COM case SCF_ERROR_HANDLE_MISMATCH:
15010946SSangeeta.Misra@Sun.COM case SCF_ERROR_HANDLE_DESTROYED:
15110946SSangeeta.Misra@Sun.COM case SCF_ERROR_VERSION_MISMATCH:
15210946SSangeeta.Misra@Sun.COM case SCF_ERROR_NOT_BOUND:
15310946SSangeeta.Misra@Sun.COM case SCF_ERROR_CONSTRAINT_VIOLATED:
15410946SSangeeta.Misra@Sun.COM case SCF_ERROR_NOT_SET:
15510946SSangeeta.Misra@Sun.COM case SCF_ERROR_TYPE_MISMATCH:
15610946SSangeeta.Misra@Sun.COM case SCF_ERROR_INVALID_ARGUMENT:
15710946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
15810946SSangeeta.Misra@Sun.COM case SCF_ERROR_NO_MEMORY:
15910946SSangeeta.Misra@Sun.COM case SCF_ERROR_NO_RESOURCES:
16010946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
16110946SSangeeta.Misra@Sun.COM case SCF_ERROR_NOT_FOUND:
16210946SSangeeta.Misra@Sun.COM case SCF_ERROR_DELETED:
16310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOENT);
16410946SSangeeta.Misra@Sun.COM case SCF_ERROR_EXISTS:
16510946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EEXIST);
16610946SSangeeta.Misra@Sun.COM case SCF_ERROR_PERMISSION_DENIED:
16710946SSangeeta.Misra@Sun.COM return (ILB_STATUS_PERMIT);
16810946SSangeeta.Misra@Sun.COM case SCF_ERROR_CALLBACK_FAILED:
16910946SSangeeta.Misra@Sun.COM return (ILB_STATUS_CALLBACK);
17010946SSangeeta.Misra@Sun.COM case SCF_ERROR_IN_USE:
17110946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INUSE);
17210946SSangeeta.Misra@Sun.COM default:
17310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
17410946SSangeeta.Misra@Sun.COM }
17510946SSangeeta.Misra@Sun.COM }
17610946SSangeeta.Misra@Sun.COM
17710946SSangeeta.Misra@Sun.COM static void
ilbd_name_to_scfpgname(ilbd_scf_pg_type_t pg_type,const char * pgname,char * scf_pgname)17810946SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(ilbd_scf_pg_type_t pg_type, const char *pgname,
17910946SSangeeta.Misra@Sun.COM char *scf_pgname)
18010946SSangeeta.Misra@Sun.COM {
18110946SSangeeta.Misra@Sun.COM switch (pg_type) {
18210946SSangeeta.Misra@Sun.COM case ILBD_SCF_RULE:
18310946SSangeeta.Misra@Sun.COM (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN,
18410946SSangeeta.Misra@Sun.COM ILBD_PG_NAME_RULE "%s", pgname);
18510946SSangeeta.Misra@Sun.COM return;
18610946SSangeeta.Misra@Sun.COM case ILBD_SCF_SG:
18710946SSangeeta.Misra@Sun.COM (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN,
18810946SSangeeta.Misra@Sun.COM ILBD_PG_NAME_SG "%s", pgname);
18910946SSangeeta.Misra@Sun.COM return;
19010946SSangeeta.Misra@Sun.COM case ILBD_SCF_HC:
19110946SSangeeta.Misra@Sun.COM (void) snprintf(scf_pgname, ILBD_MAX_NAME_LEN,
19210946SSangeeta.Misra@Sun.COM ILBD_PG_NAME_HC "%s", pgname);
19310946SSangeeta.Misra@Sun.COM return;
19410946SSangeeta.Misra@Sun.COM /* Should not happen. Log it and put ILB service in maintenance. */
19510946SSangeeta.Misra@Sun.COM default:
19610946SSangeeta.Misra@Sun.COM logerr("ilbd_name_to_scfpgname: invalid pg type %d for pg %s",
19710946SSangeeta.Misra@Sun.COM pg_type, pgname);
19810946SSangeeta.Misra@Sun.COM (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE);
19910946SSangeeta.Misra@Sun.COM exit(EXIT_FAILURE);
20010946SSangeeta.Misra@Sun.COM return;
20110946SSangeeta.Misra@Sun.COM }
20210946SSangeeta.Misra@Sun.COM }
20310946SSangeeta.Misra@Sun.COM
20410946SSangeeta.Misra@Sun.COM static void
ilbd_scf_destroy(scf_handle_t * h,scf_service_t * s,scf_instance_t * inst,scf_propertygroup_t * pg)20510946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(scf_handle_t *h, scf_service_t *s, scf_instance_t *inst,
20610946SSangeeta.Misra@Sun.COM scf_propertygroup_t *pg)
20710946SSangeeta.Misra@Sun.COM {
20810946SSangeeta.Misra@Sun.COM if (pg != NULL)
20910946SSangeeta.Misra@Sun.COM scf_pg_destroy(pg);
21010946SSangeeta.Misra@Sun.COM if (inst != NULL)
21110946SSangeeta.Misra@Sun.COM scf_instance_destroy(inst);
21210946SSangeeta.Misra@Sun.COM if (s != NULL)
21310946SSangeeta.Misra@Sun.COM scf_service_destroy(s);
21410946SSangeeta.Misra@Sun.COM if (h != NULL)
21510946SSangeeta.Misra@Sun.COM scf_handle_destroy(h);
21610946SSangeeta.Misra@Sun.COM }
21710946SSangeeta.Misra@Sun.COM
21810946SSangeeta.Misra@Sun.COM
21910946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_get_inst(scf_handle_t ** h,scf_service_t ** svc,scf_instance_t ** inst)22010946SSangeeta.Misra@Sun.COM ilbd_scf_get_inst(scf_handle_t **h, scf_service_t **svc, scf_instance_t **inst)
22110946SSangeeta.Misra@Sun.COM {
22210946SSangeeta.Misra@Sun.COM if ((*h = scf_handle_create(SCF_VERSION)) == NULL)
22310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
22410946SSangeeta.Misra@Sun.COM
22510946SSangeeta.Misra@Sun.COM if (scf_handle_bind(*h) != 0) {
22610946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(*h, NULL, NULL, NULL);
22710946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
22810946SSangeeta.Misra@Sun.COM }
22910946SSangeeta.Misra@Sun.COM
23010946SSangeeta.Misra@Sun.COM if ((*svc = scf_service_create(*h)) == NULL) {
23110946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(*h, NULL, NULL, NULL);
23210946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
23310946SSangeeta.Misra@Sun.COM }
23410946SSangeeta.Misra@Sun.COM
23510946SSangeeta.Misra@Sun.COM if (scf_handle_decode_fmri(*h, ILBD_SVC_FMRI, NULL, *svc, NULL, NULL,
23610946SSangeeta.Misra@Sun.COM NULL, SCF_DECODE_FMRI_EXACT) != 0) {
23710946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(*h, *svc, NULL, NULL);
23810946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
23910946SSangeeta.Misra@Sun.COM }
24010946SSangeeta.Misra@Sun.COM
24110946SSangeeta.Misra@Sun.COM if ((*inst = scf_instance_create(*h)) == NULL) {
24210946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(*h, *svc, NULL, NULL);
24310946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
24410946SSangeeta.Misra@Sun.COM }
24510946SSangeeta.Misra@Sun.COM
24610946SSangeeta.Misra@Sun.COM if (scf_service_get_instance(*svc, ILBD_INST_NAME, *inst) != 0) {
24710946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(*h, *svc, *inst, NULL);
24810946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
24910946SSangeeta.Misra@Sun.COM }
25010946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
25110946SSangeeta.Misra@Sun.COM }
25210946SSangeeta.Misra@Sun.COM
25310946SSangeeta.Misra@Sun.COM /*
25410946SSangeeta.Misra@Sun.COM * If create is set, create a new prop group, destroy the old one if exists.
25510946SSangeeta.Misra@Sun.COM * If create not set, try to find the prop group with given name.
25610946SSangeeta.Misra@Sun.COM * The created or found entry is returned as *pg.
25710946SSangeeta.Misra@Sun.COM * Caller frees *pg and its handle scf_pg_handle(pg)
25810946SSangeeta.Misra@Sun.COM */
25910946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_retrieve_pg(const char * pgname,scf_propertygroup_t ** pg,boolean_t create)26010946SSangeeta.Misra@Sun.COM ilbd_scf_retrieve_pg(const char *pgname, scf_propertygroup_t **pg,
26110946SSangeeta.Misra@Sun.COM boolean_t create)
26210946SSangeeta.Misra@Sun.COM {
26310946SSangeeta.Misra@Sun.COM scf_instance_t *inst;
26410946SSangeeta.Misra@Sun.COM scf_handle_t *h;
26510946SSangeeta.Misra@Sun.COM scf_service_t *svc;
26610946SSangeeta.Misra@Sun.COM ilb_status_t ret;
26710946SSangeeta.Misra@Sun.COM
26810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_inst(&h, &svc, &inst);
26910946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
27010946SSangeeta.Misra@Sun.COM return (ret);
27110946SSangeeta.Misra@Sun.COM
27210946SSangeeta.Misra@Sun.COM *pg = scf_pg_create(h);
27310946SSangeeta.Misra@Sun.COM if (*pg == NULL)
27410946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
27510946SSangeeta.Misra@Sun.COM
27610946SSangeeta.Misra@Sun.COM if (scf_instance_get_pg(inst, pgname, *pg) != 0) {
27710946SSangeeta.Misra@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND ||
27810946SSangeeta.Misra@Sun.COM (scf_error() == SCF_ERROR_NOT_FOUND && (!create))) {
27910946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, svc, inst, *pg);
28010946SSangeeta.Misra@Sun.COM *pg = NULL;
28110946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
28210946SSangeeta.Misra@Sun.COM }
28310946SSangeeta.Misra@Sun.COM } else {
28410946SSangeeta.Misra@Sun.COM /*
28510946SSangeeta.Misra@Sun.COM * Found pg, don't want to create, return EEXIST. Note that
28610946SSangeeta.Misra@Sun.COM * h cannot be destroyed here since the caller needs to use it.
28710946SSangeeta.Misra@Sun.COM * The caller gets it by calling scf_pg_handle().
28810946SSangeeta.Misra@Sun.COM */
28910946SSangeeta.Misra@Sun.COM if (!create) {
29010946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(NULL, svc, inst, NULL);
29110946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EEXIST);
29210946SSangeeta.Misra@Sun.COM }
29310946SSangeeta.Misra@Sun.COM /* found pg, need to create, destroy the existing one */
29410946SSangeeta.Misra@Sun.COM else
29510946SSangeeta.Misra@Sun.COM (void) ilbd_scf_delete_pg(*pg);
29610946SSangeeta.Misra@Sun.COM }
29710946SSangeeta.Misra@Sun.COM
29810946SSangeeta.Misra@Sun.COM if (create) {
29910946SSangeeta.Misra@Sun.COM if (scf_instance_add_pg(inst, pgname,
30010946SSangeeta.Misra@Sun.COM SCF_GROUP_APPLICATION, 0, *pg) != 0) {
30110946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, svc, inst, *pg);
30210946SSangeeta.Misra@Sun.COM *pg = NULL;
30310946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
30410946SSangeeta.Misra@Sun.COM }
30510946SSangeeta.Misra@Sun.COM }
30610946SSangeeta.Misra@Sun.COM
30710946SSangeeta.Misra@Sun.COM /*
30810946SSangeeta.Misra@Sun.COM * Note that handle cannot be destroyed here, caller sometimes needs
30910946SSangeeta.Misra@Sun.COM * to use it. It gets the handle by calling scf_pg_handle().
31010946SSangeeta.Misra@Sun.COM */
31110946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(NULL, svc, inst, NULL);
31210946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
31310946SSangeeta.Misra@Sun.COM }
31410946SSangeeta.Misra@Sun.COM
31510946SSangeeta.Misra@Sun.COM struct algo_tbl_entry {
31610946SSangeeta.Misra@Sun.COM ilb_algo_t algo_type;
31710946SSangeeta.Misra@Sun.COM const char *algo_str;
31810946SSangeeta.Misra@Sun.COM } algo_tbl[] = {
31910946SSangeeta.Misra@Sun.COM {ILB_ALG_ROUNDROBIN, "ROUNDROBIN"},
32010946SSangeeta.Misra@Sun.COM {ILB_ALG_HASH_IP, "HASH-IP"},
32110946SSangeeta.Misra@Sun.COM {ILB_ALG_HASH_IP_SPORT, "HASH-IP-PORT"},
32210946SSangeeta.Misra@Sun.COM {ILB_ALG_HASH_IP_VIP, "HASH-IP-VIP"}
32310946SSangeeta.Misra@Sun.COM };
32410946SSangeeta.Misra@Sun.COM
32510946SSangeeta.Misra@Sun.COM #define ILBD_ALGO_TBL_SIZE (sizeof (algo_tbl) / \
32610946SSangeeta.Misra@Sun.COM sizeof (*algo_tbl))
32710946SSangeeta.Misra@Sun.COM
32810946SSangeeta.Misra@Sun.COM void
ilbd_algo_to_str(ilb_algo_t algo_type,char * valstr)32910946SSangeeta.Misra@Sun.COM ilbd_algo_to_str(ilb_algo_t algo_type, char *valstr)
33010946SSangeeta.Misra@Sun.COM {
33110946SSangeeta.Misra@Sun.COM int i;
33210946SSangeeta.Misra@Sun.COM
33310946SSangeeta.Misra@Sun.COM for (i = 0; i < ILBD_ALGO_TBL_SIZE; i++) {
33410946SSangeeta.Misra@Sun.COM if (algo_type == algo_tbl[i].algo_type) {
33510946SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, algo_tbl[i].algo_str,
33610946SSangeeta.Misra@Sun.COM ILBD_MAX_VALUE_LEN);
33710946SSangeeta.Misra@Sun.COM return;
33810946SSangeeta.Misra@Sun.COM }
33910946SSangeeta.Misra@Sun.COM }
34010946SSangeeta.Misra@Sun.COM logerr("ilbd_algo_to_str: algo not found");
34110946SSangeeta.Misra@Sun.COM }
34210946SSangeeta.Misra@Sun.COM
34310946SSangeeta.Misra@Sun.COM static void
ilbd_scf_str_to_algo(ilb_algo_t * algo_type,char * valstr)34410946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_algo(ilb_algo_t *algo_type, char *valstr)
34510946SSangeeta.Misra@Sun.COM {
34610946SSangeeta.Misra@Sun.COM int i;
34710946SSangeeta.Misra@Sun.COM
34810946SSangeeta.Misra@Sun.COM for (i = 0; i < ILBD_ALGO_TBL_SIZE; i++) {
34910946SSangeeta.Misra@Sun.COM if (strcmp(valstr, algo_tbl[i].algo_str) == 0) {
35010946SSangeeta.Misra@Sun.COM *algo_type = algo_tbl[i].algo_type;
35110946SSangeeta.Misra@Sun.COM return;
35210946SSangeeta.Misra@Sun.COM }
35310946SSangeeta.Misra@Sun.COM }
35410946SSangeeta.Misra@Sun.COM logerr("ilbd_scf_str_to_algo: algo not found");
35510946SSangeeta.Misra@Sun.COM }
35610946SSangeeta.Misra@Sun.COM
35710946SSangeeta.Misra@Sun.COM struct topo_tbl_entry {
35810946SSangeeta.Misra@Sun.COM ilb_topo_t topo_type;
35910946SSangeeta.Misra@Sun.COM const char *topo_str;
36010946SSangeeta.Misra@Sun.COM } topo_tbl[] = {
36110946SSangeeta.Misra@Sun.COM {ILB_TOPO_DSR, "DSR"},
36210946SSangeeta.Misra@Sun.COM {ILB_TOPO_NAT, "NAT"},
36310946SSangeeta.Misra@Sun.COM {ILB_TOPO_HALF_NAT, "HALF-NAT"}
36410946SSangeeta.Misra@Sun.COM };
36510946SSangeeta.Misra@Sun.COM
36610946SSangeeta.Misra@Sun.COM #define ILBD_TOPO_TBL_SIZE (sizeof (topo_tbl) / \
36710946SSangeeta.Misra@Sun.COM sizeof (*topo_tbl))
36810946SSangeeta.Misra@Sun.COM
36910946SSangeeta.Misra@Sun.COM void
ilbd_topo_to_str(ilb_topo_t topo_type,char * valstr)37010946SSangeeta.Misra@Sun.COM ilbd_topo_to_str(ilb_topo_t topo_type, char *valstr)
37110946SSangeeta.Misra@Sun.COM {
37210946SSangeeta.Misra@Sun.COM int i;
37310946SSangeeta.Misra@Sun.COM
37410946SSangeeta.Misra@Sun.COM for (i = 0; i < ILBD_TOPO_TBL_SIZE; i++) {
37510946SSangeeta.Misra@Sun.COM if (topo_type == topo_tbl[i].topo_type) {
37610946SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, topo_tbl[i].topo_str,
37710946SSangeeta.Misra@Sun.COM ILBD_MAX_VALUE_LEN);
37810946SSangeeta.Misra@Sun.COM return;
37910946SSangeeta.Misra@Sun.COM }
38010946SSangeeta.Misra@Sun.COM }
38110946SSangeeta.Misra@Sun.COM logerr("ilbd_scf_topo_to_str: topo not found");
38210946SSangeeta.Misra@Sun.COM }
38310946SSangeeta.Misra@Sun.COM
38410946SSangeeta.Misra@Sun.COM static void
ilbd_scf_str_to_topo(ilb_topo_t * topo_type,char * valstr)38510946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_topo(ilb_topo_t *topo_type, char *valstr)
38610946SSangeeta.Misra@Sun.COM {
38710946SSangeeta.Misra@Sun.COM int i;
38810946SSangeeta.Misra@Sun.COM
38910946SSangeeta.Misra@Sun.COM for (i = 0; i < ILBD_TOPO_TBL_SIZE; i++) {
39010946SSangeeta.Misra@Sun.COM if (strcmp(valstr, topo_tbl[i].topo_str) == 0) {
39110946SSangeeta.Misra@Sun.COM *topo_type = topo_tbl[i].topo_type;
39210946SSangeeta.Misra@Sun.COM return;
39310946SSangeeta.Misra@Sun.COM }
39410946SSangeeta.Misra@Sun.COM }
39510946SSangeeta.Misra@Sun.COM logerr("ilbd_scf_str_to_topo: topo not found");
39610946SSangeeta.Misra@Sun.COM }
39710946SSangeeta.Misra@Sun.COM
39810946SSangeeta.Misra@Sun.COM static void
ilbd_get_svr_field(char * valstr,struct in6_addr * sgs_addr,int32_t * min_port,int32_t * max_port,int32_t * sgs_flags)39910946SSangeeta.Misra@Sun.COM ilbd_get_svr_field(char *valstr, struct in6_addr *sgs_addr,
40010946SSangeeta.Misra@Sun.COM int32_t *min_port, int32_t *max_port, int32_t *sgs_flags)
40110946SSangeeta.Misra@Sun.COM {
40210946SSangeeta.Misra@Sun.COM char *ipaddr, *ipverstr, *portstr, *flagstr;
40310946SSangeeta.Misra@Sun.COM int ip_ver;
40410946SSangeeta.Misra@Sun.COM ilb_ip_addr_t temp_ip;
40510946SSangeeta.Misra@Sun.COM void *addrptr;
40610946SSangeeta.Misra@Sun.COM char *max_portstr;
40710946SSangeeta.Misra@Sun.COM
40810946SSangeeta.Misra@Sun.COM ipaddr = strtok(valstr, ";");
40910946SSangeeta.Misra@Sun.COM ipverstr = strtok(NULL, ";");
41010946SSangeeta.Misra@Sun.COM portstr = strtok(NULL, ";");
41110946SSangeeta.Misra@Sun.COM flagstr = strtok(NULL, ";");
41210946SSangeeta.Misra@Sun.COM
41310946SSangeeta.Misra@Sun.COM if (ipaddr == NULL || ipverstr == NULL || portstr == NULL ||
41410946SSangeeta.Misra@Sun.COM flagstr == NULL) {
41510946SSangeeta.Misra@Sun.COM logerr("%s: invalid server fields", __func__);
41610946SSangeeta.Misra@Sun.COM (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE);
41710946SSangeeta.Misra@Sun.COM exit(EXIT_FAILURE);
41810946SSangeeta.Misra@Sun.COM }
41910946SSangeeta.Misra@Sun.COM ip_ver = atoi(ipverstr);
42010946SSangeeta.Misra@Sun.COM addrptr = (ip_ver == AF_INET) ? (void *)&temp_ip.ia_v4 :
42110946SSangeeta.Misra@Sun.COM (void *)&temp_ip.ia_v6;
42210946SSangeeta.Misra@Sun.COM if (inet_pton(ip_ver, ipaddr, addrptr) == NULL) {
42310946SSangeeta.Misra@Sun.COM logerr("ilbd_get_svr_field: inet_pton failed");
42410946SSangeeta.Misra@Sun.COM return;
42510946SSangeeta.Misra@Sun.COM }
42610946SSangeeta.Misra@Sun.COM
42710946SSangeeta.Misra@Sun.COM if (ip_ver == AF_INET) {
42810946SSangeeta.Misra@Sun.COM IN6_INADDR_TO_V4MAPPED(&(temp_ip.ia_v4), sgs_addr);
42910946SSangeeta.Misra@Sun.COM } else {
43010946SSangeeta.Misra@Sun.COM (void) memcpy(sgs_addr, &(temp_ip.ia_v6),
43110946SSangeeta.Misra@Sun.COM sizeof (struct in6_addr));
43210946SSangeeta.Misra@Sun.COM }
43310946SSangeeta.Misra@Sun.COM
43410946SSangeeta.Misra@Sun.COM *sgs_flags = atoi(flagstr);
43510946SSangeeta.Misra@Sun.COM *min_port = atoi(strtok(portstr, "-"));
43610946SSangeeta.Misra@Sun.COM *min_port = ntohs(*min_port);
43710946SSangeeta.Misra@Sun.COM max_portstr = strtok(NULL, "-");
43810946SSangeeta.Misra@Sun.COM if (max_portstr != NULL) {
43910946SSangeeta.Misra@Sun.COM *max_port = atoi(max_portstr);
44010946SSangeeta.Misra@Sun.COM *max_port = ntohs(*max_port);
44110946SSangeeta.Misra@Sun.COM }
44210946SSangeeta.Misra@Sun.COM }
44310946SSangeeta.Misra@Sun.COM
44410946SSangeeta.Misra@Sun.COM /*
44510946SSangeeta.Misra@Sun.COM * Convert the info of a server to its SCF string value representation.
44610946SSangeeta.Misra@Sun.COM * Argument value is assumed to be of size ILBD_MAX_VALUE_LEN.
44710946SSangeeta.Misra@Sun.COM */
44810946SSangeeta.Misra@Sun.COM static void
ilbd_srv_scf_val(ilbd_srv_t * srv,char * value)44910946SSangeeta.Misra@Sun.COM ilbd_srv_scf_val(ilbd_srv_t *srv, char *value)
45010946SSangeeta.Misra@Sun.COM {
45110946SSangeeta.Misra@Sun.COM char ipstr[INET6_ADDRSTRLEN];
45210946SSangeeta.Misra@Sun.COM int ipver;
45310946SSangeeta.Misra@Sun.COM
45410946SSangeeta.Misra@Sun.COM if (GET_AF(&srv->isv_addr) == AF_INET) {
45510946SSangeeta.Misra@Sun.COM struct in_addr v4_addr;
45610946SSangeeta.Misra@Sun.COM
45710946SSangeeta.Misra@Sun.COM IN6_V4MAPPED_TO_INADDR(&srv->isv_addr, &v4_addr);
45810946SSangeeta.Misra@Sun.COM (void) inet_ntop(AF_INET, &v4_addr, ipstr, sizeof (ipstr));
45910946SSangeeta.Misra@Sun.COM ipver = AF_INET;
46010946SSangeeta.Misra@Sun.COM } else {
46110946SSangeeta.Misra@Sun.COM (void) inet_ntop(AF_INET6, &srv->isv_addr, ipstr,
46210946SSangeeta.Misra@Sun.COM sizeof (ipstr));
46310946SSangeeta.Misra@Sun.COM ipver = AF_INET6;
46410946SSangeeta.Misra@Sun.COM }
46510946SSangeeta.Misra@Sun.COM (void) snprintf(value, ILBD_MAX_VALUE_LEN, "%s;%d;%d-%d;%d",
46610946SSangeeta.Misra@Sun.COM ipstr, ipver, ntohs(srv->isv_minport), ntohs(srv->isv_maxport),
46710946SSangeeta.Misra@Sun.COM srv->isv_flags);
46810946SSangeeta.Misra@Sun.COM }
46910946SSangeeta.Misra@Sun.COM
47010946SSangeeta.Misra@Sun.COM /* get the "ip:port:status" str of the #num server in the servergroup */
47110946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_get_svr_info(ilbd_sg_t * sg,int num,char * valstr,char * svrname)47210946SSangeeta.Misra@Sun.COM ilbd_get_svr_info(ilbd_sg_t *sg, int num, char *valstr, char *svrname)
47310946SSangeeta.Misra@Sun.COM {
47410946SSangeeta.Misra@Sun.COM int i;
47510946SSangeeta.Misra@Sun.COM ilbd_srv_t *tmp_srv = NULL;
47610946SSangeeta.Misra@Sun.COM
47710946SSangeeta.Misra@Sun.COM tmp_srv = list_head(&sg->isg_srvlist);
47810946SSangeeta.Misra@Sun.COM if (tmp_srv == NULL)
47910946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOENT);
48010946SSangeeta.Misra@Sun.COM
48110946SSangeeta.Misra@Sun.COM for (i = 0; i < num; i++)
48210946SSangeeta.Misra@Sun.COM tmp_srv = list_next(&sg->isg_srvlist, tmp_srv);
48310946SSangeeta.Misra@Sun.COM
48410946SSangeeta.Misra@Sun.COM assert(tmp_srv != NULL);
48510946SSangeeta.Misra@Sun.COM if (valstr != NULL)
48610946SSangeeta.Misra@Sun.COM ilbd_srv_scf_val(tmp_srv, valstr);
48710946SSangeeta.Misra@Sun.COM
48810946SSangeeta.Misra@Sun.COM if (svrname != NULL) {
48910946SSangeeta.Misra@Sun.COM (void) snprintf(svrname, ILBD_MAX_NAME_LEN, "server%d",
49010946SSangeeta.Misra@Sun.COM tmp_srv->isv_id);
49110946SSangeeta.Misra@Sun.COM }
49210946SSangeeta.Misra@Sun.COM
49310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
49410946SSangeeta.Misra@Sun.COM }
49510946SSangeeta.Misra@Sun.COM
49610946SSangeeta.Misra@Sun.COM /* convert a struct in6_addr to valstr */
49710946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_scf_ip_to_str(uint16_t ipversion,struct in6_addr * addr,scf_type_t * scftype,char * valstr)49810946SSangeeta.Misra@Sun.COM ilbd_scf_ip_to_str(uint16_t ipversion, struct in6_addr *addr,
49910946SSangeeta.Misra@Sun.COM scf_type_t *scftype, char *valstr)
50010946SSangeeta.Misra@Sun.COM {
50110946SSangeeta.Misra@Sun.COM size_t vallen;
50210946SSangeeta.Misra@Sun.COM ilb_ip_addr_t ipaddr;
50310946SSangeeta.Misra@Sun.COM void *addrptr;
50410946SSangeeta.Misra@Sun.COM
50510946SSangeeta.Misra@Sun.COM vallen = (ipversion == AF_INET) ? INET_ADDRSTRLEN :
50610946SSangeeta.Misra@Sun.COM INET6_ADDRSTRLEN;
50710946SSangeeta.Misra@Sun.COM if (scftype != NULL)
50810946SSangeeta.Misra@Sun.COM *scftype = (ipversion == AF_INET) ? SCF_TYPE_NET_ADDR_V4 :
50910946SSangeeta.Misra@Sun.COM SCF_TYPE_NET_ADDR_V6;
51010946SSangeeta.Misra@Sun.COM
51110946SSangeeta.Misra@Sun.COM IP_COPY_IMPL_2_CLI(addr, &ipaddr);
51210946SSangeeta.Misra@Sun.COM addrptr = (ipversion == AF_INET) ?
51310946SSangeeta.Misra@Sun.COM (void *)&ipaddr.ia_v4 : (void *)&ipaddr.ia_v6;
51410946SSangeeta.Misra@Sun.COM (void) inet_ntop(ipversion, (void *)addrptr, valstr, vallen);
51510946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
51610946SSangeeta.Misra@Sun.COM }
51710946SSangeeta.Misra@Sun.COM
51810946SSangeeta.Misra@Sun.COM /*
51910946SSangeeta.Misra@Sun.COM * This function takes a ilbd internal data struct and translate its value to
52010946SSangeeta.Misra@Sun.COM * scf value. The data struct is passed in within "data".
52110946SSangeeta.Misra@Sun.COM * Upon successful return, the scf val will be stored in "val" and the scf type
52210946SSangeeta.Misra@Sun.COM * will be returned in "scftype" if scftype != NULL, the number of values
52310946SSangeeta.Misra@Sun.COM * translated will be in "numval"
52410946SSangeeta.Misra@Sun.COM * If it failed, no data will be written to SCF
52510946SSangeeta.Misra@Sun.COM */
52610946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_data_to_scfval(ilbd_scf_pg_type_t pg_type,ilbd_var_type_t type,scf_handle_t * h,void * data,scf_value_t *** val,scf_type_t * scftype,int * numval)52710946SSangeeta.Misra@Sun.COM ilbd_data_to_scfval(ilbd_scf_pg_type_t pg_type, ilbd_var_type_t type,
52810946SSangeeta.Misra@Sun.COM scf_handle_t *h, void *data, scf_value_t ***val, scf_type_t *scftype,
52910946SSangeeta.Misra@Sun.COM int *numval)
53010946SSangeeta.Misra@Sun.COM {
53110946SSangeeta.Misra@Sun.COM scf_value_t *v, **varray = NULL;
53210946SSangeeta.Misra@Sun.COM int ret = ILB_STATUS_OK;
53310946SSangeeta.Misra@Sun.COM int i;
53410946SSangeeta.Misra@Sun.COM int scf_val_len = ILBD_MAX_VALUE_LEN;
535*12857SSangeeta.Misra@Sun.COM char *valstr = NULL;
53610946SSangeeta.Misra@Sun.COM int valint;
53710946SSangeeta.Misra@Sun.COM uint8_t valbool = 0;
53810946SSangeeta.Misra@Sun.COM ilbd_rule_t *r_ent = NULL;
53910946SSangeeta.Misra@Sun.COM ilbd_sg_t *s_ent = NULL;
54010946SSangeeta.Misra@Sun.COM ilbd_hc_t *h_ent = NULL;
54110946SSangeeta.Misra@Sun.COM
54210946SSangeeta.Misra@Sun.COM switch (pg_type) {
54310946SSangeeta.Misra@Sun.COM case ILBD_SCF_RULE:
54410946SSangeeta.Misra@Sun.COM r_ent = (ilbd_rule_t *)data;
54510946SSangeeta.Misra@Sun.COM break;
54610946SSangeeta.Misra@Sun.COM case ILBD_SCF_SG:
54710946SSangeeta.Misra@Sun.COM s_ent = (ilbd_sg_t *)data;
54810946SSangeeta.Misra@Sun.COM break;
54910946SSangeeta.Misra@Sun.COM case ILBD_SCF_HC:
55010946SSangeeta.Misra@Sun.COM h_ent = (ilbd_hc_t *)data;
55110946SSangeeta.Misra@Sun.COM break;
55210946SSangeeta.Misra@Sun.COM }
55310946SSangeeta.Misra@Sun.COM
55410946SSangeeta.Misra@Sun.COM v = scf_value_create(h);
55510946SSangeeta.Misra@Sun.COM if (v == NULL)
55610946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
55710946SSangeeta.Misra@Sun.COM
558*12857SSangeeta.Misra@Sun.COM if ((valstr = malloc(scf_val_len)) == NULL)
559*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
56010946SSangeeta.Misra@Sun.COM switch (type) {
56110946SSangeeta.Misra@Sun.COM case ILBD_RULE_STATUS:
56210946SSangeeta.Misra@Sun.COM valbool = r_ent->irl_flags & ILB_FLAGS_RULE_ENABLED;
56310946SSangeeta.Misra@Sun.COM break;
56410946SSangeeta.Misra@Sun.COM case ILBD_RULE_VIP:
56510946SSangeeta.Misra@Sun.COM ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion, &r_ent->irl_vip,
56610946SSangeeta.Misra@Sun.COM scftype, valstr);
56710946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
568*12857SSangeeta.Misra@Sun.COM free(valstr);
56910946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
57010946SSangeeta.Misra@Sun.COM return (ret);
57110946SSangeeta.Misra@Sun.COM }
57210946SSangeeta.Misra@Sun.COM break;
57310946SSangeeta.Misra@Sun.COM case ILBD_RULE_PROTO: {
57410946SSangeeta.Misra@Sun.COM struct protoent *protoent;
57510946SSangeeta.Misra@Sun.COM
57610946SSangeeta.Misra@Sun.COM protoent = getprotobynumber(r_ent->irl_proto);
577*12857SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, protoent->p_name, scf_val_len);
57810946SSangeeta.Misra@Sun.COM break;
57910946SSangeeta.Misra@Sun.COM }
58010946SSangeeta.Misra@Sun.COM case ILBD_RULE_PORT:
581*12857SSangeeta.Misra@Sun.COM (void) snprintf(valstr, scf_val_len, "%d-%d",
58210946SSangeeta.Misra@Sun.COM r_ent->irl_minport, r_ent->irl_maxport);
58310946SSangeeta.Misra@Sun.COM break;
58410946SSangeeta.Misra@Sun.COM case ILBD_RULE_ALGO:
58510946SSangeeta.Misra@Sun.COM ilbd_algo_to_str(r_ent->irl_algo, valstr);
58610946SSangeeta.Misra@Sun.COM break;
58710946SSangeeta.Misra@Sun.COM case ILBD_RULE_TOPO:
58810946SSangeeta.Misra@Sun.COM ilbd_topo_to_str(r_ent->irl_topo, valstr);
58910946SSangeeta.Misra@Sun.COM break;
59010946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_STR:
59110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion,
59210946SSangeeta.Misra@Sun.COM &r_ent->irl_nat_src_start, scftype, valstr);
59310946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
594*12857SSangeeta.Misra@Sun.COM free(valstr);
59510946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
59610946SSangeeta.Misra@Sun.COM return (ret);
59710946SSangeeta.Misra@Sun.COM }
59810946SSangeeta.Misra@Sun.COM break;
59910946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_END:
60010946SSangeeta.Misra@Sun.COM ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion,
60110946SSangeeta.Misra@Sun.COM &r_ent->irl_nat_src_end, scftype, valstr);
60210946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
603*12857SSangeeta.Misra@Sun.COM free(valstr);
60410946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
60510946SSangeeta.Misra@Sun.COM return (ret);
60610946SSangeeta.Misra@Sun.COM }
60710946SSangeeta.Misra@Sun.COM break;
60810946SSangeeta.Misra@Sun.COM case ILBD_RULE_STI_MASK:
60910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_ip_to_str(r_ent->irl_ipversion,
61010946SSangeeta.Misra@Sun.COM &r_ent->irl_stickymask, scftype, valstr);
61110946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
612*12857SSangeeta.Misra@Sun.COM free(valstr);
61310946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
61410946SSangeeta.Misra@Sun.COM return (ret);
61510946SSangeeta.Misra@Sun.COM }
61610946SSangeeta.Misra@Sun.COM break;
61710946SSangeeta.Misra@Sun.COM case ILBD_RULE_SGNAME:
618*12857SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, r_ent->irl_sgname, scf_val_len);
61910946SSangeeta.Misra@Sun.COM break;
62010946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCNAME:
62110946SSangeeta.Misra@Sun.COM if (r_ent->irl_hcname[0] != '\0')
62210946SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, r_ent->irl_hcname,
623*12857SSangeeta.Misra@Sun.COM scf_val_len);
62410946SSangeeta.Misra@Sun.COM else
62510946SSangeeta.Misra@Sun.COM bzero(valstr, ILBD_MAX_VALUE_LEN);
62610946SSangeeta.Misra@Sun.COM break;
62710946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCPORT:
62810946SSangeeta.Misra@Sun.COM valint = r_ent->irl_hcport;
62910946SSangeeta.Misra@Sun.COM break;
63010946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCPFLAG:
63110946SSangeeta.Misra@Sun.COM valint = r_ent->irl_hcpflag;
63210946SSangeeta.Misra@Sun.COM break;
63310946SSangeeta.Misra@Sun.COM case ILBD_RULE_DRAINTIME:
63410946SSangeeta.Misra@Sun.COM valint = r_ent->irl_conndrain;
63510946SSangeeta.Misra@Sun.COM break;
63610946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_TO:
63710946SSangeeta.Misra@Sun.COM valint = r_ent->irl_nat_timeout;
63810946SSangeeta.Misra@Sun.COM break;
63910946SSangeeta.Misra@Sun.COM case ILBD_RULE_PERS_TO:
64010946SSangeeta.Misra@Sun.COM valint = r_ent->irl_sticky_timeout;
64110946SSangeeta.Misra@Sun.COM break;
64210946SSangeeta.Misra@Sun.COM
64310946SSangeeta.Misra@Sun.COM case ILBD_SG_SERVER:
64410946SSangeeta.Misra@Sun.COM if (s_ent->isg_srvcount == 0) {
64510946SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, "EMPTY_SERVERGROUP",
646*12857SSangeeta.Misra@Sun.COM scf_val_len);
64710946SSangeeta.Misra@Sun.COM break;
64810946SSangeeta.Misra@Sun.COM }
64910946SSangeeta.Misra@Sun.COM
65010946SSangeeta.Misra@Sun.COM varray = calloc(sizeof (*varray), s_ent->isg_srvcount);
65110946SSangeeta.Misra@Sun.COM if (varray == NULL) {
65210946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
653*12857SSangeeta.Misra@Sun.COM free(valstr);
65410946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
65510946SSangeeta.Misra@Sun.COM }
65610946SSangeeta.Misra@Sun.COM
65710946SSangeeta.Misra@Sun.COM for (i = 0; i < s_ent->isg_srvcount; i++) {
65810946SSangeeta.Misra@Sun.COM if (v == NULL) {
65910946SSangeeta.Misra@Sun.COM for (i--; i >= 0; i--)
66010946SSangeeta.Misra@Sun.COM scf_value_destroy(varray[i]);
661*12857SSangeeta.Misra@Sun.COM free(valstr);
66210946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
66310946SSangeeta.Misra@Sun.COM }
66410946SSangeeta.Misra@Sun.COM
66510946SSangeeta.Misra@Sun.COM ret = ilbd_get_svr_info(s_ent, i, valstr, NULL);
66610946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
66710946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
66810946SSangeeta.Misra@Sun.COM for (i--; i >= 0; i--)
66910946SSangeeta.Misra@Sun.COM scf_value_destroy(varray[i]);
670*12857SSangeeta.Misra@Sun.COM free(valstr);
67110946SSangeeta.Misra@Sun.COM free(varray);
67210946SSangeeta.Misra@Sun.COM return (ret);
67310946SSangeeta.Misra@Sun.COM }
67410946SSangeeta.Misra@Sun.COM (void) scf_value_set_astring(v, valstr);
67510946SSangeeta.Misra@Sun.COM varray[i] = v;
67610946SSangeeta.Misra@Sun.COM v = scf_value_create(h);
67710946SSangeeta.Misra@Sun.COM }
67810946SSangeeta.Misra@Sun.COM /* the last 'v' we created will go unused, so drop it */
67910946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
68010946SSangeeta.Misra@Sun.COM *numval = s_ent->isg_srvcount;
68110946SSangeeta.Misra@Sun.COM *val = varray;
682*12857SSangeeta.Misra@Sun.COM free(valstr);
68310946SSangeeta.Misra@Sun.COM return (ret);
68410946SSangeeta.Misra@Sun.COM case ILBD_HC_TEST:
685*12857SSangeeta.Misra@Sun.COM (void) strlcpy(valstr, h_ent->ihc_test, scf_val_len);
68610946SSangeeta.Misra@Sun.COM break;
68710946SSangeeta.Misra@Sun.COM case ILBD_HC_TIMEOUT:
68810946SSangeeta.Misra@Sun.COM valint = h_ent->ihc_timeout;
68910946SSangeeta.Misra@Sun.COM break;
69010946SSangeeta.Misra@Sun.COM case ILBD_HC_INTERVAL:
69110946SSangeeta.Misra@Sun.COM valint = h_ent->ihc_interval;
69210946SSangeeta.Misra@Sun.COM break;
69310946SSangeeta.Misra@Sun.COM case ILBD_HC_DEF_PING:
69410946SSangeeta.Misra@Sun.COM valbool = h_ent->ihc_def_ping;
69510946SSangeeta.Misra@Sun.COM break;
69610946SSangeeta.Misra@Sun.COM case ILBD_HC_COUNT:
69710946SSangeeta.Misra@Sun.COM valint = h_ent->ihc_count;
69810946SSangeeta.Misra@Sun.COM break;
69910946SSangeeta.Misra@Sun.COM }
70010946SSangeeta.Misra@Sun.COM
70110946SSangeeta.Misra@Sun.COM switch (*scftype) {
70210946SSangeeta.Misra@Sun.COM case SCF_TYPE_BOOLEAN:
70310946SSangeeta.Misra@Sun.COM scf_value_set_boolean(v, valbool);
70410946SSangeeta.Misra@Sun.COM break;
70510946SSangeeta.Misra@Sun.COM case SCF_TYPE_ASTRING:
70610946SSangeeta.Misra@Sun.COM (void) scf_value_set_astring(v, valstr);
70710946SSangeeta.Misra@Sun.COM break;
70810946SSangeeta.Misra@Sun.COM case SCF_TYPE_INTEGER:
70910946SSangeeta.Misra@Sun.COM scf_value_set_integer(v, valint);
71010946SSangeeta.Misra@Sun.COM break;
71110946SSangeeta.Misra@Sun.COM case SCF_TYPE_NET_ADDR_V4:
71210946SSangeeta.Misra@Sun.COM (void) scf_value_set_from_string(v, SCF_TYPE_NET_ADDR_V4,
71310946SSangeeta.Misra@Sun.COM valstr);
71410946SSangeeta.Misra@Sun.COM break;
71510946SSangeeta.Misra@Sun.COM case SCF_TYPE_NET_ADDR_V6:
71610946SSangeeta.Misra@Sun.COM (void) scf_value_set_from_string(v, SCF_TYPE_NET_ADDR_V6,
71710946SSangeeta.Misra@Sun.COM valstr);
71810946SSangeeta.Misra@Sun.COM break;
71910946SSangeeta.Misra@Sun.COM }
720*12857SSangeeta.Misra@Sun.COM free(valstr);
72110946SSangeeta.Misra@Sun.COM
72210946SSangeeta.Misra@Sun.COM varray = calloc(1, sizeof (*varray));
72310946SSangeeta.Misra@Sun.COM if (varray == NULL) {
72410946SSangeeta.Misra@Sun.COM scf_value_destroy(v);
72510946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
72610946SSangeeta.Misra@Sun.COM }
72710946SSangeeta.Misra@Sun.COM varray[0] = v;
72810946SSangeeta.Misra@Sun.COM *val = varray;
72910946SSangeeta.Misra@Sun.COM *numval = 1;
73010946SSangeeta.Misra@Sun.COM return (ret);
73110946SSangeeta.Misra@Sun.COM }
73210946SSangeeta.Misra@Sun.COM
73310946SSangeeta.Misra@Sun.COM /*
73410946SSangeeta.Misra@Sun.COM * create a scf property group
73510946SSangeeta.Misra@Sun.COM */
73610946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_create_pg(ilbd_scf_pg_type_t pg_type,void * data)73710946SSangeeta.Misra@Sun.COM ilbd_create_pg(ilbd_scf_pg_type_t pg_type, void *data)
73810946SSangeeta.Misra@Sun.COM {
73910946SSangeeta.Misra@Sun.COM ilb_status_t ret;
74010946SSangeeta.Misra@Sun.COM char *pgname;
74110946SSangeeta.Misra@Sun.COM scf_propertygroup_t *pg = NULL;
74210946SSangeeta.Misra@Sun.COM scf_value_t **val;
74310946SSangeeta.Misra@Sun.COM scf_handle_t *h;
74410946SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
745*12857SSangeeta.Misra@Sun.COM char *scfpgbuf; /* property group name or group type */
74610946SSangeeta.Misra@Sun.COM int i, i_st, i_end;
74710946SSangeeta.Misra@Sun.COM
74810946SSangeeta.Misra@Sun.COM switch (pg_type) {
74910946SSangeeta.Misra@Sun.COM case ILBD_SCF_RULE: {
75010946SSangeeta.Misra@Sun.COM ilbd_rule_t *r_ent = (ilbd_rule_t *)data;
75110946SSangeeta.Misra@Sun.COM
75210946SSangeeta.Misra@Sun.COM pgname = r_ent->irl_name;
75310946SSangeeta.Misra@Sun.COM i_st = 0;
75410946SSangeeta.Misra@Sun.COM i_end = ILBD_RULE_VAR_NUM;
75510946SSangeeta.Misra@Sun.COM break;
75610946SSangeeta.Misra@Sun.COM }
75710946SSangeeta.Misra@Sun.COM case ILBD_SCF_SG: {
75810946SSangeeta.Misra@Sun.COM ilbd_sg_t *s_ent = (ilbd_sg_t *)data;
75910946SSangeeta.Misra@Sun.COM
76010946SSangeeta.Misra@Sun.COM pgname = s_ent->isg_name;
76110946SSangeeta.Misra@Sun.COM i_st = ILBD_RULE_VAR_NUM;
76210946SSangeeta.Misra@Sun.COM i_end = ILBD_RULE_VAR_NUM + ILBD_SG_VAR_NUM;
76310946SSangeeta.Misra@Sun.COM break;
76410946SSangeeta.Misra@Sun.COM }
76510946SSangeeta.Misra@Sun.COM case ILBD_SCF_HC: {
76610946SSangeeta.Misra@Sun.COM ilbd_hc_t *h_ent = (ilbd_hc_t *)data;
76710946SSangeeta.Misra@Sun.COM
76810946SSangeeta.Misra@Sun.COM pgname = h_ent->ihc_name;
76910946SSangeeta.Misra@Sun.COM i_st = ILBD_RULE_VAR_NUM + ILBD_SG_VAR_NUM;
77010946SSangeeta.Misra@Sun.COM i_end = ILBD_PROP_VAR_NUM;
77110946SSangeeta.Misra@Sun.COM break;
77210946SSangeeta.Misra@Sun.COM }
77310946SSangeeta.Misra@Sun.COM default:
77410946SSangeeta.Misra@Sun.COM logdebug("ilbd_create_pg: invalid pg type %d for pg %s",
77510946SSangeeta.Misra@Sun.COM pg_type, pgname);
77610946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
77710946SSangeeta.Misra@Sun.COM }
778*12857SSangeeta.Misra@Sun.COM if ((scfpgbuf = malloc(scf_name_len)) == NULL)
779*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
78010946SSangeeta.Misra@Sun.COM
781*12857SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(pg_type, pgname, scfpgbuf);
78210946SSangeeta.Misra@Sun.COM
783*12857SSangeeta.Misra@Sun.COM ret = ilbd_scf_retrieve_pg(scfpgbuf, &pg, B_TRUE);
784*12857SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
785*12857SSangeeta.Misra@Sun.COM free(scfpgbuf);
78610946SSangeeta.Misra@Sun.COM return (ret);
787*12857SSangeeta.Misra@Sun.COM }
78810946SSangeeta.Misra@Sun.COM h = scf_pg_handle(pg);
78910946SSangeeta.Misra@Sun.COM
79010946SSangeeta.Misra@Sun.COM /* fill in props */
79110946SSangeeta.Misra@Sun.COM for (i = i_st; i < i_end; i++) {
79210946SSangeeta.Misra@Sun.COM int num, j;
79310946SSangeeta.Misra@Sun.COM scf_type_t scftype = prop_tbl[i].scf_proptype;
79410946SSangeeta.Misra@Sun.COM
79510946SSangeeta.Misra@Sun.COM ret = ilbd_data_to_scfval(pg_type, prop_tbl[i].val_type, h,
79610946SSangeeta.Misra@Sun.COM data, &val, &scftype, &num);
79710946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
79810946SSangeeta.Misra@Sun.COM goto done;
79910946SSangeeta.Misra@Sun.COM
80010946SSangeeta.Misra@Sun.COM for (j = 0; j < num; j++) {
80110946SSangeeta.Misra@Sun.COM if (pg_type == ILBD_SCF_SG) {
80210946SSangeeta.Misra@Sun.COM ret = ilbd_get_svr_info(data, j, NULL,
803*12857SSangeeta.Misra@Sun.COM scfpgbuf);
80410946SSangeeta.Misra@Sun.COM if (ret == ILB_STATUS_ENOENT) {
805*12857SSangeeta.Misra@Sun.COM (void) strlcpy(scfpgbuf,
806*12857SSangeeta.Misra@Sun.COM "EMPTY_SERVER", scf_name_len);
80710946SSangeeta.Misra@Sun.COM }
808*12857SSangeeta.Misra@Sun.COM ret = ilbd_scf_set_prop(pg, scfpgbuf,
80910946SSangeeta.Misra@Sun.COM scftype, val[j]);
81010946SSangeeta.Misra@Sun.COM } else {
81110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_set_prop(pg,
81210946SSangeeta.Misra@Sun.COM prop_tbl[i].scf_propname, scftype, val[j]);
81310946SSangeeta.Misra@Sun.COM }
81410946SSangeeta.Misra@Sun.COM scf_value_destroy(val[j]);
81510946SSangeeta.Misra@Sun.COM }
81610946SSangeeta.Misra@Sun.COM free(val);
81710946SSangeeta.Misra@Sun.COM }
81810946SSangeeta.Misra@Sun.COM
81910946SSangeeta.Misra@Sun.COM done:
820*12857SSangeeta.Misra@Sun.COM free(scfpgbuf);
82110946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, NULL, NULL, pg);
82210946SSangeeta.Misra@Sun.COM return (ret);
82310946SSangeeta.Misra@Sun.COM }
82410946SSangeeta.Misra@Sun.COM
82510946SSangeeta.Misra@Sun.COM /*
82610946SSangeeta.Misra@Sun.COM * destroy a scf property group
82710946SSangeeta.Misra@Sun.COM */
82810946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_delete_pg(scf_propertygroup_t * pg)82910946SSangeeta.Misra@Sun.COM ilbd_scf_delete_pg(scf_propertygroup_t *pg)
83010946SSangeeta.Misra@Sun.COM {
83110946SSangeeta.Misra@Sun.COM if (scf_pg_delete(pg) != 0)
83210946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
83310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
83410946SSangeeta.Misra@Sun.COM }
83510946SSangeeta.Misra@Sun.COM
83610946SSangeeta.Misra@Sun.COM /* sg can have same name as rule */
83710946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_destroy_pg(ilbd_scf_pg_type_t pg_t,const char * pgname)83810946SSangeeta.Misra@Sun.COM ilbd_destroy_pg(ilbd_scf_pg_type_t pg_t, const char *pgname)
83910946SSangeeta.Misra@Sun.COM {
84010946SSangeeta.Misra@Sun.COM ilb_status_t ret;
84110946SSangeeta.Misra@Sun.COM scf_propertygroup_t *pg;
84210946SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
843*12857SSangeeta.Misra@Sun.COM char *scfname;
84410946SSangeeta.Misra@Sun.COM
845*12857SSangeeta.Misra@Sun.COM if ((scfname = malloc(scf_name_len)) == NULL)
846*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
84710946SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(pg_t, pgname, scfname);
84810946SSangeeta.Misra@Sun.COM
84910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_retrieve_pg(scfname, &pg, B_FALSE);
850*12857SSangeeta.Misra@Sun.COM free(scfname);
85110946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_EEXIST)
85210946SSangeeta.Misra@Sun.COM return (ret);
85310946SSangeeta.Misra@Sun.COM ret = ilbd_scf_delete_pg(pg);
85410946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(scf_pg_handle(pg), NULL, NULL, pg);
85510946SSangeeta.Misra@Sun.COM return (ret);
85610946SSangeeta.Misra@Sun.COM }
85710946SSangeeta.Misra@Sun.COM
85810946SSangeeta.Misra@Sun.COM /*
85910946SSangeeta.Misra@Sun.COM * Set named property to scf value specified. If property is new,
86010946SSangeeta.Misra@Sun.COM * create it.
86110946SSangeeta.Misra@Sun.COM */
86210946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_set_prop(scf_propertygroup_t * pg,const char * propname,scf_type_t proptype,scf_value_t * val)86310946SSangeeta.Misra@Sun.COM ilbd_scf_set_prop(scf_propertygroup_t *pg, const char *propname,
86410946SSangeeta.Misra@Sun.COM scf_type_t proptype, scf_value_t *val)
86510946SSangeeta.Misra@Sun.COM {
86610946SSangeeta.Misra@Sun.COM scf_handle_t *h = NULL;
86710946SSangeeta.Misra@Sun.COM scf_property_t *prop = NULL;
86810946SSangeeta.Misra@Sun.COM scf_value_t *oldval = NULL;
86910946SSangeeta.Misra@Sun.COM scf_transaction_t *tx = NULL;
87010946SSangeeta.Misra@Sun.COM scf_transaction_entry_t *ent = NULL;
87110946SSangeeta.Misra@Sun.COM boolean_t new = B_FALSE;
87210946SSangeeta.Misra@Sun.COM ilb_status_t ret = ILB_STATUS_OK;
87310946SSangeeta.Misra@Sun.COM int commit_ret;
87410946SSangeeta.Misra@Sun.COM
87510946SSangeeta.Misra@Sun.COM h = scf_pg_handle(pg);
87610946SSangeeta.Misra@Sun.COM if (h == NULL || propname == NULL)
87710946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
87810946SSangeeta.Misra@Sun.COM
87910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_prop_val(pg, propname, &oldval);
88010946SSangeeta.Misra@Sun.COM if (oldval != NULL)
88110946SSangeeta.Misra@Sun.COM scf_value_destroy(oldval);
88210946SSangeeta.Misra@Sun.COM if (ret == ILB_STATUS_ENOENT)
88310946SSangeeta.Misra@Sun.COM new = B_TRUE;
88410946SSangeeta.Misra@Sun.COM else if (ret != ILB_STATUS_OK)
88510946SSangeeta.Misra@Sun.COM return (ret);
88610946SSangeeta.Misra@Sun.COM
88710946SSangeeta.Misra@Sun.COM if ((prop = scf_property_create(h)) == NULL)
88810946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
88910946SSangeeta.Misra@Sun.COM if ((tx = scf_transaction_create(h)) == NULL ||
89010946SSangeeta.Misra@Sun.COM (ent = scf_entry_create(h)) == NULL) {
89110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
89210946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: create scf transaction failed\n");
89310946SSangeeta.Misra@Sun.COM goto out;
89410946SSangeeta.Misra@Sun.COM }
89510946SSangeeta.Misra@Sun.COM
89610946SSangeeta.Misra@Sun.COM if (scf_transaction_start(tx, pg) == -1) {
89710946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
89810946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: start scf transaction failed\n");
89910946SSangeeta.Misra@Sun.COM goto out;
90010946SSangeeta.Misra@Sun.COM }
90110946SSangeeta.Misra@Sun.COM
90210946SSangeeta.Misra@Sun.COM if (new) {
90310946SSangeeta.Misra@Sun.COM if (scf_transaction_property_new(tx, ent, propname,
90410946SSangeeta.Misra@Sun.COM proptype) == -1) {
90510946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
90610946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: create scf prop failed\n");
90710946SSangeeta.Misra@Sun.COM goto out;
90810946SSangeeta.Misra@Sun.COM }
90910946SSangeeta.Misra@Sun.COM } else {
91010946SSangeeta.Misra@Sun.COM if (scf_transaction_property_change(tx, ent, propname, proptype)
91110946SSangeeta.Misra@Sun.COM == -1) {
91210946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
91310946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: change scf prop failed\n");
91410946SSangeeta.Misra@Sun.COM goto out;
91510946SSangeeta.Misra@Sun.COM }
91610946SSangeeta.Misra@Sun.COM }
91710946SSangeeta.Misra@Sun.COM
91810946SSangeeta.Misra@Sun.COM if (scf_entry_add_value(ent, val) != 0) {
91910946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: add scf entry failed\n");
92010946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
92110946SSangeeta.Misra@Sun.COM goto out;
92210946SSangeeta.Misra@Sun.COM }
92310946SSangeeta.Misra@Sun.COM
92410946SSangeeta.Misra@Sun.COM commit_ret = scf_transaction_commit(tx);
92510946SSangeeta.Misra@Sun.COM switch (commit_ret) {
92610946SSangeeta.Misra@Sun.COM case 1:
92710946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_OK;
92810946SSangeeta.Misra@Sun.COM /* update pg here, so subsequent property setting succeeds */
92910946SSangeeta.Misra@Sun.COM (void) scf_pg_update(pg);
93010946SSangeeta.Misra@Sun.COM break;
93110946SSangeeta.Misra@Sun.COM case 0:
93210946SSangeeta.Misra@Sun.COM /* transaction failed due to not having most recent pg */
93310946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_INUSE;
93410946SSangeeta.Misra@Sun.COM break;
93510946SSangeeta.Misra@Sun.COM default:
93610946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
93710946SSangeeta.Misra@Sun.COM break;
93810946SSangeeta.Misra@Sun.COM }
93910946SSangeeta.Misra@Sun.COM out:
94010946SSangeeta.Misra@Sun.COM if (tx != NULL)
94110946SSangeeta.Misra@Sun.COM scf_transaction_destroy(tx);
94210946SSangeeta.Misra@Sun.COM if (ent != NULL)
94310946SSangeeta.Misra@Sun.COM scf_entry_destroy(ent);
94410946SSangeeta.Misra@Sun.COM if (prop != NULL)
94510946SSangeeta.Misra@Sun.COM scf_property_destroy(prop);
94610946SSangeeta.Misra@Sun.COM
94710946SSangeeta.Misra@Sun.COM return (ret);
94810946SSangeeta.Misra@Sun.COM }
94910946SSangeeta.Misra@Sun.COM
95010946SSangeeta.Misra@Sun.COM /*
95110946SSangeeta.Misra@Sun.COM * get a prop's scf val
95210946SSangeeta.Misra@Sun.COM */
95310946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_get_prop_val(scf_propertygroup_t * pg,const char * propname,scf_value_t ** val)95410946SSangeeta.Misra@Sun.COM ilbd_scf_get_prop_val(scf_propertygroup_t *pg, const char *propname,
95510946SSangeeta.Misra@Sun.COM scf_value_t **val)
95610946SSangeeta.Misra@Sun.COM {
95710946SSangeeta.Misra@Sun.COM scf_handle_t *h = NULL;
95810946SSangeeta.Misra@Sun.COM scf_property_t *prop = NULL;
95910946SSangeeta.Misra@Sun.COM scf_value_t *value = NULL;
96010946SSangeeta.Misra@Sun.COM ilb_status_t ret = ILB_STATUS_OK;
96110946SSangeeta.Misra@Sun.COM
96210946SSangeeta.Misra@Sun.COM h = scf_pg_handle(pg);
96310946SSangeeta.Misra@Sun.COM if (h == NULL || propname == NULL)
96410946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
96510946SSangeeta.Misra@Sun.COM
96610946SSangeeta.Misra@Sun.COM if ((prop = scf_property_create(h)) == NULL)
96710946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
96810946SSangeeta.Misra@Sun.COM
96910946SSangeeta.Misra@Sun.COM if (scf_pg_get_property(pg, propname, prop) != 0) {
97010946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
97110946SSangeeta.Misra@Sun.COM goto out;
97210946SSangeeta.Misra@Sun.COM }
97310946SSangeeta.Misra@Sun.COM
97410946SSangeeta.Misra@Sun.COM if ((value = scf_value_create(h)) == NULL) {
97510946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
97610946SSangeeta.Misra@Sun.COM goto out;
97710946SSangeeta.Misra@Sun.COM }
97810946SSangeeta.Misra@Sun.COM
97910946SSangeeta.Misra@Sun.COM if (scf_property_get_value(prop, value) != 0) {
98010946SSangeeta.Misra@Sun.COM scf_value_destroy(value);
98110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
98210946SSangeeta.Misra@Sun.COM goto out;
98310946SSangeeta.Misra@Sun.COM }
98410946SSangeeta.Misra@Sun.COM
98510946SSangeeta.Misra@Sun.COM *val = value;
98610946SSangeeta.Misra@Sun.COM out:
98710946SSangeeta.Misra@Sun.COM if (prop != NULL)
98810946SSangeeta.Misra@Sun.COM scf_property_destroy(prop);
98910946SSangeeta.Misra@Sun.COM
99010946SSangeeta.Misra@Sun.COM return (ret);
99110946SSangeeta.Misra@Sun.COM }
99210946SSangeeta.Misra@Sun.COM
99310946SSangeeta.Misra@Sun.COM typedef struct ilbd_data
99410946SSangeeta.Misra@Sun.COM {
99510946SSangeeta.Misra@Sun.COM union {
99610946SSangeeta.Misra@Sun.COM ilb_sg_info_t *sg_info;
99710946SSangeeta.Misra@Sun.COM ilb_hc_info_t *hc_info;
99810946SSangeeta.Misra@Sun.COM ilb_rule_info_t *rule_info;
99910946SSangeeta.Misra@Sun.COM } data;
100010946SSangeeta.Misra@Sun.COM ilbd_scf_pg_type_t pg_type; /* type of data */
100110946SSangeeta.Misra@Sun.COM #define sg_data data.sg_info
100210946SSangeeta.Misra@Sun.COM #define hc_data data.hc_info
100310946SSangeeta.Misra@Sun.COM #define rule_data data.rule_info
100410946SSangeeta.Misra@Sun.COM } ilbd_data_t;
100510946SSangeeta.Misra@Sun.COM
100610946SSangeeta.Misra@Sun.COM void
ilbd_scf_str_to_ip(int ipversion,char * ipstr,struct in6_addr * addr)100710946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_ip(int ipversion, char *ipstr, struct in6_addr *addr)
100810946SSangeeta.Misra@Sun.COM {
100910946SSangeeta.Misra@Sun.COM ilb_ip_addr_t ipaddr;
101010946SSangeeta.Misra@Sun.COM void *addrptr;
101110946SSangeeta.Misra@Sun.COM
101210946SSangeeta.Misra@Sun.COM addrptr = (ipversion == AF_INET) ?
101310946SSangeeta.Misra@Sun.COM (void *)&ipaddr.ia_v4 : (void *)&ipaddr.ia_v6;
101410946SSangeeta.Misra@Sun.COM (void) inet_pton(ipversion, ipstr, addrptr);
101510946SSangeeta.Misra@Sun.COM if (ipversion == AF_INET) {
101610946SSangeeta.Misra@Sun.COM IN6_INADDR_TO_V4MAPPED(&(ipaddr.ia_v4), addr);
101710946SSangeeta.Misra@Sun.COM } else {
101810946SSangeeta.Misra@Sun.COM (void) memcpy(addr, &(ipaddr.ia_v6),
101910946SSangeeta.Misra@Sun.COM sizeof (struct in6_addr));
102010946SSangeeta.Misra@Sun.COM }
102110946SSangeeta.Misra@Sun.COM }
102210946SSangeeta.Misra@Sun.COM
102310946SSangeeta.Misra@Sun.COM /*
102410946SSangeeta.Misra@Sun.COM * This function takes a scf value and writes it to the correct field of the
102510946SSangeeta.Misra@Sun.COM * corresponding data struct.
102610946SSangeeta.Misra@Sun.COM */
102710946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scfval_to_data(const char * propname,ilbd_var_type_t ilb_type,scf_value_t * val,ilbd_data_t * ilb_data)102810946SSangeeta.Misra@Sun.COM ilbd_scfval_to_data(const char *propname, ilbd_var_type_t ilb_type,
102910946SSangeeta.Misra@Sun.COM scf_value_t *val, ilbd_data_t *ilb_data)
103010946SSangeeta.Misra@Sun.COM {
103110946SSangeeta.Misra@Sun.COM
103210946SSangeeta.Misra@Sun.COM scf_type_t scf_type = scf_value_type(val);
103310946SSangeeta.Misra@Sun.COM ilbd_scf_pg_type_t pg_type = ilb_data->pg_type;
103410946SSangeeta.Misra@Sun.COM int ret = 0;
103510946SSangeeta.Misra@Sun.COM ilb_rule_info_t *r_ent = NULL;
103610946SSangeeta.Misra@Sun.COM ilb_sg_info_t *s_ent = NULL;
103710946SSangeeta.Misra@Sun.COM ilb_hc_info_t *h_ent = NULL;
103810946SSangeeta.Misra@Sun.COM char ipstr[INET6_ADDRSTRLEN];
1039*12857SSangeeta.Misra@Sun.COM char *valstr;
104010946SSangeeta.Misra@Sun.COM int64_t valint;
104110946SSangeeta.Misra@Sun.COM uint8_t valbool;
104210946SSangeeta.Misra@Sun.COM int ipversion;
104310946SSangeeta.Misra@Sun.COM
104410946SSangeeta.Misra@Sun.COM switch (pg_type) {
104510946SSangeeta.Misra@Sun.COM case ILBD_SCF_RULE:
104610946SSangeeta.Misra@Sun.COM r_ent = ilb_data->rule_data;
104710946SSangeeta.Misra@Sun.COM break;
104810946SSangeeta.Misra@Sun.COM case ILBD_SCF_HC:
104910946SSangeeta.Misra@Sun.COM h_ent = ilb_data->hc_data;
105010946SSangeeta.Misra@Sun.COM break;
105110946SSangeeta.Misra@Sun.COM case ILBD_SCF_SG:
105210946SSangeeta.Misra@Sun.COM s_ent = ilb_data->sg_data;
105310946SSangeeta.Misra@Sun.COM break;
105410946SSangeeta.Misra@Sun.COM }
105510946SSangeeta.Misra@Sun.COM
105610946SSangeeta.Misra@Sun.COM /* get scf value out */
1057*12857SSangeeta.Misra@Sun.COM if ((valstr = malloc(ILBD_MAX_VALUE_LEN)) == NULL)
1058*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
105910946SSangeeta.Misra@Sun.COM switch (scf_type) {
106010946SSangeeta.Misra@Sun.COM case SCF_TYPE_NET_ADDR_V4:
106110946SSangeeta.Misra@Sun.COM if (scf_value_get_as_string_typed(val,
1062*12857SSangeeta.Misra@Sun.COM SCF_TYPE_NET_ADDR_V4, ipstr, INET_ADDRSTRLEN) < 0) {
1063*12857SSangeeta.Misra@Sun.COM free(valstr);
106410946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1065*12857SSangeeta.Misra@Sun.COM }
106610946SSangeeta.Misra@Sun.COM ipversion = AF_INET;
106710946SSangeeta.Misra@Sun.COM break;
106810946SSangeeta.Misra@Sun.COM case SCF_TYPE_NET_ADDR_V6:
106910946SSangeeta.Misra@Sun.COM if (scf_value_get_as_string_typed(val,
1070*12857SSangeeta.Misra@Sun.COM SCF_TYPE_NET_ADDR_V6, ipstr,
1071*12857SSangeeta.Misra@Sun.COM INET6_ADDRSTRLEN) < 0) {
1072*12857SSangeeta.Misra@Sun.COM free(valstr);
107310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1074*12857SSangeeta.Misra@Sun.COM }
107510946SSangeeta.Misra@Sun.COM ipversion = AF_INET6;
107610946SSangeeta.Misra@Sun.COM break;
107710946SSangeeta.Misra@Sun.COM case SCF_TYPE_BOOLEAN:
1078*12857SSangeeta.Misra@Sun.COM if (scf_value_get_boolean(val, &valbool) < 0) {
1079*12857SSangeeta.Misra@Sun.COM free(valstr);
108010946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1081*12857SSangeeta.Misra@Sun.COM }
108210946SSangeeta.Misra@Sun.COM break;
108310946SSangeeta.Misra@Sun.COM case SCF_TYPE_ASTRING:
1084*12857SSangeeta.Misra@Sun.COM if (scf_value_get_astring(val, valstr,
1085*12857SSangeeta.Misra@Sun.COM ILBD_MAX_VALUE_LEN) < 0) {
1086*12857SSangeeta.Misra@Sun.COM free(valstr);
108710946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1088*12857SSangeeta.Misra@Sun.COM }
108910946SSangeeta.Misra@Sun.COM break;
109010946SSangeeta.Misra@Sun.COM case SCF_TYPE_INTEGER:
1091*12857SSangeeta.Misra@Sun.COM if (scf_value_get_integer(val, &valint) < 0) {
1092*12857SSangeeta.Misra@Sun.COM free(valstr);
109310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1094*12857SSangeeta.Misra@Sun.COM }
109510946SSangeeta.Misra@Sun.COM break;
109610946SSangeeta.Misra@Sun.COM default:
1097*12857SSangeeta.Misra@Sun.COM free(valstr);
109810946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
109910946SSangeeta.Misra@Sun.COM }
110010946SSangeeta.Misra@Sun.COM
110110946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_OK;
110210946SSangeeta.Misra@Sun.COM switch (ilb_type) {
110310946SSangeeta.Misra@Sun.COM case ILBD_RULE_STATUS:
110410946SSangeeta.Misra@Sun.COM if (valbool)
110510946SSangeeta.Misra@Sun.COM r_ent->rl_flags |= ILB_FLAGS_RULE_ENABLED;
110610946SSangeeta.Misra@Sun.COM break;
110710946SSangeeta.Misra@Sun.COM case ILBD_RULE_VIP:
110810946SSangeeta.Misra@Sun.COM r_ent->rl_ipversion = ipversion;
110910946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_vip);
111010946SSangeeta.Misra@Sun.COM break;
111110946SSangeeta.Misra@Sun.COM case ILBD_RULE_PROTO: {
111210946SSangeeta.Misra@Sun.COM struct protoent *protoent;
111310946SSangeeta.Misra@Sun.COM
111410946SSangeeta.Misra@Sun.COM protoent = getprotobyname(valstr);
111510946SSangeeta.Misra@Sun.COM r_ent->rl_proto = protoent->p_proto;
111610946SSangeeta.Misra@Sun.COM break;
111710946SSangeeta.Misra@Sun.COM }
111810946SSangeeta.Misra@Sun.COM case ILBD_RULE_PORT: {
111910946SSangeeta.Misra@Sun.COM char *token1, *token2;
112010946SSangeeta.Misra@Sun.COM
112110946SSangeeta.Misra@Sun.COM token1 = strtok(valstr, "-");
112210946SSangeeta.Misra@Sun.COM token2 = strtok(NULL, "-");
112310946SSangeeta.Misra@Sun.COM r_ent->rl_minport = atoi(token1);
112410946SSangeeta.Misra@Sun.COM r_ent->rl_maxport = atoi(token2);
112510946SSangeeta.Misra@Sun.COM break;
112610946SSangeeta.Misra@Sun.COM }
112710946SSangeeta.Misra@Sun.COM case ILBD_RULE_ALGO:
112810946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_algo(&(r_ent->rl_algo), valstr);
112910946SSangeeta.Misra@Sun.COM break;
113010946SSangeeta.Misra@Sun.COM case ILBD_RULE_TOPO:
113110946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_topo(&(r_ent->rl_topo), valstr);
113210946SSangeeta.Misra@Sun.COM break;
113310946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_STR:
113410946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_nat_src_start);
113510946SSangeeta.Misra@Sun.COM break;
113610946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_END:
113710946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_nat_src_end);
113810946SSangeeta.Misra@Sun.COM break;
113910946SSangeeta.Misra@Sun.COM case ILBD_RULE_STI_MASK:
114010946SSangeeta.Misra@Sun.COM ilbd_scf_str_to_ip(ipversion, ipstr, &r_ent->rl_stickymask);
114110946SSangeeta.Misra@Sun.COM if (ipversion == AF_INET) {
114210946SSangeeta.Misra@Sun.COM if (!IN6_IS_ADDR_V4MAPPED_ANY(&r_ent->rl_stickymask))
114310946SSangeeta.Misra@Sun.COM r_ent->rl_flags |= ILB_FLAGS_RULE_STICKY;
114410946SSangeeta.Misra@Sun.COM } else {
114510946SSangeeta.Misra@Sun.COM if (!IN6_IS_ADDR_UNSPECIFIED(&r_ent->rl_stickymask))
114610946SSangeeta.Misra@Sun.COM r_ent->rl_flags |= ILB_FLAGS_RULE_STICKY;
114710946SSangeeta.Misra@Sun.COM }
114810946SSangeeta.Misra@Sun.COM break;
114910946SSangeeta.Misra@Sun.COM case ILBD_RULE_SGNAME:
115010946SSangeeta.Misra@Sun.COM (void) strlcpy(r_ent->rl_sgname, valstr,
115110946SSangeeta.Misra@Sun.COM sizeof (r_ent->rl_sgname));
115210946SSangeeta.Misra@Sun.COM break;
115310946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCNAME:
115410946SSangeeta.Misra@Sun.COM (void) strlcpy(r_ent->rl_hcname, valstr,
115510946SSangeeta.Misra@Sun.COM sizeof (r_ent->rl_hcname));
115610946SSangeeta.Misra@Sun.COM break;
115710946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCPORT:
115810946SSangeeta.Misra@Sun.COM r_ent->rl_hcport = valint;
115910946SSangeeta.Misra@Sun.COM break;
116010946SSangeeta.Misra@Sun.COM case ILBD_RULE_HCPFLAG:
116110946SSangeeta.Misra@Sun.COM r_ent->rl_hcpflag = valint;
116210946SSangeeta.Misra@Sun.COM break;
116310946SSangeeta.Misra@Sun.COM case ILBD_RULE_DRAINTIME:
116410946SSangeeta.Misra@Sun.COM r_ent->rl_conndrain = valint;
116510946SSangeeta.Misra@Sun.COM break;
116610946SSangeeta.Misra@Sun.COM case ILBD_RULE_NAT_TO:
116710946SSangeeta.Misra@Sun.COM r_ent->rl_nat_timeout = valint;
116810946SSangeeta.Misra@Sun.COM break;
116910946SSangeeta.Misra@Sun.COM case ILBD_RULE_PERS_TO:
117010946SSangeeta.Misra@Sun.COM r_ent->rl_sticky_timeout = valint;
117110946SSangeeta.Misra@Sun.COM break;
117210946SSangeeta.Misra@Sun.COM
117310946SSangeeta.Misra@Sun.COM case ILBD_SG_SERVER: {
117410946SSangeeta.Misra@Sun.COM int svr_cnt = s_ent->sg_srvcount;
117510946SSangeeta.Misra@Sun.COM
117610946SSangeeta.Misra@Sun.COM /* found a new server, increase the svr count of this sg */
117710946SSangeeta.Misra@Sun.COM s_ent->sg_srvcount++;
117810946SSangeeta.Misra@Sun.COM
117910946SSangeeta.Misra@Sun.COM /*
118010946SSangeeta.Misra@Sun.COM * valstr contains information of one server in the servergroup
118110946SSangeeta.Misra@Sun.COM * valstr is in the format of "ip:minport-maxport:enable"
118210946SSangeeta.Misra@Sun.COM */
118310946SSangeeta.Misra@Sun.COM s_ent = realloc(s_ent, sizeof (ilb_sg_info_t) +
118410946SSangeeta.Misra@Sun.COM s_ent->sg_srvcount * sizeof (ilb_sg_srv_t));
118510946SSangeeta.Misra@Sun.COM
118610946SSangeeta.Misra@Sun.COM /* sgs_srvID is the sg name, leave it blank */
118710946SSangeeta.Misra@Sun.COM /*
118810946SSangeeta.Misra@Sun.COM * sgs_id is the digit in propname, propname is in a format of
118910946SSangeeta.Misra@Sun.COM * "server" + the digital serverID. We get the serverID by
119010946SSangeeta.Misra@Sun.COM * reading from the 7th char of propname.
119110946SSangeeta.Misra@Sun.COM */
119210946SSangeeta.Misra@Sun.COM s_ent->sg_servers[svr_cnt].sgs_id = atoi(&propname[6]);
119310946SSangeeta.Misra@Sun.COM
119410946SSangeeta.Misra@Sun.COM ilbd_get_svr_field(valstr,
119510946SSangeeta.Misra@Sun.COM &s_ent->sg_servers[svr_cnt].sgs_addr,
119610946SSangeeta.Misra@Sun.COM &s_ent->sg_servers[svr_cnt].sgs_minport,
119710946SSangeeta.Misra@Sun.COM &s_ent->sg_servers[svr_cnt].sgs_maxport,
119810946SSangeeta.Misra@Sun.COM &s_ent->sg_servers[svr_cnt].sgs_flags);
119910946SSangeeta.Misra@Sun.COM ilb_data->sg_data = s_ent;
120010946SSangeeta.Misra@Sun.COM
120110946SSangeeta.Misra@Sun.COM break;
120210946SSangeeta.Misra@Sun.COM }
120310946SSangeeta.Misra@Sun.COM case ILBD_HC_TEST:
120410946SSangeeta.Misra@Sun.COM (void) strlcpy(h_ent->hci_test, valstr,
120510946SSangeeta.Misra@Sun.COM sizeof (h_ent->hci_test));
120610946SSangeeta.Misra@Sun.COM break;
120710946SSangeeta.Misra@Sun.COM case ILBD_HC_TIMEOUT:
120810946SSangeeta.Misra@Sun.COM h_ent->hci_timeout = valint;
120910946SSangeeta.Misra@Sun.COM break;
121010946SSangeeta.Misra@Sun.COM case ILBD_HC_INTERVAL:
121110946SSangeeta.Misra@Sun.COM h_ent->hci_interval = valint;
121210946SSangeeta.Misra@Sun.COM break;
121310946SSangeeta.Misra@Sun.COM case ILBD_HC_DEF_PING:
121410946SSangeeta.Misra@Sun.COM h_ent->hci_def_ping = valbool;
121510946SSangeeta.Misra@Sun.COM break;
121610946SSangeeta.Misra@Sun.COM case ILBD_HC_COUNT:
121710946SSangeeta.Misra@Sun.COM h_ent->hci_count = valint;
121810946SSangeeta.Misra@Sun.COM break;
121910946SSangeeta.Misra@Sun.COM case ILBD_VAR_INVALID:
122010946SSangeeta.Misra@Sun.COM /*
122110946SSangeeta.Misra@Sun.COM * An empty server group is represented by an invalid
122210946SSangeeta.Misra@Sun.COM * SCF property. So when loading a server group, this
122310946SSangeeta.Misra@Sun.COM * case can be hit. But it should happen only for this
122410946SSangeeta.Misra@Sun.COM * single case. So if it happens in another case, move
122510946SSangeeta.Misra@Sun.COM * the service into maintenance mode.
122610946SSangeeta.Misra@Sun.COM */
122710946SSangeeta.Misra@Sun.COM if (pg_type != ILBD_SCF_SG || scf_type != SCF_TYPE_ASTRING) {
122810946SSangeeta.Misra@Sun.COM logerr("%s: invalid ilb type", __func__);
122910946SSangeeta.Misra@Sun.COM (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE);
123010946SSangeeta.Misra@Sun.COM } else {
123110946SSangeeta.Misra@Sun.COM logdebug("%s: invalid ilb type", __func__);
123210946SSangeeta.Misra@Sun.COM }
123310946SSangeeta.Misra@Sun.COM break;
123410946SSangeeta.Misra@Sun.COM }
123510946SSangeeta.Misra@Sun.COM
1236*12857SSangeeta.Misra@Sun.COM free(valstr);
123710946SSangeeta.Misra@Sun.COM return (ret);
123810946SSangeeta.Misra@Sun.COM }
123910946SSangeeta.Misra@Sun.COM
124010946SSangeeta.Misra@Sun.COM static ilbd_var_type_t
ilbd_name_to_valtype(const char * prop_name)124110946SSangeeta.Misra@Sun.COM ilbd_name_to_valtype(const char *prop_name)
124210946SSangeeta.Misra@Sun.COM {
124310946SSangeeta.Misra@Sun.COM int i;
124410946SSangeeta.Misra@Sun.COM
124510946SSangeeta.Misra@Sun.COM for (i = 0; i < ILBD_PROP_VAR_NUM; i++)
124610946SSangeeta.Misra@Sun.COM if (strncmp(prop_name, prop_tbl[i].scf_propname,
124710946SSangeeta.Misra@Sun.COM strlen(prop_tbl[i].scf_propname)) == 0)
124810946SSangeeta.Misra@Sun.COM return (prop_tbl[i].val_type);
124910946SSangeeta.Misra@Sun.COM
125010946SSangeeta.Misra@Sun.COM logdebug("ilbd_name_to_valtype: couldn't find prop %s", prop_name);
125110946SSangeeta.Misra@Sun.COM return (ILBD_VAR_INVALID);
125210946SSangeeta.Misra@Sun.COM }
125310946SSangeeta.Misra@Sun.COM
125410946SSangeeta.Misra@Sun.COM /* callback for pg_walk_prop, arg is ilbd_data_t */
125510946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_load_prop(scf_propertygroup_t * pg,const char * prop_name,void * arg)125610946SSangeeta.Misra@Sun.COM ilbd_scf_load_prop(scf_propertygroup_t *pg, const char *prop_name, void *arg)
125710946SSangeeta.Misra@Sun.COM {
125810946SSangeeta.Misra@Sun.COM scf_handle_t *h;
125910946SSangeeta.Misra@Sun.COM scf_value_t *val;
126010946SSangeeta.Misra@Sun.COM ilb_status_t ret;
126110946SSangeeta.Misra@Sun.COM ilbd_data_t *ilb_data = (ilbd_data_t *)arg;
126210946SSangeeta.Misra@Sun.COM ilbd_var_type_t val_type = ilbd_name_to_valtype(prop_name);
126310946SSangeeta.Misra@Sun.COM
126410946SSangeeta.Misra@Sun.COM h = scf_pg_handle(pg);
126510946SSangeeta.Misra@Sun.COM if (h == NULL)
126610946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
126710946SSangeeta.Misra@Sun.COM
126810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_prop_val(pg, prop_name, &val);
126910946SSangeeta.Misra@Sun.COM if (ret == ILB_STATUS_ENOENT)
127010946SSangeeta.Misra@Sun.COM return (ILB_STATUS_OK);
127110946SSangeeta.Misra@Sun.COM else if (ret != ILB_STATUS_OK)
127210946SSangeeta.Misra@Sun.COM return (ret);
127310946SSangeeta.Misra@Sun.COM
127410946SSangeeta.Misra@Sun.COM /*
127510946SSangeeta.Misra@Sun.COM * Load value to ilb_data.
127610946SSangeeta.Misra@Sun.COM */
127710946SSangeeta.Misra@Sun.COM ret = ilbd_scfval_to_data(prop_name, val_type, val, ilb_data);
127810946SSangeeta.Misra@Sun.COM
127910946SSangeeta.Misra@Sun.COM out:
128010946SSangeeta.Misra@Sun.COM if (val != NULL)
128110946SSangeeta.Misra@Sun.COM scf_value_destroy(val);
128210946SSangeeta.Misra@Sun.COM
128310946SSangeeta.Misra@Sun.COM return (ret);
128410946SSangeeta.Misra@Sun.COM }
128510946SSangeeta.Misra@Sun.COM
128610946SSangeeta.Misra@Sun.COM /*
128710946SSangeeta.Misra@Sun.COM * walk properties in one prop group, arg is ilbd_data
128810946SSangeeta.Misra@Sun.COM * cb is ilbd_scf_load_prop()
128910946SSangeeta.Misra@Sun.COM */
129010946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_pg_walk_props(scf_propertygroup_t * pg,ilb_status_t (* cb)(scf_propertygroup_t *,const char *,void *),void * arg)129110946SSangeeta.Misra@Sun.COM ilbd_scf_pg_walk_props(scf_propertygroup_t *pg,
129210946SSangeeta.Misra@Sun.COM ilb_status_t (*cb)(scf_propertygroup_t *, const char *, void *),
129310946SSangeeta.Misra@Sun.COM void *arg)
129410946SSangeeta.Misra@Sun.COM {
129510946SSangeeta.Misra@Sun.COM scf_handle_t *h;
129610946SSangeeta.Misra@Sun.COM scf_iter_t *propiter;
129710946SSangeeta.Misra@Sun.COM scf_property_t *prop;
129810946SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
1299*12857SSangeeta.Misra@Sun.COM char *prop_name = NULL;
130010946SSangeeta.Misra@Sun.COM ilb_status_t ret = ILB_STATUS_OK;
130110946SSangeeta.Misra@Sun.COM int scf_ret = -1;
130210946SSangeeta.Misra@Sun.COM
130310946SSangeeta.Misra@Sun.COM h = scf_pg_handle(pg);
130410946SSangeeta.Misra@Sun.COM if (h == NULL)
130510946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
130610946SSangeeta.Misra@Sun.COM
130710946SSangeeta.Misra@Sun.COM prop = scf_property_create(h);
130810946SSangeeta.Misra@Sun.COM propiter = scf_iter_create(h);
130910946SSangeeta.Misra@Sun.COM if (prop == NULL || propiter == NULL)
131010946SSangeeta.Misra@Sun.COM goto out;
131110946SSangeeta.Misra@Sun.COM
131210946SSangeeta.Misra@Sun.COM if (scf_iter_pg_properties(propiter, pg) != 0)
131310946SSangeeta.Misra@Sun.COM goto out;
131410946SSangeeta.Misra@Sun.COM
1315*12857SSangeeta.Misra@Sun.COM if ((prop_name = malloc(scf_name_len)) == NULL) {
1316*12857SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
1317*12857SSangeeta.Misra@Sun.COM goto out;
1318*12857SSangeeta.Misra@Sun.COM }
131910946SSangeeta.Misra@Sun.COM while ((scf_ret = scf_iter_next_property(propiter, prop)) == 1) {
1320*12857SSangeeta.Misra@Sun.COM if (scf_property_get_name(prop, prop_name, scf_name_len)
132110946SSangeeta.Misra@Sun.COM < 0) {
132210946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
132310946SSangeeta.Misra@Sun.COM goto out;
132410946SSangeeta.Misra@Sun.COM }
132510946SSangeeta.Misra@Sun.COM ret = cb(pg, prop_name, arg);
132610946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
132710946SSangeeta.Misra@Sun.COM break;
132810946SSangeeta.Misra@Sun.COM }
132910946SSangeeta.Misra@Sun.COM out:
1330*12857SSangeeta.Misra@Sun.COM if (prop_name != NULL)
1331*12857SSangeeta.Misra@Sun.COM free(prop_name);
133210946SSangeeta.Misra@Sun.COM if (scf_ret == -1)
133310946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
133410946SSangeeta.Misra@Sun.COM if (prop != NULL)
133510946SSangeeta.Misra@Sun.COM scf_property_destroy(prop);
133610946SSangeeta.Misra@Sun.COM if (propiter != NULL)
133710946SSangeeta.Misra@Sun.COM scf_iter_destroy(propiter);
133810946SSangeeta.Misra@Sun.COM
133910946SSangeeta.Misra@Sun.COM return (ret);
134010946SSangeeta.Misra@Sun.COM }
134110946SSangeeta.Misra@Sun.COM
134210946SSangeeta.Misra@Sun.COM /* cbs are libd_create_X */
134310946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbd_scf_instance_walk_pg(scf_instance_t * inst,ilbd_scf_pg_type_t pg_type,ilb_status_t (* cb)(void *,int,struct passwd *,ucred_t *),void * arg1,void * arg2)134410946SSangeeta.Misra@Sun.COM ilbd_scf_instance_walk_pg(scf_instance_t *inst,
134510946SSangeeta.Misra@Sun.COM ilbd_scf_pg_type_t pg_type,
134610946SSangeeta.Misra@Sun.COM ilb_status_t (*cb)(void *, int, struct passwd *, ucred_t *),
134710946SSangeeta.Misra@Sun.COM void *arg1, void *arg2)
134810946SSangeeta.Misra@Sun.COM {
134910946SSangeeta.Misra@Sun.COM int scf_ret;
135010946SSangeeta.Misra@Sun.COM ilb_status_t ret;
135110946SSangeeta.Misra@Sun.COM scf_handle_t *h;
135210946SSangeeta.Misra@Sun.COM scf_iter_t *pgiter;
135310946SSangeeta.Misra@Sun.COM scf_propertygroup_t *newpg;
135410946SSangeeta.Misra@Sun.COM int port = *((int *)arg1);
1355*12857SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
1356*12857SSangeeta.Misra@Sun.COM char *pg_name = NULL;
135710946SSangeeta.Misra@Sun.COM
135810946SSangeeta.Misra@Sun.COM if (inst == NULL)
135910946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
136010946SSangeeta.Misra@Sun.COM
136110946SSangeeta.Misra@Sun.COM h = scf_instance_handle(inst);
136210946SSangeeta.Misra@Sun.COM if (h == NULL)
136310946SSangeeta.Misra@Sun.COM return (ILB_STATUS_EINVAL);
136410946SSangeeta.Misra@Sun.COM
136510946SSangeeta.Misra@Sun.COM if ((newpg = scf_pg_create(h)) == NULL)
136610946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
136710946SSangeeta.Misra@Sun.COM
136810946SSangeeta.Misra@Sun.COM if ((pgiter = scf_iter_create(h)) == NULL) {
136910946SSangeeta.Misra@Sun.COM scf_pg_destroy(newpg);
137010946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
137110946SSangeeta.Misra@Sun.COM }
137210946SSangeeta.Misra@Sun.COM
137310946SSangeeta.Misra@Sun.COM if ((scf_ret = scf_iter_instance_pgs(pgiter, inst)) < 0)
137410946SSangeeta.Misra@Sun.COM goto out;
137510946SSangeeta.Misra@Sun.COM
1376*12857SSangeeta.Misra@Sun.COM if ((pg_name = malloc(scf_name_len)) == NULL) {
1377*12857SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
1378*12857SSangeeta.Misra@Sun.COM goto out;
1379*12857SSangeeta.Misra@Sun.COM }
138010946SSangeeta.Misra@Sun.COM while ((scf_ret = scf_iter_next_pg(pgiter, newpg)) > 0) {
138110946SSangeeta.Misra@Sun.COM ilbd_data_t data;
138210946SSangeeta.Misra@Sun.COM
1383*12857SSangeeta.Misra@Sun.COM if (scf_pg_get_name(newpg, pg_name, scf_name_len) < 0) {
138410946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
138510946SSangeeta.Misra@Sun.COM goto out;
138610946SSangeeta.Misra@Sun.COM }
138710946SSangeeta.Misra@Sun.COM
138810946SSangeeta.Misra@Sun.COM /*
138910946SSangeeta.Misra@Sun.COM * if pg name indicates it's a ilb configuration, walk its prop
139010946SSangeeta.Misra@Sun.COM */
139110946SSangeeta.Misra@Sun.COM data.pg_type = pg_type;
139210946SSangeeta.Misra@Sun.COM data.hc_data = NULL;
139310946SSangeeta.Misra@Sun.COM data.sg_data = NULL;
139410946SSangeeta.Misra@Sun.COM data.rule_data = NULL;
139510946SSangeeta.Misra@Sun.COM
139610946SSangeeta.Misra@Sun.COM switch (pg_type) {
139710946SSangeeta.Misra@Sun.COM case ILBD_SCF_RULE:
139810946SSangeeta.Misra@Sun.COM if (strncmp(ILBD_PG_NAME_RULE, pg_name,
139910946SSangeeta.Misra@Sun.COM strlen(ILBD_PG_NAME_RULE)) == 0) {
140010946SSangeeta.Misra@Sun.COM data.rule_data = calloc(1,
140110946SSangeeta.Misra@Sun.COM sizeof (ilb_rule_info_t));
140210946SSangeeta.Misra@Sun.COM if (data.rule_data == NULL) {
140310946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
140410946SSangeeta.Misra@Sun.COM goto out;
140510946SSangeeta.Misra@Sun.COM }
140610946SSangeeta.Misra@Sun.COM ret = ilbd_scf_pg_walk_props(newpg,
140710946SSangeeta.Misra@Sun.COM ilbd_scf_load_prop, &data);
140810946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
140910946SSangeeta.Misra@Sun.COM goto out;
141010946SSangeeta.Misra@Sun.COM assert(data.rule_data != NULL);
141110946SSangeeta.Misra@Sun.COM /* set rule name */
141210946SSangeeta.Misra@Sun.COM (void) strlcpy(data.rule_data->rl_name,
141310946SSangeeta.Misra@Sun.COM &pg_name[strlen(ILBD_PG_NAME_RULE)],
141410946SSangeeta.Misra@Sun.COM sizeof (data.rule_data->rl_name));
141510946SSangeeta.Misra@Sun.COM
141610946SSangeeta.Misra@Sun.COM ret = cb(data.rule_data, port, arg2, NULL);
141710946SSangeeta.Misra@Sun.COM free(data.rule_data);
141810946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
141910946SSangeeta.Misra@Sun.COM goto out;
142010946SSangeeta.Misra@Sun.COM }
142110946SSangeeta.Misra@Sun.COM break;
142210946SSangeeta.Misra@Sun.COM case ILBD_SCF_SG:
142310946SSangeeta.Misra@Sun.COM if (strncmp(ILBD_PG_NAME_SG, pg_name,
142410946SSangeeta.Misra@Sun.COM strlen(ILBD_PG_NAME_SG)) == 0) {
142510946SSangeeta.Misra@Sun.COM data.sg_data = calloc(1,
142610946SSangeeta.Misra@Sun.COM sizeof (ilb_sg_info_t));
1427*12857SSangeeta.Misra@Sun.COM if (data.sg_data == NULL) {
1428*12857SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
1429*12857SSangeeta.Misra@Sun.COM goto out;
1430*12857SSangeeta.Misra@Sun.COM }
143110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_pg_walk_props(newpg,
143210946SSangeeta.Misra@Sun.COM ilbd_scf_load_prop, &data);
143310946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
143410946SSangeeta.Misra@Sun.COM free(data.sg_data);
143510946SSangeeta.Misra@Sun.COM goto out;
143610946SSangeeta.Misra@Sun.COM }
143710946SSangeeta.Misra@Sun.COM assert(data.sg_data != NULL);
143810946SSangeeta.Misra@Sun.COM /* set sg name */
143910946SSangeeta.Misra@Sun.COM (void) strlcpy(data.sg_data->sg_name,
144010946SSangeeta.Misra@Sun.COM &pg_name[strlen(ILBD_PG_NAME_SG)],
144110946SSangeeta.Misra@Sun.COM sizeof (data.sg_data->sg_name));
144210946SSangeeta.Misra@Sun.COM ret = cb(data.sg_data, port, arg2, NULL);
144310946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
144410946SSangeeta.Misra@Sun.COM free(data.sg_data);
144510946SSangeeta.Misra@Sun.COM goto out;
144610946SSangeeta.Misra@Sun.COM }
144710946SSangeeta.Misra@Sun.COM /*
144810946SSangeeta.Misra@Sun.COM * create a servergroup is two-step operation.
144910946SSangeeta.Misra@Sun.COM * 1. create an empty servergroup.
145010946SSangeeta.Misra@Sun.COM * 2. add server(s) to the group.
145110946SSangeeta.Misra@Sun.COM *
145210946SSangeeta.Misra@Sun.COM * since we are here from:
145310946SSangeeta.Misra@Sun.COM * main_loop()->ilbd_read_config()->
145410946SSangeeta.Misra@Sun.COM * ilbd_walk_sg_pgs()
145510946SSangeeta.Misra@Sun.COM * there is no cli to send. So in this
145610946SSangeeta.Misra@Sun.COM * path auditing will skip the
145710946SSangeeta.Misra@Sun.COM * adt_set_from_ucred() check
145810946SSangeeta.Misra@Sun.COM */
145910946SSangeeta.Misra@Sun.COM if (data.sg_data->sg_srvcount > 0) {
146010946SSangeeta.Misra@Sun.COM ret = ilbd_add_server_to_group(
146110946SSangeeta.Misra@Sun.COM data.sg_data, port, NULL, NULL);
146210946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK) {
146310946SSangeeta.Misra@Sun.COM free(data.sg_data);
146410946SSangeeta.Misra@Sun.COM goto out;
146510946SSangeeta.Misra@Sun.COM }
146610946SSangeeta.Misra@Sun.COM free(data.sg_data);
146710946SSangeeta.Misra@Sun.COM }
146810946SSangeeta.Misra@Sun.COM }
146910946SSangeeta.Misra@Sun.COM break;
147010946SSangeeta.Misra@Sun.COM case ILBD_SCF_HC:
147110946SSangeeta.Misra@Sun.COM if (strncmp(ILBD_PG_NAME_HC, pg_name,
147210946SSangeeta.Misra@Sun.COM strlen(ILBD_PG_NAME_HC)) == 0) {
147310946SSangeeta.Misra@Sun.COM data.hc_data = calloc(1,
147410946SSangeeta.Misra@Sun.COM sizeof (ilb_hc_info_t));
1475*12857SSangeeta.Misra@Sun.COM if (data.hc_data == NULL) {
1476*12857SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
1477*12857SSangeeta.Misra@Sun.COM goto out;
1478*12857SSangeeta.Misra@Sun.COM }
147910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_pg_walk_props(newpg,
148010946SSangeeta.Misra@Sun.COM ilbd_scf_load_prop, &data);
148110946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
148210946SSangeeta.Misra@Sun.COM goto out;
148310946SSangeeta.Misra@Sun.COM assert(data.hc_data != NULL);
148410946SSangeeta.Misra@Sun.COM /* set hc name */
148510946SSangeeta.Misra@Sun.COM (void) strlcpy(data.hc_data->hci_name,
148610946SSangeeta.Misra@Sun.COM &pg_name[strlen(ILBD_PG_NAME_HC)],
148710946SSangeeta.Misra@Sun.COM sizeof (data.hc_data->hci_name));
148810946SSangeeta.Misra@Sun.COM ret = cb(data.hc_data, port, arg2, NULL);
148910946SSangeeta.Misra@Sun.COM free(data.hc_data);
149010946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
149110946SSangeeta.Misra@Sun.COM goto out;
149210946SSangeeta.Misra@Sun.COM }
149310946SSangeeta.Misra@Sun.COM break;
149410946SSangeeta.Misra@Sun.COM }
149510946SSangeeta.Misra@Sun.COM }
149610946SSangeeta.Misra@Sun.COM
149710946SSangeeta.Misra@Sun.COM out:
1498*12857SSangeeta.Misra@Sun.COM if (pg_name != NULL)
1499*12857SSangeeta.Misra@Sun.COM free(pg_name);
150010946SSangeeta.Misra@Sun.COM if (scf_ret < 0)
150110946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
150210946SSangeeta.Misra@Sun.COM scf_pg_destroy(newpg);
150310946SSangeeta.Misra@Sun.COM scf_iter_destroy(pgiter);
150410946SSangeeta.Misra@Sun.COM return (ret);
150510946SSangeeta.Misra@Sun.COM }
150610946SSangeeta.Misra@Sun.COM
150710946SSangeeta.Misra@Sun.COM typedef ilb_status_t (*ilbd_scf_walker_fn)(void *, int, struct passwd *,
150810946SSangeeta.Misra@Sun.COM ucred_t *);
150910946SSangeeta.Misra@Sun.COM
151010946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_walk_rule_pgs(ilb_status_t (* func)(ilb_rule_info_t *,int,const struct passwd *,ucred_t *),void * arg1,void * arg2)151110946SSangeeta.Misra@Sun.COM ilbd_walk_rule_pgs(ilb_status_t (*func)(ilb_rule_info_t *, int,
151210946SSangeeta.Misra@Sun.COM const struct passwd *, ucred_t *), void *arg1, void *arg2)
151310946SSangeeta.Misra@Sun.COM {
151410946SSangeeta.Misra@Sun.COM scf_instance_t *inst;
151510946SSangeeta.Misra@Sun.COM scf_handle_t *h;
151610946SSangeeta.Misra@Sun.COM scf_service_t *svc;
151710946SSangeeta.Misra@Sun.COM ilb_status_t ret;
151810946SSangeeta.Misra@Sun.COM
151910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_inst(&h, &svc, &inst);
152010946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
152110946SSangeeta.Misra@Sun.COM return (ret);
152210946SSangeeta.Misra@Sun.COM
152310946SSangeeta.Misra@Sun.COM /* get rule prop group, transfer it to ilb_lrule_info_t */
152410946SSangeeta.Misra@Sun.COM ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_RULE,
152510946SSangeeta.Misra@Sun.COM (ilbd_scf_walker_fn)func, arg1, arg2);
152610946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, svc, inst, NULL);
152710946SSangeeta.Misra@Sun.COM return (ret);
152810946SSangeeta.Misra@Sun.COM }
152910946SSangeeta.Misra@Sun.COM
153010946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_walk_sg_pgs(ilb_status_t (* func)(ilb_sg_info_t *,int,const struct passwd *,ucred_t *),void * arg1,void * arg2)153110946SSangeeta.Misra@Sun.COM ilbd_walk_sg_pgs(ilb_status_t (*func)(ilb_sg_info_t *, int,
153210946SSangeeta.Misra@Sun.COM const struct passwd *, ucred_t *), void *arg1, void *arg2)
153310946SSangeeta.Misra@Sun.COM {
153410946SSangeeta.Misra@Sun.COM scf_instance_t *inst;
153510946SSangeeta.Misra@Sun.COM scf_handle_t *h;
153610946SSangeeta.Misra@Sun.COM scf_service_t *svc;
153710946SSangeeta.Misra@Sun.COM ilb_status_t ret;
153810946SSangeeta.Misra@Sun.COM
153910946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_inst(&h, &svc, &inst);
154010946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
154110946SSangeeta.Misra@Sun.COM return (ret);
154210946SSangeeta.Misra@Sun.COM
154310946SSangeeta.Misra@Sun.COM ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_SG,
154410946SSangeeta.Misra@Sun.COM (ilbd_scf_walker_fn)func, arg1, arg2);
154510946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, svc, inst, NULL);
154610946SSangeeta.Misra@Sun.COM return (ret);
154710946SSangeeta.Misra@Sun.COM }
154810946SSangeeta.Misra@Sun.COM
154910946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_walk_hc_pgs(ilb_status_t (* func)(const ilb_hc_info_t *,int,const struct passwd *,ucred_t *),void * arg1,void * arg2)155010946SSangeeta.Misra@Sun.COM ilbd_walk_hc_pgs(ilb_status_t (*func)(const ilb_hc_info_t *, int,
155110946SSangeeta.Misra@Sun.COM const struct passwd *, ucred_t *), void *arg1, void *arg2)
155210946SSangeeta.Misra@Sun.COM {
155310946SSangeeta.Misra@Sun.COM scf_instance_t *inst;
155410946SSangeeta.Misra@Sun.COM scf_handle_t *h;
155510946SSangeeta.Misra@Sun.COM scf_service_t *svc;
155610946SSangeeta.Misra@Sun.COM ilb_status_t ret;
155710946SSangeeta.Misra@Sun.COM
155810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_get_inst(&h, &svc, &inst);
155910946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_OK)
156010946SSangeeta.Misra@Sun.COM return (ret);
156110946SSangeeta.Misra@Sun.COM
156210946SSangeeta.Misra@Sun.COM ret = ilbd_scf_instance_walk_pg(inst, ILBD_SCF_HC,
156310946SSangeeta.Misra@Sun.COM (ilbd_scf_walker_fn)func, arg1, arg2);
156410946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, svc, inst, NULL);
156510946SSangeeta.Misra@Sun.COM return (ret);
156610946SSangeeta.Misra@Sun.COM }
156710946SSangeeta.Misra@Sun.COM
156810946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_change_prop(ilbd_scf_pg_type_t pg_type,const char * pg_name,const char * prop_name,void * new_val)156910946SSangeeta.Misra@Sun.COM ilbd_change_prop(ilbd_scf_pg_type_t pg_type, const char *pg_name,
157010946SSangeeta.Misra@Sun.COM const char *prop_name, void *new_val)
157110946SSangeeta.Misra@Sun.COM {
157210946SSangeeta.Misra@Sun.COM int ret;
157310946SSangeeta.Misra@Sun.COM scf_propertygroup_t *scfpg = NULL;
1574*12857SSangeeta.Misra@Sun.COM char *scf_pgname = NULL;
157510946SSangeeta.Misra@Sun.COM scf_type_t scftype;
157610946SSangeeta.Misra@Sun.COM scf_value_t *scfval;
157710946SSangeeta.Misra@Sun.COM scf_handle_t *h;
157810946SSangeeta.Misra@Sun.COM
1579*12857SSangeeta.Misra@Sun.COM if ((scf_pgname = malloc(ILBD_MAX_NAME_LEN)) == NULL)
1580*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
158110946SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(pg_type, pg_name, scf_pgname);
158210946SSangeeta.Misra@Sun.COM ret = ilbd_scf_retrieve_pg(scf_pgname, &scfpg, B_FALSE);
1583*12857SSangeeta.Misra@Sun.COM free(scf_pgname);
1584*12857SSangeeta.Misra@Sun.COM
158510946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_EEXIST)
158610946SSangeeta.Misra@Sun.COM return (ret);
158710946SSangeeta.Misra@Sun.COM
158810946SSangeeta.Misra@Sun.COM assert(scfpg != NULL);
158910946SSangeeta.Misra@Sun.COM
159010946SSangeeta.Misra@Sun.COM h = scf_pg_handle(scfpg);
159110946SSangeeta.Misra@Sun.COM if (h == NULL) {
159210946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_EINVAL;
159310946SSangeeta.Misra@Sun.COM goto done;
159410946SSangeeta.Misra@Sun.COM }
159510946SSangeeta.Misra@Sun.COM
159610946SSangeeta.Misra@Sun.COM if ((scfval = scf_value_create(h)) == NULL) {
159710946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_ENOMEM;
159810946SSangeeta.Misra@Sun.COM goto done;
159910946SSangeeta.Misra@Sun.COM }
160010946SSangeeta.Misra@Sun.COM
160110946SSangeeta.Misra@Sun.COM if (pg_type == ILBD_SCF_RULE) {
160210946SSangeeta.Misra@Sun.COM scftype = SCF_TYPE_BOOLEAN;
160310946SSangeeta.Misra@Sun.COM scf_value_set_boolean(scfval, *(boolean_t *)new_val);
160410946SSangeeta.Misra@Sun.COM } else if (pg_type == ILBD_SCF_SG) {
160510946SSangeeta.Misra@Sun.COM scftype = SCF_TYPE_ASTRING;
160610946SSangeeta.Misra@Sun.COM (void) scf_value_set_astring(scfval, (char *)new_val);
160710946SSangeeta.Misra@Sun.COM }
160810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_set_prop(scfpg, prop_name, scftype, scfval);
160910946SSangeeta.Misra@Sun.COM
161010946SSangeeta.Misra@Sun.COM done:
161110946SSangeeta.Misra@Sun.COM if (scf_pg_handle(scfpg) != NULL)
161210946SSangeeta.Misra@Sun.COM scf_handle_destroy(scf_pg_handle(scfpg));
161310946SSangeeta.Misra@Sun.COM if (scfpg != NULL)
161410946SSangeeta.Misra@Sun.COM scf_pg_destroy(scfpg);
161510946SSangeeta.Misra@Sun.COM if (scfval != NULL)
161610946SSangeeta.Misra@Sun.COM scf_value_destroy(scfval);
161710946SSangeeta.Misra@Sun.COM return (ret);
161810946SSangeeta.Misra@Sun.COM }
161910946SSangeeta.Misra@Sun.COM
162010946SSangeeta.Misra@Sun.COM /*
162110946SSangeeta.Misra@Sun.COM * Update the persistent configuration with a new server, srv, added to a
162210946SSangeeta.Misra@Sun.COM * server group, sg.
162310946SSangeeta.Misra@Sun.COM */
162410946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_scf_add_srv(ilbd_sg_t * sg,ilbd_srv_t * srv)162510946SSangeeta.Misra@Sun.COM ilbd_scf_add_srv(ilbd_sg_t *sg, ilbd_srv_t *srv)
162610946SSangeeta.Misra@Sun.COM {
162710946SSangeeta.Misra@Sun.COM scf_propertygroup_t *pg;
162810946SSangeeta.Misra@Sun.COM scf_handle_t *h;
162910946SSangeeta.Misra@Sun.COM scf_value_t *val;
163010946SSangeeta.Misra@Sun.COM ilb_status_t ret;
163110946SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
1632*12857SSangeeta.Misra@Sun.COM char *buf = NULL;
1633*12857SSangeeta.Misra@Sun.COM
1634*12857SSangeeta.Misra@Sun.COM if ((buf = malloc(scf_name_len)) == NULL)
1635*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
163610946SSangeeta.Misra@Sun.COM
163710946SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(ILBD_SCF_SG, sg->isg_name, buf);
163810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_retrieve_pg(buf, &pg, B_FALSE);
163910946SSangeeta.Misra@Sun.COM /*
164010946SSangeeta.Misra@Sun.COM * The server group does not exist in persistent storage. This
164110946SSangeeta.Misra@Sun.COM * cannot happen. Should probably transition the service to
164210946SSangeeta.Misra@Sun.COM * maintenance since it should be there.
164310946SSangeeta.Misra@Sun.COM */
164410946SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_EEXIST) {
164510946SSangeeta.Misra@Sun.COM logerr("ilbd_scf_add_srv: SCF update failed - entering"
164610946SSangeeta.Misra@Sun.COM " maintenance mode");
164710946SSangeeta.Misra@Sun.COM (void) smf_maintain_instance(ILB_FMRI, SMF_IMMEDIATE);
1648*12857SSangeeta.Misra@Sun.COM free(buf);
164910946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
165010946SSangeeta.Misra@Sun.COM }
165110946SSangeeta.Misra@Sun.COM
165210946SSangeeta.Misra@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) {
165310946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(NULL, NULL, NULL, pg);
1654*12857SSangeeta.Misra@Sun.COM free(buf);
165510946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
165610946SSangeeta.Misra@Sun.COM }
165710946SSangeeta.Misra@Sun.COM
165810946SSangeeta.Misra@Sun.COM if ((val = scf_value_create(h)) == NULL) {
165910946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, NULL, NULL, pg);
1660*12857SSangeeta.Misra@Sun.COM free(buf);
166110946SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
166210946SSangeeta.Misra@Sun.COM }
166310946SSangeeta.Misra@Sun.COM ilbd_srv_scf_val(srv, buf);
166410946SSangeeta.Misra@Sun.COM (void) scf_value_set_astring(val, buf);
166510946SSangeeta.Misra@Sun.COM
1666*12857SSangeeta.Misra@Sun.COM (void) snprintf(buf, scf_name_len, "server%d", srv->isv_id);
1667*12857SSangeeta.Misra@Sun.COM ret = ilbd_scf_set_prop(pg, buf, SCF_TYPE_ASTRING, val);
1668*12857SSangeeta.Misra@Sun.COM free(buf);
166910946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, NULL, NULL, pg);
167010946SSangeeta.Misra@Sun.COM scf_value_destroy(val);
167110946SSangeeta.Misra@Sun.COM
167210946SSangeeta.Misra@Sun.COM return (ret);
167310946SSangeeta.Misra@Sun.COM }
167410946SSangeeta.Misra@Sun.COM
167510946SSangeeta.Misra@Sun.COM /*
167610946SSangeeta.Misra@Sun.COM * Delete a server, srv, of a server group, sg, from the persistent
167710946SSangeeta.Misra@Sun.COM * configuration.
167810946SSangeeta.Misra@Sun.COM */
167910946SSangeeta.Misra@Sun.COM ilb_status_t
ilbd_scf_del_srv(ilbd_sg_t * sg,ilbd_srv_t * srv)168010946SSangeeta.Misra@Sun.COM ilbd_scf_del_srv(ilbd_sg_t *sg, ilbd_srv_t *srv)
168110946SSangeeta.Misra@Sun.COM {
168210946SSangeeta.Misra@Sun.COM ilb_status_t ret;
168310946SSangeeta.Misra@Sun.COM scf_propertygroup_t *pg;
168410946SSangeeta.Misra@Sun.COM scf_handle_t *h;
168510946SSangeeta.Misra@Sun.COM int scf_name_len = ILBD_MAX_NAME_LEN;
1686*12857SSangeeta.Misra@Sun.COM char *buf;
168710946SSangeeta.Misra@Sun.COM scf_transaction_t *tx = NULL;
168810946SSangeeta.Misra@Sun.COM scf_transaction_entry_t *entry = NULL;
168910946SSangeeta.Misra@Sun.COM
1690*12857SSangeeta.Misra@Sun.COM if ((buf = malloc(scf_name_len)) == NULL)
1691*12857SSangeeta.Misra@Sun.COM return (ILB_STATUS_ENOMEM);
169210946SSangeeta.Misra@Sun.COM ilbd_name_to_scfpgname(ILBD_SCF_SG, sg->isg_name, buf);
169310946SSangeeta.Misra@Sun.COM ret = ilbd_scf_retrieve_pg(buf, &pg, B_FALSE);
169410946SSangeeta.Misra@Sun.COM /*
169510946SSangeeta.Misra@Sun.COM * The server group does not exist in persistent storage. This
169610946SSangeeta.Misra@Sun.COM * cannot happen. THe caller of this function puts service in
169710946SSangeeta.Misra@Sun.COM * maintenance mode.
169810946SSangeeta.Misra@Sun.COM */
1699*12857SSangeeta.Misra@Sun.COM if (ret != ILB_STATUS_EEXIST) {
1700*12857SSangeeta.Misra@Sun.COM free(buf);
170110946SSangeeta.Misra@Sun.COM return (ILB_STATUS_INTERNAL);
1702*12857SSangeeta.Misra@Sun.COM }
170310946SSangeeta.Misra@Sun.COM ret = ILB_STATUS_OK;
170410946SSangeeta.Misra@Sun.COM
170510946SSangeeta.Misra@Sun.COM if ((h = scf_pg_handle(pg)) == NULL) {
170610946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_del_srv: scf_pg_handle: %s\n",
170710946SSangeeta.Misra@Sun.COM scf_strerror(scf_error()));
170810946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(NULL, NULL, NULL, pg);
1709*12857SSangeeta.Misra@Sun.COM free(buf);
171010946SSangeeta.Misra@Sun.COM return (ilbd_scf_err_to_ilb_err());
171110946SSangeeta.Misra@Sun.COM }
171210946SSangeeta.Misra@Sun.COM
171310946SSangeeta.Misra@Sun.COM if ((tx = scf_transaction_create(h)) == NULL ||
171410946SSangeeta.Misra@Sun.COM (entry = scf_entry_create(h)) == NULL) {
171510946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_del_srv: create scf transaction failed: "
171610946SSangeeta.Misra@Sun.COM "%s\n", scf_strerror(scf_error()));
171710946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
171810946SSangeeta.Misra@Sun.COM goto out;
171910946SSangeeta.Misra@Sun.COM }
172010946SSangeeta.Misra@Sun.COM
1721*12857SSangeeta.Misra@Sun.COM (void) snprintf(buf, scf_name_len, "server%d", srv->isv_id);
172210946SSangeeta.Misra@Sun.COM
172310946SSangeeta.Misra@Sun.COM if (scf_transaction_start(tx, pg) == -1) {
172410946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: start scf transaction failed: "
172510946SSangeeta.Misra@Sun.COM "%s\n", scf_strerror(scf_error()));
172610946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
172710946SSangeeta.Misra@Sun.COM goto out;
172810946SSangeeta.Misra@Sun.COM }
172910946SSangeeta.Misra@Sun.COM if (scf_transaction_property_delete(tx, entry, buf) == -1) {
173010946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: delete property failed: %s\n",
173110946SSangeeta.Misra@Sun.COM scf_strerror(scf_error()));
173210946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
173310946SSangeeta.Misra@Sun.COM goto out;
173410946SSangeeta.Misra@Sun.COM }
173510946SSangeeta.Misra@Sun.COM if (scf_transaction_commit(tx) != 1) {
173610946SSangeeta.Misra@Sun.COM logdebug("ilbd_scf_set_prop: commit transaction failed: %s\n",
173710946SSangeeta.Misra@Sun.COM scf_strerror(scf_error()));
173810946SSangeeta.Misra@Sun.COM ret = ilbd_scf_err_to_ilb_err();
173910946SSangeeta.Misra@Sun.COM }
174010946SSangeeta.Misra@Sun.COM
174110946SSangeeta.Misra@Sun.COM out:
1742*12857SSangeeta.Misra@Sun.COM free(buf);
174310946SSangeeta.Misra@Sun.COM if (entry != NULL)
174410946SSangeeta.Misra@Sun.COM scf_entry_destroy(entry);
174510946SSangeeta.Misra@Sun.COM if (tx != NULL)
174610946SSangeeta.Misra@Sun.COM scf_transaction_destroy(tx);
174710946SSangeeta.Misra@Sun.COM ilbd_scf_destroy(h, NULL, NULL, pg);
174810946SSangeeta.Misra@Sun.COM
174910946SSangeeta.Misra@Sun.COM return (ret);
175010946SSangeeta.Misra@Sun.COM }
1751