xref: /illumos-gate/usr/src/uts/common/inet/ilb/ilb_impl.h (revision dbed73cb)
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 _INET_ILB_IMPL_H
28*dbed73cbSSangeeta Misra #define	_INET_ILB_IMPL_H
29*dbed73cbSSangeeta Misra 
30*dbed73cbSSangeeta Misra #include <sys/types.h>
31*dbed73cbSSangeeta Misra #include <sys/kstat.h>
32*dbed73cbSSangeeta Misra #include <sys/netstack.h>
33*dbed73cbSSangeeta Misra 
34*dbed73cbSSangeeta Misra #ifdef __cplusplus
35*dbed73cbSSangeeta Misra extern "C" {
36*dbed73cbSSangeeta Misra #endif
37*dbed73cbSSangeeta Misra 
38*dbed73cbSSangeeta Misra /*
39*dbed73cbSSangeeta Misra  * Statistics in ILB is stored in several kstat structures.  ilb_g_kstat
40*dbed73cbSSangeeta Misra  * represents the global statistics.  ilb_rule_kstat represents the statistics
41*dbed73cbSSangeeta Misra  * of a rule.  ilb_server_kstat represents the statistics of a server.
42*dbed73cbSSangeeta Misra  */
43*dbed73cbSSangeeta Misra #define	ILB_KSTAT_MOD_NAME	"ilb"
44*dbed73cbSSangeeta Misra 
45*dbed73cbSSangeeta Misra typedef struct ilb_g_kstat_s {
46*dbed73cbSSangeeta Misra 	kstat_named_t	num_rules;	/* Number of rules */
47*dbed73cbSSangeeta Misra 	kstat_named_t	ip_frag_in;	/* Number of input fragments */
48*dbed73cbSSangeeta Misra 	kstat_named_t	ip_frag_dropped; /* Number of fragments dropped */
49*dbed73cbSSangeeta Misra } ilb_g_kstat_t;
50*dbed73cbSSangeeta Misra 
51*dbed73cbSSangeeta Misra #define	ILB_KSTAT_UPDATE(ilbs, x, y)				\
52*dbed73cbSSangeeta Misra {								\
53*dbed73cbSSangeeta Misra 	DTRACE_PROBE1(ilb__g__kstat__##x, ilb_stack_t *,	\
54*dbed73cbSSangeeta Misra 	    (ilbs));						\
55*dbed73cbSSangeeta Misra 	((ilbs)->ilbs_kstat->x.value.ui64 += (y));		\
56*dbed73cbSSangeeta Misra }
57*dbed73cbSSangeeta Misra 
58*dbed73cbSSangeeta Misra typedef struct ilb_rule_kstat {
59*dbed73cbSSangeeta Misra 	kstat_named_t	num_servers;	/* Number of back end servers */
60*dbed73cbSSangeeta Misra 	kstat_named_t	bytes_not_processed; /* Num of bytes not processed. */
61*dbed73cbSSangeeta Misra 	kstat_named_t	pkt_not_processed; /* Num of packets not processed. */
62*dbed73cbSSangeeta Misra 	kstat_named_t	bytes_dropped;	/* Number of bytes dropped */
63*dbed73cbSSangeeta Misra 	kstat_named_t	pkt_dropped;	/* Number of packets dropped */
64*dbed73cbSSangeeta Misra 	kstat_named_t	nomem_bytes_dropped; /* Bytes dropped due to nomem */
65*dbed73cbSSangeeta Misra 	kstat_named_t	nomem_pkt_dropped; /* Packets dropped due to nomem */
66*dbed73cbSSangeeta Misra 	kstat_named_t	noport_bytes_dropped; /* No NAT sport bytes drop */
67*dbed73cbSSangeeta Misra 	kstat_named_t	noport_pkt_dropped; /* No NAT sport packet drop */
68*dbed73cbSSangeeta Misra 	kstat_named_t	icmp_echo_processed; /* No of ICMP echo processed */
69*dbed73cbSSangeeta Misra 	kstat_named_t	icmp_dropped;	/* No of ICMP packets dropped */
70*dbed73cbSSangeeta Misra 	kstat_named_t	icmp_2big_processed; /* No of ICMP 2big processed */
71*dbed73cbSSangeeta Misra 	kstat_named_t	icmp_2big_dropped; /* No of ICMP 2big dropped */
72*dbed73cbSSangeeta Misra } ilb_rule_kstat_t;
73*dbed73cbSSangeeta Misra 
74*dbed73cbSSangeeta Misra #define	ILB_R_KSTAT(rule, x)					\
75*dbed73cbSSangeeta Misra {								\
76*dbed73cbSSangeeta Misra 	DTRACE_PROBE1(ilb__r__kstat__##x, ilb_rule_t *,	\
77*dbed73cbSSangeeta Misra 	    (rule));						\
78*dbed73cbSSangeeta Misra 	((rule)->ir_kstat.x.value.ui64++);			\
79*dbed73cbSSangeeta Misra }
80*dbed73cbSSangeeta Misra #define	ILB_R_KSTAT_UPDATE(rule, x, y) 				\
81*dbed73cbSSangeeta Misra {								\
82*dbed73cbSSangeeta Misra 	DTRACE_PROBE1(ilb__r__kstat__##x, ilb_rule_t *,	\
83*dbed73cbSSangeeta Misra 	    (rule));						\
84*dbed73cbSSangeeta Misra 	((rule)->ir_kstat.x.value.ui64 += (y));			\
85*dbed73cbSSangeeta Misra }
86*dbed73cbSSangeeta Misra 
87*dbed73cbSSangeeta Misra typedef struct ilb_server_kstat {
88*dbed73cbSSangeeta Misra 	kstat_named_t	bytes_processed; /* Number of bytes processed */
89*dbed73cbSSangeeta Misra 	kstat_named_t	pkt_processed;	/* Number of packets processed */
90*dbed73cbSSangeeta Misra 	kstat_named_t	ip_address;	/* IP address of the server */
91*dbed73cbSSangeeta Misra } ilb_server_kstat_t;
92*dbed73cbSSangeeta Misra 
93*dbed73cbSSangeeta Misra #define	ILB_S_KSTAT(host, x)					\
94*dbed73cbSSangeeta Misra {								\
95*dbed73cbSSangeeta Misra 	DTRACE_PROBE1(ilb__s__kstat__##x, ilb_server_t *,	\
96*dbed73cbSSangeeta Misra 	    (host));						\
97*dbed73cbSSangeeta Misra 	((host)->iser_kstat.x.value.ui64++);			\
98*dbed73cbSSangeeta Misra }
99*dbed73cbSSangeeta Misra #define	ILB_S_KSTAT_UPDATE(host, x, y)				\
100*dbed73cbSSangeeta Misra {								\
101*dbed73cbSSangeeta Misra 	DTRACE_PROBE1(ilb__s__kstat__##x, ilb_server_t *,	\
102*dbed73cbSSangeeta Misra 	    (host));						\
103*dbed73cbSSangeeta Misra 	((host)->iser_kstat.x.value.ui64 += (y));		\
104*dbed73cbSSangeeta Misra }
105*dbed73cbSSangeeta Misra 
106*dbed73cbSSangeeta Misra /* The maximum port range, meaning all ports (65535 - 1). */
107*dbed73cbSSangeeta Misra #define	ILB_ALL_PORTS_RANGE	65534
108*dbed73cbSSangeeta Misra 
109*dbed73cbSSangeeta Misra struct ilb_nat_src_s;
110*dbed73cbSSangeeta Misra 
111*dbed73cbSSangeeta Misra /*
112*dbed73cbSSangeeta Misra  * This structure reprensents a server.
113*dbed73cbSSangeeta Misra  */
114*dbed73cbSSangeeta Misra typedef struct ilb_server_s {
115*dbed73cbSSangeeta Misra 	in6_addr_t		iser_addr_v6;
116*dbed73cbSSangeeta Misra 	in6_addr_t		iser_prefix_v6;
117*dbed73cbSSangeeta Misra #define	iser_addr_v4		iser_addr_v6.s6_addr32[3]
118*dbed73cbSSangeeta Misra #define	iser_prefix_v4		iser_prefix_v6.s6_addr32[3]
119*dbed73cbSSangeeta Misra 
120*dbed73cbSSangeeta Misra 	boolean_t		iser_port_range;
121*dbed73cbSSangeeta Misra 	in_port_t		iser_min_port;	/* In host byte order */
122*dbed73cbSSangeeta Misra 	in_port_t		iser_max_port;
123*dbed73cbSSangeeta Misra 
124*dbed73cbSSangeeta Misra 	char			iser_name[ILB_SERVER_NAMESZ];
125*dbed73cbSSangeeta Misra 	char			iser_ip_addr[INET6_ADDRSTRLEN];
126*dbed73cbSSangeeta Misra 	netstackid_t		iser_stackid;
127*dbed73cbSSangeeta Misra 	kstat_t			*iser_ksp;
128*dbed73cbSSangeeta Misra 	ilb_server_kstat_t	iser_kstat;
129*dbed73cbSSangeeta Misra 	struct ilb_server_s	*iser_next;
130*dbed73cbSSangeeta Misra 
131*dbed73cbSSangeeta Misra 	boolean_t		iser_enabled;
132*dbed73cbSSangeeta Misra 	kmutex_t		iser_lock;
133*dbed73cbSSangeeta Misra 	kcondvar_t		iser_cv;
134*dbed73cbSSangeeta Misra 	uint64_t		iser_refcnt;
135*dbed73cbSSangeeta Misra 
136*dbed73cbSSangeeta Misra 	int64_t			iser_die_time;
137*dbed73cbSSangeeta Misra 
138*dbed73cbSSangeeta Misra 	struct ilb_nat_src_s	*iser_nat_src;
139*dbed73cbSSangeeta Misra } ilb_server_t;
140*dbed73cbSSangeeta Misra 
141*dbed73cbSSangeeta Misra #define	ILB_SERVER_REFHOLD(host)	\
142*dbed73cbSSangeeta Misra {					\
143*dbed73cbSSangeeta Misra 	mutex_enter(&(host)->iser_lock);	\
144*dbed73cbSSangeeta Misra 	(host)->iser_refcnt++;		\
145*dbed73cbSSangeeta Misra 	ASSERT((host)->iser_refcnt != 1);	\
146*dbed73cbSSangeeta Misra 	mutex_exit(&(host)->iser_lock);	\
147*dbed73cbSSangeeta Misra }
148*dbed73cbSSangeeta Misra 
149*dbed73cbSSangeeta Misra #define	ILB_SERVER_REFRELE(host)		\
150*dbed73cbSSangeeta Misra {						\
151*dbed73cbSSangeeta Misra 	mutex_enter(&(host)->iser_lock);		\
152*dbed73cbSSangeeta Misra 	(host)->iser_refcnt--;			\
153*dbed73cbSSangeeta Misra 	if ((host)->iser_refcnt == 1)		\
154*dbed73cbSSangeeta Misra 		cv_signal(&(host)->iser_cv);	\
155*dbed73cbSSangeeta Misra 	mutex_exit(&(host)->iser_lock);		\
156*dbed73cbSSangeeta Misra }
157*dbed73cbSSangeeta Misra 
158*dbed73cbSSangeeta Misra struct ilb_rule_s;
159*dbed73cbSSangeeta Misra struct ilb_hash_s;
160*dbed73cbSSangeeta Misra 
161*dbed73cbSSangeeta Misra typedef struct ilb_alg_data_s {
162*dbed73cbSSangeeta Misra 	boolean_t	(*ilb_alg_lb)(in6_addr_t *, in_port_t, in6_addr_t *,
163*dbed73cbSSangeeta Misra 			    in_port_t, void *, ilb_server_t **);
164*dbed73cbSSangeeta Misra 	int		(*ilb_alg_server_add)(ilb_server_t *, void *);
165*dbed73cbSSangeeta Misra 	int		(*ilb_alg_server_del)(ilb_server_t *, void *);
166*dbed73cbSSangeeta Misra 	int		(*ilb_alg_server_enable)(ilb_server_t *, void *);
167*dbed73cbSSangeeta Misra 	int		(*ilb_alg_server_disable)(ilb_server_t *, void *);
168*dbed73cbSSangeeta Misra 	void		(*ilb_alg_fini)(struct ilb_alg_data_s **);
169*dbed73cbSSangeeta Misra 
170*dbed73cbSSangeeta Misra 	void		*ilb_alg_data;
171*dbed73cbSSangeeta Misra } ilb_alg_data_t;
172*dbed73cbSSangeeta Misra 
173*dbed73cbSSangeeta Misra /*
174*dbed73cbSSangeeta Misra  * A load balance rule has
175*dbed73cbSSangeeta Misra  *
176*dbed73cbSSangeeta Misra  * 1. a name
177*dbed73cbSSangeeta Misra  * 2. a network protocol
178*dbed73cbSSangeeta Misra  * 3. a transport protocol
179*dbed73cbSSangeeta Misra  * 4. a load balance mechanism (DSR, NAT, ...)
180*dbed73cbSSangeeta Misra  * 5. a target address (VIP)
181*dbed73cbSSangeeta Misra  * 6. a target port (or port ranges)
182*dbed73cbSSangeeta Misra  * 7. a pool of back end servers
183*dbed73cbSSangeeta Misra  * 8. a load balance algorithm (round robin, hashing, ...)
184*dbed73cbSSangeeta Misra  */
185*dbed73cbSSangeeta Misra typedef struct ilb_rule_s {
186*dbed73cbSSangeeta Misra 	char			ir_name[ILB_RULE_NAMESZ];
187*dbed73cbSSangeeta Misra 	uint8_t			ir_ipver;
188*dbed73cbSSangeeta Misra 	uint8_t			ir_proto;
189*dbed73cbSSangeeta Misra 	ilb_topo_impl_t		ir_topo;
190*dbed73cbSSangeeta Misra 	zoneid_t		ir_zoneid;
191*dbed73cbSSangeeta Misra 	uint32_t		ir_flags;
192*dbed73cbSSangeeta Misra 
193*dbed73cbSSangeeta Misra 	in6_addr_t		ir_target_v6;
194*dbed73cbSSangeeta Misra #define	ir_target_v4		ir_target_v6.s6_addr32[3]
195*dbed73cbSSangeeta Misra 	in6_addr_t		ir_prefix_v6;
196*dbed73cbSSangeeta Misra #define	ir_target_prefix_v4	ir_prefix_v6.s6_addr32[3]
197*dbed73cbSSangeeta Misra 
198*dbed73cbSSangeeta Misra 	boolean_t		ir_port_range;
199*dbed73cbSSangeeta Misra 	in_port_t		ir_min_port;	/* In host byte order */
200*dbed73cbSSangeeta Misra 	in_port_t		ir_max_port;
201*dbed73cbSSangeeta Misra 
202*dbed73cbSSangeeta Misra 	ilb_server_t		*ir_servers;
203*dbed73cbSSangeeta Misra 
204*dbed73cbSSangeeta Misra 	uint32_t		ir_nat_expiry;
205*dbed73cbSSangeeta Misra 	uint32_t		ir_conn_drain_timeout;
206*dbed73cbSSangeeta Misra 	in6_addr_t		ir_nat_src_start;
207*dbed73cbSSangeeta Misra 	in6_addr_t		ir_nat_src_end;
208*dbed73cbSSangeeta Misra 
209*dbed73cbSSangeeta Misra 	boolean_t		ir_sticky;
210*dbed73cbSSangeeta Misra 	in6_addr_t		ir_sticky_mask;
211*dbed73cbSSangeeta Misra 	uint32_t		ir_sticky_expiry;
212*dbed73cbSSangeeta Misra 
213*dbed73cbSSangeeta Misra 	struct ilb_rule_s	*ir_next;
214*dbed73cbSSangeeta Misra 
215*dbed73cbSSangeeta Misra 	struct ilb_rule_s	*ir_hash_next;
216*dbed73cbSSangeeta Misra 	struct ilb_rule_s	*ir_hash_prev;
217*dbed73cbSSangeeta Misra 	struct ilb_hash_s	*ir_hash;
218*dbed73cbSSangeeta Misra 
219*dbed73cbSSangeeta Misra 	ilb_algo_impl_t		ir_alg_type;
220*dbed73cbSSangeeta Misra 	ilb_alg_data_t		*ir_alg;
221*dbed73cbSSangeeta Misra 
222*dbed73cbSSangeeta Misra 	kstat_t			*ir_ksp;
223*dbed73cbSSangeeta Misra 	ilb_rule_kstat_t	ir_kstat;
224*dbed73cbSSangeeta Misra 	uint_t			ir_ks_instance;
225*dbed73cbSSangeeta Misra 
226*dbed73cbSSangeeta Misra 	kmutex_t		ir_lock;
227*dbed73cbSSangeeta Misra 	kcondvar_t		ir_cv;
228*dbed73cbSSangeeta Misra 	uint32_t		ir_refcnt;
229*dbed73cbSSangeeta Misra } ilb_rule_t;
230*dbed73cbSSangeeta Misra 
231*dbed73cbSSangeeta Misra #define	ILB_RULE_REFHOLD(rule)			\
232*dbed73cbSSangeeta Misra {						\
233*dbed73cbSSangeeta Misra 	mutex_enter(&(rule)->ir_lock);		\
234*dbed73cbSSangeeta Misra 	(rule)->ir_refcnt++;			\
235*dbed73cbSSangeeta Misra 	ASSERT((rule)->ir_refcnt != 1);		\
236*dbed73cbSSangeeta Misra 	mutex_exit(&(rule)->ir_lock);		\
237*dbed73cbSSangeeta Misra }
238*dbed73cbSSangeeta Misra 
239*dbed73cbSSangeeta Misra #define	ILB_RULE_REFRELE(rule)			\
240*dbed73cbSSangeeta Misra {						\
241*dbed73cbSSangeeta Misra 	mutex_enter(&(rule)->ir_lock);		\
242*dbed73cbSSangeeta Misra 	ASSERT((rule)->ir_refcnt >= 2);		\
243*dbed73cbSSangeeta Misra 	if (--(rule)->ir_refcnt <= 2)		\
244*dbed73cbSSangeeta Misra 		cv_signal(&(rule)->ir_cv);	\
245*dbed73cbSSangeeta Misra 	mutex_exit(&(rule)->ir_lock);		\
246*dbed73cbSSangeeta Misra }
247*dbed73cbSSangeeta Misra 
248*dbed73cbSSangeeta Misra 
249*dbed73cbSSangeeta Misra typedef struct ilb_hash_s {
250*dbed73cbSSangeeta Misra 	ilb_rule_t	*ilb_hash_rule;
251*dbed73cbSSangeeta Misra 	kmutex_t	ilb_hash_lock;
252*dbed73cbSSangeeta Misra #if defined(_LP64) || defined(_I32LPx)
253*dbed73cbSSangeeta Misra 	char		ilb_hash_pad[48];
254*dbed73cbSSangeeta Misra #else
255*dbed73cbSSangeeta Misra 	char		ilb_hash_pad[56];
256*dbed73cbSSangeeta Misra #endif
257*dbed73cbSSangeeta Misra } ilb_hash_t;
258*dbed73cbSSangeeta Misra 
259*dbed73cbSSangeeta Misra struct ilb_nat_src_entry_s;
260*dbed73cbSSangeeta Misra 
261*dbed73cbSSangeeta Misra /*
262*dbed73cbSSangeeta Misra  * Structure to store NAT info.
263*dbed73cbSSangeeta Misra  *
264*dbed73cbSSangeeta Misra  * Half NAT only uses the first 4 fields in the structure.
265*dbed73cbSSangeeta Misra  */
266*dbed73cbSSangeeta Misra typedef struct {
267*dbed73cbSSangeeta Misra 	in6_addr_t			vip;
268*dbed73cbSSangeeta Misra 	in6_addr_t			nat_dst;
269*dbed73cbSSangeeta Misra 	in_port_t			dport;
270*dbed73cbSSangeeta Misra 	in_port_t			nat_dport;
271*dbed73cbSSangeeta Misra 
272*dbed73cbSSangeeta Misra 	in6_addr_t			src;
273*dbed73cbSSangeeta Misra 	in6_addr_t			nat_src;
274*dbed73cbSSangeeta Misra 	in_port_t			sport;
275*dbed73cbSSangeeta Misra 	in_port_t			nat_sport;
276*dbed73cbSSangeeta Misra 
277*dbed73cbSSangeeta Misra 	struct ilb_nat_src_entry_s	*src_ent;
278*dbed73cbSSangeeta Misra } ilb_nat_info_t;
279*dbed73cbSSangeeta Misra 
280*dbed73cbSSangeeta Misra extern int ilb_kmem_flags;
281*dbed73cbSSangeeta Misra 
282*dbed73cbSSangeeta Misra #ifdef __cplusplus
283*dbed73cbSSangeeta Misra }
284*dbed73cbSSangeeta Misra #endif
285*dbed73cbSSangeeta Misra 
286*dbed73cbSSangeeta Misra #endif /* _INET_ILB_IMPL_H */
287