4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
33 #include <libilb_impl.h>
37 i_ilb_addrem_sg(ilb_handle_t h
, const char *sgname
, ilbd_cmd_t cmd
)
43 if (h
== ILB_INVALID_HANDLE
|| sgname
== NULL
|| *sgname
== '\0')
44 return (ILB_STATUS_EINVAL
);
46 if (strlen(sgname
) > ILB_SGNAME_SZ
- 1)
47 return (ILB_STATUS_NAMETOOLONG
);
49 if ((ic
= i_ilb_alloc_req(cmd
, &ic_sz
)) == NULL
)
50 return (ILB_STATUS_ENOMEM
);
52 (void) strlcpy((char *)&ic
->ic_data
, sgname
, sizeof (ilbd_name_t
));
54 rc
= i_ilb_do_comm(h
, ic
, ic_sz
, ic
, &ic_sz
);
55 if (rc
!= ILB_STATUS_OK
)
58 if (ic
->ic_cmd
!= ILBD_CMD_OK
)
59 rc
= *(ilb_status_t
*)&ic
->ic_data
;
66 ilb_destroy_servergroup(ilb_handle_t h
, const char *sgname
)
68 return (i_ilb_addrem_sg(h
, sgname
, ILBD_DESTROY_SERVERGROUP
));
72 ilb_create_servergroup(ilb_handle_t h
, const char *sgname
)
74 return (i_ilb_addrem_sg(h
, sgname
, ILBD_CREATE_SERVERGROUP
));
78 i_ilb_addrem_server_to_group(ilb_handle_t h
, const char *sgname
,
79 ilb_server_data_t
*srv
, ilbd_cmd_t cmd
)
81 ilb_status_t rc
= ILB_STATUS_OK
;
84 in_port_t h_maxport
, h_minport
;
88 if (h
== ILB_INVALID_HANDLE
|| sgname
== NULL
||
89 *sgname
== '\0' || srv
== NULL
)
90 return (ILB_STATUS_EINVAL
);
92 if (strlen(sgname
) > ILB_SGNAME_SZ
- 1)
93 return (ILB_STATUS_NAMETOOLONG
);
95 /* now all the checks have passed, we can pass on the goods */
96 if ((ic
= i_ilb_alloc_req(cmd
, &ic_sz
)) == NULL
)
97 return (ILB_STATUS_ENOMEM
);
99 sg
= (ilb_sg_info_t
*)&ic
->ic_data
;
101 (void) strlcpy(sg
->sg_name
, sgname
, sizeof (sg
->sg_name
));
103 sgs
= &sg
->sg_servers
[0];
105 IP_COPY_CLI_2_IMPL(&srv
->sd_addr
, &sgs
->sgs_addr
);
106 h_minport
= ntohs(srv
->sd_minport
);
107 h_maxport
= ntohs(srv
->sd_maxport
);
108 sgs
->sgs_minport
= srv
->sd_minport
;
109 if (h_minport
!= 0 && h_maxport
< h_minport
)
110 sgs
->sgs_maxport
= srv
->sd_minport
;
112 sgs
->sgs_maxport
= srv
->sd_maxport
;
114 sgs
->sgs_flags
= srv
->sd_flags
;
115 if (srv
->sd_srvID
[0] == ILB_SRVID_PREFIX
)
116 (void) strlcpy(sgs
->sgs_srvID
, srv
->sd_srvID
,
117 sizeof (sgs
->sgs_srvID
));
119 rc
= i_ilb_do_comm(h
, ic
, ic_sz
, ic
, &ic_sz
);
120 if (rc
!= ILB_STATUS_OK
)
123 if (ic
->ic_cmd
!= ILBD_CMD_OK
)
124 rc
= *(ilb_status_t
*)&ic
->ic_data
;
132 ilb_add_server_to_group(ilb_handle_t h
, const char *sgname
,
133 ilb_server_data_t
*srv
)
135 return (i_ilb_addrem_server_to_group(h
, sgname
, srv
,
136 ILBD_ADD_SERVER_TO_GROUP
));
140 ilb_rem_server_from_group(ilb_handle_t h
, const char *sgname
,
141 ilb_server_data_t
*srv
)
143 return (i_ilb_addrem_server_to_group(h
, sgname
, srv
,
144 ILBD_REM_SERVER_FROM_GROUP
));
148 i_ilb_retrieve_sg_names(ilb_handle_t h
, ilb_comm_t
**rbuf
, size_t *rbufsz
)
151 ilb_comm_t ic
, *tmp_rbuf
;
153 *rbufsz
= ILBD_MSG_SIZE
;
154 if ((tmp_rbuf
= malloc(*rbufsz
)) == NULL
)
155 return (ILB_STATUS_ENOMEM
);
157 ic
.ic_cmd
= ILBD_RETRIEVE_SG_NAMES
;
158 rc
= i_ilb_do_comm(h
, &ic
, sizeof (ic
), tmp_rbuf
, rbufsz
);
159 if (rc
!= ILB_STATUS_OK
)
162 if (tmp_rbuf
->ic_cmd
== ILBD_CMD_OK
) {
166 rc
= *(ilb_status_t
*)&tmp_rbuf
->ic_data
;
174 i_ilb_retrieve_sg_hosts(ilb_handle_t h
, const char *sgname
, ilb_comm_t
**rbuf
,
178 ilb_comm_t
*ic
, *tmp_rbuf
;
181 if ((ic
= i_ilb_alloc_req(ILBD_RETRIEVE_SG_HOSTS
, &ic_sz
)) == NULL
)
182 return (ILB_STATUS_ENOMEM
);
183 *rbufsz
= ILBD_MSG_SIZE
;
184 if ((tmp_rbuf
= malloc(*rbufsz
)) == NULL
) {
187 return (ILB_STATUS_ENOMEM
);
190 (void) strlcpy((char *)&ic
->ic_data
, sgname
, sizeof (ilbd_name_t
));
191 rc
= i_ilb_do_comm(h
, ic
, ic_sz
, tmp_rbuf
, rbufsz
);
192 if (rc
!= ILB_STATUS_OK
)
195 if (tmp_rbuf
->ic_cmd
== ILBD_CMD_OK
) {
200 rc
= *(ilb_status_t
*)&tmp_rbuf
->ic_data
;
214 * "walks" one sg (retrieves data) and depending on "walktype" argument
215 * call servergroup function once per sg or server function once
216 * for every server. in both cases, the argument "f" is cast to
217 * be the proper function pointer type
220 i_ilb_walk_one_sg(ilb_handle_t h
, void *f
, const char *sgname
, void *arg
,
223 ilb_status_t rc
= ILB_STATUS_OK
;
224 ilb_sg_info_t
*sg_info
;
230 rc
= i_ilb_retrieve_sg_hosts(h
, sgname
, &rbuf
, &rbufsz
);
231 if (rc
!= ILB_STATUS_OK
)
233 sg_info
= (ilb_sg_info_t
*)&rbuf
->ic_data
;
235 if (walktype
== walk_sg
) {
236 sg_walkerfunc_t sg_func
= (sg_walkerfunc_t
)f
;
239 (void) strlcpy(sgd
.sgd_name
, sg_info
->sg_name
,
240 sizeof (sgd
.sgd_name
));
241 sgd
.sgd_srvcount
= sg_info
->sg_srvcount
;
242 sgd
.sgd_flags
= sg_info
->sg_flags
;
243 rc
= sg_func(h
, &sgd
, arg
);
247 for (i
= 0; i
< sg_info
->sg_srvcount
; i
++) {
248 srv_walkerfunc_t srv_func
= (srv_walkerfunc_t
)f
;
249 ilb_server_data_t sd
;
251 srv
= &sg_info
->sg_servers
[i
];
252 IP_COPY_IMPL_2_CLI(&srv
->sgs_addr
, &sd
.sd_addr
);
253 sd
.sd_minport
= srv
->sgs_minport
;
254 sd
.sd_maxport
= srv
->sgs_maxport
;
255 sd
.sd_flags
= srv
->sgs_flags
;
256 (void) strlcpy(sd
.sd_srvID
, srv
->sgs_srvID
,
257 sizeof (sd
.sd_srvID
));
259 rc
= srv_func(h
, &sd
, sg_info
->sg_name
, arg
);
260 if (rc
!= ILB_STATUS_OK
)
270 * wrapper function for i_walk_one_sg; if necessary, gets list of
271 * SG names and calles i_walk_one_sg with every name
274 i_walk_sgs(ilb_handle_t h
, void *f
, const char *sgname
,
275 void *arg
, sgwalk_t walktype
)
278 ilbd_namelist_t
*sgl
;
283 if (sgname
!= NULL
) {
284 rc
= i_ilb_walk_one_sg(h
, f
, sgname
, arg
, walktype
);
288 rc
= i_ilb_retrieve_sg_names(h
, &rbuf
, &rbufsz
);
289 if (rc
!= ILB_STATUS_OK
)
291 sgl
= (ilbd_namelist_t
*)&rbuf
->ic_data
;
293 for (i
= 0; i
< sgl
->ilbl_count
; i
++) {
294 rc
= i_ilb_walk_one_sg(h
, f
, sgl
->ilbl_name
[i
], arg
, walktype
);
296 * The server group may have been removed by another
297 * process, just continue.
299 if (rc
== ILB_STATUS_SGUNAVAIL
) {
303 if (rc
!= ILB_STATUS_OK
)
311 ilb_walk_servergroups(ilb_handle_t h
, sg_walkerfunc_t f
, const char *sgname
,
314 return (i_walk_sgs(h
, (void *)f
, sgname
, arg
, walk_sg
));
318 ilb_walk_servers(ilb_handle_t h
, srv_walkerfunc_t f
, const char *sgname
,
321 return (i_walk_sgs(h
, (void *)f
, sgname
, arg
, walk_servers
));
325 ilb_Xable_server(ilb_handle_t h
, ilb_server_data_t
*srv
, void *reserved
,
329 ilb_sg_info_t
*sg_info
;
331 in_port_t h_maxport
, h_minport
;
336 return (ILB_STATUS_EINVAL
);
339 * In this implementation, this needs to be NULL, so
340 * there's no ugly surprises with old apps once we attach
341 * meaning to this parameter.
343 if (reserved
!= NULL
)
344 return (ILB_STATUS_EINVAL
);
346 /* now all the checks have passed, we can pass on the goods */
347 if ((ic
= i_ilb_alloc_req(cmd
, &ic_sz
)) == NULL
)
348 return (ILB_STATUS_ENOMEM
);
350 sg_info
= (ilb_sg_info_t
*)&ic
->ic_data
;
351 sg_info
->sg_srvcount
= 1;
353 sgs
= &sg_info
->sg_servers
[0];
355 /* make sure min_port <= max_port; comparison in host byte order! */
356 h_maxport
= ntohs(srv
->sd_maxport
);
357 h_minport
= ntohs(srv
->sd_minport
);
358 if (h_maxport
!= 0 && h_maxport
< h_minport
)
359 sgs
->sgs_maxport
= sgs
->sgs_minport
;
361 sgs
->sgs_maxport
= srv
->sd_maxport
;
362 sgs
->sgs_minport
= srv
->sd_minport
;
364 sgs
->sgs_flags
= srv
->sd_flags
;
365 (void) strlcpy(sgs
->sgs_srvID
, srv
->sd_srvID
, sizeof (sgs
->sgs_srvID
));
366 IP_COPY_CLI_2_IMPL(&srv
->sd_addr
, &sgs
->sgs_addr
);
368 rc
= i_ilb_do_comm(h
, ic
, ic_sz
, ic
, &ic_sz
);
369 if (rc
!= ILB_STATUS_OK
)
372 if (ic
->ic_cmd
!= ILBD_CMD_OK
)
373 rc
= *(ilb_status_t
*)&ic
->ic_data
;
380 ilb_enable_server(ilb_handle_t h
, ilb_server_data_t
*srv
, void *reserved
)
382 return (ilb_Xable_server(h
, srv
, reserved
, ILBD_ENABLE_SERVER
));
386 ilb_disable_server(ilb_handle_t h
, ilb_server_data_t
*srv
, void *reserved
)
388 return (ilb_Xable_server(h
, srv
, reserved
, ILBD_DISABLE_SERVER
));
392 i_ilb_fillin_srvdata(ilb_handle_t h
, ilb_server_data_t
*srv
, const char *sgname
,
396 ilb_sg_info_t
*sg_info
;
403 if (h
== ILB_INVALID_HANDLE
|| sgname
== NULL
||
404 *sgname
== '\0' || srv
== NULL
)
405 return (ILB_STATUS_EINVAL
);
407 if (cmd
== ILBD_SRV_ID2ADDR
&& srv
->sd_srvID
[0] == '\0')
408 return (ILB_STATUS_EINVAL
);
409 if (cmd
== ILBD_SRV_ADDR2ID
&& !IS_AF_VALID(srv
->sd_addr
.ia_af
))
410 return (ILB_STATUS_EINVAL
);
412 if ((ic
= i_ilb_alloc_req(cmd
, &ic_sz
)) == NULL
)
413 return (ILB_STATUS_ENOMEM
);
414 rbufsz
= sizeof (ilb_comm_t
) + sizeof (ilb_sg_srv_t
);
415 if ((rbuf
= malloc(rbufsz
)) == NULL
) {
417 return (ILB_STATUS_ENOMEM
);
420 sg_info
= (ilb_sg_info_t
*)&ic
->ic_data
;
421 sg_info
->sg_srvcount
= 1;
422 (void) strlcpy(sg_info
->sg_name
, sgname
, sizeof (sg_info
->sg_name
));
424 sgs
= &sg_info
->sg_servers
[0];
426 if (cmd
== ILBD_SRV_ID2ADDR
)
427 (void) strlcpy(sgs
->sgs_srvID
, srv
->sd_srvID
,
428 sizeof (sgs
->sgs_srvID
));
430 IP_COPY_CLI_2_IMPL(&srv
->sd_addr
, &sgs
->sgs_addr
);
432 rc
= i_ilb_do_comm(h
, ic
, ic_sz
, rbuf
, &rbufsz
);
433 if (rc
!= ILB_STATUS_OK
)
436 if (rbuf
->ic_cmd
== ILBD_CMD_OK
) {
437 sgs
= (ilb_sg_srv_t
*)&rbuf
->ic_data
;
438 if (cmd
== ILBD_SRV_ID2ADDR
) {
439 IP_COPY_IMPL_2_CLI(&sgs
->sgs_addr
, &srv
->sd_addr
);
441 (void) strlcpy(srv
->sd_srvID
, sgs
->sgs_srvID
,
442 sizeof (sgs
->sgs_srvID
));
447 rc
= *(ilb_status_t
*)&rbuf
->ic_data
;
454 ilb_srvID_to_address(ilb_handle_t h
, ilb_server_data_t
*srv
, const char *sgname
)
456 return (i_ilb_fillin_srvdata(h
, srv
, sgname
, ILBD_SRV_ID2ADDR
));
461 ilb_address_to_srvID(ilb_handle_t h
, ilb_server_data_t
*srv
, const char *sgname
)
463 return (i_ilb_fillin_srvdata(h
, srv
, sgname
, ILBD_SRV_ADDR2ID
));