/*++ Copyright(c) 1998,99 Microsoft Corporation Module Name: load.h Abstract: Windows Load Balancing Service (WLBS) Driver - load balancing mechanism Author: bbain --*/ #ifndef _Load_h_ #define _Load_h_ #ifndef KERNEL_MODE #define SPINLOCK THREADLOCK #define IRQLEVEL ULONG #define LOCK_INIT(lp) Lock_init(lp) #define LOCK_ENTER(lp, pirql) {if (Lock_enter((lp), INFINITE) != 1) \ UNIV_PRINT(("Lock enter error")); } #define LOCK_EXIT(lp, irql) {if (Lock_exit(lp) != 1) \ UNIV_PRINT(("Lock exit error")); } #else #include #define LINK LIST_ENTRY #define QUEUE LIST_ENTRY #define Link_init(lp) InitializeListHead (lp) #define Link_unlink(lp) {RemoveEntryList (lp) ; InitializeListHead (lp);} #define Queue_init(qp) InitializeListHead (qp) // tmp #define Queue_enq(qp, lp) InsertTailList (qp, lp) #define Queue_enq(qp, lp) if (IsListEmpty(lp)) {InsertTailList(qp, lp);} else DbgBreakPoint() #define Queue_front(qp) (IsListEmpty(qp) ? NULL : (qp) -> Flink) #define Queue_deq(qp) Queue_front(qp);\ if (! IsListEmpty (qp)) { \ PLIST_ENTRY _lp = RemoveHeadList (qp); \ InitializeListHead(_lp); } #define Queue_next(qp, lp) ((IsListEmpty (qp) || (lp) -> Flink == (qp)) ? \ NULL : (lp) -> Flink) #define SPINLOCK KSPIN_LOCK #define IRQLEVEL KIRQL #if 0 /* 1.03: Removed kernel mode locking in this module */ #define LOCK_INIT(lp) KeInitializeSpinLock (lp) #define LOCK_ENTER(lp, pirql) KeAcquireSpinLock (lp, pirql) #define LOCK_EXIT(lp, irql) KeReleaseSpinLock (lp, irql) #endif #define LOCK_INIT(lp) #define LOCK_ENTER(lp, pirql) #define LOCK_EXIT(lp, irql) #endif #include "wlbsparm.h" #include "params.h" #include "wlbsiocl.h" /* CONSTANTS */ /* This is the hardcoded second paramter to Map() when map function limiting is needed. */ #define MAP_FN_PARAMETER 0x00000000 #define CVY_LOADCODE 0xc0deba1c /* type checking code for load structure (bbain 8/19/99) */ #define CVY_ENTRCODE 0xc0debaa5 /* type checking code for conn. entry (bbain 8/19/99) */ #define CVY_DESCCODE 0xc0deba5a /* type checking code for conn. descr. (bbain 8/19/99) */ #define CVY_BINCODE 0xc0debabc /* type checking code for bin structure (bbain 8/19/99) */ #define CVY_MAXBINS 60 /* # load balancing bins; must conform to MAP_T def. V2.06 */ #define CVY_MAX_CHASH 4096 /* max. hash entries for connection hashing V1.1.4 */ #define CVY_INIT_QCONN 1024 /* initial # free connection descriptors V1.1.4 */ #define CVY_EQUAL_LOAD 50 /* load percentage used for equal load balance */ /* TCP connection status */ #define CVY_CONN_UP 1 /* connection may be coming up */ #define CVY_CONN_DOWN 2 /* connection may be going down */ #define CVY_CONN_RESET 3 /* connection is getting reset */ /* ###### added for keynote - ramkrish */ /* broadcast host states */ #define HST_NORMAL 1 /* normal operations */ #define HST_STABLE 2 /* stable convergence detected */ #define HST_CVG 3 /* converging to new load balance */ /* Bitmap for teaming, which is of the form: ------------------------------------- |XXXXXXXX|PPPPPPPP|PPPPPPPP|NNNNNHMA| ------------------------------------- X: Reserved P: XOR of the least significant 16 bits of each participant N: Number of participants H: Hashing (Reverse=1, Normal=0) M: Master (Yes=1, No=0) A: Teaming active (Yes=1, No=0) */ #define CVY_BDA_TEAMING_CODE_ACTIVE_OFFSET 0 #define CVY_BDA_TEAMING_CODE_MASTER_OFFSET 1 #define CVY_BDA_TEAMING_CODE_HASHING_OFFSET 2 #define CVY_BDA_TEAMING_CODE_NUM_MEMBERS_OFFSET 3 #define CVY_BDA_TEAMING_CODE_MEMBERS_OFFSET 8 #define CVY_BDA_TEAMING_CODE_ACTIVE_MASK 0x00000001 #define CVY_BDA_TEAMING_CODE_MASTER_MASK 0x00000002 #define CVY_BDA_TEAMING_CODE_HASHING_MASK 0x00000004 #define CVY_BDA_TEAMING_CODE_NUM_MEMBERS_MASK 0x000000f8 #define CVY_BDA_TEAMING_CODE_MEMBERS_MASK 0x00ffff00 #define CVY_BDA_TEAMING_CODE_CREATE(code,active,master,hashing,num,members) \ (code) |= ((active) << CVY_BDA_TEAMING_CODE_ACTIVE_OFFSET) & CVY_BDA_TEAMING_CODE_ACTIVE_MASK; \ (code) |= ((master) << CVY_BDA_TEAMING_CODE_MASTER_OFFSET) & CVY_BDA_TEAMING_CODE_MASTER_MASK; \ (code) |= ((hashing) << CVY_BDA_TEAMING_CODE_HASHING_OFFSET) & CVY_BDA_TEAMING_CODE_HASHING_MASK; \ (code) |= ((num) << CVY_BDA_TEAMING_CODE_NUM_MEMBERS_OFFSET) & CVY_BDA_TEAMING_CODE_NUM_MEMBERS_MASK; \ (code) |= ((members) << CVY_BDA_TEAMING_CODE_MEMBERS_OFFSET) & CVY_BDA_TEAMING_CODE_MEMBERS_MASK; #define CVY_BDA_TEAMING_CODE_RETRIEVE(code,active,master,hashing,num,members) \ active = (code & CVY_BDA_TEAMING_CODE_ACTIVE_MASK) >> CVY_BDA_TEAMING_CODE_ACTIVE_OFFSET; \ master = (code & CVY_BDA_TEAMING_CODE_MASTER_MASK) >> CVY_BDA_TEAMING_CODE_MASTER_OFFSET; \ hashing = (code & CVY_BDA_TEAMING_CODE_HASHING_MASK) >> CVY_BDA_TEAMING_CODE_HASHING_OFFSET; \ num = (code & CVY_BDA_TEAMING_CODE_NUM_MEMBERS_MASK) >> CVY_BDA_TEAMING_CODE_NUM_MEMBERS_OFFSET; \ members = (code & CVY_BDA_TEAMING_CODE_MEMBERS_MASK) >> CVY_BDA_TEAMING_CODE_MEMBERS_OFFSET; /* DATA STRUCTURES */ /* type for a bin map (V2.04) */ typedef ULONGLONG MAP_T, * PMAP_T; /* state for all bins within a port group */ /* 64-bit -- ramkrish added pad */ typedef struct { ULONG index; /* index in array of bin states */ ULONG code; /* type checking code (bbain 8/17/99) */ MAP_T targ_map; /* new target load map for local host */ MAP_T all_idle_map; /* map of bins idle in all other hosts */ MAP_T cmap; /* cache of cur_map for this host (v2.1) */ MAP_T new_map[CVY_MAX_HOSTS]; /* new map for hosts while converging */ MAP_T cur_map[CVY_MAX_HOSTS]; /* current ownership mask per host */ MAP_T chk_map[CVY_MAX_HOSTS]; /* map of cur & rdy bins for all hosts */ /* used as a check for coverage */ MAP_T idle_map[CVY_MAX_HOSTS]; /* map of idle bins per host */ BOOLEAN initialized; /* TRUE => port group has been initialized (v2.06) */ BOOLEAN compatible; /* TRUE => detected that rule codes do not match */ BOOLEAN equal_bal; /* TRUE => all hosts balance evenly */ USHORT affinity; /* TRUE => client affinity for this port */ USHORT pad64; /* 64-bit -- ramkrish */ ULONG mode; /* processing mode */ ULONG prot; /* protocol */ ULONG tot_load; /* total load percentages for all hosts */ ULONG orig_load_amt; /* original load amt. for this host */ ULONG load_amt[CVY_MAX_HOSTS]; /* multi: load percentages per host single: host priorities (1..CVY_MAXHOSTS) equal: 100 dead: 0 */ MAP_T snd_bins; /* local bins to send when ready */ MAP_T rcv_bins; /* remote bins to receive when ready */ MAP_T rdy_bins; /* snd bins that are ready to send or have been sent but not acknowledged */ MAP_T idle_bins; /* bins with no connections active */ LONG tconn; /* total # active local connections (v2.06) */ LONG nconn[CVY_MAXBINS]; /* # active local connections per bin */ QUEUE connq; /* queue of active connections on all bins */ } BIN_STATE, * PBIN_STATE; //#pragma pack(4) /* ping message */ /* 64-bit -- ramkrish change pragma pack to 1 */ #pragma pack(1) typedef struct { USHORT host_id; /* my host id */ USHORT master_id; /* current master host id */ USHORT state; /* my host's state */ USHORT nrules; /* # active rules */ ULONG hcode; /* unique host code */ ULONG pkt_count; /* count of packets handled since cvg'd (1.32B) */ ULONG teaming; /* BDA teaming configuraiton information. */ ULONG reserved2; ULONG rcode[CVY_MAX_RULES]; /* rule code */ MAP_T cur_map[CVY_MAX_RULES]; /* my current load map for each port group */ MAP_T new_map[CVY_MAX_RULES]; /* my new load map for each port group */ /* if converging */ MAP_T idle_map[CVY_MAX_RULES]; /* map of idle bins for each port group */ MAP_T rdy_bins[CVY_MAX_RULES]; /* my rdy to send bins for each port group */ ULONG load_amt[CVY_MAX_RULES]; /* my load amount for each port group */ ULONG pg_rsvd1[CVY_MAX_RULES]; /* reserved */ } PING_MSG, * PPING_MSG; #pragma pack() /* unique connection entry */ /* 64-bit -- ramkrish structure is aligned for 64-bit */ typedef struct { LINK blink; /* link into bin queue and dirty queue */ LINK rlink; /* link into the recovery queue V2.1.5 */ ULONG code; /* type checking code (bbain 8/17/99) */ BOOLEAN alloc; /* TRUE => this entry was allocated (vs. in hash table) */ BOOLEAN dirty; /* TRUE => this entry is associated with an obsolete connection and will be cleaned up after a timeout period to allow TCP/IP to purge its state (v1.32B) */ UCHAR bin; /* entry's bin number */ BOOLEAN used; /* TRUE => used for tracking connection */ ULONG fin_count; /* ###### for keynote - ramkrish to keep track of the fins */ ULONG client_ipaddr, svr_ipaddr; USHORT svr_port, client_port; #if defined (NLB_SESSION_SUPPORT) USHORT protocol; /* The protocol type for this descriptor - we no long use descriptors only for TCP connections. */ #endif } CONN_ENTRY, * PCONN_ENTRY; /* connection descriptor */ /* 64-bit -- ramkrish */ typedef struct { LINK link; /* link into free queue or hash table queue */ ULONG code; /* type checking code (bbain 8/17/99) */ ULONG pad64; /* 64-bit -- ramkrish */ CONN_ENTRY entry; } CONN_DESCR, * PCONN_DESCR; /* load module's context */ /* 64-bit -- ramkrish */ typedef struct { ULONG ref_count; /* The reference count on this load module. */ ULONG my_host_id; /* local host id and priority MINUS one */ ULONG code; /* type checking code (bbain 8/17/99) */ /* 64-bit -- ramkrish */ PING_MSG send_msg; /* current message to send */ ULONG pad64_1; /* 64-bit */ #ifndef KERNEL_MODE /* 1.03: Removed kernel mode locking in this module */ SPINLOCK lock; /* lock for mutual exclusion */ #endif ULONG def_timeout, /* default timeout in msec. */ cur_timeout, /* current timeout in msec. (v1.32B) */ cln_timeout, /* cleanup timeout in msec. (v1.32B) */ cur_time; /* current time waiting for cleanup (v1.32B) */ ULONG host_map, /* map of currently active hosts */ ping_map, /* map of currently pinged hosts */ min_missed_pings, /* # missed pings to trigger host dead */ pkt_count; /* count of packets handled since cvg'd (1.32B) */ ULONG last_hmap; /* host map after last convergence (bbain RTM RC1 6/23/99) */ ULONG nmissed_pings[CVY_MAX_HOSTS]; /* missed ping count for each host */ BOOLEAN initialized; /* TRUE => this module has been initialized */ BOOLEAN active; /* TRUE => this module is active */ BOOLEAN consistent; /* TRUE => this host has seen consistent information from other hosts */ BOOLEAN bad_team_config; /* TRUE => inconsistent BDA teaming configuration detected. */ BOOLEAN dup_hosts; /* TRUE => duplicate host id's seen */ BOOLEAN dup_sspri; /* TRUE => duplicate single server priorities seen */ BOOLEAN bad_map; /* TRUE => bad new map detected */ BOOLEAN overlap_maps; /* TRUE => overlapping maps detected */ BOOLEAN err_rcving_bins; /* TRUE => error receiving bins detected */ BOOLEAN err_orphans; /* TRUE => orphan bins detected */ BOOLEAN bad_num_rules; /* TRUE => different number of rules seen */ BOOLEAN alloc_inhibited; /* TRUE => inhibited malloc of conn's. */ BOOLEAN alloc_failed; /* TRUE => malloc failed */ BOOLEAN bad_defrule; /* TRUE => invalid default rule detected */ BOOLEAN scale_client; /* TRUE => scale client requests; FALSE => hash all client requests to one server host */ BOOLEAN cln_waiting; /* TRUE => waiting for cleanup (v1.32B) */ BOOLEAN pad64_2; /* 64-bit -- ramkrish */ BOOLEAN dirty_bin[CVY_MAXBINS]; /* TRUE => bin has dirty connections (v1.32B) */ ULONG pad64_3; /* 64-bit -- ramkrish */ ULONG stable_map; /* map of stable hosts */ ULONG min_stable_ct; /* min needed # of timeouts with stable condition */ ULONG my_stable_ct; /* count of timeouts locally stable */ ULONG all_stable_ct; /* count of timeouts with all stable condition */ ULONG dscr_per_alloc; /* # conn. descriptors per allocation */ ULONG max_dscr_allocs; /* max # descriptor allocations */ ULONG nqalloc; /* # conn. descriptor allocations */ LONG nconn; /* # active conns across all port rules (v2.1) */ PCONN_DESCR qalloc_list[CVY_MAX_MAX_DSCR_ALLOCS]; /* list of descriptor free queue allocations (bbain 2/25/99) */ // LONG nconn; /* # active conns across all port rules (v2.1) */ // 64-bit -- ramkrish // PING_MSG send_msg; /* current message to send */ BIN_STATE pg_state[CVY_MAX_RULES]; /* bin state for all active rules */ CONN_ENTRY hashed_conn[CVY_MAX_CHASH]; /* hashed connection entries */ QUEUE connq[CVY_MAX_CHASH]; /* queues for overloaded hashed conn's. */ QUEUE conn_freeq; /* queue of free descriptors */ QUEUE conn_dirtyq; /* queue of dirty connection entries (v1.32B) */ CONN_DESCR conn_descr[CVY_INIT_QCONN]; /* initial set of free descriptors */ QUEUE conn_rcvryq; /* connection recover queue V2.1.5 */ PCVY_PARAMS params; /* pointer to the global parameters */ } LOAD_CTXT, * PLOAD_CTXT; /* FUNCTIONS */ /* Load Module Functions */ #if defined (NLB_SESSION_SUPPORT) #define CVY_CONN_MATCH(ep, sa, sp, ca, cp, prot) ((ep)->used && \ (ep)->client_ipaddr == (ca) && \ (ep)->client_port == ((USHORT)(cp)) && \ (ep)->svr_ipaddr == (sa) && \ (ep)->svr_port == ((USHORT)(sp)) && \ (ep)->protocol == ((USHORT)(prot))) #else #define CVY_CONN_MATCH(ep, sa, sp, ca, cp, prot) ((ep)->used && \ (ep)->client_ipaddr == (ca) && \ (ep)->client_port == ((USHORT)(cp)) && \ (ep)->svr_ipaddr == (sa) && \ (ep)->svr_port == ((USHORT)(sp))) #endif /* Determine if a connection entry matches supplied parameters */ #if defined (NLB_SESSION_SUPPORT) #define CVY_CONN_SET(ep, sa, sp, ca, cp, prot) { \ (ep)->svr_ipaddr = (sa); \ (ep)->svr_port = (USHORT)(sp); \ (ep)->client_ipaddr = (ca); \ (ep)->client_port = (USHORT)(cp); \ (ep)->protocol = (USHORT)(prot); \ (ep)->used = TRUE; \ } #else #define CVY_CONN_SET(ep, sa, sp, ca, cp, prot) { \ (ep)->svr_ipaddr = (sa); \ (ep)->svr_port = (USHORT)(sp); \ (ep)->client_ipaddr = (ca); \ (ep)->client_port = (USHORT)(cp); \ (ep)->used = TRUE; \ } #endif /* Sets up a connection entry for the supplied parameters */ #define CVY_CONN_IN_USE(ep) ((ep)->used) /* Checks if connection entry is in use */ #define CVY_CONN_CLEAR(ep) { (ep)->used = FALSE; } /* Clears a connection entry */ extern void Load_start( PLOAD_CTXT lp); /* Start load module function: Starts load module after previously initialized or stopped. */ extern void Load_stop( PLOAD_CTXT lp); /* Stop load module function: Stops load module after previously initialized or started. */ extern void Load_init( PLOAD_CTXT lp, PCVY_PARAMS params); /* Initialize load module function: Initializes the load module for the first time. */ extern void Load_cleanup( /* (bbain 2/25/99) */ PLOAD_CTXT lp); /* Cleanup load module function: Cleans up the load module by releasing dynamically allocated memory. */ extern void Load_msg_rcv( PLOAD_CTXT lp, PPING_MSG pmsg); /* ptr. to ping message */ /* Receive a ping message */ extern PPING_MSG Load_snd_msg_get( PLOAD_CTXT lp); /* Get local ping message to send returns PPING_MSG: */ extern BOOLEAN Load_timeout( PLOAD_CTXT lp, PULONG new_timeout, PBOOLEAN pconverging, /* ptr. to boolean with TRUE => cluster converging (v2.1) */ PULONG pnconn); /* ptr. to # active conns across all port rules (v2.1) */ /* Handle timeout returns BOOLEAN: TRUE => host is attached to the network FALSE => host lost network connection */ extern BOOLEAN Load_packet_check( PLOAD_CTXT lp, ULONG svr_ipaddr, ULONG svr_port, ULONG client_ipaddr, ULONG client_port, USHORT protocol, BOOLEAN limit_map_fn); /* Check whether to accept incoming TCP/UDP packet returns BOOLEAN: TRUE => accept packet and pass on to TCP/IP FALSE => filter packet */ extern BOOLEAN Load_conn_advise( PLOAD_CTXT lp, ULONG svr_ipaddr, ULONG svr_port, ULONG client_ipaddr, ULONG client_port, USHORT protocol, ULONG conn_status, BOOLEAN limit_map_fn); /* Advise load module on possible change in TCP connection status returns BOOLEAN: TRUE => accept packet and pass on to TCP/IP if an input packet FALSE => filter packet */ extern ULONG Load_port_change( PLOAD_CTXT lp, ULONG ipaddr, ULONG port, ULONG cmd, /* enable, disable, set value */ ULONG value); /* Enable or disable traffic handling for a rule containing specified port returns ULONG: IOCTL_CVY_OK => port handling changed IOCTL_CVY_NOT_FOUND => rule for this port was found IOCTL_CVY_ALREADY => port handling was previously completed */ extern ULONG Load_hosts_query( PLOAD_CTXT lp, BOOLEAN internal, PULONG host_map); /* Log and return current host map returns ULONG: */ /* * Function: * Description: * Parameters: * Returns: * Author: shouse, 3.29.01 * Notes: */ extern BOOLEAN Load_create_dscr(PLOAD_CTXT lp, ULONG svr_ipaddr, ULONG svr_port, ULONG client_ipaddr, ULONG client_port, USHORT protocol, BOOLEAN limit_map_fn); /* * Function: * Description: * Parameters: * Returns: * Author: shouse, 3.29.01 * Notes: */ extern ULONG Load_add_reference (IN PLOAD_CTXT pLoad); /* * Function: * Description: * Parameters: * Returns: * Author: shouse, 3.29.01 * Notes: */ extern ULONG Load_release_reference (IN PLOAD_CTXT pLoad); /* * Function: * Description: * Parameters: * Returns: * Author: shouse, 3.29.01 * Notes: */ extern ULONG Load_get_reference_count (IN PLOAD_CTXT pLoad); /* * Function: * Description: * Parameters: * Returns: * Author: shouse, 5.18.01 * Notes: */ extern VOID Load_query_packet_filter ( PIOCTL_QUERY_STATE_PACKET_FILTER pQuery, PLOAD_CTXT lp, ULONG svr_ipaddr, ULONG svr_port, ULONG client_ipaddr, ULONG client_port, USHORT protocol, BOOLEAN limit_map_fn); #if defined (NLB_SESSION_SUPPORT) #define NLB_IPSEC_SESSION_SUPPORT_ENABLED() 1 #define NLB_PPTP_SESSION_SUPPORT_ENABLED() 1 #else #define NLB_IPSEC_SESSION_SUPPORT_ENABLED() 0 #define NLB_PPTP_SESSION_SUPPORT_ENABLED() 0 #endif // NLB_SESSION_SUPPORT #define NLB_SESSION_SUPPORT_ENABLED() \ (NLB_PPTP_SESSION_SUPPORT_ENABLED() \ || NLB_IPSEC_SESSION_SUPPORT_ENABLED()) #endif /* _Load_h_ */