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