History

net/mlx5e: kTLS, Fix corner-case checks in TX resync flow

There are the following cases: 1. Packet ends before start marker: bypass offload. 2. Packet starts before start marker and ends after it: drop, not supported, breaks contract with kernel. 3. packet ends before tls record info starts: drop, this packet was already acknowledged and its record info was released. Add the above as comment in code. Mind possible wraparounds of the TCP seq, replace the simple comparison with a call to the TCP before() method. In addition, remove logic that handles negative sync_len values, as it became impossible.

Tariq Toukan committed 6 years ago

Commit ffbd9ca1 parent 3b83b6c1 file · +19 −14Browse files

Unified · Split

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c+19−14
@@ -180,7 +180,7 @@ mlx5e_ktls_tx_post_param_wqes(struct mlx5e_txqsq *sq, · 179 unmodified lines
180 180
181struct tx_sync_info {181struct tx_sync_info {
182 u64 rcd_sn;182 u64 rcd_sn;
183 s32 sync_len;183 u32 sync_len;
184 int nr_frags;184 int nr_frags;
185 skb_frag_t frags[MAX_SKB_FRAGS];185 skb_frag_t frags[MAX_SKB_FRAGS];
186};186};
@@ -193,13 +193,14 @@ enum mlx5e_ktls_sync_retval { · 6 unmodified lines
193 193
194static enum mlx5e_ktls_sync_retval194static enum mlx5e_ktls_sync_retval
195tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx,195tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx,
196 u32 tcp_seq, struct tx_sync_info *info)196 u32 tcp_seq, int datalen, struct tx_sync_info *info)
197{197{
198 struct tls_offload_context_tx *tx_ctx = priv_tx->tx_ctx;198 struct tls_offload_context_tx *tx_ctx = priv_tx->tx_ctx;
199 enum mlx5e_ktls_sync_retval ret = MLX5E_KTLS_SYNC_DONE;199 enum mlx5e_ktls_sync_retval ret = MLX5E_KTLS_SYNC_DONE;
200 struct tls_record_info *record;200 struct tls_record_info *record;
201 int remaining, i = 0;201 int remaining, i = 0;
202 unsigned long flags;202 unsigned long flags;
203 bool ends_before;
203 204
204 spin_lock_irqsave(&tx_ctx->lock, flags);205 spin_lock_irqsave(&tx_ctx->lock, flags);
205 record = tls_get_record(tx_ctx, tcp_seq, &info->rcd_sn);206 record = tls_get_record(tx_ctx, tcp_seq, &info->rcd_sn);
@@ -209,9 +210,21 @@ tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, · 3 unmodified lines
209 goto out;210 goto out;
210 }211 }
211 212
212 if (unlikely(tcp_seq < tls_record_start_seq(record))) {213 /* There are the following cases:
213 ret = tls_record_is_start_marker(record) ?214 * 1. packet ends before start marker: bypass offload.
214 MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL;215 * 2. packet starts before start marker and ends after it: drop,
216 * not supported, breaks contract with kernel.
217 * 3. packet ends before tls record info starts: drop,
218 * this packet was already acknowledged and its record info
219 * was released.
220 */
221 ends_before = before(tcp_seq + datalen, tls_record_start_seq(record));
222
223 if (unlikely(tls_record_is_start_marker(record))) {
224 ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL;
225 goto out;
226 } else if (ends_before) {
227 ret = MLX5E_KTLS_SYNC_FAIL;
215 goto out;228 goto out;
216 }229 }
217 230
@@ -337,7 +350,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, · 119 unmodified lines
337 u8 num_wqebbs;350 u8 num_wqebbs;
338 int i = 0;351 int i = 0;
339 352
340 ret = tx_sync_info_get(priv_tx, seq, &info);353 ret = tx_sync_info_get(priv_tx, seq, datalen, &info);
341 if (unlikely(ret != MLX5E_KTLS_SYNC_DONE)) {354 if (unlikely(ret != MLX5E_KTLS_SYNC_DONE)) {
342 if (ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA) {355 if (ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA) {
343 stats->tls_skip_no_sync_data++;356 stats->tls_skip_no_sync_data++;
@@ -351,14 +364,6 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, · 7 unmodified lines
351 goto err_out;364 goto err_out;
352 }365 }
353 366
354 if (unlikely(info.sync_len < 0)) {
355 if (likely(datalen <= -info.sync_len))
356 return MLX5E_KTLS_SYNC_DONE;
357
358 stats->tls_drop_bypass_req++;
359 goto err_out;
360 }
361
362 stats->tls_ooo++;367 stats->tls_ooo++;
363 368
364 tx_post_resync_params(sq, priv_tx, info.rcd_sn);369 tx_post_resync_params(sq, priv_tx, info.rcd_sn);