summaryrefslogtreecommitdiffstats
path: root/test/test_lb.py
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 /test/test_lb.py
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 'test/test_lb.py')
-rw-r--r--test/test_lb.py44
1 files changed, 42 insertions, 2 deletions
diff --git a/test/test_lb.py b/test/test_lb.py
index dca9ea3f7ef..6e8d82dfe40 100644
--- a/test/test_lb.py
+++ b/test/test_lb.py
@@ -21,6 +21,7 @@ from vpp_ip import INVALID_INDEX
- IP6 to GRE6 encap on per-port vip case
- IP4 to L3DSR encap on vip case
- IP4 to L3DSR encap on per-port vip case
+ - IP4 to L3DSR encap on per-port vip with src_ip_sticky case
- IP4 to NAT4 encap on per-port vip case
- IP6 to NAT6 encap on per-port vip case
@@ -39,7 +40,7 @@ class TestLB(VppTestCase):
super(TestLB, cls).setUpClass()
cls.ass = range(5)
- cls.packets = range(1)
+ cls.packets = range(100)
try:
cls.create_pg_interfaces(range(2))
@@ -123,11 +124,12 @@ class TestLB(VppTestCase):
scapy.compat.raw(inner), scapy.compat.raw(self.info.data[IPver])
)
- def checkCapture(self, encap, isv4):
+ def checkCapture(self, encap, isv4, src_ip_sticky=False):
self.pg0.assert_nothing_captured()
out = self.pg1.get_capture(len(self.packets))
load = [0] * len(self.ass)
+ sticky_as = {}
self.info = None
for p in out:
try:
@@ -201,6 +203,13 @@ class TestLB(VppTestCase):
udp = UDP(scapy.compat.raw(p[IPv6].payload))
self.assertEqual(udp.dport, 3307)
load[asid] += 1
+
+ # In case of source ip sticky, check that packets with same
+ # src_ip are routed to same as.
+ if src_ip_sticky and sticky_as.get(ip.src, asid) != asid:
+ raise Exception("Packets with same src_ip are routed to another as")
+ sticky_as[ip.src] = asid
+
except:
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
@@ -420,6 +429,37 @@ class TestLB(VppTestCase):
)
self.vapi.cli("test lb flowtable flush")
+ def test_lb_ip4_l3dsr_port_src_ip_sticky(self):
+ """Load Balancer IP4 L3DSR on per-port-vip with src_ip_sticky case"""
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap l3dsr dscp 7 src_ip_sticky"
+ )
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u" % (asid)
+ )
+
+ # Generate duplicated packets
+ pkts = self.generatePackets(self.pg0, isv4=True)
+ pkts = pkts[: len(pkts) // 2]
+ pkts = pkts + pkts
+
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap="l3dsr", isv4=True, src_ip_sticky=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u del" % (asid)
+ )
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap l3dsr dscp 7 src_ip_sticky del"
+ )
+ self.vapi.cli("test lb flowtable flush")
+
def test_lb_ip4_nat4_port(self):
"""Load Balancer IP4 NAT4 on per-port-vip case"""
try: