Unleashed v1.4
[unleashed.git] / usr / src / lib / libilb / common / ilb_rules.c
blobdf01041e4c920d890c8fd2d6143bc4713fe778a4
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <stdlib.h>
29 #include <strings.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/stropts.h>
33 #include <netinet/in.h>
34 #include <stddef.h>
35 #include "libilb.h"
36 #include "libilb_impl.h"
38 /* ARGSUSED */
39 static ilb_status_t
40 i_drop_hc(ilb_handle_t h, ilb_hc_info_t *hc, void *arg)
42 return (ilb_destroy_hc(h, hc->hci_name));
45 /* ARGSUSED */
46 static ilb_status_t
47 i_drop_rule(ilb_handle_t h, ilb_rule_data_t *rd, void *arg)
49 return (ilb_destroy_rule(h, rd->r_name));
52 /* ARGSUSED */
53 static ilb_status_t
54 i_drop_sg_srvs(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
55 void *arg)
57 return (ilb_rem_server_from_group(h, sgname, srv));
60 /* ARGSUSED */
61 static ilb_status_t
62 i_drop_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
64 ilb_status_t rc;
66 rc = ilb_walk_servers(h, i_drop_sg_srvs, sg->sgd_name, (void *)sg);
67 if (rc != ILB_STATUS_OK)
68 return (rc);
70 return (ilb_destroy_servergroup(h, sg->sgd_name));
73 ilb_status_t
74 ilb_reset_config(ilb_handle_t h)
76 ilb_status_t rc;
78 if (h == NULL)
79 return (ILB_STATUS_EINVAL);
81 rc = ilb_walk_rules(h, i_drop_rule, NULL, NULL);
82 if (rc != ILB_STATUS_OK)
83 goto out;
85 rc = ilb_walk_servergroups(h, i_drop_sg, NULL, NULL);
86 if (rc != ILB_STATUS_OK)
87 goto out;
89 rc = ilb_walk_hc(h, i_drop_hc, NULL);
90 out:
91 return (rc);
94 ilb_status_t
95 ilb_create_rule(ilb_handle_t h, const ilb_rule_data_t *rd)
97 ilb_status_t rc;
98 ilb_comm_t *ic;
99 size_t ic_sz;
100 ilb_rule_info_t *rl;
102 if (h == ILB_INVALID_HANDLE || rd == NULL || *rd->r_name == '\0')
103 return (ILB_STATUS_EINVAL);
105 if ((ic = i_ilb_alloc_req(ILBD_CREATE_RULE, &ic_sz)) == NULL)
106 return (ILB_STATUS_ENOMEM);
107 rl = (ilb_rule_info_t *)&ic->ic_data;
110 * Since the IP address representation in ilb_rule_data_t and
111 * ilb_rule_info_t is different, we need to convert between
112 * them.
114 (void) strlcpy(rl->rl_name, rd->r_name, sizeof (rl->rl_name));
115 (void) strlcpy(rl->rl_sgname, rd->r_sgname, sizeof (rl->rl_sgname));
116 (void) strlcpy(rl->rl_hcname, rd->r_hcname, sizeof (rl->rl_hcname));
117 rl->rl_flags = rd->r_flags;
118 rl->rl_proto = rd->r_proto;
119 rl->rl_ipversion = rd->r_vip.ia_af;
120 rl->rl_minport = rd->r_minport;
121 if (ntohs(rd->r_maxport) < ntohs(rd->r_minport))
122 rl->rl_maxport = rd->r_minport;
123 else
124 rl->rl_maxport = rd->r_maxport;
125 rl->rl_algo = rd->r_algo;
126 rl->rl_topo = rd->r_topo;
127 rl->rl_conndrain = rd->r_conndrain;
128 rl->rl_nat_timeout = rd->r_nat_timeout;
129 rl->rl_sticky_timeout = rd->r_sticky_timeout;
130 rl->rl_hcport = rd->r_hcport;
131 rl->rl_hcpflag = rd->r_hcpflag;
133 IP_COPY_CLI_2_IMPL(&rd->r_vip, &rl->rl_vip);
134 IP_COPY_CLI_2_IMPL(&rd->r_stickymask, &rl->rl_stickymask);
135 IP_COPY_CLI_2_IMPL(&rd->r_nat_src_start, &rl->rl_nat_src_start);
136 IP_COPY_CLI_2_IMPL(&rd->r_nat_src_end, &rl->rl_nat_src_end);
138 rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
139 if (rc != ILB_STATUS_OK)
140 goto out;
142 if (ic->ic_cmd != ILBD_CMD_OK)
143 rc = *(ilb_status_t *)&ic->ic_data;
145 out:
146 free(ic);
147 return (rc);
150 static ilb_status_t
151 i_ilb_rule_action(ilb_handle_t h, const char *name, ilbd_cmd_t cmd)
153 ilb_status_t rc;
154 ilb_comm_t *ic;
155 size_t ic_sz;
157 if (h == ILB_INVALID_HANDLE)
158 return (ILB_STATUS_EINVAL);
160 if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
161 return (ILB_STATUS_ENOMEM);
163 if (name == NULL) {
164 bzero(&ic->ic_data, sizeof (ilbd_name_t));
165 } else {
166 (void) strlcpy((char *)&ic->ic_data, name,
167 sizeof (ilbd_name_t));
170 rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
171 if (rc != ILB_STATUS_OK)
172 goto out;
174 if (ic->ic_cmd != ILBD_CMD_OK)
175 rc = *(ilb_status_t *)&ic->ic_data;
177 out:
178 free(ic);
179 return (rc);
182 ilb_status_t
183 ilb_destroy_rule(ilb_handle_t h, const char *name)
185 return (i_ilb_rule_action(h, name, ILBD_DESTROY_RULE));
188 ilb_status_t
189 ilb_enable_rule(ilb_handle_t h, const char *name)
191 return (i_ilb_rule_action(h, name, ILBD_ENABLE_RULE));
194 ilb_status_t
195 ilb_disable_rule(ilb_handle_t h, const char *name)
197 return (i_ilb_rule_action(h, name, ILBD_DISABLE_RULE));
200 ilb_status_t
201 i_ilb_retrieve_rule_names(ilb_handle_t h, ilb_comm_t **rbuf, size_t *rbufsz)
203 ilb_status_t rc;
204 ilb_comm_t ic, *tmp_rbuf;
206 *rbufsz = ILBD_MSG_SIZE;
207 if ((tmp_rbuf = malloc(*rbufsz)) == NULL)
208 return (ILB_STATUS_ENOMEM);
210 ic.ic_cmd = ILBD_RETRIEVE_RULE_NAMES;
212 rc = i_ilb_do_comm(h, &ic, sizeof (ic), tmp_rbuf, rbufsz);
213 if (rc != ILB_STATUS_OK)
214 goto out;
216 if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) {
217 *rbuf = tmp_rbuf;
218 return (rc);
220 rc = *(ilb_status_t *)&tmp_rbuf->ic_data;
221 out:
222 free(tmp_rbuf);
223 *rbuf = NULL;
224 return (rc);
227 static ilb_status_t
228 i_ilb_walk_one_rule(ilb_handle_t h, rule_walkerfunc_t f, const char *name,
229 void *arg)
231 ilb_status_t rc = ILB_STATUS_OK;
232 ilb_rule_info_t *rl = NULL;
233 ilb_rule_data_t rd;
234 ilb_comm_t *ic, *rbuf;
235 size_t ic_sz, rbufsz;
238 if ((ic = i_ilb_alloc_req(ILBD_RETRIEVE_RULE, &ic_sz)) == NULL)
239 return (ILB_STATUS_ENOMEM);
240 rbufsz = sizeof (ilb_comm_t) + sizeof (ilb_rule_info_t);
241 if ((rbuf = malloc(rbufsz)) == NULL) {
242 free(ic);
243 return (ILB_STATUS_ENOMEM);
246 (void) strlcpy((char *)&ic->ic_data, name, sizeof (ilbd_name_t));
247 rc = i_ilb_do_comm(h, ic, ic_sz, rbuf, &rbufsz);
248 if (rc != ILB_STATUS_OK)
249 goto out;
250 if (rbuf->ic_cmd != ILBD_CMD_OK) {
251 rc = *(ilb_status_t *)&rbuf->ic_data;
252 goto out;
254 rl = (ilb_rule_info_t *)&rbuf->ic_data;
257 * Since the IP address representation in ilb_rule_data_t and
258 * ilb_rule_info_t is different, we need to convert between
259 * them.
261 (void) strlcpy(rd.r_name, rl->rl_name, sizeof (rd.r_name));
262 (void) strlcpy(rd.r_hcname, rl->rl_hcname, sizeof (rd.r_hcname));
263 (void) strlcpy(rd.r_sgname, rl->rl_sgname, sizeof (rd.r_sgname));
264 rd.r_flags = rl->rl_flags;
265 rd.r_proto = rl->rl_proto;
266 rd.r_minport = rl->rl_minport;
267 rd.r_maxport = rl->rl_maxport;
268 rd.r_algo = rl->rl_algo;
269 rd.r_topo = rl->rl_topo;
270 rd.r_conndrain = rl->rl_conndrain;
271 rd.r_nat_timeout = rl->rl_nat_timeout;
272 rd.r_sticky_timeout = rl->rl_sticky_timeout;
273 rd.r_hcport = rl->rl_hcport;
274 rd.r_hcpflag = rl->rl_hcpflag;
276 IP_COPY_IMPL_2_CLI(&rl->rl_vip, &rd.r_vip);
277 IP_COPY_IMPL_2_CLI(&rl->rl_nat_src_start, &rd.r_nat_src_start);
278 IP_COPY_IMPL_2_CLI(&rl->rl_nat_src_end, &rd.r_nat_src_end);
279 IP_COPY_IMPL_2_CLI(&rl->rl_stickymask, &rd.r_stickymask);
281 rc = f(h, &rd, arg);
283 out:
284 free(ic);
285 free(rbuf);
286 return (rc);
289 ilb_status_t
290 ilb_walk_rules(ilb_handle_t h, rule_walkerfunc_t f, const char *name,
291 void *arg)
293 ilb_status_t rc;
294 ilbd_namelist_t *names;
295 ilb_comm_t *rbuf;
296 size_t rbufsz;
297 int i;
299 if (h == NULL)
300 return (ILB_STATUS_EINVAL);
302 if (name != NULL)
303 return (i_ilb_walk_one_rule(h, f, name, arg));
305 rc = i_ilb_retrieve_rule_names(h, &rbuf, &rbufsz);
306 if (rc != ILB_STATUS_OK)
307 return (rc);
309 names = (ilbd_namelist_t *)&rbuf->ic_data;
310 for (i = 0; i < names->ilbl_count; i++) {
311 rc = i_ilb_walk_one_rule(h, f, names->ilbl_name[i], arg);
313 * The rule may have been removed by another process since
314 * we retrieve all the rule names, just continue.
316 if (rc == ILB_STATUS_ENOENT) {
317 rc = ILB_STATUS_OK;
318 continue;
320 if (rc != ILB_STATUS_OK)
321 break;
324 free(rbuf);
325 return (rc);