xref: /illumos-gate/usr/src/lib/libilb/common/ilb_rules.c (revision dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9)
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 
28*dbed73cbSSangeeta Misra #include <stdlib.h>
29*dbed73cbSSangeeta Misra #include <strings.h>
30*dbed73cbSSangeeta Misra #include <sys/types.h>
31*dbed73cbSSangeeta Misra #include <sys/socket.h>
32*dbed73cbSSangeeta Misra #include <sys/stropts.h>
33*dbed73cbSSangeeta Misra #include <netinet/in.h>
34*dbed73cbSSangeeta Misra #include <stddef.h>
35*dbed73cbSSangeeta Misra #include "libilb.h"
36*dbed73cbSSangeeta Misra #include "libilb_impl.h"
37*dbed73cbSSangeeta Misra 
38*dbed73cbSSangeeta Misra /* ARGSUSED */
39*dbed73cbSSangeeta Misra static ilb_status_t
i_drop_hc(ilb_handle_t h,ilb_hc_info_t * hc,void * arg)40*dbed73cbSSangeeta Misra i_drop_hc(ilb_handle_t h, ilb_hc_info_t *hc, void *arg)
41*dbed73cbSSangeeta Misra {
42*dbed73cbSSangeeta Misra 	return (ilb_destroy_hc(h, hc->hci_name));
43*dbed73cbSSangeeta Misra }
44*dbed73cbSSangeeta Misra 
45*dbed73cbSSangeeta Misra /* ARGSUSED */
46*dbed73cbSSangeeta Misra static ilb_status_t
i_drop_rule(ilb_handle_t h,ilb_rule_data_t * rd,void * arg)47*dbed73cbSSangeeta Misra i_drop_rule(ilb_handle_t h, ilb_rule_data_t *rd, void *arg)
48*dbed73cbSSangeeta Misra {
49*dbed73cbSSangeeta Misra 	return (ilb_destroy_rule(h, rd->r_name));
50*dbed73cbSSangeeta Misra }
51*dbed73cbSSangeeta Misra 
52*dbed73cbSSangeeta Misra /* ARGSUSED */
53*dbed73cbSSangeeta Misra static ilb_status_t
i_drop_sg_srvs(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname,void * arg)54*dbed73cbSSangeeta Misra i_drop_sg_srvs(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
55*dbed73cbSSangeeta Misra     void *arg)
56*dbed73cbSSangeeta Misra {
57*dbed73cbSSangeeta Misra 	return (ilb_rem_server_from_group(h, sgname, srv));
58*dbed73cbSSangeeta Misra }
59*dbed73cbSSangeeta Misra 
60*dbed73cbSSangeeta Misra /* ARGSUSED */
61*dbed73cbSSangeeta Misra static ilb_status_t
i_drop_sg(ilb_handle_t h,ilb_sg_data_t * sg,void * arg)62*dbed73cbSSangeeta Misra i_drop_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
63*dbed73cbSSangeeta Misra {
64*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
65*dbed73cbSSangeeta Misra 
66*dbed73cbSSangeeta Misra 	rc = ilb_walk_servers(h, i_drop_sg_srvs, sg->sgd_name, (void *)sg);
67*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
68*dbed73cbSSangeeta Misra 		return (rc);
69*dbed73cbSSangeeta Misra 
70*dbed73cbSSangeeta Misra 	return (ilb_destroy_servergroup(h, sg->sgd_name));
71*dbed73cbSSangeeta Misra }
72*dbed73cbSSangeeta Misra 
73*dbed73cbSSangeeta Misra ilb_status_t
ilb_reset_config(ilb_handle_t h)74*dbed73cbSSangeeta Misra ilb_reset_config(ilb_handle_t h)
75*dbed73cbSSangeeta Misra {
76*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
77*dbed73cbSSangeeta Misra 
78*dbed73cbSSangeeta Misra 	if (h == NULL)
79*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
80*dbed73cbSSangeeta Misra 
81*dbed73cbSSangeeta Misra 	rc = ilb_walk_rules(h, i_drop_rule, NULL, NULL);
82*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
83*dbed73cbSSangeeta Misra 		goto out;
84*dbed73cbSSangeeta Misra 
85*dbed73cbSSangeeta Misra 	rc = ilb_walk_servergroups(h, i_drop_sg, NULL, NULL);
86*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
87*dbed73cbSSangeeta Misra 		goto out;
88*dbed73cbSSangeeta Misra 
89*dbed73cbSSangeeta Misra 	rc = ilb_walk_hc(h, i_drop_hc, NULL);
90*dbed73cbSSangeeta Misra out:
91*dbed73cbSSangeeta Misra 	return (rc);
92*dbed73cbSSangeeta Misra }
93*dbed73cbSSangeeta Misra 
94*dbed73cbSSangeeta Misra ilb_status_t
ilb_create_rule(ilb_handle_t h,const ilb_rule_data_t * rd)95*dbed73cbSSangeeta Misra ilb_create_rule(ilb_handle_t h, const ilb_rule_data_t *rd)
96*dbed73cbSSangeeta Misra {
97*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
98*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic;
99*dbed73cbSSangeeta Misra 	size_t		ic_sz;
100*dbed73cbSSangeeta Misra 	ilb_rule_info_t	*rl;
101*dbed73cbSSangeeta Misra 
102*dbed73cbSSangeeta Misra 	if (h == ILB_INVALID_HANDLE || rd == NULL || *rd->r_name == '\0')
103*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
104*dbed73cbSSangeeta Misra 
105*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_CREATE_RULE, &ic_sz)) == NULL)
106*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
107*dbed73cbSSangeeta Misra 	rl = (ilb_rule_info_t *)&ic->ic_data;
108*dbed73cbSSangeeta Misra 
109*dbed73cbSSangeeta Misra 	/*
110*dbed73cbSSangeeta Misra 	 * Since the IP address representation in ilb_rule_data_t and
111*dbed73cbSSangeeta Misra 	 * ilb_rule_info_t is different, we need to convert between
112*dbed73cbSSangeeta Misra 	 * them.
113*dbed73cbSSangeeta Misra 	 */
114*dbed73cbSSangeeta Misra 	(void) strlcpy(rl->rl_name, rd->r_name, sizeof (rl->rl_name));
115*dbed73cbSSangeeta Misra 	(void) strlcpy(rl->rl_sgname, rd->r_sgname, sizeof (rl->rl_sgname));
116*dbed73cbSSangeeta Misra 	(void) strlcpy(rl->rl_hcname, rd->r_hcname, sizeof (rl->rl_hcname));
117*dbed73cbSSangeeta Misra 	rl->rl_flags = rd->r_flags;
118*dbed73cbSSangeeta Misra 	rl->rl_proto = rd->r_proto;
119*dbed73cbSSangeeta Misra 	rl->rl_ipversion = rd->r_vip.ia_af;
120*dbed73cbSSangeeta Misra 	rl->rl_minport = rd->r_minport;
121*dbed73cbSSangeeta Misra 	if (ntohs(rd->r_maxport) < ntohs(rd->r_minport))
122*dbed73cbSSangeeta Misra 		rl->rl_maxport = rd->r_minport;
123*dbed73cbSSangeeta Misra 	else
124*dbed73cbSSangeeta Misra 		rl->rl_maxport = rd->r_maxport;
125*dbed73cbSSangeeta Misra 	rl->rl_algo = rd->r_algo;
126*dbed73cbSSangeeta Misra 	rl->rl_topo = rd->r_topo;
127*dbed73cbSSangeeta Misra 	rl->rl_conndrain = rd->r_conndrain;
128*dbed73cbSSangeeta Misra 	rl->rl_nat_timeout = rd->r_nat_timeout;
129*dbed73cbSSangeeta Misra 	rl->rl_sticky_timeout = rd->r_sticky_timeout;
130*dbed73cbSSangeeta Misra 	rl->rl_hcport = rd->r_hcport;
131*dbed73cbSSangeeta Misra 	rl->rl_hcpflag = rd->r_hcpflag;
132*dbed73cbSSangeeta Misra 
133*dbed73cbSSangeeta Misra 	IP_COPY_CLI_2_IMPL(&rd->r_vip, &rl->rl_vip);
134*dbed73cbSSangeeta Misra 	IP_COPY_CLI_2_IMPL(&rd->r_stickymask, &rl->rl_stickymask);
135*dbed73cbSSangeeta Misra 	IP_COPY_CLI_2_IMPL(&rd->r_nat_src_start, &rl->rl_nat_src_start);
136*dbed73cbSSangeeta Misra 	IP_COPY_CLI_2_IMPL(&rd->r_nat_src_end, &rl->rl_nat_src_end);
137*dbed73cbSSangeeta Misra 
138*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
139*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
140*dbed73cbSSangeeta Misra 		goto out;
141*dbed73cbSSangeeta Misra 
142*dbed73cbSSangeeta Misra 	if (ic->ic_cmd != ILBD_CMD_OK)
143*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&ic->ic_data;
144*dbed73cbSSangeeta Misra 
145*dbed73cbSSangeeta Misra out:
146*dbed73cbSSangeeta Misra 	free(ic);
147*dbed73cbSSangeeta Misra 	return (rc);
148*dbed73cbSSangeeta Misra }
149*dbed73cbSSangeeta Misra 
150*dbed73cbSSangeeta Misra static ilb_status_t
i_ilb_rule_action(ilb_handle_t h,const char * name,ilbd_cmd_t cmd)151*dbed73cbSSangeeta Misra i_ilb_rule_action(ilb_handle_t h, const char *name, ilbd_cmd_t cmd)
152*dbed73cbSSangeeta Misra {
153*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
154*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic;
155*dbed73cbSSangeeta Misra 	size_t		ic_sz;
156*dbed73cbSSangeeta Misra 
157*dbed73cbSSangeeta Misra 	if (h == ILB_INVALID_HANDLE)
158*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
159*dbed73cbSSangeeta Misra 
160*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(cmd, &ic_sz)) == NULL)
161*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
162*dbed73cbSSangeeta Misra 
163*dbed73cbSSangeeta Misra 	if (name == NULL) {
164*dbed73cbSSangeeta Misra 		bzero(&ic->ic_data, sizeof (ilbd_name_t));
165*dbed73cbSSangeeta Misra 	} else {
166*dbed73cbSSangeeta Misra 		(void) strlcpy((char *)&ic->ic_data, name,
167*dbed73cbSSangeeta Misra 		    sizeof (ilbd_name_t));
168*dbed73cbSSangeeta Misra 	}
169*dbed73cbSSangeeta Misra 
170*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
171*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
172*dbed73cbSSangeeta Misra 		goto out;
173*dbed73cbSSangeeta Misra 
174*dbed73cbSSangeeta Misra 	if (ic->ic_cmd != ILBD_CMD_OK)
175*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&ic->ic_data;
176*dbed73cbSSangeeta Misra 
177*dbed73cbSSangeeta Misra out:
178*dbed73cbSSangeeta Misra 	free(ic);
179*dbed73cbSSangeeta Misra 	return (rc);
180*dbed73cbSSangeeta Misra }
181*dbed73cbSSangeeta Misra 
182*dbed73cbSSangeeta Misra ilb_status_t
ilb_destroy_rule(ilb_handle_t h,const char * name)183*dbed73cbSSangeeta Misra ilb_destroy_rule(ilb_handle_t h, const char *name)
184*dbed73cbSSangeeta Misra {
185*dbed73cbSSangeeta Misra 	return (i_ilb_rule_action(h, name, ILBD_DESTROY_RULE));
186*dbed73cbSSangeeta Misra }
187*dbed73cbSSangeeta Misra 
188*dbed73cbSSangeeta Misra ilb_status_t
ilb_enable_rule(ilb_handle_t h,const char * name)189*dbed73cbSSangeeta Misra ilb_enable_rule(ilb_handle_t h, const char *name)
190*dbed73cbSSangeeta Misra {
191*dbed73cbSSangeeta Misra 	return (i_ilb_rule_action(h, name, ILBD_ENABLE_RULE));
192*dbed73cbSSangeeta Misra }
193*dbed73cbSSangeeta Misra 
194*dbed73cbSSangeeta Misra ilb_status_t
ilb_disable_rule(ilb_handle_t h,const char * name)195*dbed73cbSSangeeta Misra ilb_disable_rule(ilb_handle_t h, const char *name)
196*dbed73cbSSangeeta Misra {
197*dbed73cbSSangeeta Misra 	return (i_ilb_rule_action(h, name, ILBD_DISABLE_RULE));
198*dbed73cbSSangeeta Misra }
199*dbed73cbSSangeeta Misra 
200*dbed73cbSSangeeta Misra ilb_status_t
i_ilb_retrieve_rule_names(ilb_handle_t h,ilb_comm_t ** rbuf,size_t * rbufsz)201*dbed73cbSSangeeta Misra i_ilb_retrieve_rule_names(ilb_handle_t h, ilb_comm_t **rbuf, size_t *rbufsz)
202*dbed73cbSSangeeta Misra {
203*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
204*dbed73cbSSangeeta Misra 	ilb_comm_t	ic, *tmp_rbuf;
205*dbed73cbSSangeeta Misra 
206*dbed73cbSSangeeta Misra 	*rbufsz = ILBD_MSG_SIZE;
207*dbed73cbSSangeeta Misra 	if ((tmp_rbuf = malloc(*rbufsz)) == NULL)
208*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
209*dbed73cbSSangeeta Misra 
210*dbed73cbSSangeeta Misra 	ic.ic_cmd = ILBD_RETRIEVE_RULE_NAMES;
211*dbed73cbSSangeeta Misra 
212*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, &ic, sizeof (ic), tmp_rbuf, rbufsz);
213*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
214*dbed73cbSSangeeta Misra 		goto out;
215*dbed73cbSSangeeta Misra 
216*dbed73cbSSangeeta Misra 	if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) {
217*dbed73cbSSangeeta Misra 		*rbuf = tmp_rbuf;
218*dbed73cbSSangeeta Misra 		return (rc);
219*dbed73cbSSangeeta Misra 	}
220*dbed73cbSSangeeta Misra 	rc = *(ilb_status_t *)&tmp_rbuf->ic_data;
221*dbed73cbSSangeeta Misra out:
222*dbed73cbSSangeeta Misra 	free(tmp_rbuf);
223*dbed73cbSSangeeta Misra 	*rbuf = NULL;
224*dbed73cbSSangeeta Misra 	return (rc);
225*dbed73cbSSangeeta Misra }
226*dbed73cbSSangeeta Misra 
227*dbed73cbSSangeeta Misra static ilb_status_t
i_ilb_walk_one_rule(ilb_handle_t h,rule_walkerfunc_t f,const char * name,void * arg)228*dbed73cbSSangeeta Misra i_ilb_walk_one_rule(ilb_handle_t h, rule_walkerfunc_t f, const char *name,
229*dbed73cbSSangeeta Misra     void *arg)
230*dbed73cbSSangeeta Misra {
231*dbed73cbSSangeeta Misra 	ilb_status_t		rc = ILB_STATUS_OK;
232*dbed73cbSSangeeta Misra 	ilb_rule_info_t		*rl = NULL;
233*dbed73cbSSangeeta Misra 	ilb_rule_data_t		rd;
234*dbed73cbSSangeeta Misra 	ilb_comm_t		*ic, *rbuf;
235*dbed73cbSSangeeta Misra 	size_t			ic_sz, rbufsz;
236*dbed73cbSSangeeta Misra 
237*dbed73cbSSangeeta Misra 
238*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_RETRIEVE_RULE, &ic_sz)) == NULL)
239*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
240*dbed73cbSSangeeta Misra 	rbufsz = sizeof (ilb_comm_t) + sizeof (ilb_rule_info_t);
241*dbed73cbSSangeeta Misra 	if ((rbuf = malloc(rbufsz)) == NULL) {
242*dbed73cbSSangeeta Misra 		free(ic);
243*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
244*dbed73cbSSangeeta Misra 	}
245*dbed73cbSSangeeta Misra 
246*dbed73cbSSangeeta Misra 	(void) strlcpy((char *)&ic->ic_data,  name, sizeof (ilbd_name_t));
247*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, rbuf, &rbufsz);
248*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
249*dbed73cbSSangeeta Misra 		goto out;
250*dbed73cbSSangeeta Misra 	if (rbuf->ic_cmd != ILBD_CMD_OK) {
251*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&rbuf->ic_data;
252*dbed73cbSSangeeta Misra 		goto out;
253*dbed73cbSSangeeta Misra 	}
254*dbed73cbSSangeeta Misra 	rl = (ilb_rule_info_t *)&rbuf->ic_data;
255*dbed73cbSSangeeta Misra 
256*dbed73cbSSangeeta Misra 	/*
257*dbed73cbSSangeeta Misra 	 * Since the IP address representation in ilb_rule_data_t and
258*dbed73cbSSangeeta Misra 	 * ilb_rule_info_t is different, we need to convert between
259*dbed73cbSSangeeta Misra 	 * them.
260*dbed73cbSSangeeta Misra 	 */
261*dbed73cbSSangeeta Misra 	(void) strlcpy(rd.r_name, rl->rl_name, sizeof (rd.r_name));
262*dbed73cbSSangeeta Misra 	(void) strlcpy(rd.r_hcname, rl->rl_hcname, sizeof (rd.r_hcname));
263*dbed73cbSSangeeta Misra 	(void) strlcpy(rd.r_sgname, rl->rl_sgname, sizeof (rd.r_sgname));
264*dbed73cbSSangeeta Misra 	rd.r_flags = rl->rl_flags;
265*dbed73cbSSangeeta Misra 	rd.r_proto = rl->rl_proto;
266*dbed73cbSSangeeta Misra 	rd.r_minport = rl->rl_minport;
267*dbed73cbSSangeeta Misra 	rd.r_maxport = rl->rl_maxport;
268*dbed73cbSSangeeta Misra 	rd.r_algo = rl->rl_algo;
269*dbed73cbSSangeeta Misra 	rd.r_topo = rl->rl_topo;
270*dbed73cbSSangeeta Misra 	rd.r_conndrain = rl->rl_conndrain;
271*dbed73cbSSangeeta Misra 	rd.r_nat_timeout = rl->rl_nat_timeout;
272*dbed73cbSSangeeta Misra 	rd.r_sticky_timeout = rl->rl_sticky_timeout;
273*dbed73cbSSangeeta Misra 	rd.r_hcport = rl->rl_hcport;
274*dbed73cbSSangeeta Misra 	rd.r_hcpflag = rl->rl_hcpflag;
275*dbed73cbSSangeeta Misra 
276*dbed73cbSSangeeta Misra 	IP_COPY_IMPL_2_CLI(&rl->rl_vip, &rd.r_vip);
277*dbed73cbSSangeeta Misra 	IP_COPY_IMPL_2_CLI(&rl->rl_nat_src_start, &rd.r_nat_src_start);
278*dbed73cbSSangeeta Misra 	IP_COPY_IMPL_2_CLI(&rl->rl_nat_src_end, &rd.r_nat_src_end);
279*dbed73cbSSangeeta Misra 	IP_COPY_IMPL_2_CLI(&rl->rl_stickymask, &rd.r_stickymask);
280*dbed73cbSSangeeta Misra 
281*dbed73cbSSangeeta Misra 	rc = f(h, &rd, arg);
282*dbed73cbSSangeeta Misra 
283*dbed73cbSSangeeta Misra out:
284*dbed73cbSSangeeta Misra 	free(ic);
285*dbed73cbSSangeeta Misra 	free(rbuf);
286*dbed73cbSSangeeta Misra 	return (rc);
287*dbed73cbSSangeeta Misra }
288*dbed73cbSSangeeta Misra 
289*dbed73cbSSangeeta Misra ilb_status_t
ilb_walk_rules(ilb_handle_t h,rule_walkerfunc_t f,const char * name,void * arg)290*dbed73cbSSangeeta Misra ilb_walk_rules(ilb_handle_t h, rule_walkerfunc_t f, const char *name,
291*dbed73cbSSangeeta Misra     void *arg)
292*dbed73cbSSangeeta Misra {
293*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
294*dbed73cbSSangeeta Misra 	ilbd_namelist_t	*names;
295*dbed73cbSSangeeta Misra 	ilb_comm_t	*rbuf;
296*dbed73cbSSangeeta Misra 	size_t		rbufsz;
297*dbed73cbSSangeeta Misra 	int		i;
298*dbed73cbSSangeeta Misra 
299*dbed73cbSSangeeta Misra 	if (h == NULL)
300*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
301*dbed73cbSSangeeta Misra 
302*dbed73cbSSangeeta Misra 	if (name != NULL)
303*dbed73cbSSangeeta Misra 		return (i_ilb_walk_one_rule(h, f, name, arg));
304*dbed73cbSSangeeta Misra 
305*dbed73cbSSangeeta Misra 	rc = i_ilb_retrieve_rule_names(h, &rbuf, &rbufsz);
306*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
307*dbed73cbSSangeeta Misra 		return (rc);
308*dbed73cbSSangeeta Misra 
309*dbed73cbSSangeeta Misra 	names = (ilbd_namelist_t *)&rbuf->ic_data;
310*dbed73cbSSangeeta Misra 	for (i = 0; i < names->ilbl_count; i++) {
311*dbed73cbSSangeeta Misra 		rc = i_ilb_walk_one_rule(h, f, names->ilbl_name[i], arg);
312*dbed73cbSSangeeta Misra 		/*
313*dbed73cbSSangeeta Misra 		 * The rule may have been removed by another process since
314*dbed73cbSSangeeta Misra 		 * we retrieve all the rule names, just continue.
315*dbed73cbSSangeeta Misra 		 */
316*dbed73cbSSangeeta Misra 		if (rc == ILB_STATUS_ENOENT) {
317*dbed73cbSSangeeta Misra 			rc = ILB_STATUS_OK;
318*dbed73cbSSangeeta Misra 			continue;
319*dbed73cbSSangeeta Misra 		}
320*dbed73cbSSangeeta Misra 		if (rc != ILB_STATUS_OK)
321*dbed73cbSSangeeta Misra 			break;
322*dbed73cbSSangeeta Misra 	}
323*dbed73cbSSangeeta Misra 
324*dbed73cbSSangeeta Misra 	free(rbuf);
325*dbed73cbSSangeeta Misra 	return (rc);
326*dbed73cbSSangeeta Misra }
327