aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgaoginskx <gabrielx.oginski@intel.com>2021-06-07 12:07:01 +0100
committerFan Zhang <fanzhang.oss@gmail.com>2023-06-08 09:18:58 +0000
commitf441b5d0ed8ff9d87412c1640dfec93e9cba03bd (patch)
tree457879317037cc833dd635d9f5b3b48862963ffd
parentf50929d370aa0216417f51f457770acdc2324c6c (diff)
crypto: use fixed crypto frame pool
The async frames pool may be resized once drained. This will cause 2 problems: original pool pointer is invalidated and pool size changed, both problems will confuse the crypto infra user graph nodes (like IPsec and Wireguard) and crypto engines if they expect the pool pointers always valid and the pool size never changed (for performance reason). This patch introduces fixed size of the async frames pool. This helps zeroing surprise to the components shown above and avoiding segmentation fault when pool resizing happened. In addition, the crypto engine may take advantage of the feature to sync its own pool/vector with crypto infra. Type: improvement Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com> Signed-off-by: Piotr Bronowski <piotrx.bronowski@intel.com> Change-Id: I2a71783b90149fa376848b9c4f84ce8c6c034bef
-rw-r--r--src/plugins/wireguard/wireguard_input.c2
-rw-r--r--src/plugins/wireguard/wireguard_output_tun.c2
-rw-r--r--src/vnet/crypto/crypto.c3
-rw-r--r--src/vnet/crypto/crypto.h16
-rw-r--r--src/vnet/ipsec/esp_decrypt.c9
-rw-r--r--src/vnet/ipsec/esp_encrypt.c10
-rw-r--r--src/vnet/ipsec/ipsec.api12
7 files changed, 46 insertions, 8 deletions
diff --git a/src/plugins/wireguard/wireguard_input.c b/src/plugins/wireguard/wireguard_input.c
index db37fa54175..cf8a59715dc 100644
--- a/src/plugins/wireguard/wireguard_input.c
+++ b/src/plugins/wireguard/wireguard_input.c
@@ -611,6 +611,8 @@ wg_input_process (vlib_main_t *vm, wg_per_thread_data_t *ptd,
{
*async_frame = vnet_crypto_async_get_frame (
vm, VNET_CRYPTO_OP_CHACHA20_POLY1305_TAG16_AAD0_DEC);
+ if (PREDICT_FALSE (NULL == *async_frame))
+ goto error;
/* Save the frame to the list we'll submit at the end */
vec_add1 (ptd->async_frames, *async_frame);
}
diff --git a/src/plugins/wireguard/wireguard_output_tun.c b/src/plugins/wireguard/wireguard_output_tun.c
index 4ff1621b4a3..a5630811b9d 100644
--- a/src/plugins/wireguard/wireguard_output_tun.c
+++ b/src/plugins/wireguard/wireguard_output_tun.c
@@ -368,6 +368,8 @@ wg_add_to_async_frame (vlib_main_t *vm, wg_per_thread_data_t *ptd,
{
*async_frame = vnet_crypto_async_get_frame (
vm, VNET_CRYPTO_OP_CHACHA20_POLY1305_TAG16_AAD0_ENC);
+ if (PREDICT_FALSE (NULL == *async_frame))
+ goto error;
/* Save the frame to the list we'll submit at the end */
vec_add1 (ptd->async_frames, *async_frame);
}
diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c
index 5d951a118b8..81cbda8fd59 100644
--- a/src/vnet/crypto/crypto.c
+++ b/src/vnet/crypto/crypto.c
@@ -706,8 +706,7 @@ vnet_crypto_init (vlib_main_t * vm)
cm->async_alg_index_by_name = hash_create_string (0, sizeof (uword));
vec_validate_aligned (cm->threads, tm->n_vlib_mains, CLIB_CACHE_LINE_BYTES);
vec_foreach (ct, cm->threads)
- pool_alloc_aligned (ct->frame_pool, VNET_CRYPTO_FRAME_POOL_SIZE,
- CLIB_CACHE_LINE_BYTES);
+ pool_init_fixed (ct->frame_pool, VNET_CRYPTO_FRAME_POOL_SIZE);
vec_validate (cm->algs, VNET_CRYPTO_N_ALGS);
vec_validate (cm->async_algs, VNET_CRYPTO_N_ASYNC_ALGS);
diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h
index 36fde2a548f..c16839ddead 100644
--- a/src/vnet/crypto/crypto.h
+++ b/src/vnet/crypto/crypto.h
@@ -556,12 +556,16 @@ vnet_crypto_async_get_frame (vlib_main_t * vm, vnet_crypto_async_op_id_t opt)
vnet_crypto_thread_t *ct = cm->threads + vm->thread_index;
vnet_crypto_async_frame_t *f = NULL;
- pool_get_aligned (ct->frame_pool, f, CLIB_CACHE_LINE_BYTES);
- if (CLIB_DEBUG > 0)
- clib_memset (f, 0xfe, sizeof (*f));
- f->state = VNET_CRYPTO_FRAME_STATE_NOT_PROCESSED;
- f->op = opt;
- f->n_elts = 0;
+ if (PREDICT_TRUE (pool_free_elts (ct->frame_pool)))
+ {
+ pool_get_aligned (ct->frame_pool, f, CLIB_CACHE_LINE_BYTES);
+#if CLIB_DEBUG > 0
+ clib_memset (f, 0xfe, sizeof (*f));
+#endif
+ f->state = VNET_CRYPTO_FRAME_STATE_NOT_PROCESSED;
+ f->op = opt;
+ f->n_elts = 0;
+ }
return f;
}
diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c
index 6db1fe305c8..43d292d27e8 100644
--- a/src/vnet/ipsec/esp_decrypt.c
+++ b/src/vnet/ipsec/esp_decrypt.c
@@ -1183,6 +1183,15 @@ esp_decrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
{
async_frames[async_op] =
vnet_crypto_async_get_frame (vm, async_op);
+ if (PREDICT_FALSE (!async_frames[async_op]))
+ {
+ err = ESP_DECRYPT_ERROR_NO_AVAIL_FRAME;
+ esp_decrypt_set_next_index (
+ b[0], node, thread_index, err, n_noop, noop_nexts,
+ ESP_DECRYPT_NEXT_DROP, current_sa_index);
+ goto next;
+ }
+
/* Save the frame to the list we'll submit at the end */
vec_add1 (ptd->async_frames, async_frames[async_op]);
}
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index ea0bf34dba4..7f9b5ed8adf 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -999,6 +999,16 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
{
async_frames[async_op] =
vnet_crypto_async_get_frame (vm, async_op);
+
+ if (PREDICT_FALSE (!async_frames[async_op]))
+ {
+ err = ESP_ENCRYPT_ERROR_NO_AVAIL_FRAME;
+ esp_encrypt_set_next_index (b[0], node, thread_index, err,
+ n_noop, noop_nexts, drop_next,
+ current_sa_index);
+ goto trace;
+ }
+
/* Save the frame to the list we'll submit at the end */
vec_add1 (ptd->async_frames, async_frames[async_op]);
}
diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api
index 6cbad6e74fa..2e69e625034 100644
--- a/src/vnet/ipsec/ipsec.api
+++ b/src/vnet/ipsec/ipsec.api
@@ -607,6 +607,12 @@ counters esp_decrypt {
units "packets";
description "unsupported payload";
};
+ no_avail_frame {
+ severity error;
+ type counter64;
+ units "packets";
+ description "no available frame (packet dropped)";
+ };
};
counters esp_encrypt {
@@ -664,6 +670,12 @@ counters esp_encrypt {
units "packets";
description "no Encrypting SA (packet dropped)";
};
+ no_avail_frame {
+ severity error;
+ type counter64;
+ units "packets";
+ description "no available frame (packet dropped)";
+ };
};
counters ah_encrypt {