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)
This commit is contained in:
Neale Ranns
2022-11-18 04:24:09 +00:00
parent 07e0c05e69
commit 267175fd04
3 changed files with 53 additions and 15 deletions

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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 = [
(