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