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.
2533f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
26dbed73cbSSangeeta Misra */
27dbed73cbSSangeeta Misra
28dbed73cbSSangeeta Misra #include <stdio.h>
29dbed73cbSSangeeta Misra #include <unistd.h>
30dbed73cbSSangeeta Misra #include <stdlib.h>
31dbed73cbSSangeeta Misra #include <strings.h>
32dbed73cbSSangeeta Misra #include <stddef.h>
33dbed73cbSSangeeta Misra #include <assert.h>
34dbed73cbSSangeeta Misra #include <errno.h>
35dbed73cbSSangeeta Misra #include <sys/types.h>
36dbed73cbSSangeeta Misra #include <sys/socket.h>
37dbed73cbSSangeeta Misra #include <netinet/in.h>
38dbed73cbSSangeeta Misra #include <arpa/inet.h>
39dbed73cbSSangeeta Misra #include <sys/list.h>
40dbed73cbSSangeeta Misra #include <ofmt.h>
41dbed73cbSSangeeta Misra #include <libilb.h>
42dbed73cbSSangeeta Misra #include "ilbadm.h"
43dbed73cbSSangeeta Misra
44dbed73cbSSangeeta Misra static ilbadm_key_name_t servrange_keys[] = {
45dbed73cbSSangeeta Misra {ILB_KEY_SERVER, "server", "servers"},
46dbed73cbSSangeeta Misra {ILB_KEY_SERVRANGE, "server", "servers"},
47dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""}
48dbed73cbSSangeeta Misra };
49dbed73cbSSangeeta Misra
50dbed73cbSSangeeta Misra static ilbadm_key_name_t serverID_keys[] = {
51dbed73cbSSangeeta Misra {ILB_KEY_SERVERID, "server", ""},
52dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""}
53dbed73cbSSangeeta Misra };
54dbed73cbSSangeeta Misra
55dbed73cbSSangeeta Misra typedef struct sg_export_arg {
56dbed73cbSSangeeta Misra FILE *fp;
57dbed73cbSSangeeta Misra ilbadm_sgroup_t *sg;
58dbed73cbSSangeeta Misra } sg_export_arg_t;
59dbed73cbSSangeeta Misra
60dbed73cbSSangeeta Misra typedef struct arg_struct {
61dbed73cbSSangeeta Misra int flags;
62dbed73cbSSangeeta Misra char *o_str;
63dbed73cbSSangeeta Misra ofmt_field_t *o_fields;
64dbed73cbSSangeeta Misra ofmt_handle_t oh;
65dbed73cbSSangeeta Misra } list_arg_t;
66dbed73cbSSangeeta Misra
67dbed73cbSSangeeta Misra typedef struct sg_srv_o_struct {
68dbed73cbSSangeeta Misra char *sgname;
69dbed73cbSSangeeta Misra ilb_server_data_t *sd;
70dbed73cbSSangeeta Misra } sg_srv_o_arg_t;
71dbed73cbSSangeeta Misra
72dbed73cbSSangeeta Misra static ofmt_cb_t of_sgname;
73dbed73cbSSangeeta Misra static ofmt_cb_t of_srvID;
74dbed73cbSSangeeta Misra static ofmt_cb_t of_port;
75dbed73cbSSangeeta Misra static ofmt_cb_t of_ip;
76dbed73cbSSangeeta Misra
77dbed73cbSSangeeta Misra static ofmt_field_t sgfields_v4[] = {
78dbed73cbSSangeeta Misra {"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
79dbed73cbSSangeeta Misra {"SERVERID", ILB_NAMESZ, 0, of_srvID},
80dbed73cbSSangeeta Misra {"MINPORT", 8, 0, of_port},
81dbed73cbSSangeeta Misra {"MAXPORT", 8, 1, of_port},
82dbed73cbSSangeeta Misra {"IP_ADDRESS", 15, 0, of_ip},
83dbed73cbSSangeeta Misra {NULL, 0, 0, NULL}
84dbed73cbSSangeeta Misra };
85dbed73cbSSangeeta Misra static ofmt_field_t sgfields_v6[] = {
86dbed73cbSSangeeta Misra {"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
87dbed73cbSSangeeta Misra {"SERVERID", ILB_NAMESZ, 0, of_srvID},
88dbed73cbSSangeeta Misra {"MINPORT", 8, 0, of_port},
89dbed73cbSSangeeta Misra {"MAXPORT", 8, 1, of_port},
90dbed73cbSSangeeta Misra {"IP_ADDRESS", 39, 0, of_ip},
91dbed73cbSSangeeta Misra {NULL, 0, 0, NULL}
92dbed73cbSSangeeta Misra };
93dbed73cbSSangeeta Misra
94dbed73cbSSangeeta Misra #define MAXCOLS 80 /* make flexible? */
95dbed73cbSSangeeta Misra
96dbed73cbSSangeeta Misra extern int optind, optopt, opterr;
97dbed73cbSSangeeta Misra extern char *optarg;
98dbed73cbSSangeeta Misra
99dbed73cbSSangeeta Misra static boolean_t
of_sgname(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)100dbed73cbSSangeeta Misra of_sgname(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
101dbed73cbSSangeeta Misra {
102dbed73cbSSangeeta Misra sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
103dbed73cbSSangeeta Misra
104dbed73cbSSangeeta Misra (void) strlcpy(buf, l->sgname, bufsize);
105dbed73cbSSangeeta Misra return (B_TRUE);
106dbed73cbSSangeeta Misra }
107dbed73cbSSangeeta Misra
108dbed73cbSSangeeta Misra static boolean_t
of_srvID(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)109dbed73cbSSangeeta Misra of_srvID(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
110dbed73cbSSangeeta Misra {
111dbed73cbSSangeeta Misra sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
112dbed73cbSSangeeta Misra
113dbed73cbSSangeeta Misra (void) strlcpy(buf, l->sd->sd_srvID, bufsize);
114dbed73cbSSangeeta Misra return (B_TRUE);
115dbed73cbSSangeeta Misra }
116dbed73cbSSangeeta Misra
117dbed73cbSSangeeta Misra static boolean_t
of_port(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)118dbed73cbSSangeeta Misra of_port(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
119dbed73cbSSangeeta Misra {
120dbed73cbSSangeeta Misra sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
121dbed73cbSSangeeta Misra int port;
122dbed73cbSSangeeta Misra
123dbed73cbSSangeeta Misra if (of_arg->ofmt_id == 0) {
124dbed73cbSSangeeta Misra port = ntohs(l->sd->sd_minport);
125dbed73cbSSangeeta Misra if (port == 0)
126dbed73cbSSangeeta Misra *buf = '\0';
127dbed73cbSSangeeta Misra else
128dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%d", port);
129dbed73cbSSangeeta Misra } else {
130dbed73cbSSangeeta Misra port = ntohs(l->sd->sd_maxport);
131dbed73cbSSangeeta Misra if (port == 0)
132dbed73cbSSangeeta Misra *buf = '\0';
133dbed73cbSSangeeta Misra else
134dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%d", port);
135dbed73cbSSangeeta Misra }
136dbed73cbSSangeeta Misra return (B_TRUE);
137dbed73cbSSangeeta Misra }
138dbed73cbSSangeeta Misra
139dbed73cbSSangeeta Misra static boolean_t
of_ip(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)140dbed73cbSSangeeta Misra of_ip(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
141dbed73cbSSangeeta Misra {
142dbed73cbSSangeeta Misra sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
143dbed73cbSSangeeta Misra
144dbed73cbSSangeeta Misra ip2str(&l->sd->sd_addr, buf, bufsize, V6_ADDRONLY);
145dbed73cbSSangeeta Misra return (B_TRUE);
146dbed73cbSSangeeta Misra }
147dbed73cbSSangeeta Misra
148dbed73cbSSangeeta Misra ilbadm_status_t
i_list_sg_srv_ofmt(char * sgname,ilb_server_data_t * sd,void * arg)149dbed73cbSSangeeta Misra i_list_sg_srv_ofmt(char *sgname, ilb_server_data_t *sd, void *arg)
150dbed73cbSSangeeta Misra {
151dbed73cbSSangeeta Misra list_arg_t *larg = (list_arg_t *)arg;
152dbed73cbSSangeeta Misra sg_srv_o_arg_t line_arg;
153dbed73cbSSangeeta Misra
154dbed73cbSSangeeta Misra line_arg.sgname = sgname;
155dbed73cbSSangeeta Misra line_arg.sd = sd;
156dbed73cbSSangeeta Misra ofmt_print(larg->oh, &line_arg);
157dbed73cbSSangeeta Misra return (ILBADM_OK);
158dbed73cbSSangeeta Misra }
159dbed73cbSSangeeta Misra
160dbed73cbSSangeeta Misra /*
161dbed73cbSSangeeta Misra * This function is always called via ilb_walk_servergroups()
162dbed73cbSSangeeta Misra * and so must return libilb errors.
163dbed73cbSSangeeta Misra * That's why we need to retain currently unused "h" argument
164dbed73cbSSangeeta Misra */
165dbed73cbSSangeeta Misra /* ARGSUSED */
166dbed73cbSSangeeta Misra static ilb_status_t
ilbadm_list_sg_srv(ilb_handle_t h,ilb_server_data_t * sd,const char * sgname,void * arg)167dbed73cbSSangeeta Misra ilbadm_list_sg_srv(ilb_handle_t h, ilb_server_data_t *sd, const char *sgname,
168dbed73cbSSangeeta Misra void *arg)
169dbed73cbSSangeeta Misra {
170dbed73cbSSangeeta Misra char ip_str[2*INET6_ADDRSTRLEN + 3] = "";
171dbed73cbSSangeeta Misra char port_str[INET6_ADDRSTRLEN];
172dbed73cbSSangeeta Misra list_arg_t *larg = (list_arg_t *)arg;
173dbed73cbSSangeeta Misra ofmt_status_t oerr;
174dbed73cbSSangeeta Misra int oflags = 0;
175dbed73cbSSangeeta Misra int ocols = MAXCOLS;
176dbed73cbSSangeeta Misra int h_minport, h_maxport;
177dbed73cbSSangeeta Misra static ofmt_handle_t oh = (ofmt_handle_t)NULL;
178dbed73cbSSangeeta Misra ofmt_field_t *ofp;
179dbed73cbSSangeeta Misra
180dbed73cbSSangeeta Misra if (larg->o_str != NULL) {
181dbed73cbSSangeeta Misra if (oh == NULL) {
182dbed73cbSSangeeta Misra if (sd->sd_addr.ia_af == AF_INET)
183dbed73cbSSangeeta Misra ofp = sgfields_v6;
184dbed73cbSSangeeta Misra else
185dbed73cbSSangeeta Misra ofp = sgfields_v4;
186dbed73cbSSangeeta Misra
187dbed73cbSSangeeta Misra if (larg->flags & ILBADM_LIST_PARSE)
188dbed73cbSSangeeta Misra oflags |= OFMT_PARSABLE;
189dbed73cbSSangeeta Misra
190dbed73cbSSangeeta Misra oerr = ofmt_open(larg->o_str, ofp, oflags, ocols, &oh);
191dbed73cbSSangeeta Misra if (oerr != OFMT_SUCCESS) {
192dbed73cbSSangeeta Misra char e[80];
193dbed73cbSSangeeta Misra
194dbed73cbSSangeeta Misra ilbadm_err(gettext("ofmt_open failed: %s"),
195dbed73cbSSangeeta Misra ofmt_strerror(oh, oerr, e, sizeof (e)));
196dbed73cbSSangeeta Misra return (ILB_STATUS_GENERIC);
197dbed73cbSSangeeta Misra }
198dbed73cbSSangeeta Misra larg->oh = oh;
199dbed73cbSSangeeta Misra }
200dbed73cbSSangeeta Misra
201dbed73cbSSangeeta Misra
202dbed73cbSSangeeta Misra (void) i_list_sg_srv_ofmt((char *)sgname, sd, arg);
203dbed73cbSSangeeta Misra return (ILB_STATUS_OK);
204dbed73cbSSangeeta Misra }
205dbed73cbSSangeeta Misra
206dbed73cbSSangeeta Misra ip2str(&sd->sd_addr, ip_str, sizeof (ip_str), 0);
207dbed73cbSSangeeta Misra
208dbed73cbSSangeeta Misra h_minport = ntohs(sd->sd_minport);
209dbed73cbSSangeeta Misra h_maxport = ntohs(sd->sd_maxport);
210dbed73cbSSangeeta Misra if (h_minport == 0)
211dbed73cbSSangeeta Misra *port_str = '\0';
212dbed73cbSSangeeta Misra else if (h_maxport > h_minport)
213dbed73cbSSangeeta Misra (void) sprintf(port_str, ":%d-%d", h_minport, h_maxport);
214dbed73cbSSangeeta Misra else
215dbed73cbSSangeeta Misra (void) sprintf(port_str, ":%d", h_minport);
216dbed73cbSSangeeta Misra
217dbed73cbSSangeeta Misra (void) printf("%s: id:%s %s%s\n", sgname,
218*e8ef49e9SToomas Soome sd->sd_srvID, ip_str, port_str);
219dbed73cbSSangeeta Misra return (ILB_STATUS_OK);
220dbed73cbSSangeeta Misra }
221dbed73cbSSangeeta Misra
222dbed73cbSSangeeta Misra ilb_status_t
ilbadm_list_sg(ilb_handle_t h,ilb_sg_data_t * sg,void * arg)223dbed73cbSSangeeta Misra ilbadm_list_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
224dbed73cbSSangeeta Misra {
225dbed73cbSSangeeta Misra if (sg->sgd_srvcount == 0) {
226dbed73cbSSangeeta Misra ilb_server_data_t tmp_srv;
227dbed73cbSSangeeta Misra
228dbed73cbSSangeeta Misra bzero(&tmp_srv, sizeof (tmp_srv));
229dbed73cbSSangeeta Misra return (ilbadm_list_sg_srv(h, &tmp_srv, sg->sgd_name, arg));
230dbed73cbSSangeeta Misra }
231dbed73cbSSangeeta Misra
232dbed73cbSSangeeta Misra return (ilb_walk_servers(h, ilbadm_list_sg_srv, sg->sgd_name, arg));
233dbed73cbSSangeeta Misra }
234dbed73cbSSangeeta Misra
235dbed73cbSSangeeta Misra static char *def_fields = "SGNAME,SERVERID,MINPORT,MAXPORT,IP_ADDRESS";
236dbed73cbSSangeeta Misra
237dbed73cbSSangeeta Misra /* ARGSUSED */
238dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_show_servergroups(int argc,char * argv[])239dbed73cbSSangeeta Misra ilbadm_show_servergroups(int argc, char *argv[])
240dbed73cbSSangeeta Misra {
241dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
242dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
243dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
244dbed73cbSSangeeta Misra int c;
245dbed73cbSSangeeta Misra char optstr[] = ":po:";
246dbed73cbSSangeeta Misra
247dbed73cbSSangeeta Misra boolean_t o_opt = B_FALSE, p_opt = B_FALSE;
248dbed73cbSSangeeta Misra list_arg_t larg = {0, def_fields, NULL, NULL};
249dbed73cbSSangeeta Misra
250dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, optstr)) != -1) {
251dbed73cbSSangeeta Misra switch ((char)c) {
252dbed73cbSSangeeta Misra case 'p': p_opt = B_TRUE;
253dbed73cbSSangeeta Misra larg.flags |= ILBADM_LIST_PARSE;
254dbed73cbSSangeeta Misra break;
255dbed73cbSSangeeta Misra case 'o': larg.o_str = optarg;
256dbed73cbSSangeeta Misra o_opt = B_TRUE;
257dbed73cbSSangeeta Misra break;
258dbed73cbSSangeeta Misra case ':': ilbadm_err(gettext("missing option argument"
259dbed73cbSSangeeta Misra " for %c"), (char)optopt);
260dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
261dbed73cbSSangeeta Misra goto out;
262dbed73cbSSangeeta Misra default: unknown_opt(argv, optind-1);
263dbed73cbSSangeeta Misra /* not reached */
264dbed73cbSSangeeta Misra break;
265dbed73cbSSangeeta Misra }
266dbed73cbSSangeeta Misra }
267dbed73cbSSangeeta Misra
268dbed73cbSSangeeta Misra if (p_opt && !o_opt) {
269dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires -o"));
270dbed73cbSSangeeta Misra exit(1);
271dbed73cbSSangeeta Misra }
272dbed73cbSSangeeta Misra
273dbed73cbSSangeeta Misra if (p_opt && larg.o_str != NULL &&
274dbed73cbSSangeeta Misra (strcasecmp(larg.o_str, "all") == 0)) {
275dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires explicit field"
276dbed73cbSSangeeta Misra " names for -o"));
277dbed73cbSSangeeta Misra exit(1);
278dbed73cbSSangeeta Misra }
279dbed73cbSSangeeta Misra
280dbed73cbSSangeeta Misra rclib = ilb_open(&h);
281dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
282dbed73cbSSangeeta Misra goto out;
283dbed73cbSSangeeta Misra
284dbed73cbSSangeeta Misra if (optind >= argc) {
285dbed73cbSSangeeta Misra rclib = ilb_walk_servergroups(h, ilbadm_list_sg, NULL,
286dbed73cbSSangeeta Misra (void*)&larg);
287dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
288dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
289dbed73cbSSangeeta Misra } else {
290dbed73cbSSangeeta Misra while (optind < argc) {
291dbed73cbSSangeeta Misra rclib = ilb_walk_servergroups(h, ilbadm_list_sg,
292dbed73cbSSangeeta Misra argv[optind++], (void*)&larg);
293dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
294dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
295dbed73cbSSangeeta Misra break;
296dbed73cbSSangeeta Misra }
297dbed73cbSSangeeta Misra }
298dbed73cbSSangeeta Misra }
299dbed73cbSSangeeta Misra
300dbed73cbSSangeeta Misra if (larg.oh != NULL)
301dbed73cbSSangeeta Misra ofmt_close(larg.oh);
302dbed73cbSSangeeta Misra out:
303dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
304dbed73cbSSangeeta Misra (void) ilb_close(h);
305dbed73cbSSangeeta Misra
306dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
307dbed73cbSSangeeta Misra /*
308dbed73cbSSangeeta Misra * The show function returns ILB_STATUS_GENERIC after printing
309dbed73cbSSangeeta Misra * out an error message. So we don't need to print it again.
310dbed73cbSSangeeta Misra */
311dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_GENERIC)
312dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib));
313dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
314dbed73cbSSangeeta Misra }
315dbed73cbSSangeeta Misra
316dbed73cbSSangeeta Misra return (rc);
317dbed73cbSSangeeta Misra }
318dbed73cbSSangeeta Misra
319dbed73cbSSangeeta Misra ilbadm_servnode_t *
i_new_sg_elem(ilbadm_sgroup_t * sgp)320dbed73cbSSangeeta Misra i_new_sg_elem(ilbadm_sgroup_t *sgp)
321dbed73cbSSangeeta Misra {
322dbed73cbSSangeeta Misra ilbadm_servnode_t *s;
323dbed73cbSSangeeta Misra
324dbed73cbSSangeeta Misra s = (ilbadm_servnode_t *)calloc(sizeof (*s), 1);
325dbed73cbSSangeeta Misra if (s != NULL) {
326dbed73cbSSangeeta Misra list_insert_tail(&sgp->sg_serv_list, s);
327dbed73cbSSangeeta Misra sgp->sg_count++;
328dbed73cbSSangeeta Misra }
329dbed73cbSSangeeta Misra return (s);
330dbed73cbSSangeeta Misra }
331dbed73cbSSangeeta Misra
332dbed73cbSSangeeta Misra static ilbadm_status_t
i_parse_servrange_list(char * arg,ilbadm_sgroup_t * sgp)333dbed73cbSSangeeta Misra i_parse_servrange_list(char *arg, ilbadm_sgroup_t *sgp)
334dbed73cbSSangeeta Misra {
335dbed73cbSSangeeta Misra ilbadm_status_t rc;
336dbed73cbSSangeeta Misra int count;
337dbed73cbSSangeeta Misra
338dbed73cbSSangeeta Misra rc = i_parse_optstring(arg, (void *) sgp, servrange_keys,
339dbed73cbSSangeeta Misra OPT_VALUE_LIST|OPT_IP_RANGE|OPT_PORTS, &count);
340dbed73cbSSangeeta Misra return (rc);
341dbed73cbSSangeeta Misra }
342dbed73cbSSangeeta Misra
343dbed73cbSSangeeta Misra static ilbadm_status_t
i_parse_serverIDs(char * arg,ilbadm_sgroup_t * sgp)344dbed73cbSSangeeta Misra i_parse_serverIDs(char *arg, ilbadm_sgroup_t *sgp)
345dbed73cbSSangeeta Misra {
346dbed73cbSSangeeta Misra ilbadm_status_t rc;
347dbed73cbSSangeeta Misra int count;
348dbed73cbSSangeeta Misra
349dbed73cbSSangeeta Misra rc = i_parse_optstring(arg, (void *) sgp, serverID_keys,
350dbed73cbSSangeeta Misra OPT_VALUE_LIST|OPT_PORTS, &count);
351dbed73cbSSangeeta Misra return (rc);
352dbed73cbSSangeeta Misra }
353dbed73cbSSangeeta Misra
354dbed73cbSSangeeta Misra static ilbadm_status_t
i_mod_sg(ilb_handle_t h,ilbadm_sgroup_t * sgp,ilbadm_cmd_t cmd,int flags)355dbed73cbSSangeeta Misra i_mod_sg(ilb_handle_t h, ilbadm_sgroup_t *sgp, ilbadm_cmd_t cmd,
356dbed73cbSSangeeta Misra int flags)
357dbed73cbSSangeeta Misra {
358dbed73cbSSangeeta Misra ilbadm_servnode_t *sn;
359dbed73cbSSangeeta Misra ilb_server_data_t *srv;
360dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
361dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
362dbed73cbSSangeeta Misra
363dbed73cbSSangeeta Misra if (h == ILB_INVALID_HANDLE && cmd != cmd_enable_server &&
364dbed73cbSSangeeta Misra cmd != cmd_disable_server)
365dbed73cbSSangeeta Misra return (ILBADM_LIBERR);
366dbed73cbSSangeeta Misra
367dbed73cbSSangeeta Misra sn = list_head(&sgp->sg_serv_list);
368dbed73cbSSangeeta Misra while (sn != NULL) {
369dbed73cbSSangeeta Misra srv = &sn->s_spec;
370dbed73cbSSangeeta Misra
371dbed73cbSSangeeta Misra srv->sd_flags |= flags;
372dbed73cbSSangeeta Misra if (cmd == cmd_create_sg || cmd == cmd_add_srv) {
373dbed73cbSSangeeta Misra rclib = ilb_add_server_to_group(h, sgp->sg_name,
374dbed73cbSSangeeta Misra srv);
375dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
376dbed73cbSSangeeta Misra char buf[INET6_ADDRSTRLEN + 1];
377dbed73cbSSangeeta Misra
378dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
379dbed73cbSSangeeta Misra ip2str(&srv->sd_addr, buf, sizeof (buf),
380dbed73cbSSangeeta Misra V6_ADDRONLY);
381dbed73cbSSangeeta Misra ilbadm_err(gettext("cannot add %s to %s: %s"),
382dbed73cbSSangeeta Misra buf, sgp->sg_name, ilb_errstr(rclib));
383dbed73cbSSangeeta Misra /* if we created the SG, we bail out */
384dbed73cbSSangeeta Misra if (cmd == cmd_create_sg)
385dbed73cbSSangeeta Misra return (rc);
386dbed73cbSSangeeta Misra }
387dbed73cbSSangeeta Misra } else {
388dbed73cbSSangeeta Misra assert(cmd == cmd_rem_srv);
389dbed73cbSSangeeta Misra rclib = ilb_rem_server_from_group(h, sgp->sg_name,
390dbed73cbSSangeeta Misra srv);
391dbed73cbSSangeeta Misra /* if we fail, we tell user and continue */
392dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
393dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
394dbed73cbSSangeeta Misra ilbadm_err(
395dbed73cbSSangeeta Misra gettext("cannot remove %s from %s: %s"),
396dbed73cbSSangeeta Misra srv->sd_srvID, sgp->sg_name,
397dbed73cbSSangeeta Misra ilb_errstr(rclib));
398dbed73cbSSangeeta Misra }
399dbed73cbSSangeeta Misra }
400dbed73cbSSangeeta Misra
401dbed73cbSSangeeta Misra /*
402dbed73cbSSangeeta Misra * list_next returns NULL instead of cycling back to head
403dbed73cbSSangeeta Misra * so we don't have to check for list_head explicitly.
404dbed73cbSSangeeta Misra */
405dbed73cbSSangeeta Misra sn = list_next(&sgp->sg_serv_list, sn);
406dbed73cbSSangeeta Misra };
407dbed73cbSSangeeta Misra
408dbed73cbSSangeeta Misra return (rc);
409dbed73cbSSangeeta Misra }
410dbed73cbSSangeeta Misra
411dbed73cbSSangeeta Misra static void
i_ilbadm_alloc_sgroup(ilbadm_sgroup_t ** sgp)412dbed73cbSSangeeta Misra i_ilbadm_alloc_sgroup(ilbadm_sgroup_t **sgp)
413dbed73cbSSangeeta Misra {
414dbed73cbSSangeeta Misra ilbadm_sgroup_t *sg;
415dbed73cbSSangeeta Misra
416dbed73cbSSangeeta Misra *sgp = sg = (ilbadm_sgroup_t *)calloc(sizeof (*sg), 1);
417dbed73cbSSangeeta Misra if (sg == NULL)
418dbed73cbSSangeeta Misra return;
419dbed73cbSSangeeta Misra list_create(&sg->sg_serv_list, sizeof (ilbadm_servnode_t),
420dbed73cbSSangeeta Misra offsetof(ilbadm_servnode_t, s_link));
421dbed73cbSSangeeta Misra }
422dbed73cbSSangeeta Misra
423dbed73cbSSangeeta Misra static void
i_ilbadm_free_sgroup(ilbadm_sgroup_t * sg)424dbed73cbSSangeeta Misra i_ilbadm_free_sgroup(ilbadm_sgroup_t *sg)
425dbed73cbSSangeeta Misra {
426dbed73cbSSangeeta Misra ilbadm_servnode_t *s;
427dbed73cbSSangeeta Misra
428dbed73cbSSangeeta Misra while ((s = list_remove_head(&sg->sg_serv_list)) != NULL)
429dbed73cbSSangeeta Misra free(s);
430dbed73cbSSangeeta Misra
431dbed73cbSSangeeta Misra list_destroy(&sg->sg_serv_list);
432dbed73cbSSangeeta Misra }
433dbed73cbSSangeeta Misra
434dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_create_servergroup(int argc,char * argv[])435dbed73cbSSangeeta Misra ilbadm_create_servergroup(int argc, char *argv[])
436dbed73cbSSangeeta Misra {
437dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
438dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
439dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
440dbed73cbSSangeeta Misra ilbadm_sgroup_t *sg;
441dbed73cbSSangeeta Misra int c;
442dbed73cbSSangeeta Misra int flags = 0;
443dbed73cbSSangeeta Misra
444dbed73cbSSangeeta Misra i_ilbadm_alloc_sgroup(&sg);
445dbed73cbSSangeeta Misra
446dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":s:")) != -1) {
447dbed73cbSSangeeta Misra switch ((char)c) {
448dbed73cbSSangeeta Misra case 's':
449dbed73cbSSangeeta Misra rc = i_parse_servrange_list(optarg, sg);
450dbed73cbSSangeeta Misra break;
451dbed73cbSSangeeta Misra case ':':
452dbed73cbSSangeeta Misra ilbadm_err(gettext("missing option-argument for"
453dbed73cbSSangeeta Misra " %c"), (char)optopt);
454dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
455dbed73cbSSangeeta Misra break;
456dbed73cbSSangeeta Misra case '?':
457dbed73cbSSangeeta Misra default:
458dbed73cbSSangeeta Misra unknown_opt(argv, optind-1);
459dbed73cbSSangeeta Misra /* not reached */
460dbed73cbSSangeeta Misra break;
461dbed73cbSSangeeta Misra }
462dbed73cbSSangeeta Misra
463dbed73cbSSangeeta Misra if (rc != ILBADM_OK)
464dbed73cbSSangeeta Misra goto out;
465dbed73cbSSangeeta Misra }
466dbed73cbSSangeeta Misra
467dbed73cbSSangeeta Misra if (optind >= argc) {
468dbed73cbSSangeeta Misra ilbadm_err(gettext("missing mandatory arguments - please refer"
469dbed73cbSSangeeta Misra " to 'create-servergroup' subcommand"
470bbf21555SRichard Lowe " description in ilbadm(8)"));
471dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
472dbed73cbSSangeeta Misra goto out;
473dbed73cbSSangeeta Misra }
474dbed73cbSSangeeta Misra
475dbed73cbSSangeeta Misra if (strlen(argv[optind]) > ILB_SGNAME_SZ - 1) {
476dbed73cbSSangeeta Misra ilbadm_err(gettext("servergroup name %s is too long -"
477dbed73cbSSangeeta Misra " must not exceed %d chars"), argv[optind],
478dbed73cbSSangeeta Misra ILB_SGNAME_SZ - 1);
479dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
480dbed73cbSSangeeta Misra goto out;
481dbed73cbSSangeeta Misra }
482dbed73cbSSangeeta Misra
483dbed73cbSSangeeta Misra sg->sg_name = argv[optind];
484dbed73cbSSangeeta Misra
485dbed73cbSSangeeta Misra rclib = ilb_open(&h);
486dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
487dbed73cbSSangeeta Misra goto out;
488dbed73cbSSangeeta Misra
489dbed73cbSSangeeta Misra rclib = ilb_create_servergroup(h, sg->sg_name);
490dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
491dbed73cbSSangeeta Misra goto out;
492dbed73cbSSangeeta Misra
493dbed73cbSSangeeta Misra /* we create a servergroup with all servers enabled */
494dbed73cbSSangeeta Misra ILB_SET_ENABLED(flags);
495dbed73cbSSangeeta Misra rc = i_mod_sg(h, sg, cmd_create_sg, flags);
496dbed73cbSSangeeta Misra
497dbed73cbSSangeeta Misra if (rc != ILBADM_OK)
498dbed73cbSSangeeta Misra (void) ilb_destroy_servergroup(h, sg->sg_name);
499dbed73cbSSangeeta Misra
500dbed73cbSSangeeta Misra out:
501dbed73cbSSangeeta Misra i_ilbadm_free_sgroup(sg);
502dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
503dbed73cbSSangeeta Misra (void) ilb_close(h);
504dbed73cbSSangeeta Misra
505dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
506dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib));
507dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
508dbed73cbSSangeeta Misra }
509dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
510dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc));
511dbed73cbSSangeeta Misra
512dbed73cbSSangeeta Misra return (rc);
513dbed73cbSSangeeta Misra }
514dbed73cbSSangeeta Misra
515dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_add_server_to_group(int argc,char ** argv)516dbed73cbSSangeeta Misra ilbadm_add_server_to_group(int argc, char **argv)
517dbed73cbSSangeeta Misra {
518dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
519dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
520dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
521dbed73cbSSangeeta Misra ilbadm_sgroup_t *sg;
522dbed73cbSSangeeta Misra int c;
523dbed73cbSSangeeta Misra int flags = 0;
524dbed73cbSSangeeta Misra
525dbed73cbSSangeeta Misra i_ilbadm_alloc_sgroup(&sg);
526dbed73cbSSangeeta Misra
527dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":s:")) != -1) {
528dbed73cbSSangeeta Misra switch ((char)c) {
529dbed73cbSSangeeta Misra case 's':
530dbed73cbSSangeeta Misra rc = i_parse_servrange_list(optarg, sg);
531dbed73cbSSangeeta Misra break;
532dbed73cbSSangeeta Misra case ':':
533dbed73cbSSangeeta Misra ilbadm_err(gettext("missing option-argument for"
534dbed73cbSSangeeta Misra " %c"), (char)optopt);
535dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
536dbed73cbSSangeeta Misra break;
537dbed73cbSSangeeta Misra case '?':
538dbed73cbSSangeeta Misra default: unknown_opt(argv, optind-1);
539dbed73cbSSangeeta Misra /* not reached */
540dbed73cbSSangeeta Misra break;
541dbed73cbSSangeeta Misra }
542dbed73cbSSangeeta Misra
543dbed73cbSSangeeta Misra if (rc != ILBADM_OK)
544dbed73cbSSangeeta Misra goto out;
545dbed73cbSSangeeta Misra }
546dbed73cbSSangeeta Misra
547dbed73cbSSangeeta Misra if (optind >= argc) {
548dbed73cbSSangeeta Misra ilbadm_err(gettext("missing mandatory arguments - please refer"
549bbf21555SRichard Lowe " to 'add-server' subcommand description in ilbadm(8)"));
550dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
551dbed73cbSSangeeta Misra goto out;
552dbed73cbSSangeeta Misra }
553dbed73cbSSangeeta Misra
554dbed73cbSSangeeta Misra sg->sg_name = argv[optind];
555dbed73cbSSangeeta Misra
556dbed73cbSSangeeta Misra rclib = ilb_open(&h);
557dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
558dbed73cbSSangeeta Misra goto out;
559dbed73cbSSangeeta Misra
560dbed73cbSSangeeta Misra /* A server is added enabled */
561dbed73cbSSangeeta Misra ILB_SET_ENABLED(flags);
562dbed73cbSSangeeta Misra rc = i_mod_sg(h, sg, cmd_add_srv, flags);
563dbed73cbSSangeeta Misra out:
564dbed73cbSSangeeta Misra i_ilbadm_free_sgroup(sg);
565dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
566dbed73cbSSangeeta Misra (void) ilb_close(h);
567dbed73cbSSangeeta Misra
568dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
569dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc));
570dbed73cbSSangeeta Misra return (rc);
571dbed73cbSSangeeta Misra }
572dbed73cbSSangeeta Misra
573dbed73cbSSangeeta Misra /* ARGSUSED */
574dbed73cbSSangeeta Misra static ilbadm_status_t
ilbadm_Xable_server(int argc,char * argv[],ilbadm_cmd_t cmd)575dbed73cbSSangeeta Misra ilbadm_Xable_server(int argc, char *argv[], ilbadm_cmd_t cmd)
576dbed73cbSSangeeta Misra {
577dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
578dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
579dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
580dbed73cbSSangeeta Misra int i;
581dbed73cbSSangeeta Misra
582dbed73cbSSangeeta Misra if (argc < 2) {
583dbed73cbSSangeeta Misra ilbadm_err(gettext("missing required argument"
584dbed73cbSSangeeta Misra " (server specification)"));
585dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
586dbed73cbSSangeeta Misra goto out;
587dbed73cbSSangeeta Misra }
588dbed73cbSSangeeta Misra
589dbed73cbSSangeeta Misra rclib = ilb_open(&h);
590dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
591dbed73cbSSangeeta Misra goto out;
592dbed73cbSSangeeta Misra
593dbed73cbSSangeeta Misra /* enable-server and disable-server only accepts serverids */
594dbed73cbSSangeeta Misra for (i = 1; i < argc && rclib == ILB_STATUS_OK; i++) {
595dbed73cbSSangeeta Misra ilb_server_data_t srv;
596dbed73cbSSangeeta Misra
597dbed73cbSSangeeta Misra if (argv[i][0] != ILB_SRVID_PREFIX) {
598dbed73cbSSangeeta Misra rc = ILBADM_INVAL_SRVID;
599dbed73cbSSangeeta Misra goto out;
600dbed73cbSSangeeta Misra }
601dbed73cbSSangeeta Misra
602dbed73cbSSangeeta Misra bzero(&srv, sizeof (srv));
603dbed73cbSSangeeta Misra /* to do: check length */
604dbed73cbSSangeeta Misra (void) strlcpy(srv.sd_srvID, argv[i], sizeof (srv.sd_srvID));
605dbed73cbSSangeeta Misra switch (cmd) {
606dbed73cbSSangeeta Misra case cmd_enable_server:
607dbed73cbSSangeeta Misra rclib = ilb_enable_server(h, &srv, NULL);
608dbed73cbSSangeeta Misra break;
609dbed73cbSSangeeta Misra case cmd_disable_server:
610dbed73cbSSangeeta Misra rclib = ilb_disable_server(h, &srv, NULL);
611dbed73cbSSangeeta Misra break;
612dbed73cbSSangeeta Misra }
613dbed73cbSSangeeta Misra
614dbed73cbSSangeeta Misra /* if we can't find a given server ID, just plough on */
615dbed73cbSSangeeta Misra if (rclib == ILB_STATUS_ENOENT) {
616dbed73cbSSangeeta Misra const char *msg = ilb_errstr(rclib);
617dbed73cbSSangeeta Misra
618dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
619dbed73cbSSangeeta Misra ilbadm_err("%s: %s", msg, argv[i]);
620dbed73cbSSangeeta Misra rclib = ILB_STATUS_OK;
621dbed73cbSSangeeta Misra continue;
622dbed73cbSSangeeta Misra }
623dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
624dbed73cbSSangeeta Misra break;
625dbed73cbSSangeeta Misra }
626dbed73cbSSangeeta Misra out:
627dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
628dbed73cbSSangeeta Misra (void) ilb_close(h);
629dbed73cbSSangeeta Misra
630dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
631dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib));
632dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
633dbed73cbSSangeeta Misra }
634dbed73cbSSangeeta Misra
635dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
636dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc));
637dbed73cbSSangeeta Misra return (rc);
638dbed73cbSSangeeta Misra }
639dbed73cbSSangeeta Misra
640dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_disable_server(int argc,char * argv[])641dbed73cbSSangeeta Misra ilbadm_disable_server(int argc, char *argv[])
642dbed73cbSSangeeta Misra {
643dbed73cbSSangeeta Misra return (ilbadm_Xable_server(argc, argv, cmd_disable_server));
644dbed73cbSSangeeta Misra }
645dbed73cbSSangeeta Misra
646dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_enable_server(int argc,char * argv[])647dbed73cbSSangeeta Misra ilbadm_enable_server(int argc, char *argv[])
648dbed73cbSSangeeta Misra {
649dbed73cbSSangeeta Misra return (ilbadm_Xable_server(argc, argv, cmd_enable_server));
650dbed73cbSSangeeta Misra }
651dbed73cbSSangeeta Misra
652dbed73cbSSangeeta Misra /* ARGSUSED */
653dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_rem_server_from_group(int argc,char * argv[])654dbed73cbSSangeeta Misra ilbadm_rem_server_from_group(int argc, char *argv[])
655dbed73cbSSangeeta Misra {
656dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
657dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
658dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
659dbed73cbSSangeeta Misra ilbadm_sgroup_t *sg;
660dbed73cbSSangeeta Misra int c;
661dbed73cbSSangeeta Misra
662dbed73cbSSangeeta Misra i_ilbadm_alloc_sgroup(&sg);
663dbed73cbSSangeeta Misra
664dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":s:")) != -1) {
665dbed73cbSSangeeta Misra switch ((char)c) {
666dbed73cbSSangeeta Misra case 's':
667dbed73cbSSangeeta Misra rc = i_parse_serverIDs(optarg, sg);
668dbed73cbSSangeeta Misra break;
669dbed73cbSSangeeta Misra case ':':
670dbed73cbSSangeeta Misra ilbadm_err(gettext("missing option-argument for"
671dbed73cbSSangeeta Misra " %c"), (char)optopt);
672dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
673dbed73cbSSangeeta Misra break;
674dbed73cbSSangeeta Misra case '?':
675dbed73cbSSangeeta Misra default: unknown_opt(argv, optind-1);
676dbed73cbSSangeeta Misra /* not reached */
677dbed73cbSSangeeta Misra break;
678dbed73cbSSangeeta Misra }
679dbed73cbSSangeeta Misra if (rc != ILBADM_OK)
680dbed73cbSSangeeta Misra goto out;
681dbed73cbSSangeeta Misra }
682dbed73cbSSangeeta Misra
683dbed73cbSSangeeta Misra /* we need servergroup name and at least one serverID to remove */
684dbed73cbSSangeeta Misra if (optind >= argc || sg->sg_count == 0) {
685dbed73cbSSangeeta Misra rc = ILBADM_ENOOPTION;
686dbed73cbSSangeeta Misra goto out;
687dbed73cbSSangeeta Misra }
688dbed73cbSSangeeta Misra
689dbed73cbSSangeeta Misra sg->sg_name = argv[optind];
690dbed73cbSSangeeta Misra
691dbed73cbSSangeeta Misra rclib = ilb_open(&h);
692dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
693dbed73cbSSangeeta Misra goto out;
694dbed73cbSSangeeta Misra
695dbed73cbSSangeeta Misra rc = i_mod_sg(h, sg, cmd_rem_srv, 0);
696dbed73cbSSangeeta Misra out:
697dbed73cbSSangeeta Misra i_ilbadm_free_sgroup(sg);
698dbed73cbSSangeeta Misra
699dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
700dbed73cbSSangeeta Misra (void) ilb_close(h);
701dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
702dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc));
703dbed73cbSSangeeta Misra return (rc);
704dbed73cbSSangeeta Misra }
705dbed73cbSSangeeta Misra
706dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_destroy_servergroup(int argc,char * argv[])707dbed73cbSSangeeta Misra ilbadm_destroy_servergroup(int argc, char *argv[])
708dbed73cbSSangeeta Misra {
709dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE;
710dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
711dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
712dbed73cbSSangeeta Misra char *sgname;
713dbed73cbSSangeeta Misra
714dbed73cbSSangeeta Misra if (argc != 2) {
715dbed73cbSSangeeta Misra ilbadm_err(gettext("usage:ilbadm"
716dbed73cbSSangeeta Misra " delete-servergroup groupname"));
717dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
718dbed73cbSSangeeta Misra goto out;
719dbed73cbSSangeeta Misra }
720dbed73cbSSangeeta Misra
721dbed73cbSSangeeta Misra sgname = argv[1];
722dbed73cbSSangeeta Misra
723dbed73cbSSangeeta Misra rclib = ilb_open(&h);
724dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK)
725dbed73cbSSangeeta Misra goto out;
726dbed73cbSSangeeta Misra
727dbed73cbSSangeeta Misra rclib = ilb_destroy_servergroup(h, sgname);
728dbed73cbSSangeeta Misra out:
729dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE)
730dbed73cbSSangeeta Misra (void) ilb_close(h);
731dbed73cbSSangeeta Misra
732dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
733dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib));
734dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
735dbed73cbSSangeeta Misra }
736dbed73cbSSangeeta Misra
737dbed73cbSSangeeta Misra return (rc);
738dbed73cbSSangeeta Misra }
739dbed73cbSSangeeta Misra
740dbed73cbSSangeeta Misra #define BUFSZ 1024
741dbed73cbSSangeeta Misra
742dbed73cbSSangeeta Misra static int
export_srv_spec(ilb_server_data_t * srv,char * buf,const int bufsize)743dbed73cbSSangeeta Misra export_srv_spec(ilb_server_data_t *srv, char *buf, const int bufsize)
744dbed73cbSSangeeta Misra {
745dbed73cbSSangeeta Misra int len = 0, bufsz = (int)bufsize;
746dbed73cbSSangeeta Misra
747dbed73cbSSangeeta Misra ip2str(&srv->sd_addr, buf, bufsz, 0);
748dbed73cbSSangeeta Misra
749dbed73cbSSangeeta Misra len += strlen(buf);
750dbed73cbSSangeeta Misra bufsz -= len;
751dbed73cbSSangeeta Misra
752dbed73cbSSangeeta Misra if (srv->sd_minport != 0) {
753dbed73cbSSangeeta Misra in_port_t h_min, h_max;
754dbed73cbSSangeeta Misra int inc;
755dbed73cbSSangeeta Misra
756dbed73cbSSangeeta Misra h_min = ntohs(srv->sd_minport);
757dbed73cbSSangeeta Misra h_max = ntohs(srv->sd_maxport);
758dbed73cbSSangeeta Misra
759dbed73cbSSangeeta Misra /* to do: if service name was given, print that, not number */
760dbed73cbSSangeeta Misra if (h_max <= h_min)
761dbed73cbSSangeeta Misra inc = snprintf(buf+len, bufsz, ":%d", h_min);
762dbed73cbSSangeeta Misra else
763dbed73cbSSangeeta Misra inc = snprintf(buf+len, bufsz, ":%d-%d", h_min, h_max);
764dbed73cbSSangeeta Misra
765dbed73cbSSangeeta Misra if (inc > bufsz) /* too little space */
766dbed73cbSSangeeta Misra return (-1);
767dbed73cbSSangeeta Misra len += inc;
768dbed73cbSSangeeta Misra }
769dbed73cbSSangeeta Misra
770dbed73cbSSangeeta Misra return (len);
771dbed73cbSSangeeta Misra }
772dbed73cbSSangeeta Misra
773dbed73cbSSangeeta Misra
774dbed73cbSSangeeta Misra /*
775dbed73cbSSangeeta Misra * this is called by ilb_walk_servers(), therefore we return ilb_status_t
776dbed73cbSSangeeta Misra * not ilbadm_status, and retain an unused function argument
777dbed73cbSSangeeta Misra */
778dbed73cbSSangeeta Misra /* ARGSUSED */
779dbed73cbSSangeeta Misra ilb_status_t
ilbadm_export_a_srv(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname,void * arg)780dbed73cbSSangeeta Misra ilbadm_export_a_srv(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
781dbed73cbSSangeeta Misra void *arg)
782dbed73cbSSangeeta Misra {
783dbed73cbSSangeeta Misra sg_export_arg_t *larg = (sg_export_arg_t *)arg;
784dbed73cbSSangeeta Misra FILE *fp = larg->fp;
785dbed73cbSSangeeta Misra char linebuf[BUFSZ]; /* XXXms make that dynamic */
786dbed73cbSSangeeta Misra int sz = BUFSZ;
787dbed73cbSSangeeta Misra
788dbed73cbSSangeeta Misra if (export_srv_spec(srv, linebuf, sz) == -1)
789dbed73cbSSangeeta Misra return (ILB_STATUS_OK);
790dbed73cbSSangeeta Misra
791dbed73cbSSangeeta Misra (void) fprintf(fp, "add-server -s server=");
792dbed73cbSSangeeta Misra
793dbed73cbSSangeeta Misra (void) fprintf(fp, "%s %s\n", linebuf, sgname);
794dbed73cbSSangeeta Misra return (ILB_STATUS_OK);
795dbed73cbSSangeeta Misra }
796dbed73cbSSangeeta Misra
797dbed73cbSSangeeta Misra ilb_status_t
ilbadm_export_sg(ilb_handle_t h,ilb_sg_data_t * sg,void * arg)798dbed73cbSSangeeta Misra ilbadm_export_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
799dbed73cbSSangeeta Misra {
800dbed73cbSSangeeta Misra ilb_status_t rc = ILB_STATUS_OK;
801dbed73cbSSangeeta Misra sg_export_arg_t *larg = (sg_export_arg_t *)arg;
802dbed73cbSSangeeta Misra FILE *fp = larg->fp;
803dbed73cbSSangeeta Misra
804dbed73cbSSangeeta Misra (void) fprintf(fp, "create-servergroup %s\n", sg->sgd_name);
805dbed73cbSSangeeta Misra if (sg->sgd_srvcount == 0)
806dbed73cbSSangeeta Misra return (ILB_STATUS_OK);
807dbed73cbSSangeeta Misra
808dbed73cbSSangeeta Misra rc = ilb_walk_servers(h, ilbadm_export_a_srv, sg->sgd_name, arg);
809dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK)
810dbed73cbSSangeeta Misra goto out;
811dbed73cbSSangeeta Misra
812dbed73cbSSangeeta Misra if (fflush(fp) == EOF)
813dbed73cbSSangeeta Misra rc = ILB_STATUS_WRITE;
814dbed73cbSSangeeta Misra
815dbed73cbSSangeeta Misra out:
816dbed73cbSSangeeta Misra return (rc);
817dbed73cbSSangeeta Misra }
818dbed73cbSSangeeta Misra
819dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_export_servergroups(ilb_handle_t h,FILE * fp)820dbed73cbSSangeeta Misra ilbadm_export_servergroups(ilb_handle_t h, FILE *fp)
821dbed73cbSSangeeta Misra {
822dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK;
823dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK;
824dbed73cbSSangeeta Misra sg_export_arg_t arg;
825dbed73cbSSangeeta Misra
826dbed73cbSSangeeta Misra arg.fp = fp;
827dbed73cbSSangeeta Misra arg.sg = NULL;
828dbed73cbSSangeeta Misra
829dbed73cbSSangeeta Misra rclib = ilb_walk_servergroups(h, ilbadm_export_sg, NULL, (void *)&arg);
830dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) {
831dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib));
832dbed73cbSSangeeta Misra rc = ILBADM_LIBERR;
833dbed73cbSSangeeta Misra }
834dbed73cbSSangeeta Misra
835dbed73cbSSangeeta Misra return (rc);
836dbed73cbSSangeeta Misra }
837