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