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.
Unified · Split
| @@ -180,7 +180,7 @@ mlx5e_ktls_tx_post_param_wqes(struct mlx5e_txqsq *sq, · 179 unmodified lines | |||
| 180 | 180 | ||
| 181 | struct tx_sync_info { | 181 | struct 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 | ||
| 194 | static enum mlx5e_ktls_sync_retval | 194 | static enum mlx5e_ktls_sync_retval |
| 195 | tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, | 195 | tx_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); |