summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2022-11-18 04:24:09 +0000
committerNeale Ranns <neale@graphiant.com>2022-11-21 01:02:29 +0000
commit267175fd0416acb5355332693f5769fb0d2d65ee (patch)
tree2fbfd80dfa42f0e06a1114df3d6b765776f3098c
parent07e0c05e698cf5ffd1e2d2de0296d1907519dc3d (diff)
ipsec: Failure at the start of the batch should not invalidate the rest of the batch
Type: fix Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: Icd1e43a5764496784c355c93066273435f16dd35 (cherry picked from commit fe2d23f916d1991f4a1a8384eae41b5cceb80189)
-rw-r--r--src/plugins/crypto_sw_scheduler/main.c38
-rw-r--r--src/vnet/ipsec/esp_decrypt.c2
-rw-r--r--test/template_ipsec.py28
3 files changed, 53 insertions, 15 deletions
diff --git a/src/plugins/crypto_sw_scheduler/main.c b/src/plugins/crypto_sw_scheduler/main.c
index 09d4a0b9b94..991ef6a43f7 100644
--- a/src/plugins/crypto_sw_scheduler/main.c
+++ b/src/plugins/crypto_sw_scheduler/main.c
@@ -260,17 +260,22 @@ process_ops (vlib_main_t * vm, vnet_crypto_async_frame_t * f,
n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
- while (n_fail)
+ /*
+ * If we had a failure in the ops then we need to walk all the ops
+ * and set the status in the corresponding frame. This status is
+ * not set in the case with no failures, as in that case the overall
+ * frame status is success.
+ */
+ if (n_fail)
{
- ASSERT (op - ops < n_ops);
-
- if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
+ for (int i = 0; i < n_ops; i++)
{
+ ASSERT (op - ops < n_ops);
+
f->elts[op->user_data].status = op->status;
- *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
- n_fail--;
+ op++;
}
- op++;
+ *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
}
}
@@ -287,17 +292,22 @@ process_chained_ops (vlib_main_t * vm, vnet_crypto_async_frame_t * f,
n_fail = n_ops - vnet_crypto_process_chained_ops (vm, op, chunks, n_ops);
- while (n_fail)
+ /*
+ * If we had a failure in the ops then we need to walk all the ops
+ * and set the status in the corresponding frame. This status is
+ * not set in the case with no failures, as in that case the overall
+ * frame status is success.
+ */
+ if (n_fail)
{
- ASSERT (op - ops < n_ops);
-
- if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
+ for (int i = 0; i < n_ops; i++)
{
+ ASSERT (op - ops < n_ops);
+
f->elts[op->user_data].status = op->status;
- *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
- n_fail--;
+ op++;
}
- op++;
+ *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
}
}
diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c
index af90bc4c7ba..9737155dcec 100644
--- a/src/vnet/ipsec/esp_decrypt.c
+++ b/src/vnet/ipsec/esp_decrypt.c
@@ -1189,7 +1189,7 @@ esp_decrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
else
esp_decrypt_prepare_sync_op (
vm, node, ptd, &crypto_ops, &integ_ops, op, sa0, payload, len,
- cpd.icv_sz, cpd.iv_sz, pd, pd2, b[0], sync_next, b - bufs);
+ cpd.icv_sz, cpd.iv_sz, pd, pd2, b[0], sync_next, n_sync);
/* next */
next:
if (ESP_DECRYPT_ERROR_RX_PKTS != err)
diff --git a/test/template_ipsec.py b/test/template_ipsec.py
index def31cbebbd..9d9ea3a86d3 100644
--- a/test/template_ipsec.py
+++ b/test/template_ipsec.py
@@ -432,6 +432,34 @@ class IpsecTra4(object):
]
recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)
+ # a replayed packet, then an out of window, then a legit
+ # tests that a early failure on the batch doesn't affect subsequent 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=203,
+ )
+ ),
+ (
+ 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=81,
+ )
+ ),
+ (
+ 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=204,
+ )
+ ),
+ ]
+ n_rx = 1 if ar_on else 3
+ recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if, n_rx=n_rx)
+
# move the window over half way to a wrap
pkts = [
(