diff --git a/include/types/backend.h b/include/types/backend.h index 7e5b3420d..a73a36a96 100644 --- a/include/types/backend.h +++ b/include/types/backend.h @@ -28,27 +28,64 @@ #include #include -/* Parameters for lbprm.algo. - * The low part of the value is unique for each algo so that applying the mask - * BE_LB_ALGO returns a unique algorithm. - * The high part indicates specific properties. +/* Parameters for lbprm.algo */ + +/* Lower bits define the kind of load balancing method, which means the type of + * algorithm, and which criterion it is based on. For this reason, those bits + * also include information about dependencies, so that the config parser can + * detect incompatibilities. */ -/* Masks to extract algorithm properties */ -#define BE_LB_ALGO 0x000007FF /* mask to extract all algorithm flags */ -#define BE_LB_PROP_DYN 0x00000100 /* mask to match dynamic algorithms */ -#define BE_LB_PROP_L4 0x00000200 /* mask to match layer4-based algorithms */ -#define BE_LB_PROP_L7 0x00000400 /* mask to match layer7-based algorithms */ +/* LB parameters. Depends on the LB kind. Right now, only hashing uses this. */ +#define BE_LB_HASH_SRC 0x00000 /* hash source IP */ +#define BE_LB_HASH_URI 0x00001 /* hash HTTP URI */ +#define BE_LB_HASH_PRM 0x00002 /* hash HTTP URL parameter */ +#define BE_LB_HASH_HDR 0x00003 /* hash HTTP header value */ +#define BE_LB_HASH_RDP 0x00004 /* hash RDP cookie value */ +#define BE_LB_PARM 0x000FF /* mask to get/clear the LB param */ + +/* Required input(s) */ +#define BE_LB_NEED_NONE 0x00000 /* no input needed */ +#define BE_LB_NEED_ADDR 0x00100 /* only source address needed */ +#define BE_LB_NEED_DATA 0x00200 /* some payload is needed */ +#define BE_LB_NEED_HTTP 0x00400 /* an HTTP request is needed */ +/* not used: 0x0800 */ +#define BE_LB_NEED 0x00F00 /* mask to get/clear dependencies */ + +/* Algorithm */ +#define BE_LB_KIND_NONE 0x00000 /* algorithm not set */ +#define BE_LB_KIND_RR 0x01000 /* round-robin */ +#define BE_LB_KIND_LC 0x02000 /* least connections */ +#define BE_LB_KIND_HI 0x03000 /* hash of input (see hash inputs below) */ +#define BE_LB_KIND 0x07000 /* mask to get/clear LB algorithm */ + +/* All known variants of load balancing algorithms. These can be cleared using + * the BE_LB_ALGO mask. For a check, using BE_LB_KIND is preferred. + */ +#define BE_LB_ALGO_NONE (BE_LB_KIND_NONE | BE_LB_NEED_NONE) /* not defined */ +#define BE_LB_ALGO_RR (BE_LB_KIND_RR | BE_LB_NEED_NONE) /* round robin */ +#define BE_LB_ALGO_LC (BE_LB_KIND_LC | BE_LB_NEED_NONE) /* least connections */ +#define BE_LB_ALGO_SH (BE_LB_KIND_HI | BE_LB_NEED_ADDR | BE_LB_HASH_SRC) /* hash: source IP */ +#define BE_LB_ALGO_UH (BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_URI) /* hash: HTTP URI */ +#define BE_LB_ALGO_PH (BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_PRM) /* hash: HTTP URL parameter */ +#define BE_LB_ALGO_HH (BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_HDR) /* hash: HTTP header value */ +#define BE_LB_ALGO_RCH (BE_LB_KIND_HI | BE_LB_NEED_DATA | BE_LB_HASH_RDP) /* hash: RDP cookie value */ +#define BE_LB_ALGO (BE_LB_KIND | BE_LB_NEED | BE_LB_PARM ) /* mask to clear algo */ + +/* Higher bits define how a given criterion is mapped to a server. In fact it + * designates the LB function by itself. The dynamic algorithms will also have + * the DYN bit set. These flags are automatically set at the end of the parsing. + */ +#define BE_LB_LKUP_NONE 0x00000 /* not defined */ +#define BE_LB_LKUP_MAP 0x10000 /* static map based lookup */ +#define BE_LB_LKUP_RRTREE 0x20000 /* FWRR tree lookup */ +#define BE_LB_LKUP_LCTREE 0x30000 /* FWLC tree lookup */ +#define BE_LB_LKUP 0x70000 /* mask to get just the LKUP value */ + +/* additional properties */ +#define BE_LB_PROP_DYN 0x80000 /* bit to indicate a dynamic algorithm */ + -/* the algorithms themselves */ -#define BE_LB_ALGO_NONE 0x00000000 /* dispatch or transparent mode */ -#define BE_LB_ALGO_RR (BE_LB_PROP_DYN | 0x01) /* fast weighted round-robin mode (dynamic) */ -#define BE_LB_ALGO_SH (BE_LB_PROP_L4 | 0x02) /* balance on source IP hash */ -#define BE_LB_ALGO_UH (BE_LB_PROP_L7 | 0x03) /* balance on URI hash */ -#define BE_LB_ALGO_PH (BE_LB_PROP_L7 | 0x04) /* balance on URL parameter hash */ -#define BE_LB_ALGO_LC (BE_LB_PROP_DYN | 0x05) /* fast weighted leastconn mode (dynamic) */ -#define BE_LB_ALGO_HH (BE_LB_PROP_L7 | 0x06) /* balance on Http Header value */ -#define BE_LB_ALGO_RCH (BE_LB_PROP_L4 | 0x07) /* balance on RDP Cookie value */ /* various constants */ @@ -64,7 +101,7 @@ /* LB parameters for all algorithms */ struct lbprm { - int algo; /* load balancing algorithm and variants: BE_LB_ALGO_* */ + int algo; /* load balancing algorithm and variants: BE_LB_* */ int tot_wact, tot_wbck; /* total effective weights of active and backup servers */ int tot_weight; /* total effective weight of servers participating to LB */ int tot_used; /* total number of servers used for LB */ diff --git a/src/backend.c b/src/backend.c index 444daff7a..3e0bc8ee0 100644 --- a/src/backend.c +++ b/src/backend.c @@ -494,7 +494,7 @@ int assign_server(struct session *s) */ s->srv = NULL; - if (s->be->lbprm.algo & BE_LB_ALGO) { + if (s->be->lbprm.algo & BE_LB_KIND) { int len; /* we must check if we have at least one server available */ if (!s->be->lbprm.tot_weight) { @@ -646,7 +646,7 @@ int assign_server_address(struct session *s) fprintf(stderr,"assign_server_address : s=%p\n",s); #endif - if ((s->flags & SN_DIRECT) || (s->be->lbprm.algo & BE_LB_ALGO)) { + if ((s->flags & SN_DIRECT) || (s->be->lbprm.algo & BE_LB_KIND)) { /* A server is necessarily known for this session */ if (!(s->flags & SN_ASSIGNED)) return SRV_STATUS_INTERNAL; diff --git a/src/cfgparse.c b/src/cfgparse.c index 70662b9f6..de84f376c 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3985,7 +3985,7 @@ int check_config_validity() } if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) { - if (curproxy->lbprm.algo & BE_LB_ALGO) { + if (curproxy->lbprm.algo & BE_LB_KIND) { if (curproxy->options & PR_O_TRANSP) { Alert("config : %s '%s' cannot use both transparent and balance mode.\n", proxy_type_str(curproxy), curproxy->id); @@ -4189,13 +4189,25 @@ int check_config_validity() curproxy->lbprm.wmult = 1; /* default weight multiplier */ curproxy->lbprm.wdiv = 1; /* default weight divider */ - /* round robin relies on a weight tree */ - if ((curproxy->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_RR) + /* We have to initialize the server lookup mechanism depending + * on what LB algorithm was choosen. + */ + + curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN); + switch (curproxy->lbprm.algo & BE_LB_KIND) { + case BE_LB_KIND_RR: + curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN; fwrr_init_server_groups(curproxy); - else if ((curproxy->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_LC) + break; + case BE_LB_KIND_LC: + curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN; fwlc_init_server_tree(curproxy); - else + break; + case BE_LB_KIND_HI: + curproxy->lbprm.algo |= BE_LB_LKUP_MAP; init_server_map(curproxy); + break; + } if (curproxy->options & PR_O_LOGASAP) curproxy->to_log &= ~LW_BYTES; diff --git a/src/proxy.c b/src/proxy.c index 7dce8c835..05ed05acc 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -323,7 +323,7 @@ int proxy_cfg_ensure_no_http(struct proxy *curproxy) Warning("config : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n", proxy_type_str(curproxy), curproxy->id); } - if (curproxy->lbprm.algo & BE_LB_PROP_L7) { + if (curproxy->lbprm.algo & BE_LB_NEED_HTTP) { curproxy->lbprm.algo &= ~BE_LB_ALGO; curproxy->lbprm.algo |= BE_LB_ALGO_RR; Warning("config : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",