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 #ifndef _LIBILB_IMPL_H
28*dbed73cbSSangeeta Misra #define	_LIBILB_IMPL_H
29*dbed73cbSSangeeta Misra 
30*dbed73cbSSangeeta Misra #ifdef __cplusplus
31*dbed73cbSSangeeta Misra extern "C" {
32*dbed73cbSSangeeta Misra #endif
33*dbed73cbSSangeeta Misra 
34*dbed73cbSSangeeta Misra #include <sys/types.h>
35*dbed73cbSSangeeta Misra #include <sys/socket.h>
36*dbed73cbSSangeeta Misra #include <sys/note.h>
37*dbed73cbSSangeeta Misra #include <netinet/in.h>
38*dbed73cbSSangeeta Misra #include <netdb.h>
39*dbed73cbSSangeeta Misra #include <net/if.h>
40*dbed73cbSSangeeta Misra #include <inet/ilb.h>
41*dbed73cbSSangeeta Misra #include <libilb.h>
42*dbed73cbSSangeeta Misra #include <thread.h>
43*dbed73cbSSangeeta Misra #include <synch.h>
44*dbed73cbSSangeeta Misra 
45*dbed73cbSSangeeta Misra #if !defined max
46*dbed73cbSSangeeta Misra #define	max(a, b)	((a) > (b) ? (a) : (b))
47*dbed73cbSSangeeta Misra #endif
48*dbed73cbSSangeeta Misra 
49*dbed73cbSSangeeta Misra /* The UNIX domain socket path to talk to ilbd. */
50*dbed73cbSSangeeta Misra #define	SOCKET_PATH	"/var/run/daemon/ilb_sock"
51*dbed73cbSSangeeta Misra 
52*dbed73cbSSangeeta Misra /* The max message size for communicating with ilbd */
53*dbed73cbSSangeeta Misra #define	ILBD_MSG_SIZE	102400
54*dbed73cbSSangeeta Misra 
55*dbed73cbSSangeeta Misra /*
56*dbed73cbSSangeeta Misra  * moral equivalent of ntohl for IPv6 addresses, MSB and LSB (64 bit each),
57*dbed73cbSSangeeta Misra  * assign to uint64_t variables
58*dbed73cbSSangeeta Misra  */
59*dbed73cbSSangeeta Misra #define	INV6_N2H_MSB64(addr)				\
60*dbed73cbSSangeeta Misra 	(((uint64_t)ntohl((addr)->_S6_un._S6_u32[0]) << 32) + 	\
61*dbed73cbSSangeeta Misra 	    (ntohl((addr)->_S6_un._S6_u32[1])))
62*dbed73cbSSangeeta Misra 
63*dbed73cbSSangeeta Misra #define	INV6_N2H_LSB64(addr)				\
64*dbed73cbSSangeeta Misra 	(((uint64_t)ntohl((addr)->_S6_un._S6_u32[2]) << 32) + 	\
65*dbed73cbSSangeeta Misra 	    (ntohl((addr)->_S6_un._S6_u32[3])))
66*dbed73cbSSangeeta Misra 
67*dbed73cbSSangeeta Misra /*
68*dbed73cbSSangeeta Misra  * moral equiv. of htonl of MSB and LSB 64-bit portions to an IPv6 address
69*dbed73cbSSangeeta Misra  */
70*dbed73cbSSangeeta Misra #define	INV6_H2N_MSB64(addr, msb)				\
71*dbed73cbSSangeeta Misra 	(addr)->_S6_un._S6_u32[0] = htonl((msb) >> 32);		\
72*dbed73cbSSangeeta Misra 	(addr)->_S6_un._S6_u32[1] = htonl((msb) & 0xffffffff)
73*dbed73cbSSangeeta Misra 
74*dbed73cbSSangeeta Misra #define	INV6_H2N_LSB64(addr, lsb)				\
75*dbed73cbSSangeeta Misra 	(addr)->_S6_un._S6_u32[2] = htonl((lsb) >> 32);		\
76*dbed73cbSSangeeta Misra 	(addr)->_S6_un._S6_u32[3] = htonl((lsb) & 0xffffffff)
77*dbed73cbSSangeeta Misra 
78*dbed73cbSSangeeta Misra #define	IP_COPY_CLI_2_IMPL(_e, _i)				\
79*dbed73cbSSangeeta Misra 	bzero(_i, sizeof (*(_i)));				\
80*dbed73cbSSangeeta Misra 	if ((_e)->ia_af == AF_INET6)  				\
81*dbed73cbSSangeeta Misra 		(void) memcpy((_i), &(_e)->ia_v6, sizeof (*(_i)));	\
82*dbed73cbSSangeeta Misra 	else							\
83*dbed73cbSSangeeta Misra 		IN6_INADDR_TO_V4MAPPED(&(_e)->ia_v4, (_i))
84*dbed73cbSSangeeta Misra 
85*dbed73cbSSangeeta Misra #define	IP_COPY_IMPL_2_CLI(_i, _e)				\
86*dbed73cbSSangeeta Misra 	do {							\
87*dbed73cbSSangeeta Misra 		bzero(_e, sizeof (*(_e)));			\
88*dbed73cbSSangeeta Misra 		if (IN6_IS_ADDR_V4MAPPED(_i)) {			\
89*dbed73cbSSangeeta Misra 			(_e)->ia_af = AF_INET;			\
90*dbed73cbSSangeeta Misra 			IN6_V4MAPPED_TO_INADDR((_i), &(_e)->ia_v4); \
91*dbed73cbSSangeeta Misra 		} else {					\
92*dbed73cbSSangeeta Misra 			(_e)->ia_af = AF_INET6;			\
93*dbed73cbSSangeeta Misra 			(void) memcpy(&(_e)->ia_v6, (_i), 	\
94*dbed73cbSSangeeta Misra 			    sizeof ((_e)->ia_v6));		\
95*dbed73cbSSangeeta Misra 		}						\
96*dbed73cbSSangeeta Misra 		_NOTE(CONSTCOND)				\
97*dbed73cbSSangeeta Misra 	} while (0)
98*dbed73cbSSangeeta Misra 
99*dbed73cbSSangeeta Misra #define	GET_AF(_a) IN6_IS_ADDR_V4MAPPED(_a)?AF_INET:AF_INET6
100*dbed73cbSSangeeta Misra #define	IS_AF_VALID(_af) (_af == AF_INET || _af == AF_INET6)
101*dbed73cbSSangeeta Misra 
102*dbed73cbSSangeeta Misra typedef enum {
103*dbed73cbSSangeeta Misra 	ILBD_BAD_CMD = 0,
104*dbed73cbSSangeeta Misra 				/* servergroup commands */
105*dbed73cbSSangeeta Misra 	ILBD_CREATE_SERVERGROUP,
106*dbed73cbSSangeeta Misra 	ILBD_ADD_SERVER_TO_GROUP,
107*dbed73cbSSangeeta Misra 	ILBD_REM_SERVER_FROM_GROUP,
108*dbed73cbSSangeeta Misra 	ILBD_ENABLE_SERVER,
109*dbed73cbSSangeeta Misra 	ILBD_DISABLE_SERVER,
110*dbed73cbSSangeeta Misra 	ILBD_DESTROY_SERVERGROUP,
111*dbed73cbSSangeeta Misra 	ILBD_RETRIEVE_SG_NAMES,		/* names of all SGs registered */
112*dbed73cbSSangeeta Misra 	ILBD_RETRIEVE_SG_HOSTS,		/* all hosts for a given SG (hndl) */
113*dbed73cbSSangeeta Misra 	ILBD_SRV_ADDR2ID,	/* fill in serverID for given address */
114*dbed73cbSSangeeta Misra 	ILBD_SRV_ID2ADDR,	/* fill in address from given serverID */
115*dbed73cbSSangeeta Misra 				/* rule commands */
116*dbed73cbSSangeeta Misra 	ILBD_CREATE_RULE,
117*dbed73cbSSangeeta Misra 	ILBD_DESTROY_RULE,
118*dbed73cbSSangeeta Misra 	ILBD_ENABLE_RULE,
119*dbed73cbSSangeeta Misra 	ILBD_DISABLE_RULE,
120*dbed73cbSSangeeta Misra 	ILBD_RETRIEVE_RULE_NAMES,
121*dbed73cbSSangeeta Misra 	ILBD_RETRIEVE_RULE,
122*dbed73cbSSangeeta Misra 
123*dbed73cbSSangeeta Misra 	ILBD_CREATE_HC,
124*dbed73cbSSangeeta Misra 	ILBD_DESTROY_HC,
125*dbed73cbSSangeeta Misra 	ILBD_GET_HC_INFO,
126*dbed73cbSSangeeta Misra 	ILBD_GET_HC_SRVS,
127*dbed73cbSSangeeta Misra 	ILBD_GET_HC_RULES,
128*dbed73cbSSangeeta Misra 	ILBD_RETRIEVE_HC_NAMES,
129*dbed73cbSSangeeta Misra 
130*dbed73cbSSangeeta Misra 	ILBD_SHOW_NAT,		/* list the NAT table */
131*dbed73cbSSangeeta Misra 	ILBD_SHOW_PERSIST,	/* list the sticky table */
132*dbed73cbSSangeeta Misra 
133*dbed73cbSSangeeta Misra 	ILBD_CMD_OK,		/* Requested operation succeeds. */
134*dbed73cbSSangeeta Misra 	ILBD_CMD_ERROR		/* Rquested operation fails. */
135*dbed73cbSSangeeta Misra } ilbd_cmd_t;
136*dbed73cbSSangeeta Misra 
137*dbed73cbSSangeeta Misra typedef struct sg_srv {
138*dbed73cbSSangeeta Misra 	int32_t		sgs_flags;	/* enabled, dis- */
139*dbed73cbSSangeeta Misra 	struct in6_addr	sgs_addr;
140*dbed73cbSSangeeta Misra 	int32_t		sgs_minport;
141*dbed73cbSSangeeta Misra 	int32_t		sgs_maxport;
142*dbed73cbSSangeeta Misra 	int32_t		sgs_id;		/* numerical part of srvID */
143*dbed73cbSSangeeta Misra 	char		sgs_srvID[ILB_NAMESZ];	/* "name" given to server */
144*dbed73cbSSangeeta Misra } ilb_sg_srv_t;
145*dbed73cbSSangeeta Misra 
146*dbed73cbSSangeeta Misra typedef struct sg_info {
147*dbed73cbSSangeeta Misra 	int32_t		sg_flags;
148*dbed73cbSSangeeta Misra 	char		sg_name[ILB_SGNAME_SZ];
149*dbed73cbSSangeeta Misra 	int32_t		sg_srvcount;
150*dbed73cbSSangeeta Misra 	ilb_sg_srv_t	sg_servers[];
151*dbed73cbSSangeeta Misra } ilb_sg_info_t;
152*dbed73cbSSangeeta Misra 
153*dbed73cbSSangeeta Misra typedef char	ilbd_name_t[ILB_NAMESZ];
154*dbed73cbSSangeeta Misra 
155*dbed73cbSSangeeta Misra typedef struct ilbd_namelist {
156*dbed73cbSSangeeta Misra 	int32_t		ilbl_flags;
157*dbed73cbSSangeeta Misra 	int32_t		ilbl_count;
158*dbed73cbSSangeeta Misra 	ilbd_name_t	ilbl_name[];
159*dbed73cbSSangeeta Misra } ilbd_namelist_t;
160*dbed73cbSSangeeta Misra 
161*dbed73cbSSangeeta Misra #define	ILBL_NAME_OFFSET	(offsetof(ilbd_namelist_t, ilbl_name))
162*dbed73cbSSangeeta Misra 
163*dbed73cbSSangeeta Misra typedef struct rule_info {
164*dbed73cbSSangeeta Misra 	int32_t		rl_flags;
165*dbed73cbSSangeeta Misra 	char		rl_name[ILB_NAMESZ];
166*dbed73cbSSangeeta Misra 	struct in6_addr	rl_vip;
167*dbed73cbSSangeeta Misra 	uint16_t	rl_proto;
168*dbed73cbSSangeeta Misra 	uint16_t	rl_ipversion;
169*dbed73cbSSangeeta Misra 	int32_t		rl_minport;
170*dbed73cbSSangeeta Misra 	int32_t		rl_maxport;
171*dbed73cbSSangeeta Misra 	ilb_algo_t	rl_algo;
172*dbed73cbSSangeeta Misra 	ilb_topo_t	rl_topo;
173*dbed73cbSSangeeta Misra 	struct in6_addr	rl_nat_src_start;
174*dbed73cbSSangeeta Misra 	struct in6_addr	rl_nat_src_end;
175*dbed73cbSSangeeta Misra 	struct in6_addr	rl_stickymask;
176*dbed73cbSSangeeta Misra 	uint32_t	rl_conndrain;
177*dbed73cbSSangeeta Misra 	uint32_t	rl_nat_timeout;
178*dbed73cbSSangeeta Misra 	uint32_t	rl_sticky_timeout;
179*dbed73cbSSangeeta Misra 	in_port_t	rl_hcport;
180*dbed73cbSSangeeta Misra 	ilb_hcp_flags_t	rl_hcpflag;
181*dbed73cbSSangeeta Misra 	char		rl_sgname[ILB_SGNAME_SZ];
182*dbed73cbSSangeeta Misra 	char		rl_hcname[ILB_NAMESZ];
183*dbed73cbSSangeeta Misra } ilb_rule_info_t;
184*dbed73cbSSangeeta Misra 
185*dbed73cbSSangeeta Misra /*
186*dbed73cbSSangeeta Misra  * Struct to represent show NAT request and reply.
187*dbed73cbSSangeeta Misra  *
188*dbed73cbSSangeeta Misra  * sn_num: (request) indicates the number of entries wanted;
189*dbed73cbSSangeeta Misra  *         (reply) the number of entries returned;
190*dbed73cbSSangeeta Misra  * sn_data: NAT/persist able entries (is uint32_t aligned).
191*dbed73cbSSangeeta Misra  */
192*dbed73cbSSangeeta Misra typedef struct {
193*dbed73cbSSangeeta Misra 	uint32_t	sn_num;
194*dbed73cbSSangeeta Misra 	uint32_t	sn_data[];
195*dbed73cbSSangeeta Misra } ilb_show_info_t;
196*dbed73cbSSangeeta Misra 
197*dbed73cbSSangeeta Misra /*
198*dbed73cbSSangeeta Misra  * Struct to represent the set of servers associated with a hc object.
199*dbed73cbSSangeeta Misra  *
200*dbed73cbSSangeeta Misra  * rs_num_srvs: number of servers in this struct.
201*dbed73cbSSangeeta Misra  * rs_srvs: array of servers.
202*dbed73cbSSangeeta Misra  */
203*dbed73cbSSangeeta Misra typedef struct {
204*dbed73cbSSangeeta Misra 	uint32_t	rs_num_srvs;
205*dbed73cbSSangeeta Misra 	ilb_hc_srv_t	rs_srvs[];
206*dbed73cbSSangeeta Misra } ilb_hc_rule_srv_t;
207*dbed73cbSSangeeta Misra 
208*dbed73cbSSangeeta Misra typedef struct ilb_handle_impl {
209*dbed73cbSSangeeta Misra 	mutex_t		h_lock;
210*dbed73cbSSangeeta Misra 	cond_t		h_cv;
211*dbed73cbSSangeeta Misra 	boolean_t	h_busy;
212*dbed73cbSSangeeta Misra 	boolean_t	h_valid;
213*dbed73cbSSangeeta Misra 	boolean_t	h_closing;
214*dbed73cbSSangeeta Misra 	uint32_t	h_waiter;
215*dbed73cbSSangeeta Misra 	int		h_socket;
216*dbed73cbSSangeeta Misra 	ilb_status_t	h_error;	/* ... that caused invalidation */
217*dbed73cbSSangeeta Misra } ilb_handle_impl_t;
218*dbed73cbSSangeeta Misra 
219*dbed73cbSSangeeta Misra /*
220*dbed73cbSSangeeta Misra  * Communication flags used in ilb_comm_t.
221*dbed73cbSSangeeta Misra  *
222*dbed73cbSSangeeta Misra  * ILB_COMM_END: end of communication
223*dbed73cbSSangeeta Misra  */
224*dbed73cbSSangeeta Misra #define	ILB_COMM_END	0x1
225*dbed73cbSSangeeta Misra 
226*dbed73cbSSangeeta Misra /*
227*dbed73cbSSangeeta Misra  * The message structure used to communicate with ilbd.
228*dbed73cbSSangeeta Misra  *
229*dbed73cbSSangeeta Misra  * ic_cmd: the message type.
230*dbed73cbSSangeeta Misra  * ic_flags: communication flags
231*dbed73cbSSangeeta Misra  * ic_data: message data (is uint32_t aligned).
232*dbed73cbSSangeeta Misra  */
233*dbed73cbSSangeeta Misra typedef struct {
234*dbed73cbSSangeeta Misra 	ilbd_cmd_t	ic_cmd;
235*dbed73cbSSangeeta Misra 	int32_t		ic_flags;
236*dbed73cbSSangeeta Misra 	uint32_t	ic_data[];
237*dbed73cbSSangeeta Misra } ilb_comm_t;
238*dbed73cbSSangeeta Misra 
239*dbed73cbSSangeeta Misra ilb_status_t	i_check_ip_range(ilb_ip_addr_t *, ilb_ip_addr_t *);
240*dbed73cbSSangeeta Misra ilb_status_t	i_ilb_do_comm(ilb_handle_t, ilb_comm_t *, size_t, ilb_comm_t *,
241*dbed73cbSSangeeta Misra 		    size_t *);
242*dbed73cbSSangeeta Misra void		i_ilb_close_comm(ilb_handle_t);
243*dbed73cbSSangeeta Misra struct in6_addr	i_next_ip_addr(struct in6_addr *, int);
244*dbed73cbSSangeeta Misra 
245*dbed73cbSSangeeta Misra ilb_status_t	i_ilb_retrieve_rule_names(ilb_handle_t, ilb_comm_t **,
246*dbed73cbSSangeeta Misra 		    size_t *);
247*dbed73cbSSangeeta Misra ilb_comm_t 	*i_ilb_alloc_req(ilbd_cmd_t, size_t *);
248*dbed73cbSSangeeta Misra 
249*dbed73cbSSangeeta Misra #ifdef __cplusplus
250*dbed73cbSSangeeta Misra }
251*dbed73cbSSangeeta Misra #endif
252*dbed73cbSSangeeta Misra 
253*dbed73cbSSangeeta Misra #endif /* _LIBILB_IMPL_H */
254