aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2018-09-03 05:02:23 -0700
committerDamjan Marion <dmarion@me.com>2018-09-03 14:48:54 +0000
commitea5b5be4eeb0f4cd80cb466bd6e31cad33c57960 (patch)
treeb40903f9c38e53e34fd0cd86613046838aca9505 /test
parent7ff0a265a8b5692268c0f44385712c7be8e32775 (diff)
NAT44: client-IP based session affinity for load-balancing (VPP-1297)
Enable client-IP based session affinity per LB NAT rule with specific timeout. Change-Id: I9aade152e330218d21dfda99cc5e984d769ab806 Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'test')
-rw-r--r--test/test_nat.py61
-rw-r--r--test/vpp_papi_provider.py3
2 files changed, 64 insertions, 0 deletions
diff --git a/test/test_nat.py b/test/test_nat.py
index 79d26224ad0..73e414ad1ae 100644
--- a/test/test_nat.py
+++ b/test/test_nat.py
@@ -3741,6 +3741,67 @@ class TestNAT44EndpointDependent(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
+ def test_lb_affinity(self):
+ """ NAT44 local service load balancing affinity """
+ external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
+ external_port = 80
+ local_port = 8080
+ server1 = self.pg0.remote_hosts[0]
+ server2 = self.pg0.remote_hosts[1]
+
+ locals = [{'addr': server1.ip4n,
+ 'port': local_port,
+ 'probability': 50,
+ 'vrf_id': 0},
+ {'addr': server2.ip4n,
+ 'port': local_port,
+ 'probability': 50,
+ 'vrf_id': 0}]
+
+ self.nat44_add_address(self.nat_addr)
+ self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
+ external_port,
+ IP_PROTOS.tcp,
+ affinity=10800,
+ local_num=len(locals),
+ locals=locals)
+ self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
+ self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
+ is_inside=0)
+
+ p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
+ IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
+ TCP(sport=1025, dport=external_port))
+ self.pg1.add_stream(p)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(1)
+ backend = capture[0][IP].dst
+
+ sessions = self.vapi.nat44_user_session_dump(
+ socket.inet_pton(socket.AF_INET, backend), 0)
+ self.assertEqual(len(sessions), 1)
+ self.assertTrue(sessions[0].ext_host_valid)
+ self.vapi.nat44_del_session(
+ sessions[0].inside_ip_address,
+ sessions[0].inside_port,
+ sessions[0].protocol,
+ ext_host_address=sessions[0].ext_host_address,
+ ext_host_port=sessions[0].ext_host_port)
+
+ pkts = []
+ for port in range(1030, 1100):
+ p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
+ IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
+ TCP(sport=port, dport=external_port))
+ pkts.append(p)
+ self.pg1.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ for p in capture:
+ self.assertEqual(p[IP].dst, backend)
+
def test_unknown_proto(self):
""" NAT44 translate packet with unknown protocol """
self.nat44_add_address(self.nat_addr)
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index e3d8459b0b1..e0d55c16cee 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -1594,6 +1594,7 @@ class VppPapiProvider(object):
self_twice_nat=0,
out2in_only=0,
tag='',
+ affinity=0,
local_num=0,
locals=[],
is_add=1):
@@ -1601,6 +1602,7 @@ class VppPapiProvider(object):
:param twice_nat: 1 if translate external host address and port
:param tag: Opaque string tag
+ :param affinity: if 0 disabled, otherwise client IP affinity timeout
:param is_add - 1 if add, 0 if delete
"""
return self.api(
@@ -1613,6 +1615,7 @@ class VppPapiProvider(object):
'self_twice_nat': self_twice_nat,
'out2in_only': out2in_only,
'tag': tag,
+ 'affinity': affinity,
'local_num': local_num,
'locals': locals})