summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorArthur de Kerhor <arthurdekerhor@gmail.com>2022-11-16 19:12:05 +0100
committerBeno�t Ganne <bganne@cisco.com>2023-03-23 08:58:55 +0000
commitad95b06181c354291f4433c5e550cb89c5122252 (patch)
treef40bc5447c51cbe5f4f5fc5ca5a8e54f72297268 /test
parentf6ba56296c4034d299784b828a8ac1661adc74da (diff)
ipsec: add per-SA error counters
Error counters are added on a per-node basis. In Ipsec, it is useful to also track the errors that occured per SA. Type: feature Change-Id: Iabcdcb439f67ad3c6c202b36ffc44ab39abac1bc Signed-off-by: Arthur de Kerhor <arthurdekerhor@gmail.com>
Diffstat (limited to 'test')
-rw-r--r--test/template_ipsec.py42
-rw-r--r--test/test_ipsec_spd_fp_input.py8
-rw-r--r--test/test_ipsec_tun_if_esp.py2
-rw-r--r--test/vpp_ipsec.py4
4 files changed, 43 insertions, 13 deletions
diff --git a/test/template_ipsec.py b/test/template_ipsec.py
index 72784dd4ea7..ba1c2465f12 100644
--- a/test/template_ipsec.py
+++ b/test/template_ipsec.py
@@ -632,10 +632,17 @@ class IpsecTra4(object):
replay_count = self.get_replay_counts(p)
hash_failed_count = self.get_hash_failed_counts(p)
seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)
+ hash_err = "integ_error"
if ESP == self.encryption_type:
undersize_node_name = "/err/%s/runt" % self.tra4_decrypt_node_name[0]
undersize_count = self.statistics.get_err_counter(undersize_node_name)
+ # For AES-GCM an error in the hash is reported as a decryption failure
+ if p.crypt_algo == "AES-GCM":
+ hash_err = "decryption_failed"
+ # In async mode, we don't report errors in the hash.
+ if p.async_mode:
+ hash_err = ""
#
# send packets with seq numbers 1->34
@@ -661,6 +668,8 @@ class IpsecTra4(object):
self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
replay_count += len(pkts)
self.assertEqual(self.get_replay_counts(p), replay_count)
+ err = p.tra_sa_in.get_err("replay")
+ self.assertEqual(err, replay_count)
#
# now send a batch of packets all with the same sequence number
@@ -677,6 +686,8 @@ class IpsecTra4(object):
recv_pkts = self.send_and_expect(self.tra_if, pkts * 8, self.tra_if, n_rx=1)
replay_count += 7
self.assertEqual(self.get_replay_counts(p), replay_count)
+ err = p.tra_sa_in.get_err("replay")
+ self.assertEqual(err, replay_count)
#
# now move the window over to 257 (more than one byte) and into Case A
@@ -694,6 +705,8 @@ class IpsecTra4(object):
self.send_and_assert_no_replies(self.tra_if, pkt * 3, timeout=0.2)
replay_count += 3
self.assertEqual(self.get_replay_counts(p), replay_count)
+ err = p.tra_sa_in.get_err("replay")
+ self.assertEqual(err, replay_count)
# the window size is 64 packets
# in window are still accepted
@@ -724,6 +737,9 @@ class IpsecTra4(object):
hash_failed_count += 17
self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
+ if hash_err != "":
+ err = p.tra_sa_in.get_err(hash_err)
+ self.assertEqual(err, hash_failed_count)
# a malformed 'runt' packet
# created by a mis-constructed SA
@@ -739,6 +755,8 @@ class IpsecTra4(object):
undersize_count += 17
self.assert_error_counter_equal(undersize_node_name, undersize_count)
+ err = p.tra_sa_in.get_err("runt")
+ self.assertEqual(err, undersize_count)
# which we can determine since this packet is still in the window
pkt = Ether(
@@ -767,10 +785,15 @@ class IpsecTra4(object):
# wrap. but since it isn't then the verify will fail.
hash_failed_count += 17
self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
+ if hash_err != "":
+ err = p.tra_sa_in.get_err(hash_err)
+ self.assertEqual(err, hash_failed_count)
else:
replay_count += 17
self.assertEqual(self.get_replay_counts(p), replay_count)
+ err = p.tra_sa_in.get_err("replay")
+ self.assertEqual(err, replay_count)
# valid packet moves the window over to 258
pkt = Ether(
@@ -861,6 +884,9 @@ class IpsecTra4(object):
hash_failed_count += 1
self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
+ if hash_err != "":
+ err = p.tra_sa_in.get_err(hash_err)
+ self.assertEqual(err, hash_failed_count)
#
# but if we move the window forward to case B, then we can wrap
@@ -894,6 +920,8 @@ class IpsecTra4(object):
self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
seq_cycle_count += len(pkts)
self.assert_error_counter_equal(seq_cycle_node_name, seq_cycle_count)
+ err = p.tra_sa_out.get_err("seq_cycled")
+ self.assertEqual(err, seq_cycle_count)
# move the security-associations seq number on to the last we used
self.vapi.cli("test ipsec sa %d seq 0x15f" % p.scapy_tra_sa_id)
@@ -924,7 +952,7 @@ class IpsecTra4(object):
]
self.send_and_expect(self.tra_if, pkts, self.tra_if)
- self.assertEqual(p.tra_sa_in.get_lost(), 0)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 0)
# skip a sequence number
pkts = [
@@ -939,7 +967,7 @@ class IpsecTra4(object):
]
self.send_and_expect(self.tra_if, pkts, self.tra_if)
- self.assertEqual(p.tra_sa_in.get_lost(), 0)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 0)
# the lost packet are counted untill we get up past the first
# sizeof(replay_window) packets
@@ -955,7 +983,7 @@ class IpsecTra4(object):
]
self.send_and_expect(self.tra_if, pkts, self.tra_if)
- self.assertEqual(p.tra_sa_in.get_lost(), 1)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 1)
# lost of holes in the sequence
pkts = [
@@ -982,7 +1010,7 @@ class IpsecTra4(object):
]
self.send_and_expect(self.tra_if, pkts, self.tra_if)
- self.assertEqual(p.tra_sa_in.get_lost(), 51)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 51)
# a big hole in the seq number space
pkts = [
@@ -997,7 +1025,7 @@ class IpsecTra4(object):
]
self.send_and_expect(self.tra_if, pkts, self.tra_if)
- self.assertEqual(p.tra_sa_in.get_lost(), 151)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 151)
def verify_tra_basic4(self, count=1, payload_size=54):
"""ipsec v4 transport basic test"""
@@ -1036,8 +1064,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.assertEqual(p.tra_sa_out.get_err("lost"), 0)
+ self.assertEqual(p.tra_sa_in.get_err("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)
diff --git a/test/test_ipsec_spd_fp_input.py b/test/test_ipsec_spd_fp_input.py
index bf00c1c26ab..d70623ef2ea 100644
--- a/test/test_ipsec_spd_fp_input.py
+++ b/test/test_ipsec_spd_fp_input.py
@@ -293,8 +293,8 @@ class IPSec4SpdTestCaseProtect(SpdFastPathInboundProtect):
pkt_count,
"incorrect SA out counts: expected %d != %d" % (pkt_count, pkts),
)
- self.assertEqual(p.tra_sa_out.get_lost(), 0)
- self.assertEqual(p.tra_sa_in.get_lost(), 0)
+ self.assertEqual(p.tra_sa_out.get_err("lost"), 0)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 0)
class IPSec4SpdTestCaseAddIPRange(SpdFastPathInbound):
@@ -876,8 +876,8 @@ class IPSec6SpdTestCaseProtect(SpdFastPathIPv6InboundProtect):
pkt_count,
"incorrect SA out counts: expected %d != %d" % (pkt_count, pkts),
)
- self.assertEqual(p.tra_sa_out.get_lost(), 0)
- self.assertEqual(p.tra_sa_in.get_lost(), 0)
+ self.assertEqual(p.tra_sa_out.get_err("lost"), 0)
+ self.assertEqual(p.tra_sa_in.get_err("lost"), 0)
if __name__ == "__main__":
diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py
index 38d0dc3dde5..06b63cae759 100644
--- a/test/test_ipsec_tun_if_esp.py
+++ b/test/test_ipsec_tun_if_esp.py
@@ -1990,6 +1990,8 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
self.send_and_assert_no_replies(self.tun_if, tx)
node_name = "/err/%s/unsup_payload" % self.tun4_decrypt_node_name[0]
self.assertEqual(1, self.statistics.get_err_counter(node_name))
+ err = p.tun_sa_in.get_err("unsup_payload")
+ self.assertEqual(err, 1)
class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
diff --git a/test/vpp_ipsec.py b/test/vpp_ipsec.py
index f50d491c396..7a5a95a457a 100644
--- a/test/vpp_ipsec.py
+++ b/test/vpp_ipsec.py
@@ -358,8 +358,8 @@ 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")
+ def get_err(self, name, worker=None):
+ c = self.test.statistics.get_counter("/net/ipsec/sa/err/" + name)
if worker is None:
total = 0
for t in c:
y infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.