xref: /onnv-gate/usr/src/lib/libilb/common/ilb_sg.c (revision 10946:324bab2b3370)
1*10946SSangeeta.Misra@Sun.COM /*
2*10946SSangeeta.Misra@Sun.COM  * CDDL HEADER START
3*10946SSangeeta.Misra@Sun.COM  *
4*10946SSangeeta.Misra@Sun.COM  * The contents of this file are subject to the terms of the
5*10946SSangeeta.Misra@Sun.COM  * Common Development and Distribution License (the "License").
6*10946SSangeeta.Misra@Sun.COM  * You may not use this file except in compliance with the License.
7*10946SSangeeta.Misra@Sun.COM  *
8*10946SSangeeta.Misra@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10946SSangeeta.Misra@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*10946SSangeeta.Misra@Sun.COM  * See the License for the specific language governing permissions
11*10946SSangeeta.Misra@Sun.COM  * and limitations under the License.
12*10946SSangeeta.Misra@Sun.COM  *
13*10946SSangeeta.Misra@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*10946SSangeeta.Misra@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10946SSangeeta.Misra@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*10946SSangeeta.Misra@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*10946SSangeeta.Misra@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10946SSangeeta.Misra@Sun.COM  *
19*10946SSangeeta.Misra@Sun.COM  * CDDL HEADER END
20*10946SSangeeta.Misra@Sun.COM  */
21*10946SSangeeta.Misra@Sun.COM 
22*10946SSangeeta.Misra@Sun.COM /*
23*10946SSangeeta.Misra@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*10946SSangeeta.Misra@Sun.COM  * Use is subject to license terms.
25*10946SSangeeta.Misra@Sun.COM  */
26*10946SSangeeta.Misra@Sun.COM 
27*10946SSangeeta.Misra@Sun.COM #include <stdlib.h>
28*10946SSangeeta.Misra@Sun.COM #include <strings.h>
29*10946SSangeeta.Misra@Sun.COM #include <sys/types.h>
30*10946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
31*10946SSangeeta.Misra@Sun.COM #include <netinet/in.h>
32*10946SSangeeta.Misra@Sun.COM #include <stddef.h>
33*10946SSangeeta.Misra@Sun.COM #include <libilb_impl.h>
34*10946SSangeeta.Misra@Sun.COM #include <libilb.h>
35*10946SSangeeta.Misra@Sun.COM 
36*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_addrem_sg(ilb_handle_t h,const char * sgname,ilbd_cmd_t cmd)37*10946SSangeeta.Misra@Sun.COM i_ilb_addrem_sg(ilb_handle_t h, const char *sgname, ilbd_cmd_t cmd)
38*10946SSangeeta.Misra@Sun.COM {
39*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
40*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*ic;
41*10946SSangeeta.Misra@Sun.COM 	size_t		ic_sz;
42*10946SSangeeta.Misra@Sun.COM 
43*10946SSangeeta.Misra@Sun.COM 	if (h == ILB_INVALID_HANDLE || sgname == NULL || *sgname == '\0')
44*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
45*10946SSangeeta.Misra@Sun.COM 
46*10946SSangeeta.Misra@Sun.COM 	if (strlen(sgname) > ILB_SGNAME_SZ - 1)
47*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_NAMETOOLONG);
48*10946SSangeeta.Misra@Sun.COM 
49*10946SSangeeta.Misra@Sun.COM 	if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
50*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
51*10946SSangeeta.Misra@Sun.COM 
52*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy((char *)&ic->ic_data, sgname, sizeof (ilbd_name_t));
53*10946SSangeeta.Misra@Sun.COM 
54*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
55*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
56*10946SSangeeta.Misra@Sun.COM 		goto out;
57*10946SSangeeta.Misra@Sun.COM 
58*10946SSangeeta.Misra@Sun.COM 	if (ic->ic_cmd != ILBD_CMD_OK)
59*10946SSangeeta.Misra@Sun.COM 		rc = *(ilb_status_t *)&ic->ic_data;
60*10946SSangeeta.Misra@Sun.COM out:
61*10946SSangeeta.Misra@Sun.COM 	free(ic);
62*10946SSangeeta.Misra@Sun.COM 	return (rc);
63*10946SSangeeta.Misra@Sun.COM }
64*10946SSangeeta.Misra@Sun.COM 
65*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_destroy_servergroup(ilb_handle_t h,const char * sgname)66*10946SSangeeta.Misra@Sun.COM ilb_destroy_servergroup(ilb_handle_t h, const char *sgname)
67*10946SSangeeta.Misra@Sun.COM {
68*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_addrem_sg(h, sgname, ILBD_DESTROY_SERVERGROUP));
69*10946SSangeeta.Misra@Sun.COM }
70*10946SSangeeta.Misra@Sun.COM 
71*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_create_servergroup(ilb_handle_t h,const char * sgname)72*10946SSangeeta.Misra@Sun.COM ilb_create_servergroup(ilb_handle_t h, const char *sgname)
73*10946SSangeeta.Misra@Sun.COM {
74*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_addrem_sg(h, sgname, ILBD_CREATE_SERVERGROUP));
75*10946SSangeeta.Misra@Sun.COM }
76*10946SSangeeta.Misra@Sun.COM 
77*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_addrem_server_to_group(ilb_handle_t h,const char * sgname,ilb_server_data_t * srv,ilbd_cmd_t cmd)78*10946SSangeeta.Misra@Sun.COM i_ilb_addrem_server_to_group(ilb_handle_t h, const char *sgname,
79*10946SSangeeta.Misra@Sun.COM     ilb_server_data_t *srv, ilbd_cmd_t cmd)
80*10946SSangeeta.Misra@Sun.COM {
81*10946SSangeeta.Misra@Sun.COM 	ilb_status_t		rc = ILB_STATUS_OK;
82*10946SSangeeta.Misra@Sun.COM 	ilb_sg_info_t		*sg;
83*10946SSangeeta.Misra@Sun.COM 	ilb_sg_srv_t		*sgs;
84*10946SSangeeta.Misra@Sun.COM 	in_port_t		h_maxport, h_minport;
85*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t		*ic;
86*10946SSangeeta.Misra@Sun.COM 	size_t			ic_sz;
87*10946SSangeeta.Misra@Sun.COM 
88*10946SSangeeta.Misra@Sun.COM 	if (h == ILB_INVALID_HANDLE || sgname == NULL ||
89*10946SSangeeta.Misra@Sun.COM 	    *sgname == '\0' || srv == NULL)
90*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
91*10946SSangeeta.Misra@Sun.COM 
92*10946SSangeeta.Misra@Sun.COM 	if (strlen(sgname) > ILB_SGNAME_SZ - 1)
93*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_NAMETOOLONG);
94*10946SSangeeta.Misra@Sun.COM 
95*10946SSangeeta.Misra@Sun.COM 	/* now all the checks have passed, we can pass on the goods */
96*10946SSangeeta.Misra@Sun.COM 	if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
97*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
98*10946SSangeeta.Misra@Sun.COM 
99*10946SSangeeta.Misra@Sun.COM 	sg = (ilb_sg_info_t *)&ic->ic_data;
100*10946SSangeeta.Misra@Sun.COM 	sg->sg_srvcount = 1;
101*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy(sg->sg_name, sgname, sizeof (sg->sg_name));
102*10946SSangeeta.Misra@Sun.COM 
103*10946SSangeeta.Misra@Sun.COM 	sgs = &sg->sg_servers[0];
104*10946SSangeeta.Misra@Sun.COM 
105*10946SSangeeta.Misra@Sun.COM 	IP_COPY_CLI_2_IMPL(&srv->sd_addr, &sgs->sgs_addr);
106*10946SSangeeta.Misra@Sun.COM 	h_minport = ntohs(srv->sd_minport);
107*10946SSangeeta.Misra@Sun.COM 	h_maxport = ntohs(srv->sd_maxport);
108*10946SSangeeta.Misra@Sun.COM 	sgs->sgs_minport = srv->sd_minport;
109*10946SSangeeta.Misra@Sun.COM 	if (h_minport != 0 && h_maxport < h_minport)
110*10946SSangeeta.Misra@Sun.COM 		sgs->sgs_maxport = srv->sd_minport;
111*10946SSangeeta.Misra@Sun.COM 	else
112*10946SSangeeta.Misra@Sun.COM 		sgs->sgs_maxport = srv->sd_maxport;
113*10946SSangeeta.Misra@Sun.COM 
114*10946SSangeeta.Misra@Sun.COM 	sgs->sgs_flags = srv->sd_flags;
115*10946SSangeeta.Misra@Sun.COM 	if (srv->sd_srvID[0] == ILB_SRVID_PREFIX)
116*10946SSangeeta.Misra@Sun.COM 		(void) strlcpy(sgs->sgs_srvID, srv->sd_srvID,
117*10946SSangeeta.Misra@Sun.COM 		    sizeof (sgs->sgs_srvID));
118*10946SSangeeta.Misra@Sun.COM 
119*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
120*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
121*10946SSangeeta.Misra@Sun.COM 		goto out;
122*10946SSangeeta.Misra@Sun.COM 
123*10946SSangeeta.Misra@Sun.COM 	if (ic->ic_cmd != ILBD_CMD_OK)
124*10946SSangeeta.Misra@Sun.COM 		rc = *(ilb_status_t *)&ic->ic_data;
125*10946SSangeeta.Misra@Sun.COM 
126*10946SSangeeta.Misra@Sun.COM out:
127*10946SSangeeta.Misra@Sun.COM 	free(ic);
128*10946SSangeeta.Misra@Sun.COM 	return (rc);
129*10946SSangeeta.Misra@Sun.COM }
130*10946SSangeeta.Misra@Sun.COM 
131*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_add_server_to_group(ilb_handle_t h,const char * sgname,ilb_server_data_t * srv)132*10946SSangeeta.Misra@Sun.COM ilb_add_server_to_group(ilb_handle_t h, const char *sgname,
133*10946SSangeeta.Misra@Sun.COM     ilb_server_data_t *srv)
134*10946SSangeeta.Misra@Sun.COM {
135*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_addrem_server_to_group(h, sgname, srv,
136*10946SSangeeta.Misra@Sun.COM 	    ILBD_ADD_SERVER_TO_GROUP));
137*10946SSangeeta.Misra@Sun.COM }
138*10946SSangeeta.Misra@Sun.COM 
139*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_rem_server_from_group(ilb_handle_t h,const char * sgname,ilb_server_data_t * srv)140*10946SSangeeta.Misra@Sun.COM ilb_rem_server_from_group(ilb_handle_t h, const char *sgname,
141*10946SSangeeta.Misra@Sun.COM     ilb_server_data_t *srv)
142*10946SSangeeta.Misra@Sun.COM {
143*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_addrem_server_to_group(h, sgname, srv,
144*10946SSangeeta.Misra@Sun.COM 	    ILBD_REM_SERVER_FROM_GROUP));
145*10946SSangeeta.Misra@Sun.COM }
146*10946SSangeeta.Misra@Sun.COM 
147*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_retrieve_sg_names(ilb_handle_t h,ilb_comm_t ** rbuf,size_t * rbufsz)148*10946SSangeeta.Misra@Sun.COM i_ilb_retrieve_sg_names(ilb_handle_t h, ilb_comm_t **rbuf, size_t *rbufsz)
149*10946SSangeeta.Misra@Sun.COM {
150*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
151*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	ic, *tmp_rbuf;
152*10946SSangeeta.Misra@Sun.COM 
153*10946SSangeeta.Misra@Sun.COM 	*rbufsz = ILBD_MSG_SIZE;
154*10946SSangeeta.Misra@Sun.COM 	if ((tmp_rbuf = malloc(*rbufsz)) == NULL)
155*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
156*10946SSangeeta.Misra@Sun.COM 
157*10946SSangeeta.Misra@Sun.COM 	ic.ic_cmd = ILBD_RETRIEVE_SG_NAMES;
158*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, &ic, sizeof (ic), tmp_rbuf, rbufsz);
159*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
160*10946SSangeeta.Misra@Sun.COM 		goto out;
161*10946SSangeeta.Misra@Sun.COM 
162*10946SSangeeta.Misra@Sun.COM 	if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) {
163*10946SSangeeta.Misra@Sun.COM 		*rbuf = tmp_rbuf;
164*10946SSangeeta.Misra@Sun.COM 		return (rc);
165*10946SSangeeta.Misra@Sun.COM 	}
166*10946SSangeeta.Misra@Sun.COM 	rc = *(ilb_status_t *)&tmp_rbuf->ic_data;
167*10946SSangeeta.Misra@Sun.COM out:
168*10946SSangeeta.Misra@Sun.COM 	free(tmp_rbuf);
169*10946SSangeeta.Misra@Sun.COM 	*rbuf = NULL;
170*10946SSangeeta.Misra@Sun.COM 	return (rc);
171*10946SSangeeta.Misra@Sun.COM }
172*10946SSangeeta.Misra@Sun.COM 
173*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_retrieve_sg_hosts(ilb_handle_t h,const char * sgname,ilb_comm_t ** rbuf,size_t * rbufsz)174*10946SSangeeta.Misra@Sun.COM i_ilb_retrieve_sg_hosts(ilb_handle_t h, const char *sgname, ilb_comm_t **rbuf,
175*10946SSangeeta.Misra@Sun.COM     size_t *rbufsz)
176*10946SSangeeta.Misra@Sun.COM {
177*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
178*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*ic, *tmp_rbuf;
179*10946SSangeeta.Misra@Sun.COM 	size_t		ic_sz;
180*10946SSangeeta.Misra@Sun.COM 
181*10946SSangeeta.Misra@Sun.COM 	if ((ic = i_ilb_alloc_req(ILBD_RETRIEVE_SG_HOSTS, &ic_sz)) == NULL)
182*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
183*10946SSangeeta.Misra@Sun.COM 	*rbufsz = ILBD_MSG_SIZE;
184*10946SSangeeta.Misra@Sun.COM 	if ((tmp_rbuf = malloc(*rbufsz)) == NULL) {
185*10946SSangeeta.Misra@Sun.COM 		free(ic);
186*10946SSangeeta.Misra@Sun.COM 		*rbuf = NULL;
187*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
188*10946SSangeeta.Misra@Sun.COM 	}
189*10946SSangeeta.Misra@Sun.COM 
190*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy((char *)&ic->ic_data, sgname, sizeof (ilbd_name_t));
191*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, ic, ic_sz, tmp_rbuf, rbufsz);
192*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
193*10946SSangeeta.Misra@Sun.COM 		goto out;
194*10946SSangeeta.Misra@Sun.COM 
195*10946SSangeeta.Misra@Sun.COM 	if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) {
196*10946SSangeeta.Misra@Sun.COM 		*rbuf = tmp_rbuf;
197*10946SSangeeta.Misra@Sun.COM 		free(ic);
198*10946SSangeeta.Misra@Sun.COM 		return (rc);
199*10946SSangeeta.Misra@Sun.COM 	}
200*10946SSangeeta.Misra@Sun.COM 	rc = *(ilb_status_t *)&tmp_rbuf->ic_data;
201*10946SSangeeta.Misra@Sun.COM out:
202*10946SSangeeta.Misra@Sun.COM 	free(ic);
203*10946SSangeeta.Misra@Sun.COM 	free(tmp_rbuf);
204*10946SSangeeta.Misra@Sun.COM 	*rbuf = NULL;
205*10946SSangeeta.Misra@Sun.COM 	return (rc);
206*10946SSangeeta.Misra@Sun.COM }
207*10946SSangeeta.Misra@Sun.COM 
208*10946SSangeeta.Misra@Sun.COM typedef enum {
209*10946SSangeeta.Misra@Sun.COM 	walk_servers,
210*10946SSangeeta.Misra@Sun.COM 	walk_sg
211*10946SSangeeta.Misra@Sun.COM } sgwalk_t;
212*10946SSangeeta.Misra@Sun.COM 
213*10946SSangeeta.Misra@Sun.COM /*
214*10946SSangeeta.Misra@Sun.COM  * "walks" one sg (retrieves data) and depending on "walktype" argument
215*10946SSangeeta.Misra@Sun.COM  * call servergroup function once per sg or server function once
216*10946SSangeeta.Misra@Sun.COM  * for every server. in both cases, the argument "f" is cast to
217*10946SSangeeta.Misra@Sun.COM  * be the proper function pointer type
218*10946SSangeeta.Misra@Sun.COM  */
219*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_walk_one_sg(ilb_handle_t h,void * f,const char * sgname,void * arg,sgwalk_t walktype)220*10946SSangeeta.Misra@Sun.COM i_ilb_walk_one_sg(ilb_handle_t h, void *f, const char *sgname, void *arg,
221*10946SSangeeta.Misra@Sun.COM     sgwalk_t walktype)
222*10946SSangeeta.Misra@Sun.COM {
223*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc = ILB_STATUS_OK;
224*10946SSangeeta.Misra@Sun.COM 	ilb_sg_info_t	*sg_info;
225*10946SSangeeta.Misra@Sun.COM 	ilb_sg_srv_t	*srv;
226*10946SSangeeta.Misra@Sun.COM 	int		i;
227*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*rbuf;
228*10946SSangeeta.Misra@Sun.COM 	size_t		rbufsz;
229*10946SSangeeta.Misra@Sun.COM 
230*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_retrieve_sg_hosts(h, sgname, &rbuf, &rbufsz);
231*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
232*10946SSangeeta.Misra@Sun.COM 		return (rc);
233*10946SSangeeta.Misra@Sun.COM 	sg_info = (ilb_sg_info_t *)&rbuf->ic_data;
234*10946SSangeeta.Misra@Sun.COM 
235*10946SSangeeta.Misra@Sun.COM 	if (walktype == walk_sg) {
236*10946SSangeeta.Misra@Sun.COM 		sg_walkerfunc_t	sg_func = (sg_walkerfunc_t)f;
237*10946SSangeeta.Misra@Sun.COM 		ilb_sg_data_t	sgd;
238*10946SSangeeta.Misra@Sun.COM 
239*10946SSangeeta.Misra@Sun.COM 		(void) strlcpy(sgd.sgd_name, sg_info->sg_name,
240*10946SSangeeta.Misra@Sun.COM 		    sizeof (sgd.sgd_name));
241*10946SSangeeta.Misra@Sun.COM 		sgd.sgd_srvcount = sg_info->sg_srvcount;
242*10946SSangeeta.Misra@Sun.COM 		sgd.sgd_flags = sg_info->sg_flags;
243*10946SSangeeta.Misra@Sun.COM 		rc = sg_func(h, &sgd, arg);
244*10946SSangeeta.Misra@Sun.COM 		goto out;
245*10946SSangeeta.Misra@Sun.COM 	}
246*10946SSangeeta.Misra@Sun.COM 
247*10946SSangeeta.Misra@Sun.COM 	for (i = 0; i < sg_info->sg_srvcount; i++) {
248*10946SSangeeta.Misra@Sun.COM 		srv_walkerfunc_t srv_func = (srv_walkerfunc_t)f;
249*10946SSangeeta.Misra@Sun.COM 		ilb_server_data_t	 sd;
250*10946SSangeeta.Misra@Sun.COM 
251*10946SSangeeta.Misra@Sun.COM 		srv = &sg_info->sg_servers[i];
252*10946SSangeeta.Misra@Sun.COM 		IP_COPY_IMPL_2_CLI(&srv->sgs_addr, &sd.sd_addr);
253*10946SSangeeta.Misra@Sun.COM 		sd.sd_minport = srv->sgs_minport;
254*10946SSangeeta.Misra@Sun.COM 		sd.sd_maxport = srv->sgs_maxport;
255*10946SSangeeta.Misra@Sun.COM 		sd.sd_flags = srv->sgs_flags;
256*10946SSangeeta.Misra@Sun.COM 		(void) strlcpy(sd.sd_srvID, srv->sgs_srvID,
257*10946SSangeeta.Misra@Sun.COM 		    sizeof (sd.sd_srvID));
258*10946SSangeeta.Misra@Sun.COM 
259*10946SSangeeta.Misra@Sun.COM 		rc = srv_func(h, &sd, sg_info->sg_name, arg);
260*10946SSangeeta.Misra@Sun.COM 		if (rc != ILB_STATUS_OK)
261*10946SSangeeta.Misra@Sun.COM 			break;
262*10946SSangeeta.Misra@Sun.COM 	}
263*10946SSangeeta.Misra@Sun.COM 
264*10946SSangeeta.Misra@Sun.COM out:
265*10946SSangeeta.Misra@Sun.COM 	free(rbuf);
266*10946SSangeeta.Misra@Sun.COM 	return (rc);
267*10946SSangeeta.Misra@Sun.COM }
268*10946SSangeeta.Misra@Sun.COM 
269*10946SSangeeta.Misra@Sun.COM /*
270*10946SSangeeta.Misra@Sun.COM  * wrapper function for i_walk_one_sg; if necessary, gets list of
271*10946SSangeeta.Misra@Sun.COM  * SG names and calles i_walk_one_sg with every name
272*10946SSangeeta.Misra@Sun.COM  */
273*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_walk_sgs(ilb_handle_t h,void * f,const char * sgname,void * arg,sgwalk_t walktype)274*10946SSangeeta.Misra@Sun.COM i_walk_sgs(ilb_handle_t h, void *f, const char *sgname,
275*10946SSangeeta.Misra@Sun.COM     void *arg, sgwalk_t walktype)
276*10946SSangeeta.Misra@Sun.COM {
277*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
278*10946SSangeeta.Misra@Sun.COM 	ilbd_namelist_t	*sgl;
279*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*rbuf;
280*10946SSangeeta.Misra@Sun.COM 	size_t		rbufsz;
281*10946SSangeeta.Misra@Sun.COM 	int		i;
282*10946SSangeeta.Misra@Sun.COM 
283*10946SSangeeta.Misra@Sun.COM 	if (sgname != NULL) {
284*10946SSangeeta.Misra@Sun.COM 		rc = i_ilb_walk_one_sg(h, f, sgname, arg, walktype);
285*10946SSangeeta.Misra@Sun.COM 		return (rc);
286*10946SSangeeta.Misra@Sun.COM 	}
287*10946SSangeeta.Misra@Sun.COM 
288*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_retrieve_sg_names(h, &rbuf, &rbufsz);
289*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
290*10946SSangeeta.Misra@Sun.COM 		return (rc);
291*10946SSangeeta.Misra@Sun.COM 	sgl = (ilbd_namelist_t *)&rbuf->ic_data;
292*10946SSangeeta.Misra@Sun.COM 
293*10946SSangeeta.Misra@Sun.COM 	for (i = 0; i < sgl->ilbl_count; i++) {
294*10946SSangeeta.Misra@Sun.COM 		rc = i_ilb_walk_one_sg(h, f, sgl->ilbl_name[i], arg, walktype);
295*10946SSangeeta.Misra@Sun.COM 		/*
296*10946SSangeeta.Misra@Sun.COM 		 * The server group may have been removed by another
297*10946SSangeeta.Misra@Sun.COM 		 * process, just continue.
298*10946SSangeeta.Misra@Sun.COM 		 */
299*10946SSangeeta.Misra@Sun.COM 		if (rc == ILB_STATUS_SGUNAVAIL) {
300*10946SSangeeta.Misra@Sun.COM 			rc = ILB_STATUS_OK;
301*10946SSangeeta.Misra@Sun.COM 			continue;
302*10946SSangeeta.Misra@Sun.COM 		}
303*10946SSangeeta.Misra@Sun.COM 		if (rc != ILB_STATUS_OK)
304*10946SSangeeta.Misra@Sun.COM 			break;
305*10946SSangeeta.Misra@Sun.COM 	}
306*10946SSangeeta.Misra@Sun.COM 	free(rbuf);
307*10946SSangeeta.Misra@Sun.COM 	return (rc);
308*10946SSangeeta.Misra@Sun.COM }
309*10946SSangeeta.Misra@Sun.COM 
310*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_walk_servergroups(ilb_handle_t h,sg_walkerfunc_t f,const char * sgname,void * arg)311*10946SSangeeta.Misra@Sun.COM ilb_walk_servergroups(ilb_handle_t h, sg_walkerfunc_t f, const char *sgname,
312*10946SSangeeta.Misra@Sun.COM     void *arg)
313*10946SSangeeta.Misra@Sun.COM {
314*10946SSangeeta.Misra@Sun.COM 	return (i_walk_sgs(h, (void *)f, sgname, arg, walk_sg));
315*10946SSangeeta.Misra@Sun.COM }
316*10946SSangeeta.Misra@Sun.COM 
317*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_walk_servers(ilb_handle_t h,srv_walkerfunc_t f,const char * sgname,void * arg)318*10946SSangeeta.Misra@Sun.COM ilb_walk_servers(ilb_handle_t h, srv_walkerfunc_t f, const char *sgname,
319*10946SSangeeta.Misra@Sun.COM     void *arg)
320*10946SSangeeta.Misra@Sun.COM {
321*10946SSangeeta.Misra@Sun.COM 	return (i_walk_sgs(h, (void *)f, sgname, arg, walk_servers));
322*10946SSangeeta.Misra@Sun.COM }
323*10946SSangeeta.Misra@Sun.COM 
324*10946SSangeeta.Misra@Sun.COM static ilb_status_t
ilb_Xable_server(ilb_handle_t h,ilb_server_data_t * srv,void * reserved,ilbd_cmd_t cmd)325*10946SSangeeta.Misra@Sun.COM ilb_Xable_server(ilb_handle_t h, ilb_server_data_t *srv, void *reserved,
326*10946SSangeeta.Misra@Sun.COM     ilbd_cmd_t cmd)
327*10946SSangeeta.Misra@Sun.COM {
328*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
329*10946SSangeeta.Misra@Sun.COM 	ilb_sg_info_t	*sg_info;
330*10946SSangeeta.Misra@Sun.COM 	ilb_sg_srv_t	*sgs;
331*10946SSangeeta.Misra@Sun.COM 	in_port_t	h_maxport, h_minport;
332*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*ic;
333*10946SSangeeta.Misra@Sun.COM 	size_t		ic_sz;
334*10946SSangeeta.Misra@Sun.COM 
335*10946SSangeeta.Misra@Sun.COM 	if (h == NULL)
336*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
337*10946SSangeeta.Misra@Sun.COM 
338*10946SSangeeta.Misra@Sun.COM 	/*
339*10946SSangeeta.Misra@Sun.COM 	 * In this implementation, this needs to be NULL, so
340*10946SSangeeta.Misra@Sun.COM 	 * there's no ugly surprises with old apps once we attach
341*10946SSangeeta.Misra@Sun.COM 	 * meaning to this parameter.
342*10946SSangeeta.Misra@Sun.COM 	 */
343*10946SSangeeta.Misra@Sun.COM 	if (reserved != NULL)
344*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
345*10946SSangeeta.Misra@Sun.COM 
346*10946SSangeeta.Misra@Sun.COM 	/* now all the checks have passed, we can pass on the goods */
347*10946SSangeeta.Misra@Sun.COM 	if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
348*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
349*10946SSangeeta.Misra@Sun.COM 
350*10946SSangeeta.Misra@Sun.COM 	sg_info = (ilb_sg_info_t *)&ic->ic_data;
351*10946SSangeeta.Misra@Sun.COM 	sg_info->sg_srvcount = 1;
352*10946SSangeeta.Misra@Sun.COM 
353*10946SSangeeta.Misra@Sun.COM 	sgs = &sg_info->sg_servers[0];
354*10946SSangeeta.Misra@Sun.COM 
355*10946SSangeeta.Misra@Sun.COM 	/* make sure min_port <= max_port; comparison in host byte order! */
356*10946SSangeeta.Misra@Sun.COM 	h_maxport = ntohs(srv->sd_maxport);
357*10946SSangeeta.Misra@Sun.COM 	h_minport = ntohs(srv->sd_minport);
358*10946SSangeeta.Misra@Sun.COM 	if (h_maxport != 0 && h_maxport < h_minport)
359*10946SSangeeta.Misra@Sun.COM 		sgs->sgs_maxport = sgs->sgs_minport;
360*10946SSangeeta.Misra@Sun.COM 	else
361*10946SSangeeta.Misra@Sun.COM 		sgs->sgs_maxport = srv->sd_maxport;
362*10946SSangeeta.Misra@Sun.COM 	sgs->sgs_minport = srv->sd_minport;
363*10946SSangeeta.Misra@Sun.COM 
364*10946SSangeeta.Misra@Sun.COM 	sgs->sgs_flags = srv->sd_flags;
365*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy(sgs->sgs_srvID, srv->sd_srvID, sizeof (sgs->sgs_srvID));
366*10946SSangeeta.Misra@Sun.COM 	IP_COPY_CLI_2_IMPL(&srv->sd_addr, &sgs->sgs_addr);
367*10946SSangeeta.Misra@Sun.COM 
368*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
369*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
370*10946SSangeeta.Misra@Sun.COM 		goto out;
371*10946SSangeeta.Misra@Sun.COM 
372*10946SSangeeta.Misra@Sun.COM 	if (ic->ic_cmd != ILBD_CMD_OK)
373*10946SSangeeta.Misra@Sun.COM 		rc = *(ilb_status_t *)&ic->ic_data;
374*10946SSangeeta.Misra@Sun.COM out:
375*10946SSangeeta.Misra@Sun.COM 	free(ic);
376*10946SSangeeta.Misra@Sun.COM 	return (rc);
377*10946SSangeeta.Misra@Sun.COM }
378*10946SSangeeta.Misra@Sun.COM 
379*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_enable_server(ilb_handle_t h,ilb_server_data_t * srv,void * reserved)380*10946SSangeeta.Misra@Sun.COM ilb_enable_server(ilb_handle_t h, ilb_server_data_t *srv, void *reserved)
381*10946SSangeeta.Misra@Sun.COM {
382*10946SSangeeta.Misra@Sun.COM 	return (ilb_Xable_server(h, srv, reserved, ILBD_ENABLE_SERVER));
383*10946SSangeeta.Misra@Sun.COM }
384*10946SSangeeta.Misra@Sun.COM 
385*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_disable_server(ilb_handle_t h,ilb_server_data_t * srv,void * reserved)386*10946SSangeeta.Misra@Sun.COM ilb_disable_server(ilb_handle_t h, ilb_server_data_t *srv, void *reserved)
387*10946SSangeeta.Misra@Sun.COM {
388*10946SSangeeta.Misra@Sun.COM 	return (ilb_Xable_server(h, srv, reserved, ILBD_DISABLE_SERVER));
389*10946SSangeeta.Misra@Sun.COM }
390*10946SSangeeta.Misra@Sun.COM 
391*10946SSangeeta.Misra@Sun.COM static ilb_status_t
i_ilb_fillin_srvdata(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname,ilbd_cmd_t cmd)392*10946SSangeeta.Misra@Sun.COM i_ilb_fillin_srvdata(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
393*10946SSangeeta.Misra@Sun.COM     ilbd_cmd_t cmd)
394*10946SSangeeta.Misra@Sun.COM {
395*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc;
396*10946SSangeeta.Misra@Sun.COM 	ilb_sg_info_t	*sg_info;
397*10946SSangeeta.Misra@Sun.COM 	ilb_sg_srv_t	*sgs;
398*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*ic;
399*10946SSangeeta.Misra@Sun.COM 	size_t		ic_sz;
400*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*rbuf;
401*10946SSangeeta.Misra@Sun.COM 	size_t		rbufsz;
402*10946SSangeeta.Misra@Sun.COM 
403*10946SSangeeta.Misra@Sun.COM 	if (h == ILB_INVALID_HANDLE || sgname == NULL ||
404*10946SSangeeta.Misra@Sun.COM 	    *sgname == '\0' || srv == NULL)
405*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
406*10946SSangeeta.Misra@Sun.COM 
407*10946SSangeeta.Misra@Sun.COM 	if (cmd == ILBD_SRV_ID2ADDR && srv->sd_srvID[0] == '\0')
408*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
409*10946SSangeeta.Misra@Sun.COM 	if (cmd == ILBD_SRV_ADDR2ID && !IS_AF_VALID(srv->sd_addr.ia_af))
410*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_EINVAL);
411*10946SSangeeta.Misra@Sun.COM 
412*10946SSangeeta.Misra@Sun.COM 	if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
413*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
414*10946SSangeeta.Misra@Sun.COM 	rbufsz = sizeof (ilb_comm_t) + sizeof (ilb_sg_srv_t);
415*10946SSangeeta.Misra@Sun.COM 	if ((rbuf = malloc(rbufsz)) == NULL) {
416*10946SSangeeta.Misra@Sun.COM 		free(ic);
417*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_ENOMEM);
418*10946SSangeeta.Misra@Sun.COM 	}
419*10946SSangeeta.Misra@Sun.COM 
420*10946SSangeeta.Misra@Sun.COM 	sg_info = (ilb_sg_info_t *)&ic->ic_data;
421*10946SSangeeta.Misra@Sun.COM 	sg_info->sg_srvcount = 1;
422*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy(sg_info->sg_name, sgname, sizeof (sg_info->sg_name));
423*10946SSangeeta.Misra@Sun.COM 
424*10946SSangeeta.Misra@Sun.COM 	sgs = &sg_info->sg_servers[0];
425*10946SSangeeta.Misra@Sun.COM 
426*10946SSangeeta.Misra@Sun.COM 	if (cmd == ILBD_SRV_ID2ADDR)
427*10946SSangeeta.Misra@Sun.COM 		(void) strlcpy(sgs->sgs_srvID, srv->sd_srvID,
428*10946SSangeeta.Misra@Sun.COM 		    sizeof (sgs->sgs_srvID));
429*10946SSangeeta.Misra@Sun.COM 	else
430*10946SSangeeta.Misra@Sun.COM 		IP_COPY_CLI_2_IMPL(&srv->sd_addr, &sgs->sgs_addr);
431*10946SSangeeta.Misra@Sun.COM 
432*10946SSangeeta.Misra@Sun.COM 	rc = i_ilb_do_comm(h, ic, ic_sz, rbuf, &rbufsz);
433*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
434*10946SSangeeta.Misra@Sun.COM 		goto out;
435*10946SSangeeta.Misra@Sun.COM 
436*10946SSangeeta.Misra@Sun.COM 	if (rbuf->ic_cmd == ILBD_CMD_OK) {
437*10946SSangeeta.Misra@Sun.COM 		sgs = (ilb_sg_srv_t *)&rbuf->ic_data;
438*10946SSangeeta.Misra@Sun.COM 		if (cmd == ILBD_SRV_ID2ADDR) {
439*10946SSangeeta.Misra@Sun.COM 			IP_COPY_IMPL_2_CLI(&sgs->sgs_addr, &srv->sd_addr);
440*10946SSangeeta.Misra@Sun.COM 		} else {
441*10946SSangeeta.Misra@Sun.COM 			(void) strlcpy(srv->sd_srvID, sgs->sgs_srvID,
442*10946SSangeeta.Misra@Sun.COM 			    sizeof (sgs->sgs_srvID));
443*10946SSangeeta.Misra@Sun.COM 		}
444*10946SSangeeta.Misra@Sun.COM 		return (rc);
445*10946SSangeeta.Misra@Sun.COM 	}
446*10946SSangeeta.Misra@Sun.COM 
447*10946SSangeeta.Misra@Sun.COM 	rc = *(ilb_status_t *)&rbuf->ic_data;
448*10946SSangeeta.Misra@Sun.COM out:
449*10946SSangeeta.Misra@Sun.COM 	free(ic);
450*10946SSangeeta.Misra@Sun.COM 	return (rc);
451*10946SSangeeta.Misra@Sun.COM }
452*10946SSangeeta.Misra@Sun.COM 
453*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_srvID_to_address(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname)454*10946SSangeeta.Misra@Sun.COM ilb_srvID_to_address(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname)
455*10946SSangeeta.Misra@Sun.COM {
456*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_fillin_srvdata(h, srv, sgname, ILBD_SRV_ID2ADDR));
457*10946SSangeeta.Misra@Sun.COM 
458*10946SSangeeta.Misra@Sun.COM }
459*10946SSangeeta.Misra@Sun.COM 
460*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilb_address_to_srvID(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname)461*10946SSangeeta.Misra@Sun.COM ilb_address_to_srvID(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname)
462*10946SSangeeta.Misra@Sun.COM {
463*10946SSangeeta.Misra@Sun.COM 	return (i_ilb_fillin_srvdata(h, srv, sgname, ILBD_SRV_ADDR2ID));
464*10946SSangeeta.Misra@Sun.COM }
465