ipsec: store outbound seq as u64 70/42270/4
authorDamjan Marion <[email protected]>
Thu, 30 Jan 2025 18:39:25 +0000 (18:39 +0000)
committerOle Tr�an <[email protected]>
Fri, 31 Jan 2025 15:54:42 +0000 (15:54 +0000)
Type: improvement
Change-Id: Id7717de00558ab90dbd312a58becd58d008397ea
Signed-off-by: Damjan Marion <[email protected]>
src/plugins/unittest/ipsec_test.c
src/vnet/ipsec/ah_encrypt.c
src/vnet/ipsec/esp.h
src/vnet/ipsec/esp_encrypt.c
src/vnet/ipsec/ipsec_api.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_sa.h

index 23867e1..b505c58 100644 (file)
@@ -50,10 +50,7 @@ test_ipsec_command_fn (vlib_main_t *vm, unformat_input_t *input,
       ort = ipsec_sa_get_outb_rt (sa);
 
       if (ort)
-       {
-         ort->seq = seq_num & 0xffffffff;
-         ort->seq_hi = seq_num >> 32;
-       }
+       ort->seq64 = seq_num;
 
       if (irt)
        {
index 7269f90..1b32b8d 100644 (file)
@@ -43,8 +43,7 @@ typedef struct
 {
   u32 sa_index;
   u32 spi;
-  u32 seq_lo;
-  u32 seq_hi;
+  u64 seq;
   ipsec_integ_alg_t integ_alg;
 } ah_encrypt_trace_t;
 
@@ -56,9 +55,9 @@ format_ah_encrypt_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   ah_encrypt_trace_t *t = va_arg (*args, ah_encrypt_trace_t *);
 
-  s = format (s, "ah: sa-index %d spi %u (0x%08x) seq %u:%u integrity %U",
-             t->sa_index, t->spi, t->spi, t->seq_hi, t->seq_lo,
-             format_ipsec_integ_alg, t->integ_alg);
+  s = format (s, "ah: sa-index %d spi %u (0x%08x) seq %lu integrity %U",
+             t->sa_index, t->spi, t->spi, t->seq, format_ipsec_integ_alg,
+             t->integ_alg);
   return s;
 }
 
@@ -261,7 +260,7 @@ ah_encrypt_inline (vlib_main_t * vm,
          oh6_0->ah.reserved = 0;
          oh6_0->ah.nexthdr = next_hdr_type;
          oh6_0->ah.spi = ort->spi_be;
-         oh6_0->ah.seq_no = clib_net_to_host_u32 (ort->seq);
+         oh6_0->ah.seq_no = clib_net_to_host_u32 (ort->seq64);
          oh6_0->ip6.payload_length =
            clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]) -
                                  sizeof (ip6_header_t));
@@ -315,7 +314,7 @@ ah_encrypt_inline (vlib_main_t * vm,
          oh0->ip4.length =
            clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]));
          oh0->ah.spi = ort->spi_be;
-         oh0->ah.seq_no = clib_net_to_host_u32 (ort->seq);
+         oh0->ah.seq_no = clib_net_to_host_u32 (ort->seq64);
          oh0->ah.nexthdr = next_hdr_type;
          oh0->ah.hdrlen =
            (sizeof (ah_header_t) + icv_size + padding_len) / 4 - 2;
@@ -352,11 +351,9 @@ ah_encrypt_inline (vlib_main_t * vm,
          op->user_data = b - bufs;
          if (ort->use_esn)
            {
-             u32 seq_hi = clib_host_to_net_u32 (ort->seq_hi);
-
-             op->len += sizeof (seq_hi);
-             clib_memcpy (op->src + b[0]->current_length, &seq_hi,
-                          sizeof (seq_hi));
+             *(u32u *) (op->src + b[0]->current_length) =
+               clib_host_to_net_u32 (ort->seq64 >> 32);
+             op->len += sizeof (u32);
            }
        }
 
@@ -375,8 +372,7 @@ ah_encrypt_inline (vlib_main_t * vm,
          ah_encrypt_trace_t *tr =
            vlib_add_trace (vm, node, b[0], sizeof (*tr));
          tr->spi = sa->spi;
-         tr->seq_lo = ort->seq;
-         tr->seq_hi = ort->seq_hi;
+         tr->seq = ort->seq64;
          tr->integ_alg = sa->integ_alg;
          tr->sa_index = pd->sa_index;
        }
index 12d811c..a31e314 100644 (file)
@@ -79,32 +79,16 @@ typedef struct esp_aead_t_
   u32 data[3];
 } __clib_packed esp_aead_t;
 
-#define ESP_SEQ_MAX            (4294967295UL)
-
 u8 *format_esp_header (u8 * s, va_list * args);
 
 /* TODO seq increment should be atomic to be accessed by multiple workers */
 always_inline int
 esp_seq_advance (ipsec_sa_outb_rt_t *ort)
 {
-  if (PREDICT_TRUE (ort->use_esn))
-    {
-      if (PREDICT_FALSE (ort->seq == ESP_SEQ_MAX))
-       {
-         if (PREDICT_FALSE (ort->use_anti_replay &&
-                            ort->seq_hi == ESP_SEQ_MAX))
-           return 1;
-         ort->seq_hi++;
-       }
-      ort->seq++;
-    }
-  else
-    {
-      if (PREDICT_FALSE (ort->use_anti_replay && ort->seq == ESP_SEQ_MAX))
-       return 1;
-      ort->seq++;
-    }
-
+  u64 max = ort->use_esn ? CLIB_U64_MAX : CLIB_U32_MAX;
+  if (ort->seq64 == max)
+    return 1;
+  ort->seq64++;
   return 0;
 }
 
index c41647a..8916eb1 100644 (file)
@@ -49,8 +49,7 @@ typedef struct
 {
   u32 sa_index;
   u32 spi;
-  u32 seq;
-  u32 sa_seq_hi;
+  u64 seq;
   u8 udp_encap;
   ipsec_crypto_alg_t crypto_alg;
   ipsec_integ_alg_t integ_alg;
@@ -71,13 +70,11 @@ format_esp_encrypt_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   esp_encrypt_trace_t *t = va_arg (*args, esp_encrypt_trace_t *);
 
-  s =
-    format (s,
-           "esp: sa-index %d spi %u (0x%08x) seq %u sa-seq-hi %u crypto %U integrity %U%s",
-           t->sa_index, t->spi, t->spi, t->seq, t->sa_seq_hi,
-           format_ipsec_crypto_alg,
-           t->crypto_alg, format_ipsec_integ_alg, t->integ_alg,
-           t->udp_encap ? " udp-encap-enabled" : "");
+  s = format (
+    s, "esp: sa-index %d spi %u (0x%08x) seq %lu crypto %U integrity %U%s",
+    t->sa_index, t->spi, t->spi, t->seq, format_ipsec_crypto_alg,
+    t->crypto_alg, format_ipsec_integ_alg, t->integ_alg,
+    t->udp_encap ? " udp-encap-enabled" : "");
   return s;
 }
 
@@ -353,10 +350,9 @@ esp_encrypt_chain_integ (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
          total_len += ch->len = cb->current_length - icv_sz;
          if (ort->use_esn)
            {
-             u32 seq_hi = clib_net_to_host_u32 (ort->seq_hi);
-             clib_memcpy_fast (digest, &seq_hi, sizeof (seq_hi));
-             ch->len += sizeof (seq_hi);
-             total_len += sizeof (seq_hi);
+             *(u32u *) digest = clib_net_to_host_u32 (ort->seq64 >> 32);
+             ch->len += sizeof (u32);
+             total_len += sizeof (u32);
            }
        }
       else
@@ -522,7 +518,7 @@ esp_prepare_async_frame (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
        {
          /* constuct aad in a scratch space in front of the nonce */
          aad = (u8 *) nonce - sizeof (esp_aead_t);
-         esp_aad_fill (aad, esp, ort->use_esn, ort->seq_hi);
+         esp_aad_fill (aad, esp, ort->use_esn, ort->seq64 >> 32);
          if (PREDICT_FALSE (ort->is_null_gmac))
            {
              /* RFC-4543 ENCR_NULL_AUTH_AES_GMAC: IV is part of AAD */
@@ -573,9 +569,8 @@ esp_prepare_async_frame (vlib_main_t *vm, ipsec_per_thread_data_t *ptd,
        }
       else if (ort->use_esn)
        {
-         u32 seq_hi = clib_net_to_host_u32 (ort->seq_hi);
-         clib_memcpy_fast (tag, &seq_hi, sizeof (seq_hi));
-         integ_total_len += sizeof (seq_hi);
+         *(u32u *) tag = clib_net_to_host_u32 (ort->seq64 >> 32);
+         integ_total_len += sizeof (u32);
        }
     }
 
@@ -1021,7 +1016,7 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
        }
 
       esp->spi = spi;
-      esp->seq = clib_net_to_host_u32 (ort->seq);
+      esp->seq = clib_net_to_host_u32 (ort->seq64);
 
       if (is_async)
        {
@@ -1054,9 +1049,9 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
                                   async_next_node, lb);
        }
       else
-       esp_prepare_sync_op (vm, ptd, crypto_ops, integ_ops, ort, ort->seq_hi,
-                            payload, payload_len, iv_sz, icv_sz, n_sync, b,
-                            lb, hdr_len, esp);
+       esp_prepare_sync_op (vm, ptd, crypto_ops, integ_ops, ort,
+                            ort->seq64 >> 32, payload, payload_len, iv_sz,
+                            icv_sz, n_sync, b, lb, hdr_len, esp);
 
       vlib_buffer_advance (b[0], 0LL - hdr_len);
 
@@ -1075,8 +1070,7 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
              ipsec_sa_t *sa = ipsec_sa_get (sa_index0);
              tr->sa_index = sa_index0;
              tr->spi = sa->spi;
-             tr->seq = ort->seq;
-             tr->sa_seq_hi = ort->seq_hi;
+             tr->seq = ort->seq64;
              tr->udp_encap = ort->udp_encap;
              tr->crypto_alg = sa->crypto_alg;
              tr->integ_alg = sa->integ_alg;
index 49bd3aa..2dd9b9f 100644 (file)
@@ -58,9 +58,7 @@ ipsec_sa_get_outb_seq (ipsec_sa_t *sa)
   ipsec_sa_outb_rt_t *ort = ipsec_sa_get_outb_rt (sa);
   u64 seq;
 
-  seq = ort->seq;
-  if (ipsec_sa_is_set_USE_ESN (sa))
-    seq |= (u64) ort->seq_hi << 32;
+  seq = ort->seq64;
   return seq;
 }
 
index 1162c4c..0bbdc85 100644 (file)
@@ -476,7 +476,7 @@ format_ipsec_sa (u8 * s, va_list * args)
   if (irt)
     s = format (s, "\n   inbound seq %u seq-hi %u", irt->seq, irt->seq_hi);
   if (ort)
-    s = format (s, "\n   outbound seq %u seq-hi %u", ort->seq, ort->seq_hi);
+    s = format (s, "\n   outbound seq %lu", ort->seq64);
   if (irt)
     {
       s = format (s, "\n   window-size: %llu",
index 86bc4e2..ce2964a 100644 (file)
@@ -194,8 +194,7 @@ typedef struct
   u8 integ_icv_size;
   u16 thread_index;
   u32 salt;
-  u32 seq;
-  u32 seq_hi;
+  u64 seq64;
   u32 spi_be;
   ip_dscp_t t_dscp;
   dpo_id_t dpo;