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:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 = [
|
||||
(
|
||||
|
Reference in New Issue
Block a user