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