|
|
/*++
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 <ntddk.h>
#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: <ptr. to ping message to send> */
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: <one of IOCTL_CVY_...state defined in params.h> */
/*
* 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_ */
|