summaryrefslogtreecommitdiffstats
path: root/src/plugins/lb/lb.h
diff options
context:
space:
mode:
authorNobuhiro MIKI <nmiki@yahoo-corp.jp>2022-09-28 15:53:17 +0900
committerBeno�t Ganne <bganne@cisco.com>2023-01-18 10:53:23 +0000
commit613e6dc0bf928def5d337312d522e1a15df87b00 (patch)
tree04e592643029774fadcbfc8f8e82df778b867df9 /src/plugins/lb/lb.h
parent893a0c3130e1d868c939db6dcde258da1277cf41 (diff)
lb: add source ip based sticky load balancing
This patch adds source ip based sticky session, which is already implemented in many hardware LBs and software LBs. Note that sticky sessions may be reset if the hash is recalculated as ASs are added or deleted. Since this feature is unrelated to the other existing options, the lb_add_del_vip API version has been upgraded to v2 and a new option "src_ip_sticky" has been added. Type: feature Signed-off-by: Nobuhiro MIKI <nmiki@yahoo-corp.jp> Change-Id: I3eb3680a28defbc701f28c873933ec2fb54544ab
Diffstat (limited to 'src/plugins/lb/lb.h')
-rw-r--r--src/plugins/lb/lb.h85
1 files changed, 76 insertions, 9 deletions
diff --git a/src/plugins/lb/lb.h b/src/plugins/lb/lb.h
index 4618015071e..fa1cfaadc25 100644
--- a/src/plugins/lb/lb.h
+++ b/src/plugins/lb/lb.h
@@ -324,6 +324,7 @@ typedef struct {
*/
u8 flags;
#define LB_VIP_FLAGS_USED 0x1
+#define LB_VIP_FLAGS_SRC_IP_STICKY 0x2
/**
* Pool of AS indexes used for this VIP.
@@ -346,43 +347,100 @@ typedef struct {
|| (vip)->type == LB_VIP_TYPE_IP4_L3DSR \
|| (vip)->type == LB_VIP_TYPE_IP4_NAT4 )
+#define lb_vip_is_src_ip_sticky(vip) \
+ (((vip)->flags & LB_VIP_FLAGS_SRC_IP_STICKY) != 0)
+
+/* clang-format off */
#define lb_vip_is_gre4(vip) (((vip)->type == LB_VIP_TYPE_IP6_GRE4 \
|| (vip)->type == LB_VIP_TYPE_IP4_GRE4) \
- && ((vip)->port == 0))
-
+ && ((vip)->port == 0) \
+ && !lb_vip_is_src_ip_sticky (vip))
#define lb_vip_is_gre6(vip) (((vip)->type == LB_VIP_TYPE_IP6_GRE6 \
|| (vip)->type == LB_VIP_TYPE_IP4_GRE6) \
- && ((vip)->port == 0))
+ && ((vip)->port == 0) \
+ && !lb_vip_is_src_ip_sticky (vip))
#define lb_vip_is_gre4_port(vip) (((vip)->type == LB_VIP_TYPE_IP6_GRE4 \
|| (vip)->type == LB_VIP_TYPE_IP4_GRE4) \
- && ((vip)->port != 0))
+ && ((vip)->port != 0) \
+ && !lb_vip_is_src_ip_sticky (vip))
#define lb_vip_is_gre6_port(vip) (((vip)->type == LB_VIP_TYPE_IP6_GRE6 \
|| (vip)->type == LB_VIP_TYPE_IP4_GRE6) \
- && ((vip)->port != 0))
+ && ((vip)->port != 0) \
+ && !lb_vip_is_src_ip_sticky (vip))
+/* clang-format on */
+
+#define lb_vip_is_gre4_sticky(vip) \
+ (((vip)->type == LB_VIP_TYPE_IP6_GRE4 || \
+ (vip)->type == LB_VIP_TYPE_IP4_GRE4) && \
+ ((vip)->port == 0) && lb_vip_is_src_ip_sticky (vip))
+
+#define lb_vip_is_gre6_sticky(vip) \
+ (((vip)->type == LB_VIP_TYPE_IP6_GRE6 || \
+ (vip)->type == LB_VIP_TYPE_IP4_GRE6) && \
+ ((vip)->port == 0) && lb_vip_is_src_ip_sticky (vip))
+
+#define lb_vip_is_gre4_port_sticky(vip) \
+ (((vip)->type == LB_VIP_TYPE_IP6_GRE4 || \
+ (vip)->type == LB_VIP_TYPE_IP4_GRE4) && \
+ ((vip)->port != 0) && lb_vip_is_src_ip_sticky (vip))
+
+#define lb_vip_is_gre6_port_sticky(vip) \
+ (((vip)->type == LB_VIP_TYPE_IP6_GRE6 || \
+ (vip)->type == LB_VIP_TYPE_IP4_GRE6) && \
+ ((vip)->port != 0) && lb_vip_is_src_ip_sticky (vip))
always_inline bool
lb_vip_is_l3dsr(const lb_vip_t *vip)
{
- return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port ==0);
+ return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port == 0 &&
+ !lb_vip_is_src_ip_sticky (vip));
}
always_inline bool
lb_vip_is_l3dsr_port(const lb_vip_t *vip)
{
- return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port !=0);
+ return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port != 0 &&
+ !lb_vip_is_src_ip_sticky (vip));
}
always_inline bool
lb_vip_is_nat4_port(const lb_vip_t *vip)
{
- return (vip->type == LB_VIP_TYPE_IP4_NAT4 && vip->port !=0);
+ return (vip->type == LB_VIP_TYPE_IP4_NAT4 && vip->port != 0 &&
+ !lb_vip_is_src_ip_sticky (vip));
}
always_inline bool
lb_vip_is_nat6_port(const lb_vip_t *vip)
{
- return (vip->type == LB_VIP_TYPE_IP6_NAT6 && vip->port !=0);
+ return (vip->type == LB_VIP_TYPE_IP6_NAT6 && vip->port != 0 &&
+ !lb_vip_is_src_ip_sticky (vip));
+}
+
+always_inline bool
+lb_vip_is_l3dsr_sticky (const lb_vip_t *vip)
+{
+ return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port == 0 &&
+ lb_vip_is_src_ip_sticky (vip));
+}
+always_inline bool
+lb_vip_is_l3dsr_port_sticky (const lb_vip_t *vip)
+{
+ return (vip->type == LB_VIP_TYPE_IP4_L3DSR && vip->port != 0 &&
+ lb_vip_is_src_ip_sticky (vip));
+}
+always_inline bool
+lb_vip_is_nat4_port_sticky (const lb_vip_t *vip)
+{
+ return (vip->type == LB_VIP_TYPE_IP4_NAT4 && vip->port != 0 &&
+ lb_vip_is_src_ip_sticky (vip));
+}
+always_inline bool
+lb_vip_is_nat6_port_sticky (const lb_vip_t *vip)
+{
+ return (vip->type == LB_VIP_TYPE_IP6_NAT6 && vip->port != 0 &&
+ lb_vip_is_src_ip_sticky (vip));
}
format_function_t format_lb_vip;
@@ -542,6 +600,14 @@ typedef struct {
dpo_type_t dpo_l3dsr_port_type;
dpo_type_t dpo_nat4_port_type;
dpo_type_t dpo_nat6_port_type;
+ dpo_type_t dpo_gre4_sticky_type;
+ dpo_type_t dpo_gre6_sticky_type;
+ dpo_type_t dpo_gre4_port_sticky_type;
+ dpo_type_t dpo_gre6_port_sticky_type;
+ dpo_type_t dpo_l3dsr_sticky_type;
+ dpo_type_t dpo_l3dsr_port_sticky_type;
+ dpo_type_t dpo_nat4_port_sticky_type;
+ dpo_type_t dpo_nat6_port_sticky_type;
/**
* Node type for registering to fib changes.
*/
@@ -575,6 +641,7 @@ typedef struct {
u8 plen;
u8 protocol;
u16 port;
+ u8 src_ip_sticky;
lb_vip_type_t type;
u32 new_length;
lb_vip_encap_args_t encap_args;