1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #ifndef _ILBD_H 27 #define _ILBD_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #include <stdio.h> 34 #include <ucred.h> 35 #include <pwd.h> 36 #include <priv.h> 37 #include <stdarg.h> 38 #include <syslog.h> 39 #include <sys/list.h> 40 #include <libscf.h> 41 #include <libintl.h> 42 #include <locale.h> 43 #include <libinetutil.h> 44 #include <auth_list.h> 45 #include <bsm/adt.h> 46 #include <bsm/adt_event.h> 47 48 #define SGNAME_SZ 80 49 #define ILB_FMRI "svc:/network/loadbalancer/ilb:default" 50 51 #define HC_ACTION ILB_SRV_DISABLED_HC 52 #define ADMIN_ACTION ILB_SRV_DISABLED_ADMIN 53 54 /* Max name and value length for scf properties */ 55 #define ILBD_MAX_NAME_LEN ilbd_scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) 56 #define ILBD_MAX_VALUE_LEN ilbd_scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) 57 58 /* Different events ILBD is interested in. */ 59 typedef enum { 60 ILBD_EVENT_NEW_REQ, /* New client request */ 61 ILBD_EVENT_REQ, /* Client request comes in */ 62 ILBD_EVENT_REP_OK, /* Reply channel to client is writeable */ 63 ILBD_EVENT_PROBE, /* A HC returns some result */ 64 ILBD_EVENT_TIMER /* ilbd_timer_q fired */ 65 } ilbd_event_t; 66 67 typedef enum { 68 ILBD_SCF_RULE, /* prop group for rules */ 69 ILBD_SCF_SG, /* prop group for servergroups */ 70 ILBD_SCF_HC /* prop group for healthchecks */ 71 } ilbd_scf_pg_type_t; 72 73 typedef enum { 74 ILBD_SCF_CREATE, 75 ILBD_SCF_DESTROY, 76 ILBD_SCF_ENABLE_DISABLE 77 } ilbd_scf_cmd_t; 78 79 typedef enum { 80 ILBD_STRING, /* string */ 81 ILBD_INT, /* int */ 82 ILBD_ADDR_V4, /* ipv4 addr */ 83 ILBD_ADDR_V6 /* ipv6 addr */ 84 } ilbd_scf_data_type_t; 85 86 typedef enum { 87 stat_enable_server, 88 stat_disable_server, 89 stat_declare_srv_dead, 90 stat_declare_srv_alive 91 } ilbd_srv_status_ind_t; 92 93 /* 94 * All user struct pointer passed to port_associate() should have the first 95 * field as ilbd_event_t. The following struct can be used to find the 96 * event. 97 */ 98 typedef struct { 99 ilbd_event_t ev; 100 } ilbd_event_obj_t; 101 102 typedef struct { 103 ilbd_event_t ev; 104 timer_t timerid; 105 } ilbd_timer_event_obj_t; 106 107 typedef struct ilbd_srv { 108 list_node_t isv_srv_link; 109 ilb_sg_srv_t isv_srv; 110 #define isv_addr isv_srv.sgs_addr 111 #define isv_minport isv_srv.sgs_minport 112 #define isv_maxport isv_srv.sgs_maxport 113 #define isv_flags isv_srv.sgs_flags 114 #define isv_id isv_srv.sgs_id 115 #define isv_srvID isv_srv.sgs_srvID 116 } ilbd_srv_t; 117 118 #define MAX_SRVCOUNT 1000 119 #define MAX_SRVID (MAX_SRVCOUNT - 1) 120 #define BAD_SRVID (-1) 121 122 typedef struct ilbd_sg { 123 list_t isg_srvlist; /* list of ilbd_srv_t */ 124 char isg_name[ILB_SGNAME_SZ]; 125 int32_t isg_srvcount; 126 int32_t isg_max_id; 127 list_t isg_rulelist; /* list of ilbd_rule_t */ 128 char isg_id_arr[MAX_SRVCOUNT]; /* for server ID allocation */ 129 130 list_node_t isg_link; /* linkage for sg list */ 131 } ilbd_sg_t; 132 133 typedef struct ilbd_rule { 134 list_node_t irl_link; 135 list_node_t irl_sglink; 136 ilbd_sg_t *irl_sg; 137 ilb_rule_info_t irl_info; 138 #define irl_flags irl_info.rl_flags 139 #define irl_name irl_info.rl_name 140 #define irl_vip irl_info.rl_vip 141 #define irl_proto irl_info.rl_proto 142 #define irl_ipversion irl_info.rl_ipversion 143 #define irl_minport irl_info.rl_minport 144 #define irl_maxport irl_info.rl_maxport 145 #define irl_algo irl_info.rl_algo 146 #define irl_topo irl_info.rl_topo 147 #define irl_nat_src_start irl_info.rl_nat_src_start 148 #define irl_nat_src_end irl_info.rl_nat_src_end 149 #define irl_stickymask irl_info.rl_stickymask 150 #define irl_conndrain irl_info.rl_conndrain 151 #define irl_nat_timeout irl_info.rl_nat_timeout 152 #define irl_sticky_timeout irl_info.rl_sticky_timeout 153 #define irl_hcport irl_info.rl_hcport 154 #define irl_hcpflag irl_info.rl_hcpflag 155 #define irl_sgname irl_info.rl_sgname 156 #define irl_hcname irl_info.rl_hcname 157 } ilbd_rule_t; 158 159 /* 160 * Health check related definitions 161 */ 162 163 /* Default health check probe program provided */ 164 #define ILB_PROBE_PROTO "/usr/lib/inet/ilb/ilb_probe" 165 166 /* Command name (argv[0]) passed to ilb_probe to indicate a ping test */ 167 #define ILB_PROBE_PING "ilb_ping" 168 169 /* Use the first character of the rule's hcname to decide if rule has HC. */ 170 #define RULE_HAS_HC(irl) ((irl)->irl_info.rl_hcname[0] != '\0') 171 172 /* Type of probe test */ 173 typedef enum { 174 ILBD_HC_PING = 1, /* ICMP Echo probe */ 175 ILBD_HC_TCP, /* TCP connect probe */ 176 ILBD_HC_UDP, /* UDP packet probe */ 177 ILBD_HC_USER /* User supplied probe */ 178 } ilbd_hc_test_t; 179 180 /* Struct representing a hc object in ilbd */ 181 typedef struct { 182 list_node_t ihc_link; /* List linkage */ 183 184 ilb_hc_info_t ihc_info; 185 /* Short hand for the fields inside ilb_hc_info_t */ 186 #define ihc_name ihc_info.hci_name 187 #define ihc_test ihc_info.hci_test 188 #define ihc_timeout ihc_info.hci_timeout 189 #define ihc_count ihc_info.hci_count 190 #define ihc_interval ihc_info.hci_interval 191 #define ihc_def_ping ihc_info.hci_def_ping 192 193 ilbd_hc_test_t ihc_test_type; /* Type of probe test */ 194 int ihc_rule_cnt; /* Num of rules associated with hc */ 195 list_t ihc_rules; /* Rules associated with this hc */ 196 } ilbd_hc_t; 197 198 struct ilbd_hc_srv_s; 199 200 /* 201 * Struct representing a hc rule object 202 * 203 * hcr_link: list linkage 204 * hcr_rule: pointer to the ilbd rule object 205 * hcr_servers: list of servers of this rule 206 */ 207 typedef struct { 208 list_node_t hcr_link; 209 ilbd_rule_t const *hcr_rule; 210 list_t hcr_servers; 211 } ilbd_hc_rule_t; 212 213 struct ilbd_hc_srv_s; 214 215 /* 216 * Struct representing a event of the probe process 217 * 218 * ihp_ev: the event type, which is ILBD_EVENT_PROBE 219 * ihp_srv: pointer to the hc server object 220 * ihp_pid: pid of the probe process 221 * ihp_done: is ilbd done reading the output of the probe process 222 */ 223 typedef struct { 224 ilbd_event_t ihp_ev; 225 struct ilbd_hc_srv_s *ihp_srv; 226 pid_t ihp_pid; 227 boolean_t ihp_done; 228 } ilbd_hc_probe_event_t; 229 230 /* 231 * ilbd_hc_srv_t state 232 * 233 * ihd_hc_def_pinging: the default ping should be run 234 * ihd-hc_probing: the probe process should be started 235 */ 236 enum ilbd_hc_state { 237 ilbd_hc_def_pinging, 238 ilbd_hc_probing 239 }; 240 241 /* 242 * Struct representing a server associated with a hc object 243 * 244 * shc_srv_link: list linkage 245 * shc_hc: pointer to the hc object 246 * shc_hc_rule: pointer to the hc rule object 247 * shc_sg_srv: pointer to the server group object 248 * shc_tid: timeout ID 249 * shc_cur_cnt: number of times the hc probe has been run 250 * shc_fail_cnt: number of consecutive probe failure 251 * shc_status: health status 252 * shc_rtt: rtt (in micro sec) to the backend server 253 * shc_lasttimer: last time a probe sequence is executed 254 * shc_nexttime: next time a probe sequence is executed 255 * shc_state: hc probe state 256 * shc_child_pid: pid of the probe process 257 * shc_child_fd: fd to the output of the probe process 258 * shc_ev: event object of the probe process 259 * shc_ev_port: event port of the event object 260 */ 261 typedef struct ilbd_hc_srv_s { 262 list_node_t shc_srv_link; 263 ilbd_hc_t *shc_hc; 264 ilbd_hc_rule_t *shc_hc_rule; 265 ilb_sg_srv_t const *shc_sg_srv; 266 267 iu_timer_id_t shc_tid; 268 uint_t shc_cur_cnt; 269 uint_t shc_fail_cnt; 270 ilb_hc_srv_status_t shc_status; 271 uint32_t shc_rtt; 272 time_t shc_lasttime; 273 time_t shc_nexttime; 274 275 enum ilbd_hc_state shc_state; 276 pid_t shc_child_pid; 277 int shc_child_fd; 278 ilbd_hc_probe_event_t *shc_ev; 279 int shc_ev_port; 280 } ilbd_hc_srv_t; 281 282 /* 283 * Structure for holding audit server and servergroup event 284 * data. Not all events use all members of the structure. 285 */ 286 typedef struct audit_sg_event_data { 287 char *ed_server_address; /* server's IP address */ 288 char *ed_serverid; /* serverid. */ 289 uint16_t ed_minport; /* server's minport */ 290 uint16_t ed_maxport; /* server's maxport */ 291 char *ed_sgroup; /* servergroup */ 292 } audit_sg_event_data_t; 293 294 /* Struct to store client info */ 295 typedef struct { 296 ilbd_event_t cli_ev; 297 int cli_sd; 298 struct passwd cli_pw; 299 size_t cli_pw_bufsz; 300 char *cli_pw_buf; 301 ilbd_cmd_t cli_cmd; 302 ilb_comm_t *cli_saved_reply; 303 size_t cli_saved_size; 304 ucred_t *cli_peer_ucredp; /* needed for auditing */ 305 } ilbd_client_t; 306 307 void ilbd_reply_ok(uint32_t *, size_t *); 308 void ilbd_reply_err(uint32_t *, size_t *, ilb_status_t); 309 310 ilb_status_t ilbd_check_client_config_auth(const struct passwd *); 311 ilb_status_t ilbd_check_client_enable_auth(const struct passwd *); 312 ilb_status_t ilbd_retrieve_names(ilbd_cmd_t, uint32_t *, size_t *); 313 void i_setup_sg_hlist(void); 314 void i_setup_rule_hlist(void); 315 void logperror(const char *); 316 ilb_status_t ilbd_add_server_to_group(ilb_sg_info_t *, int, 317 const struct passwd *, ucred_t *); 318 ilb_status_t ilbd_rem_server_from_group(ilb_sg_info_t *, int, 319 const struct passwd *, ucred_t *); 320 ilb_status_t ilbd_create_sg(ilb_sg_info_t *, int, 321 const struct passwd *, ucred_t *); 322 323 ilb_status_t ilbd_destroy_sg(const char *, const struct passwd *, 324 ucred_t *); 325 ilb_status_t ilbd_retrieve_sg_hosts(const char *, uint32_t *, size_t *); 326 327 ilb_status_t ilbd_enable_server(ilb_sg_info_t *, const struct passwd *, 328 ucred_t *); 329 ilb_status_t ilbd_disable_server(ilb_sg_info_t *, const struct passwd *, 330 ucred_t *); 331 ilb_status_t ilbd_k_Xable_server(const struct in6_addr *, const char *, 332 ilbd_srv_status_ind_t); 333 334 ilb_status_t i_add_srv2krules(list_t *, ilb_sg_srv_t *, int); 335 ilb_status_t i_rem_srv_frm_krules(list_t *, ilb_sg_srv_t *, int); 336 int ilbd_get_num_krules(void); 337 ilb_status_t ilbd_get_krule_names(ilbd_namelist_t **, int); 338 ilb_status_t ilb_get_krule_servers(ilb_sg_info_t *); 339 ilbd_sg_t *i_find_sg_byname(const char *); 340 ilb_status_t i_check_srv2rules(list_t *, ilb_sg_srv_t *); 341 342 ilb_status_t ilbd_address_to_srvID(ilb_sg_info_t *, uint32_t *, size_t *); 343 ilb_status_t ilbd_srvID_to_address(ilb_sg_info_t *, uint32_t *, size_t *); 344 345 ilb_status_t do_ioctl(void *, ssize_t); 346 347 ilb_status_t ilbd_create_rule(ilb_rule_info_t *, int, const struct passwd *, 348 ucred_t *); 349 ilb_status_t ilbd_retrieve_rule(ilbd_name_t, uint32_t *, size_t *); 350 351 ilb_status_t ilbd_destroy_rule(ilbd_name_t, const struct passwd *, 352 ucred_t *); 353 ilb_status_t ilbd_enable_rule(ilbd_name_t, const struct passwd *, ucred_t *); 354 ilb_status_t ilbd_disable_rule(ilbd_name_t, const struct passwd *, 355 ucred_t *); 356 357 boolean_t is_debugging_on(void); 358 ilb_status_t ilbd_sg_check_rule_port(ilbd_sg_t *, ilb_rule_info_t *); 359 360 void ilbd_enable_debug(void); 361 ilb_status_t ilb_map_errno2ilbstat(int); 362 363 ilb_status_t i_attach_rule2sg(ilbd_sg_t *, ilbd_rule_t *); 364 365 /* Logging routine and macros */ 366 void ilbd_log(int, const char *, ...); 367 #define logerr(...) ilbd_log(LOG_ERR, __VA_ARGS__) 368 #define logdebug(...) ilbd_log(LOG_DEBUG, __VA_ARGS__) 369 370 /* Health check manipulation routines */ 371 void i_ilbd_setup_hc_list(void); 372 ilb_status_t ilbd_create_hc(const ilb_hc_info_t *, int, 373 const struct passwd *, ucred_t *); 374 ilb_status_t ilbd_destroy_hc(const char *, const struct passwd *, ucred_t *); 375 ilbd_hc_t *ilbd_get_hc(const char *); 376 ilb_status_t ilbd_get_hc_info(const char *, uint32_t *, size_t *); 377 ilb_status_t ilbd_get_hc_srvs(const char *, uint32_t *, size_t *); 378 ilb_status_t ilbd_hc_associate_rule(const ilbd_rule_t *, int); 379 ilb_status_t ilbd_hc_dissociate_rule(const ilbd_rule_t *); 380 ilb_status_t ilbd_hc_add_server(const ilbd_rule_t *, const ilb_sg_srv_t *, 381 int); 382 ilb_status_t ilbd_hc_del_server(const ilbd_rule_t *, const ilb_sg_srv_t *); 383 ilb_status_t ilbd_hc_enable_rule(const ilbd_rule_t *); 384 ilb_status_t ilbd_hc_disable_rule(const ilbd_rule_t *); 385 ilb_status_t ilbd_hc_enable_server(const ilbd_rule_t *, 386 const ilb_sg_srv_t *); 387 ilb_status_t ilbd_hc_disable_server(const ilbd_rule_t *, 388 const ilb_sg_srv_t *); 389 390 /* Health check timer routines */ 391 void ilbd_hc_probe_return(int, int, int, ilbd_hc_probe_event_t *); 392 void ilbd_hc_timer_init(int, ilbd_timer_event_obj_t *); 393 void ilbd_hc_timeout(void); 394 void ilbd_hc_timer_update(ilbd_timer_event_obj_t *); 395 396 /* Show NAT info routines */ 397 ilb_status_t ilbd_show_nat(void *, const ilb_comm_t *, uint32_t *, 398 size_t *); 399 void ilbd_show_nat_cleanup(void); 400 401 402 /* Show sticky info routines */ 403 ilb_status_t ilbd_show_sticky(void *, const ilb_comm_t *, uint32_t *, 404 size_t *); 405 void ilbd_show_sticky_cleanup(void); 406 407 ilb_status_t ilbd_create_pg(ilbd_scf_pg_type_t, void *); 408 ilb_status_t ilbd_destroy_pg(ilbd_scf_pg_type_t, const char *); 409 ilb_status_t ilbd_change_prop(ilbd_scf_pg_type_t, const char *, 410 const char *, void *); 411 void ilbd_scf_str_to_ip(int, char *, struct in6_addr *); 412 ilb_status_t ilbd_scf_ip_to_str(uint16_t, struct in6_addr *, scf_type_t *, 413 char *); 414 ilb_status_t ilbd_scf_add_srv(ilbd_sg_t *, ilbd_srv_t *); 415 ilb_status_t ilbd_scf_del_srv(ilbd_sg_t *, ilbd_srv_t *); 416 int ilbd_scf_limit(int); 417 418 ilb_status_t ilbd_walk_rule_pgs(ilb_status_t (*)(ilb_rule_info_t *, int, 419 const struct passwd *, ucred_t *), void *, void *); 420 ilb_status_t ilbd_walk_sg_pgs(ilb_status_t (*)(ilb_sg_info_t *, int, 421 const struct passwd *, ucred_t *), void *, void *); 422 ilb_status_t ilbd_walk_hc_pgs(ilb_status_t (*)(const ilb_hc_info_t *, int, 423 const struct passwd *, ucred_t *), void *, void *); 424 void ilbd_addr2str(struct in6_addr *, char *, size_t); 425 void addr2str(ilb_ip_addr_t, char *, size_t); 426 void ilbd_algo_to_str(ilb_algo_t, char *); 427 void ilbd_topo_to_str(ilb_topo_t, char *); 428 void ilbd_ip_to_str(uint16_t, struct in6_addr *, char *); 429 int ilberror2auditerror(ilb_status_t); 430 431 #ifdef __cplusplus 432 } 433 #endif 434 435 #endif /* _ILBD_H */ 436