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