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.
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.
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]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
42 #include <libinetutil.h>
43 #include <auth_list.h>
45 #include <bsm/adt_event.h>
48 #define ILB_FMRI "svc:/network/loadbalancer/ilb:default"
50 #define HC_ACTION ILB_SRV_DISABLED_HC
51 #define ADMIN_ACTION ILB_SRV_DISABLED_ADMIN
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)
57 /* Different events ILBD is interested in. */
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 */
67 ILBD_SCF_RULE
, /* prop group for rules */
68 ILBD_SCF_SG
, /* prop group for servergroups */
69 ILBD_SCF_HC
/* prop group for healthchecks */
75 ILBD_SCF_ENABLE_DISABLE
79 ILBD_STRING
, /* string */
81 ILBD_ADDR_V4
, /* ipv4 addr */
82 ILBD_ADDR_V6
/* ipv6 addr */
83 } ilbd_scf_data_type_t
;
88 stat_declare_srv_dead
,
89 stat_declare_srv_alive
90 } ilbd_srv_status_ind_t
;
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
104 } ilbd_timer_event_obj_t
;
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
117 #define MAX_SRVCOUNT 1000
118 #define MAX_SRVID (MAX_SRVCOUNT - 1)
119 #define BAD_SRVID (-1)
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
;
126 list_t isg_rulelist
; /* list of ilbd_rule_t */
127 char isg_id_arr
[MAX_SRVCOUNT
]; /* for server ID allocation */
129 list_node_t isg_link
; /* linkage for sg list */
132 typedef struct ilbd_rule
{
133 list_node_t irl_link
;
134 list_node_t irl_sglink
;
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
159 * Health check related definitions
162 /* Default health check probe program provided */
163 #define ILB_PROBE_PROTO "/usr/lib/inet/ilb/ilb_probe"
165 /* Command name (argv[0]) passed to ilb_probe to indicate a ping test */
166 #define ILB_PROBE_PING "ilb_ping"
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')
171 /* Type of probe test */
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 */
179 /* Struct representing a hc object in ilbd */
181 list_node_t ihc_link
; /* List linkage */
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
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 */
197 struct ilbd_hc_srv_s
;
200 * Struct representing a hc rule object
202 * hcr_link: list linkage
203 * hcr_rule: pointer to the ilbd rule object
204 * hcr_servers: list of servers of this rule
207 list_node_t hcr_link
;
208 ilbd_rule_t
const *hcr_rule
;
212 struct ilbd_hc_srv_s
;
215 * Struct representing a event of the probe process
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
224 struct ilbd_hc_srv_s
*ihp_srv
;
227 } ilbd_hc_probe_event_t
;
230 * ilbd_hc_srv_t state
232 * ihd_hc_def_pinging: the default ping should be run
233 * ihd-hc_probing: the probe process should be started
241 * Struct representing a server associated with a hc object
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
260 typedef struct ilbd_hc_srv_s
{
261 list_node_t shc_srv_link
;
263 ilbd_hc_rule_t
*shc_hc_rule
;
264 ilb_sg_srv_t
const *shc_sg_srv
;
266 iu_timer_id_t shc_tid
;
269 ilb_hc_srv_status_t shc_status
;
274 enum ilbd_hc_state shc_state
;
277 ilbd_hc_probe_event_t
*shc_ev
;
282 * Structure for holding audit server and servergroup event
283 * data. Not all events use all members of the structure.
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
;
294 /* Struct to store client info */
298 struct passwd cli_pw
;
302 ilb_comm_t
*cli_saved_reply
;
303 size_t cli_saved_size
;
304 ucred_t
*cli_peer_ucredp
; /* needed for auditing */
307 void ilbd_reply_ok(uint32_t *, size_t *);
308 void ilbd_reply_err(uint32_t *, size_t *, ilb_status_t
);
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
*);
323 ilb_status_t
ilbd_destroy_sg(const char *, const struct passwd
*,
325 ilb_status_t
ilbd_retrieve_sg_hosts(const char *, uint32_t *, size_t *);
327 ilb_status_t
ilbd_enable_server(ilb_sg_info_t
*, const struct passwd
*,
329 ilb_status_t
ilbd_disable_server(ilb_sg_info_t
*, const struct passwd
*,
331 ilb_status_t
ilbd_k_Xable_server(const struct in6_addr
*, const char *,
332 ilbd_srv_status_ind_t
);
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
*);
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 *);
345 ilb_status_t
do_ioctl(void *, ssize_t
);
347 ilb_status_t
ilbd_create_rule(ilb_rule_info_t
*, int, const struct passwd
*,
349 ilb_status_t
ilbd_retrieve_rule(ilbd_name_t
, uint32_t *, size_t *);
351 ilb_status_t
ilbd_destroy_rule(ilbd_name_t
, const struct passwd
*,
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
*,
357 boolean_t
is_debugging_on(void);
358 ilb_status_t
ilbd_sg_check_rule_port(ilbd_sg_t
*, ilb_rule_info_t
*);
360 void ilbd_enable_debug(void);
361 ilb_status_t
ilb_map_errno2ilbstat(int);
363 ilb_status_t
i_attach_rule2sg(ilbd_sg_t
*, ilbd_rule_t
*);
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__)
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
*,
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
*);
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
*);
396 /* Show NAT info routines */
397 ilb_status_t
ilbd_show_nat(void *, const ilb_comm_t
*, uint32_t *,
399 void ilbd_show_nat_cleanup(void);
402 /* Show sticky info routines */
403 ilb_status_t
ilbd_show_sticky(void *, const ilb_comm_t
*, uint32_t *,
405 void ilbd_show_sticky_cleanup(void);
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
*,
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);
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
);