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