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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 #ifndef _ILBD_H 26 #define _ILBD_H 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #include <stdio.h> 33 #include <ucred.h> 34 #include <pwd.h> 35 #include <priv.h> 36 #include <stdarg.h> 37 #include <syslog.h> 38 #include <sys/list.h> 39 #include <libscf.h> 40 #include <libintl.h> 41 #include <locale.h> 42 #include <libinetutil.h> 43 #include <auth_list.h> 44 #include <bsm/adt.h> 45 #include <bsm/adt_event.h> 46 47 #define SGNAME_SZ 80 48 #define ILB_FMRI "svc:/network/loadbalancer/ilb:default" 49 50 #define HC_ACTION ILB_SRV_DISABLED_HC 51 #define ADMIN_ACTION ILB_SRV_DISABLED_ADMIN 52 53 /* Max name and value length for scf properties */ 54 #define ILBD_MAX_NAME_LEN ilbd_scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) 55 #define ILBD_MAX_VALUE_LEN ilbd_scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) 56 57 /* Different events ILBD is interested in. */ 58 typedef enum { 59 ILBD_EVENT_NEW_REQ, /* New client request */ 60 ILBD_EVENT_REQ, /* Client request comes in */ 61 ILBD_EVENT_REP_OK, /* Reply channel to client is writeable */ 62 ILBD_EVENT_PROBE, /* A HC returns some result */ 63 ILBD_EVENT_TIMER /* ilbd_timer_q fired */ 64 } ilbd_event_t; 65 66 typedef enum { 67 ILBD_SCF_RULE, /* prop group for rules */ 68 ILBD_SCF_SG, /* prop group for servergroups */ 69 ILBD_SCF_HC /* prop group for healthchecks */ 70 } ilbd_scf_pg_type_t; 71 72 typedef enum { 73 ILBD_SCF_CREATE, 74 ILBD_SCF_DESTROY, 75 ILBD_SCF_ENABLE_DISABLE 76 } ilbd_scf_cmd_t; 77 78 typedef enum { 79 ILBD_STRING, /* string */ 80 ILBD_INT, /* int */ 81 ILBD_ADDR_V4, /* ipv4 addr */ 82 ILBD_ADDR_V6 /* ipv6 addr */ 83 } ilbd_scf_data_type_t; 84 85 typedef enum { 86 stat_enable_server, 87 stat_disable_server, 88 stat_declare_srv_dead, 89 stat_declare_srv_alive 90 } ilbd_srv_status_ind_t; 91 92 /* 93 * All user struct pointer passed to port_associate() should have the first 94 * field as ilbd_event_t. The following struct can be used to find the 95 * event. 96 */ 97 typedef struct { 98 ilbd_event_t ev; 99 } ilbd_event_obj_t; 100 101 typedef struct { 102 ilbd_event_t ev; 103 timer_t timerid; 104 } ilbd_timer_event_obj_t; 105 106 typedef struct ilbd_srv { 107 list_node_t isv_srv_link; 108 ilb_sg_srv_t isv_srv; 109 #define isv_addr isv_srv.sgs_addr 110 #define isv_minport isv_srv.sgs_minport 111 #define isv_maxport isv_srv.sgs_maxport 112 #define isv_flags isv_srv.sgs_flags 113 #define isv_id isv_srv.sgs_id 114 #define isv_srvID isv_srv.sgs_srvID 115 } ilbd_srv_t; 116 117 #define MAX_SRVCOUNT 1000 118 #define MAX_SRVID (MAX_SRVCOUNT - 1) 119 #define BAD_SRVID (-1) 120 121 typedef struct ilbd_sg { 122 list_t isg_srvlist; /* list of ilbd_srv_t */ 123 char isg_name[ILB_SGNAME_SZ]; 124 int32_t isg_srvcount; 125 int32_t isg_max_id; 126 list_t isg_rulelist; /* list of ilbd_rule_t */ 127 char isg_id_arr[MAX_SRVCOUNT]; /* for server ID allocation */ 128 129 list_node_t isg_link; /* linkage for sg list */ 130 } ilbd_sg_t; 131 132 typedef struct ilbd_rule { 133 list_node_t irl_link; 134 list_node_t irl_sglink; 135 ilbd_sg_t *irl_sg; 136 ilb_rule_info_t irl_info; 137 #define irl_flags irl_info.rl_flags 138 #define irl_name irl_info.rl_name 139 #define irl_vip irl_info.rl_vip 140 #define irl_proto irl_info.rl_proto 141 #define irl_ipversion irl_info.rl_ipversion 142 #define irl_minport irl_info.rl_minport 143 #define irl_maxport irl_info.rl_maxport 144 #define irl_algo irl_info.rl_algo 145 #define irl_topo irl_info.rl_topo 146 #define irl_nat_src_start irl_info.rl_nat_src_start 147 #define irl_nat_src_end irl_info.rl_nat_src_end 148 #define irl_stickymask irl_info.rl_stickymask 149 #define irl_conndrain irl_info.rl_conndrain 150 #define irl_nat_timeout irl_info.rl_nat_timeout 151 #define irl_sticky_timeout irl_info.rl_sticky_timeout 152 #define irl_hcport irl_info.rl_hcport 153 #define irl_hcpflag irl_info.rl_hcpflag 154 #define irl_sgname irl_info.rl_sgname 155 #define irl_hcname irl_info.rl_hcname 156 } ilbd_rule_t; 157 158 /* 159 * Health check related definitions 160 */ 161 162 /* Default health check probe program provided */ 163 #define ILB_PROBE_PROTO "/usr/lib/inet/ilb/ilb_probe" 164 165 /* Command name (argv[0]) passed to ilb_probe to indicate a ping test */ 166 #define ILB_PROBE_PING "ilb_ping" 167 168 /* Use the first character of the rule's hcname to decide if rule has HC. */ 169 #define RULE_HAS_HC(irl) ((irl)->irl_info.rl_hcname[0] != '\0') 170 171 /* Type of probe test */ 172 typedef enum { 173 ILBD_HC_PING = 1, /* ICMP Echo probe */ 174 ILBD_HC_TCP, /* TCP connect probe */ 175 ILBD_HC_UDP, /* UDP packet probe */ 176 ILBD_HC_USER /* User supplied probe */ 177 } ilbd_hc_test_t; 178 179 /* Struct representing a hc object in ilbd */ 180 typedef struct { 181 list_node_t ihc_link; /* List linkage */ 182 183 ilb_hc_info_t ihc_info; 184 /* Short hand for the fields inside ilb_hc_info_t */ 185 #define ihc_name ihc_info.hci_name 186 #define ihc_test ihc_info.hci_test 187 #define ihc_timeout ihc_info.hci_timeout 188 #define ihc_count ihc_info.hci_count 189 #define ihc_interval ihc_info.hci_interval 190 #define ihc_def_ping ihc_info.hci_def_ping 191 192 ilbd_hc_test_t ihc_test_type; /* Type of probe test */ 193 int ihc_rule_cnt; /* Num of rules associated with hc */ 194 list_t ihc_rules; /* Rules associated with this hc */ 195 } ilbd_hc_t; 196 197 struct ilbd_hc_srv_s; 198 199 /* 200 * Struct representing a hc rule object 201 * 202 * hcr_link: list linkage 203 * hcr_rule: pointer to the ilbd rule object 204 * hcr_servers: list of servers of this rule 205 */ 206 typedef struct { 207 list_node_t hcr_link; 208 ilbd_rule_t const *hcr_rule; 209 list_t hcr_servers; 210 } ilbd_hc_rule_t; 211 212 struct ilbd_hc_srv_s; 213 214 /* 215 * Struct representing a event of the probe process 216 * 217 * ihp_ev: the event type, which is ILBD_EVENT_PROBE 218 * ihp_srv: pointer to the hc server object 219 * ihp_pid: pid of the probe process 220 * ihp_done: is ilbd done reading the output of the probe process 221 */ 222 typedef struct { 223 ilbd_event_t ihp_ev; 224 struct ilbd_hc_srv_s *ihp_srv; 225 pid_t ihp_pid; 226 boolean_t ihp_done; 227 } ilbd_hc_probe_event_t; 228 229 /* 230 * ilbd_hc_srv_t state 231 * 232 * ihd_hc_def_pinging: the default ping should be run 233 * ihd-hc_probing: the probe process should be started 234 */ 235 enum ilbd_hc_state { 236 ilbd_hc_def_pinging, 237 ilbd_hc_probing 238 }; 239 240 /* 241 * Struct representing a server associated with a hc object 242 * 243 * shc_srv_link: list linkage 244 * shc_hc: pointer to the hc object 245 * shc_hc_rule: pointer to the hc rule object 246 * shc_sg_srv: pointer to the server group object 247 * shc_tid: timeout ID 248 * shc_cur_cnt: number of times the hc probe has been run 249 * shc_fail_cnt: number of consecutive probe failure 250 * shc_status: health status 251 * shc_rtt: rtt (in micro sec) to the backend server 252 * shc_lasttimer: last time a probe sequence is executed 253 * shc_nexttime: next time a probe sequence is executed 254 * shc_state: hc probe state 255 * shc_child_pid: pid of the probe process 256 * shc_child_fd: fd to the output of the probe process 257 * shc_ev: event object of the probe process 258 * shc_ev_port: event port of the event object 259 */ 260 typedef struct ilbd_hc_srv_s { 261 list_node_t shc_srv_link; 262 ilbd_hc_t *shc_hc; 263 ilbd_hc_rule_t *shc_hc_rule; 264 ilb_sg_srv_t const *shc_sg_srv; 265 266 iu_timer_id_t shc_tid; 267 uint_t shc_cur_cnt; 268 uint_t shc_fail_cnt; 269 ilb_hc_srv_status_t shc_status; 270 uint32_t shc_rtt; 271 time_t shc_lasttime; 272 time_t shc_nexttime; 273 274 enum ilbd_hc_state shc_state; 275 pid_t shc_child_pid; 276 int shc_child_fd; 277 ilbd_hc_probe_event_t *shc_ev; 278 int shc_ev_port; 279 } ilbd_hc_srv_t; 280 281 /* 282 * Structure for holding audit server and servergroup event 283 * data. Not all events use all members of the structure. 284 */ 285 typedef struct audit_sg_event_data { 286 int32_t ed_ipaddr_type; /* ADT_IPv4 or ADT_IPv6 */ 287 uint32_t ed_server_address[4]; /* 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_algo_to_str(ilb_algo_t, char *); 425 void ilbd_topo_to_str(ilb_topo_t, char *); 426 void ilbd_ip_to_str(uint16_t, struct in6_addr *, char *); 427 void cvt_addr(uint32_t *, int32_t, struct in6_addr); 428 int ilberror2auditerror(ilb_status_t); 429 430 #ifdef __cplusplus 431 } 432 #endif 433 434 #endif /* _ILBD_H */ 435