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