From da34f4add5f141d58670d81d53553986e9a472b4 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 14 Sep 2023 22:14:38 +0500 Subject: nat: add ipfix rate-limiter for nat44-ed, nat44-ei and nat64 This prevents ipfix flood with the repeating events and allows to enable nat64 max_session and max_bibs events. Also fix wrong endian for det44 and nat64 ipfix tests, now should be fine with extended tests enabled. Max session per user event @ nat44-ei requires more precise rate limiter per user address, probably with sparse vec, not handled. Type: improvement Signed-off-by: Vladislav Grishenko Change-Id: Ib20cc1ee3f81e7acc88a415fe83b4e2deae2a836 --- test/test_det44.py | 6 +++--- test/test_nat44_ei.py | 16 ++++++++++++---- test/test_nat64.py | 22 ++++++++++++++-------- 3 files changed, 29 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/test_det44.py b/test/test_det44.py index ecd57a65b05..ede80981349 100644 --- a/test/test_det44.py +++ b/test/test_det44.py @@ -98,9 +98,9 @@ class TestDET44(VppTestCase): # natEvent self.assertEqual(scapy.compat.orb(record[230]), 13) # natQuotaExceededEvent - self.assertEqual(struct.pack("I", 3), record[466]) + self.assertEqual(struct.pack("!I", 3), record[466]) # maxEntriesPerUser - self.assertEqual(struct.pack("I", limit), record[473]) + self.assertEqual(struct.pack("!I", limit), record[473]) # sourceIPv4Address self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8]) @@ -724,7 +724,7 @@ class TestDET44(VppTestCase): # verify IPFIX logging self.vapi.ipfix_flush() - capture = self.pg2.get_capture(2) + capture = self.pg2.get_capture(7) ipfix = IPFIXDecoder() # first load template for p in capture: diff --git a/test/test_nat44_ei.py b/test/test_nat44_ei.py index 15eb70a6664..dc74d03771b 100644 --- a/test/test_nat44_ei.py +++ b/test/test_nat44_ei.py @@ -663,6 +663,7 @@ class MethodHolder(VppTestCase): self.assertEqual(scapy.compat.orb(record[230]), 3) # natPoolID self.assertEqual(struct.pack("!I", 0), record[283]) + return len(data) def verify_ipfix_max_sessions(self, data, limit): self.assertEqual(1, len(data)) @@ -673,6 +674,7 @@ class MethodHolder(VppTestCase): self.assertEqual(struct.pack("!I", 1), record[466]) # maxSessionEntries self.assertEqual(struct.pack("!I", limit), record[471]) + return len(data) def verify_no_nat44_user(self): """Verify that there is no NAT44EI user""" @@ -2463,7 +2465,7 @@ class TestNAT44EI(MethodHolder): Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / TCP(sport=3025) - ) + ) * 3 self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -2482,10 +2484,12 @@ class TestNAT44EI(MethodHolder): if p.haslayer(Template): ipfix.add_template(p.getlayer(Template)) # verify events in data set + event_count = 0 for p in capture: if p.haslayer(Data): data = ipfix.decode_data_set(p.getlayer(Set)) - self.verify_ipfix_addr_exhausted(data) + event_count += self.verify_ipfix_addr_exhausted(data) + self.assertEqual(event_count, 1) def test_ipfix_max_sessions(self): """NAT44EI IPFIX logging maximum session entries exceeded""" @@ -2529,7 +2533,7 @@ class TestNAT44EI(MethodHolder): Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / TCP(sport=1025) - ) + ) * 3 self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -2548,10 +2552,14 @@ class TestNAT44EI(MethodHolder): if p.haslayer(Template): ipfix.add_template(p.getlayer(Template)) # verify events in data set + event_count = 0 for p in capture: if p.haslayer(Data): data = ipfix.decode_data_set(p.getlayer(Set)) - self.verify_ipfix_max_sessions(data, max_sessions_per_thread) + event_count += self.verify_ipfix_max_sessions( + data, max_sessions_per_thread + ) + self.assertEqual(event_count, 1) def test_syslog_apmap(self): """NAT44EI syslog address and port mapping creation and deletion""" diff --git a/test/test_nat64.py b/test/test_nat64.py index 05a2031f921..4ae9f6614dd 100644 --- a/test/test_nat64.py +++ b/test/test_nat64.py @@ -462,9 +462,10 @@ class TestNAT64(VppTestCase): # natEvent self.assertEqual(scapy.compat.orb(record[230]), 13) # natQuotaExceededEvent - self.assertEqual(struct.pack("I", 2), record[466]) + self.assertEqual(struct.pack("!I", 2), record[466]) # maxBIBEntries - self.assertEqual(struct.pack("I", limit), record[472]) + self.assertEqual(struct.pack("!I", limit), record[472]) + return len(data) def verify_ipfix_bib(self, data, is_create, src_addr): """ @@ -622,9 +623,10 @@ class TestNAT64(VppTestCase): # natEvent self.assertEqual(scapy.compat.orb(record[230]), 13) # natQuotaExceededEvent - self.assertEqual(struct.pack("I", 1), record[466]) + self.assertEqual(struct.pack("!I", 1), record[466]) # maxSessionEntries - self.assertEqual(struct.pack("I", limit), record[471]) + self.assertEqual(struct.pack("!I", limit), record[471]) + return len(data) def test_nat64_inside_interface_handles_neighbor_advertisement(self): """NAT64 inside interface handles Neighbor Advertisement""" @@ -1859,7 +1861,7 @@ class TestNAT64(VppTestCase): Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IPv6(src=src, dst=remote_host_ip6) / TCP(sport=12345, dport=25) - ) + ) * 3 self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -1878,16 +1880,18 @@ class TestNAT64(VppTestCase): if p.haslayer(Template): ipfix.add_template(p.getlayer(Template)) # verify events in data set + event_count = 0 for p in capture: if p.haslayer(Data): data = ipfix.decode_data_set(p.getlayer(Set)) - self.verify_ipfix_max_sessions(data, max_sessions) + event_count += self.verify_ipfix_max_sessions(data, max_sessions) + self.assertEqual(event_count, 1) p = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) / TCP(sport=12345, dport=80) - ) + ) * 3 self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -1895,6 +1899,7 @@ class TestNAT64(VppTestCase): self.vapi.ipfix_flush() capture = self.pg3.get_capture(1) # verify events in data set + event_count = 0 for p in capture: self.assertTrue(p.haslayer(IPFIX)) self.assertEqual(p[IP].src, self.pg3.local_ip4) @@ -1904,7 +1909,8 @@ class TestNAT64(VppTestCase): self.assertEqual(p[IPFIX].observationDomainID, self.ipfix_domain_id) if p.haslayer(Data): data = ipfix.decode_data_set(p.getlayer(Set)) - self.verify_ipfix_max_bibs(data, max_bibs) + event_count += self.verify_ipfix_max_bibs(data, max_bibs) + self.assertEqual(event_count, 1) def test_ipfix_bib_ses(self): """IPFIX logging NAT64 BIB/session create and delete events""" -- cgit 1.2.3-korg