xref: /onnv-gate/usr/src/lib/libilb/common/ilb_subr.c (revision 10946:324bab2b3370)
1*10946SSangeeta.Misra@Sun.COM /*
2*10946SSangeeta.Misra@Sun.COM  * CDDL HEADER START
3*10946SSangeeta.Misra@Sun.COM  *
4*10946SSangeeta.Misra@Sun.COM  * The contents of this file are subject to the terms of the
5*10946SSangeeta.Misra@Sun.COM  * Common Development and Distribution License (the "License").
6*10946SSangeeta.Misra@Sun.COM  * You may not use this file except in compliance with the License.
7*10946SSangeeta.Misra@Sun.COM  *
8*10946SSangeeta.Misra@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10946SSangeeta.Misra@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*10946SSangeeta.Misra@Sun.COM  * See the License for the specific language governing permissions
11*10946SSangeeta.Misra@Sun.COM  * and limitations under the License.
12*10946SSangeeta.Misra@Sun.COM  *
13*10946SSangeeta.Misra@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*10946SSangeeta.Misra@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10946SSangeeta.Misra@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*10946SSangeeta.Misra@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*10946SSangeeta.Misra@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10946SSangeeta.Misra@Sun.COM  *
19*10946SSangeeta.Misra@Sun.COM  * CDDL HEADER END
20*10946SSangeeta.Misra@Sun.COM  */
21*10946SSangeeta.Misra@Sun.COM 
22*10946SSangeeta.Misra@Sun.COM /*
23*10946SSangeeta.Misra@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*10946SSangeeta.Misra@Sun.COM  * Use is subject to license terms.
25*10946SSangeeta.Misra@Sun.COM  */
26*10946SSangeeta.Misra@Sun.COM 
27*10946SSangeeta.Misra@Sun.COM #include <stdlib.h>
28*10946SSangeeta.Misra@Sun.COM #include <strings.h>
29*10946SSangeeta.Misra@Sun.COM #include <sys/types.h>
30*10946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
31*10946SSangeeta.Misra@Sun.COM #include <inttypes.h>
32*10946SSangeeta.Misra@Sun.COM #include <assert.h>
33*10946SSangeeta.Misra@Sun.COM #include <libilb.h>
34*10946SSangeeta.Misra@Sun.COM #include <libilb_impl.h>
35*10946SSangeeta.Misra@Sun.COM #include <locale.h>
36*10946SSangeeta.Misra@Sun.COM 
37*10946SSangeeta.Misra@Sun.COM typedef enum {
38*10946SSangeeta.Misra@Sun.COM 	internal,
39*10946SSangeeta.Misra@Sun.COM 	external
40*10946SSangeeta.Misra@Sun.COM } ip_addr_type_t;
41*10946SSangeeta.Misra@Sun.COM 
42*10946SSangeeta.Misra@Sun.COM static int
sign64(int64_t n)43*10946SSangeeta.Misra@Sun.COM sign64(int64_t n)
44*10946SSangeeta.Misra@Sun.COM {
45*10946SSangeeta.Misra@Sun.COM 	if (n >= 0)
46*10946SSangeeta.Misra@Sun.COM 		return (1);
47*10946SSangeeta.Misra@Sun.COM 	return (-1);
48*10946SSangeeta.Misra@Sun.COM }
49*10946SSangeeta.Misra@Sun.COM 
50*10946SSangeeta.Misra@Sun.COM static int
sign32(int32_t n)51*10946SSangeeta.Misra@Sun.COM sign32(int32_t n)
52*10946SSangeeta.Misra@Sun.COM {
53*10946SSangeeta.Misra@Sun.COM 	if (n >= 0)
54*10946SSangeeta.Misra@Sun.COM 		return (1);
55*10946SSangeeta.Misra@Sun.COM 	return (-1);
56*10946SSangeeta.Misra@Sun.COM }
57*10946SSangeeta.Misra@Sun.COM 
58*10946SSangeeta.Misra@Sun.COM /*
59*10946SSangeeta.Misra@Sun.COM  * since the difference between two uint64_ts can be greater than
60*10946SSangeeta.Misra@Sun.COM  * what a int64_t can hold, we need to cap the result at +/- INT64_MAX
61*10946SSangeeta.Misra@Sun.COM  * return: < 0: x < y, 0: x == y, > 0: x > y
62*10946SSangeeta.Misra@Sun.COM  */
63*10946SSangeeta.Misra@Sun.COM static int64_t
signed_diff64(uint64_t x,uint64_t y)64*10946SSangeeta.Misra@Sun.COM signed_diff64(uint64_t x, uint64_t y)
65*10946SSangeeta.Misra@Sun.COM {
66*10946SSangeeta.Misra@Sun.COM 	uint64_t	ud;
67*10946SSangeeta.Misra@Sun.COM 	int		s = -1;
68*10946SSangeeta.Misra@Sun.COM 
69*10946SSangeeta.Misra@Sun.COM 	if (x == y)
70*10946SSangeeta.Misra@Sun.COM 		return (0);
71*10946SSangeeta.Misra@Sun.COM 
72*10946SSangeeta.Misra@Sun.COM 	/* make sure we have x < y */
73*10946SSangeeta.Misra@Sun.COM 	if (x > y) {
74*10946SSangeeta.Misra@Sun.COM 		uint64_t	t;
75*10946SSangeeta.Misra@Sun.COM 
76*10946SSangeeta.Misra@Sun.COM 		s = 1;
77*10946SSangeeta.Misra@Sun.COM 		t = x; x = y; y = t;
78*10946SSangeeta.Misra@Sun.COM 	}
79*10946SSangeeta.Misra@Sun.COM 
80*10946SSangeeta.Misra@Sun.COM 	ud = y - x;
81*10946SSangeeta.Misra@Sun.COM 	if (ud > INT64_MAX)
82*10946SSangeeta.Misra@Sun.COM 		return (INT64_MAX * s);
83*10946SSangeeta.Misra@Sun.COM 
84*10946SSangeeta.Misra@Sun.COM 	return ((int64_t)ud * s);
85*10946SSangeeta.Misra@Sun.COM }
86*10946SSangeeta.Misra@Sun.COM 
87*10946SSangeeta.Misra@Sun.COM static uint64_t
unsigned_diff64(uint64_t x,uint64_t y,int * sgn)88*10946SSangeeta.Misra@Sun.COM unsigned_diff64(uint64_t x, uint64_t y, int *sgn)
89*10946SSangeeta.Misra@Sun.COM {
90*10946SSangeeta.Misra@Sun.COM 	int		s = -1;
91*10946SSangeeta.Misra@Sun.COM 
92*10946SSangeeta.Misra@Sun.COM 	if (x == y)
93*10946SSangeeta.Misra@Sun.COM 		return (0);
94*10946SSangeeta.Misra@Sun.COM 
95*10946SSangeeta.Misra@Sun.COM 	/* make sure we have x < y */
96*10946SSangeeta.Misra@Sun.COM 	if (x > y) {
97*10946SSangeeta.Misra@Sun.COM 		uint64_t	t;
98*10946SSangeeta.Misra@Sun.COM 
99*10946SSangeeta.Misra@Sun.COM 		s = 1;
100*10946SSangeeta.Misra@Sun.COM 		t = x; x = y; y = t;
101*10946SSangeeta.Misra@Sun.COM 	}
102*10946SSangeeta.Misra@Sun.COM 	*sgn = s;
103*10946SSangeeta.Misra@Sun.COM 	return (y - x);
104*10946SSangeeta.Misra@Sun.COM }
105*10946SSangeeta.Misra@Sun.COM 
106*10946SSangeeta.Misra@Sun.COM /*
107*10946SSangeeta.Misra@Sun.COM  * compare ip addresses ip1 and ip2 (as unsigned integers)
108*10946SSangeeta.Misra@Sun.COM  * return: -1: ip1 < ip2, 0: ip1 == ip2, 1: ip1 > ip2
109*10946SSangeeta.Misra@Sun.COM  * input addresses are assumed to be in network byte order
110*10946SSangeeta.Misra@Sun.COM  * diff contains the difference between the two with the same
111*10946SSangeeta.Misra@Sun.COM  * sign as the comparison result;
112*10946SSangeeta.Misra@Sun.COM  * NOTE: since ipv6 address (difference)s can be more than a 64bit
113*10946SSangeeta.Misra@Sun.COM  * value can express, the difference is capped at +/- INT64_MAX
114*10946SSangeeta.Misra@Sun.COM  */
115*10946SSangeeta.Misra@Sun.COM static int
i_cmp_addr_impl(void * ip1,void * ip2,ip_addr_type_t atype,int64_t * diff)116*10946SSangeeta.Misra@Sun.COM i_cmp_addr_impl(void *ip1, void *ip2, ip_addr_type_t atype, int64_t *diff)
117*10946SSangeeta.Misra@Sun.COM {
118*10946SSangeeta.Misra@Sun.COM 	struct in6_addr	*a6_1, *a6_2;
119*10946SSangeeta.Misra@Sun.COM 	uint32_t	i1, i2;
120*10946SSangeeta.Misra@Sun.COM 	uint32_t	l1, l2;
121*10946SSangeeta.Misra@Sun.COM 	int		af, sgn;
122*10946SSangeeta.Misra@Sun.COM 	int64_t		d;
123*10946SSangeeta.Misra@Sun.COM 
124*10946SSangeeta.Misra@Sun.COM 	if (atype == internal) {
125*10946SSangeeta.Misra@Sun.COM 		af = GET_AF((struct in6_addr *)ip1);
126*10946SSangeeta.Misra@Sun.COM 		if (af == AF_INET) {
127*10946SSangeeta.Misra@Sun.COM 			IN6_V4MAPPED_TO_IPADDR((struct in6_addr *)ip1, i1);
128*10946SSangeeta.Misra@Sun.COM 			IN6_V4MAPPED_TO_IPADDR((struct in6_addr *)ip2, i2);
129*10946SSangeeta.Misra@Sun.COM 
130*10946SSangeeta.Misra@Sun.COM 			l1 = ntohl(i1);
131*10946SSangeeta.Misra@Sun.COM 			l2 = ntohl(i2);
132*10946SSangeeta.Misra@Sun.COM 		} else {
133*10946SSangeeta.Misra@Sun.COM 			a6_1 = (struct in6_addr *)ip1;
134*10946SSangeeta.Misra@Sun.COM 			a6_2 = (struct in6_addr *)ip2;
135*10946SSangeeta.Misra@Sun.COM 		}
136*10946SSangeeta.Misra@Sun.COM 	} else {
137*10946SSangeeta.Misra@Sun.COM 		af = ((ilb_ip_addr_t *)ip1)->ia_af;
138*10946SSangeeta.Misra@Sun.COM 		if (af == AF_INET) {
139*10946SSangeeta.Misra@Sun.COM 			struct in_addr	*a1, *a2;
140*10946SSangeeta.Misra@Sun.COM 
141*10946SSangeeta.Misra@Sun.COM 			a1 = &((ilb_ip_addr_t *)ip1)->ia_v4;
142*10946SSangeeta.Misra@Sun.COM 			a2 = &((ilb_ip_addr_t *)ip2)->ia_v4;
143*10946SSangeeta.Misra@Sun.COM 
144*10946SSangeeta.Misra@Sun.COM 			l1 = ntohl((uint32_t)a1->s_addr);
145*10946SSangeeta.Misra@Sun.COM 			l2 = ntohl((uint32_t)a2->s_addr);
146*10946SSangeeta.Misra@Sun.COM 		} else {
147*10946SSangeeta.Misra@Sun.COM 			a6_1 = &((ilb_ip_addr_t *)ip1)->ia_v6;
148*10946SSangeeta.Misra@Sun.COM 			a6_2 = &((ilb_ip_addr_t *)ip2)->ia_v6;
149*10946SSangeeta.Misra@Sun.COM 		}
150*10946SSangeeta.Misra@Sun.COM 	}
151*10946SSangeeta.Misra@Sun.COM 
152*10946SSangeeta.Misra@Sun.COM 	if (af == AF_INET) {
153*10946SSangeeta.Misra@Sun.COM 		d = l1 - l2;
154*10946SSangeeta.Misra@Sun.COM 		sgn = sign32((int32_t)d);
155*10946SSangeeta.Misra@Sun.COM 	} else {
156*10946SSangeeta.Misra@Sun.COM 		/*
157*10946SSangeeta.Misra@Sun.COM 		 * we're facing the dilemma that 128-bit ipv6 addresses are
158*10946SSangeeta.Misra@Sun.COM 		 * larger than the largest integer type - int64_t.
159*10946SSangeeta.Misra@Sun.COM 		 * we handle this thus:
160*10946SSangeeta.Misra@Sun.COM 		 * 1. seperate high-order and low-order bits (64 each) into
161*10946SSangeeta.Misra@Sun.COM 		 *    *h and *l variables (unsigned).
162*10946SSangeeta.Misra@Sun.COM 		 * 2. calculate difference for *h and *l:
163*10946SSangeeta.Misra@Sun.COM 		 *    low: unsigned
164*10946SSangeeta.Misra@Sun.COM 		 *    high: signed
165*10946SSangeeta.Misra@Sun.COM 		 * 3. if high-order diff == 0, we can take low-order
166*10946SSangeeta.Misra@Sun.COM 		 *    diff, if necessary cap it, convert it to signed
167*10946SSangeeta.Misra@Sun.COM 		 *    and be done
168*10946SSangeeta.Misra@Sun.COM 		 * 4. if high-order and low-order signs are the same, the low-
169*10946SSangeeta.Misra@Sun.COM 		 *    order bits won't significantly impact high-order
170*10946SSangeeta.Misra@Sun.COM 		 *    difference, so we know that we've overflowed an int64_t;
171*10946SSangeeta.Misra@Sun.COM 		 *    if high-order diff is > 1, any low-order difference won't
172*10946SSangeeta.Misra@Sun.COM 		 *    change the overflow.
173*10946SSangeeta.Misra@Sun.COM 		 * 5. (dh == 1 and l_sign <= 0) or (dh == -1 and l_sign > 0),
174*10946SSangeeta.Misra@Sun.COM 		 *    ie, dh == +/- 2^64
175*10946SSangeeta.Misra@Sun.COM 		 *  5a. if dl < INT64_MAX, the result is still > INT64_MAX, so
176*10946SSangeeta.Misra@Sun.COM 		 *    we cap again.
177*10946SSangeeta.Misra@Sun.COM 		 *  5b. dl >= INT64_MAX
178*10946SSangeeta.Misra@Sun.COM 		 *    we need to express (for dh == 1):
179*10946SSangeeta.Misra@Sun.COM 		 *    (2^64) + x	(where x < 0).
180*10946SSangeeta.Misra@Sun.COM 		 *    Since the largest number we have is
181*10946SSangeeta.Misra@Sun.COM 		 *    2^64 - 1 == UINT64_MAX
182*10946SSangeeta.Misra@Sun.COM 		 *    we  use
183*10946SSangeeta.Misra@Sun.COM 		 *    (2^64 - 1) + x + 1
184*10946SSangeeta.Misra@Sun.COM 		 *
185*10946SSangeeta.Misra@Sun.COM 		 *    for dh == -1, all we have is
186*10946SSangeeta.Misra@Sun.COM 		 *    -(2^63 - 1), so to express
187*10946SSangeeta.Misra@Sun.COM 		 *    -(2^64) + x,
188*10946SSangeeta.Misra@Sun.COM 		 *    we first do (dl - (2^63-1)) (which is then also < 2^63),
189*10946SSangeeta.Misra@Sun.COM 		 *    si we can then add that to  -(2^63 - 1);
190*10946SSangeeta.Misra@Sun.COM 		 */
191*10946SSangeeta.Misra@Sun.COM 		uint64_t	i1h, i1l;
192*10946SSangeeta.Misra@Sun.COM 		uint64_t	i2h, i2l;
193*10946SSangeeta.Misra@Sun.COM 		uint64_t	dl;
194*10946SSangeeta.Misra@Sun.COM 		int64_t		dh;
195*10946SSangeeta.Misra@Sun.COM 		int		l_sign;
196*10946SSangeeta.Misra@Sun.COM 
197*10946SSangeeta.Misra@Sun.COM 		/* 1. */
198*10946SSangeeta.Misra@Sun.COM 		i1h = INV6_N2H_MSB64(a6_1);
199*10946SSangeeta.Misra@Sun.COM 		i1l = INV6_N2H_LSB64(a6_1);
200*10946SSangeeta.Misra@Sun.COM 		i2h = INV6_N2H_MSB64(a6_2);
201*10946SSangeeta.Misra@Sun.COM 		i2l = INV6_N2H_LSB64(a6_2);
202*10946SSangeeta.Misra@Sun.COM 
203*10946SSangeeta.Misra@Sun.COM 		/* 2. */
204*10946SSangeeta.Misra@Sun.COM 		dh = signed_diff64(i1h, i2h);
205*10946SSangeeta.Misra@Sun.COM 		dl = unsigned_diff64(i1l, i2l, &l_sign);
206*10946SSangeeta.Misra@Sun.COM 
207*10946SSangeeta.Misra@Sun.COM 		/* 3. */
208*10946SSangeeta.Misra@Sun.COM 		if (dh == 0) {
209*10946SSangeeta.Misra@Sun.COM 			if (dl > INT64_MAX)
210*10946SSangeeta.Misra@Sun.COM 				dl = INT64_MAX;
211*10946SSangeeta.Misra@Sun.COM 
212*10946SSangeeta.Misra@Sun.COM 			d = dl * l_sign;
213*10946SSangeeta.Misra@Sun.COM 		/* 4, */
214*10946SSangeeta.Misra@Sun.COM 		} else if (l_sign == sign64(dh) || abs(dh) > 1) {
215*10946SSangeeta.Misra@Sun.COM 			if (dh > 0)
216*10946SSangeeta.Misra@Sun.COM 				d = INT64_MAX;
217*10946SSangeeta.Misra@Sun.COM 			else
218*10946SSangeeta.Misra@Sun.COM 				d = -INT64_MAX;
219*10946SSangeeta.Misra@Sun.COM 		/* 5. */
220*10946SSangeeta.Misra@Sun.COM 		} else {
221*10946SSangeeta.Misra@Sun.COM 			if (dl < INT64_MAX) {
222*10946SSangeeta.Misra@Sun.COM 				d = INT64_MAX;
223*10946SSangeeta.Misra@Sun.COM 			} else {
224*10946SSangeeta.Misra@Sun.COM 				if (dh == 1)
225*10946SSangeeta.Misra@Sun.COM 					d = UINT64_MAX - dl + 1;
226*10946SSangeeta.Misra@Sun.COM 				else
227*10946SSangeeta.Misra@Sun.COM 					d = -INT64_MAX - (dl - INT64_MAX) - 1;
228*10946SSangeeta.Misra@Sun.COM 			}
229*10946SSangeeta.Misra@Sun.COM 		}
230*10946SSangeeta.Misra@Sun.COM 		sgn = sign64(d);
231*10946SSangeeta.Misra@Sun.COM 	}
232*10946SSangeeta.Misra@Sun.COM 	if (diff != NULL)
233*10946SSangeeta.Misra@Sun.COM 		*diff = d;
234*10946SSangeeta.Misra@Sun.COM 	if (d == 0)
235*10946SSangeeta.Misra@Sun.COM 		return (0);
236*10946SSangeeta.Misra@Sun.COM 	return (sgn);
237*10946SSangeeta.Misra@Sun.COM }
238*10946SSangeeta.Misra@Sun.COM 
239*10946SSangeeta.Misra@Sun.COM int
ilb_cmp_in6_addr(struct in6_addr * ip1,struct in6_addr * ip2,int64_t * diff)240*10946SSangeeta.Misra@Sun.COM ilb_cmp_in6_addr(struct in6_addr *ip1, struct in6_addr *ip2, int64_t *diff)
241*10946SSangeeta.Misra@Sun.COM {
242*10946SSangeeta.Misra@Sun.COM 	int res;
243*10946SSangeeta.Misra@Sun.COM 
244*10946SSangeeta.Misra@Sun.COM 	res = i_cmp_addr_impl(ip1, ip2, internal, diff);
245*10946SSangeeta.Misra@Sun.COM 	return (res);
246*10946SSangeeta.Misra@Sun.COM }
247*10946SSangeeta.Misra@Sun.COM 
248*10946SSangeeta.Misra@Sun.COM int
ilb_cmp_ipaddr(ilb_ip_addr_t * ip1,ilb_ip_addr_t * ip2,int64_t * diff)249*10946SSangeeta.Misra@Sun.COM ilb_cmp_ipaddr(ilb_ip_addr_t *ip1, ilb_ip_addr_t *ip2, int64_t *diff)
250*10946SSangeeta.Misra@Sun.COM {
251*10946SSangeeta.Misra@Sun.COM 	int res;
252*10946SSangeeta.Misra@Sun.COM 
253*10946SSangeeta.Misra@Sun.COM 	res = i_cmp_addr_impl(ip1, ip2, external, diff);
254*10946SSangeeta.Misra@Sun.COM 	return (res);
255*10946SSangeeta.Misra@Sun.COM }
256*10946SSangeeta.Misra@Sun.COM 
257*10946SSangeeta.Misra@Sun.COM /*
258*10946SSangeeta.Misra@Sun.COM  * Error strings for error values returned by libilb functions
259*10946SSangeeta.Misra@Sun.COM  */
260*10946SSangeeta.Misra@Sun.COM const char *
ilb_errstr(ilb_status_t rc)261*10946SSangeeta.Misra@Sun.COM ilb_errstr(ilb_status_t rc)
262*10946SSangeeta.Misra@Sun.COM {
263*10946SSangeeta.Misra@Sun.COM 	switch (rc) {
264*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_OK:
265*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "no error"));
266*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INTERNAL:
267*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "error internal to the library"));
268*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_EINVAL:
269*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "invalid argument(s) - see"
270*10946SSangeeta.Misra@Sun.COM 		    " man page"));
271*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_ENOMEM:
272*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "not enough memory"
273*10946SSangeeta.Misra@Sun.COM 		    " for operation"));
274*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_ENOENT:
275*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "no such/no more element(s)"));
276*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SOCKET:
277*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "socket() failed"));
278*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_READ:
279*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "read() failed"));
280*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_WRITE:
281*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "fflush() or send() failed"));
282*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_TIMER:
283*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "health check timer"
284*10946SSangeeta.Misra@Sun.COM 		    " create/setup error"));
285*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INUSE:
286*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "object is in use,"
287*10946SSangeeta.Misra@Sun.COM 		    " cannot destroy"));
288*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_EEXIST:
289*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "object already exists"));
290*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_PERMIT:
291*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "no scf permit"));
292*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_CALLBACK:
293*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "scf callback error"));
294*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INPROGRESS:
295*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "operation is progress"));
296*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SEND:
297*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "send() failed"));
298*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_ENOHCINFO:
299*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "missing healthcheck info"));
300*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INVAL_HCTESTTYPE:
301*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "invalid  health check"
302*10946SSangeeta.Misra@Sun.COM 		    " test type"));
303*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INVAL_CMD:
304*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "invalid command"));
305*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_DUP_RULE:
306*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "specified rule name already"
307*10946SSangeeta.Misra@Sun.COM 		    " exists"));
308*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_ENORULE:
309*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "specified rule does not exist"));
310*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_MISMATCHSG:
311*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "address family mismatch with"
312*10946SSangeeta.Misra@Sun.COM 		    " servergroup"));
313*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_MISMATCHH:
314*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "address family mismatch"
315*10946SSangeeta.Misra@Sun.COM 		    " with previous hosts in servergroup or with rule"));
316*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SGUNAVAIL:
317*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "cannot find specified"
318*10946SSangeeta.Misra@Sun.COM 		    " server group"));
319*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SGINUSE:
320*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "cannot remove server"
321*10946SSangeeta.Misra@Sun.COM 		    " group - its in use with other active rules"));
322*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SGEXISTS:
323*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "servergroup already exists"));
324*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SGFULL:
325*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "servergroup is full - cannot"
326*10946SSangeeta.Misra@Sun.COM 		    " add any more servers to this servergroup"));
327*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SGEMPTY:
328*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "servergroup does not contain"
329*10946SSangeeta.Misra@Sun.COM 		    " any servers"));
330*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_NAMETOOLONG:
331*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "servergroup name can"
332*10946SSangeeta.Misra@Sun.COM 		    " only contain a maximum of 14 characters"));
333*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_CFGAUTH:
334*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "user is not authorized to"
335*10946SSangeeta.Misra@Sun.COM 		    " execute command"));
336*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_CFGUPDATE:
337*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "a failure occurred while trying"
338*10946SSangeeta.Misra@Sun.COM 		    " to update persistent config. Panic?"));
339*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_BADSG:
340*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "the rule's port range"
341*10946SSangeeta.Misra@Sun.COM 		    " does not match that of the servers' in associated"
342*10946SSangeeta.Misra@Sun.COM 		    " servergroup"));
343*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INVAL_SRVR:
344*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "server cannot be added to the"
345*10946SSangeeta.Misra@Sun.COM 		    " servergroup, as the servergroup is associated to rule(s)"
346*10946SSangeeta.Misra@Sun.COM 		    " with port/port range that is incompatible"
347*10946SSangeeta.Misra@Sun.COM 		    "with the server's port"));
348*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_INVAL_ENBSRVR:
349*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "server cannot be enabled"
350*10946SSangeeta.Misra@Sun.COM 		    " because it's not associated with any rule"));
351*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_BADPORT:
352*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "the rule's port value does"
353*10946SSangeeta.Misra@Sun.COM 		    " not match that of the servers' in"
354*10946SSangeeta.Misra@Sun.COM 		    " associated servergroup"));
355*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_SRVUNAVAIL:
356*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "cannot find specified server"));
357*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_RULE_NO_HC:
358*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "rule does not have health "
359*10946SSangeeta.Misra@Sun.COM 		    "check enabled"));
360*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_RULE_HC_MISMATCH:
361*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "protocol used in rule and "
362*10946SSangeeta.Misra@Sun.COM 		    "health check does not match"));
363*10946SSangeeta.Misra@Sun.COM 	case ILB_STATUS_HANDLE_CLOSING:
364*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "handle is being closed"));
365*10946SSangeeta.Misra@Sun.COM 
366*10946SSangeeta.Misra@Sun.COM 	default:
367*10946SSangeeta.Misra@Sun.COM 		return (dgettext(TEXT_DOMAIN, "unknown error"));
368*10946SSangeeta.Misra@Sun.COM 	}
369*10946SSangeeta.Misra@Sun.COM }
370*10946SSangeeta.Misra@Sun.COM 
371*10946SSangeeta.Misra@Sun.COM /* Allocate space for a specified request to be sent to ilbd. */
372*10946SSangeeta.Misra@Sun.COM ilb_comm_t *
i_ilb_alloc_req(ilbd_cmd_t cmd,size_t * ic_sz)373*10946SSangeeta.Misra@Sun.COM i_ilb_alloc_req(ilbd_cmd_t cmd, size_t *ic_sz)
374*10946SSangeeta.Misra@Sun.COM {
375*10946SSangeeta.Misra@Sun.COM 	ilb_comm_t	*ic;
376*10946SSangeeta.Misra@Sun.COM 	size_t		sz;
377*10946SSangeeta.Misra@Sun.COM 
378*10946SSangeeta.Misra@Sun.COM 	sz = sizeof (ilb_comm_t);
379*10946SSangeeta.Misra@Sun.COM 
380*10946SSangeeta.Misra@Sun.COM 	switch (cmd) {
381*10946SSangeeta.Misra@Sun.COM 	case ILBD_CREATE_RULE:
382*10946SSangeeta.Misra@Sun.COM 		sz += sizeof (ilb_rule_info_t);
383*10946SSangeeta.Misra@Sun.COM 		break;
384*10946SSangeeta.Misra@Sun.COM 
385*10946SSangeeta.Misra@Sun.COM 	case ILBD_RETRIEVE_RULE:
386*10946SSangeeta.Misra@Sun.COM 	case ILBD_DESTROY_RULE:
387*10946SSangeeta.Misra@Sun.COM 	case ILBD_ENABLE_RULE:
388*10946SSangeeta.Misra@Sun.COM 	case ILBD_DISABLE_RULE:
389*10946SSangeeta.Misra@Sun.COM 	case ILBD_RETRIEVE_SG_HOSTS:
390*10946SSangeeta.Misra@Sun.COM 	case ILBD_DESTROY_SERVERGROUP:
391*10946SSangeeta.Misra@Sun.COM 	case ILBD_CREATE_SERVERGROUP:
392*10946SSangeeta.Misra@Sun.COM 	case ILBD_DESTROY_HC:
393*10946SSangeeta.Misra@Sun.COM 	case ILBD_GET_HC_INFO:
394*10946SSangeeta.Misra@Sun.COM 	case ILBD_GET_HC_SRVS:
395*10946SSangeeta.Misra@Sun.COM 		sz += sizeof (ilbd_name_t);
396*10946SSangeeta.Misra@Sun.COM 		break;
397*10946SSangeeta.Misra@Sun.COM 
398*10946SSangeeta.Misra@Sun.COM 	case ILBD_ENABLE_SERVER:
399*10946SSangeeta.Misra@Sun.COM 	case ILBD_DISABLE_SERVER:
400*10946SSangeeta.Misra@Sun.COM 	case ILBD_ADD_SERVER_TO_GROUP:
401*10946SSangeeta.Misra@Sun.COM 	case ILBD_REM_SERVER_FROM_GROUP:
402*10946SSangeeta.Misra@Sun.COM 	case ILBD_SRV_ADDR2ID:
403*10946SSangeeta.Misra@Sun.COM 	case ILBD_SRV_ID2ADDR:
404*10946SSangeeta.Misra@Sun.COM 		sz += sizeof (ilb_sg_info_t) + sizeof (ilb_sg_srv_t);
405*10946SSangeeta.Misra@Sun.COM 		break;
406*10946SSangeeta.Misra@Sun.COM 
407*10946SSangeeta.Misra@Sun.COM 	case ILBD_CREATE_HC:
408*10946SSangeeta.Misra@Sun.COM 		sz += sizeof (ilb_hc_info_t);
409*10946SSangeeta.Misra@Sun.COM 		break;
410*10946SSangeeta.Misra@Sun.COM 
411*10946SSangeeta.Misra@Sun.COM 	default:
412*10946SSangeeta.Misra@Sun.COM 		/* Should not reach here. */
413*10946SSangeeta.Misra@Sun.COM 		assert(0);
414*10946SSangeeta.Misra@Sun.COM 		break;
415*10946SSangeeta.Misra@Sun.COM 	}
416*10946SSangeeta.Misra@Sun.COM 
417*10946SSangeeta.Misra@Sun.COM 	if ((ic = calloc(1, sz)) == NULL)
418*10946SSangeeta.Misra@Sun.COM 		return (NULL);
419*10946SSangeeta.Misra@Sun.COM 
420*10946SSangeeta.Misra@Sun.COM 	*ic_sz = sz;
421*10946SSangeeta.Misra@Sun.COM 	ic->ic_cmd = cmd;
422*10946SSangeeta.Misra@Sun.COM 	ic->ic_flags = 0;
423*10946SSangeeta.Misra@Sun.COM 	return (ic);
424*10946SSangeeta.Misra@Sun.COM }
425