Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

592 lines
23 KiB

/*++
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_ */