summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-09-21 12:34:19 +0000
committerBeno�t Ganne <bganne@cisco.com>2021-09-29 14:27:48 +0000
commite11203e5b8fd61986573e0cba9e47cefcf50e60d (patch)
treeb5b34bf9742962290ebed720963b72ce5045c6da /test
parent979545e79579bdc6fe3cb2d3cfd0036c588acb32 (diff)
ipsec: Record the number of packets lost from an SA
Type: feature Gaps in the sequence numbers received on an SA indicate packets that were lost. Gaps are identified using the anti-replay window that records the sequences seen. Publish the number of lost packets in the stats segment at /net/ipsec/sa/lost Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: I8af1c09b7b25a705e18bf82e1623b3ce19e5a74d
Diffstat (limited to 'test')
-rw-r--r--test/template_ipsec.py87
-rw-r--r--test/test_ipsec_esp.py3
-rw-r--r--test/vpp_ipsec.py11
3 files changed, 101 insertions, 0 deletions
diff --git a/test/template_ipsec.py b/test/template_ipsec.py
index d5f13322a59..e4797353ecd 100644
--- a/test/template_ipsec.py
+++ b/test/template_ipsec.py
@@ -792,6 +792,87 @@ class IpsecTra4(object):
p.scapy_tra_sa.seq_num = 351
p.vpp_tra_sa.seq_num = 351
+ def verify_tra_lost(self):
+ p = self.params[socket.AF_INET]
+ esn_en = p.vpp_tra_sa.esn_en
+
+ #
+ # send packets with seq numbers 1->34
+ # this means the window size is still in Case B (see RFC4303
+ # Appendix A)
+ #
+ # for reasons i haven't investigated Scapy won't create a packet with
+ # seq_num=0
+ #
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(1, 3)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ self.assertEqual(p.tra_sa_out.get_lost(), 0)
+
+ # skip a sequence number
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(4, 6)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ self.assertEqual(p.tra_sa_out.get_lost(), 0)
+
+ # the lost packet are counted untill we get up past the first
+ # sizeof(replay_window) packets
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(6, 100)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ self.assertEqual(p.tra_sa_out.get_lost(), 1)
+
+ # lost of holes in the sequence
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(100, 200, 2)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if, n_rx=50)
+
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(200, 300)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ self.assertEqual(p.tra_sa_out.get_lost(), 51)
+
+ # a big hole in the seq number space
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(400, 500)]
+ self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ self.assertEqual(p.tra_sa_out.get_lost(), 151)
+
def verify_tra_basic4(self, count=1, payload_size=54):
""" ipsec v4 transport basic test """
self.vapi.cli("clear errors")
@@ -826,6 +907,8 @@ class IpsecTra4(object):
self.assertEqual(pkts, count,
"incorrect SA out counts: expected %d != %d" %
(count, pkts))
+ self.assertEqual(p.tra_sa_out.get_lost(), 0)
+ self.assertEqual(p.tra_sa_in.get_lost(), 0)
self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
self.assert_packet_counter_equal(self.tra4_decrypt_node_name[0], count)
@@ -837,6 +920,10 @@ class IpsecTra4Tests(IpsecTra4):
""" ipsec v4 transport anti-replay test """
self.verify_tra_anti_replay()
+ def test_tra_lost(self):
+ """ ipsec v4 transport lost packet test """
+ self.verify_tra_lost()
+
def test_tra_basic(self, count=1):
""" ipsec v4 transport basic test """
self.verify_tra_basic4(count=1)
diff --git a/test/test_ipsec_esp.py b/test/test_ipsec_esp.py
index 14112d6d71a..0e0aaee425c 100644
--- a/test/test_ipsec_esp.py
+++ b/test/test_ipsec_esp.py
@@ -974,6 +974,9 @@ class RunTestIpsecEspAll(ConfigIpsecESP,
self.unconfig_network()
self.config_network(self.params.values())
self.verify_hi_seq_num()
+ self.unconfig_network()
+ self.config_network(self.params.values())
+ self.verify_tra_lost()
#
# swap the handlers while SAs are up
diff --git a/test/vpp_ipsec.py b/test/vpp_ipsec.py
index f9b7bc43752..76080e05c3a 100644
--- a/test/vpp_ipsec.py
+++ b/test/vpp_ipsec.py
@@ -313,6 +313,17 @@ class VppIpsecSA(VppObject):
# +1 to skip main thread
return c[worker+1][self.stat_index]
+ def get_lost(self, worker=None):
+ c = self.test.statistics.get_counter("/net/ipsec/sa/lost")
+ if worker is None:
+ total = 0
+ for t in c:
+ total += t[self.stat_index]
+ return total
+ else:
+ # +1 to skip main thread
+ return c[worker+1][self.stat_index]
+
class VppIpsecTunProtect(VppObject):
"""