ipsec: Failure at the start of the batch should not invalidate the rest of the batch 77/37677/2
authorNeale Ranns <neale@graphiant.com>
Fri, 18 Nov 2022 04:24:09 +0000 (04:24 +0000)
committerBeno�t Ganne <bganne@cisco.com>
Fri, 18 Nov 2022 08:09:29 +0000 (08:09 +0000)
Type: fix

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Icd1e43a5764496784c355c93066273435f16dd35

src/plugins/crypto_sw_scheduler/main.c
src/vnet/ipsec/esp_decrypt.c
test/template_ipsec.py

index 09d4a0b..991ef6a 100644 (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;
     }
 }
 
index f80b379..306fb7d 100644 (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)
index def31cb..9d9ea3a 100644 (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 = [
             (