ikev2: accept rekey request for IKE SA
[vpp.git] / src / plugins / ikev2 / ikev2_payload.c
index 294864d..689c502 100644 (file)
@@ -167,8 +167,8 @@ ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
 }
 
 void
-ikev2_payload_add_sa (ikev2_payload_chain_t * c,
-                     ikev2_sa_proposal_t * proposals)
+ikev2_payload_add_sa (ikev2_payload_chain_t *c, ikev2_sa_proposal_t *proposals,
+                     u8 force_spi)
 {
   ike_payload_header_t *ph;
   ike_sa_proposal_data_t *prop;
@@ -184,7 +184,13 @@ ikev2_payload_add_sa (ikev2_payload_chain_t * c,
 
   vec_foreach (p, proposals)
   {
-    int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0;
+    int spi_size = 0;
+
+    if (p->protocol_id == IKEV2_PROTOCOL_ESP)
+      spi_size = 4;
+    else if (force_spi && p->protocol_id == IKEV2_PROTOCOL_IKE)
+      spi_size = 8;
+
     pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size);
     prop = (ike_sa_proposal_data_t *) pr_data;
     prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0;
@@ -193,8 +199,13 @@ ikev2_payload_add_sa (ikev2_payload_chain_t * c,
     prop->spi_size = spi_size;
     prop->num_transforms = vec_len (p->transforms);
 
-    if (spi_size)
+    if (spi_size == 4)
       prop->spi[0] = clib_host_to_net_u32 (p->spi);
+    else if (spi_size == 8)
+      {
+       u64 s = clib_host_to_net_u64 (p->spi);
+       clib_memcpy_fast (prop->spi, &s, sizeof (s));
+      }
 
     vec_foreach (t, p->transforms)
     {
@@ -384,8 +395,9 @@ ikev2_parse_sa_payload (ike_payload_header_t * ikep, u32 rlen)
       sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr];
       int i, transform_ptr;
 
-      /* IKE proposal should not have SPI */
-      if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0)
+      /* IKE proposal should have 8 bytes or no SPI */
+      if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0 &&
+         sap->spi_size != 8)
        goto data_corrupted;
 
       /* IKE proposal should not have SPI */
@@ -404,6 +416,12 @@ ikev2_parse_sa_payload (ike_payload_header_t * ikep, u32 rlen)
        {
          proposal->spi = clib_net_to_host_u32 (sap->spi[0]);
        }
+      else if (sap->spi_size == 8)
+       {
+         u64 s;
+         clib_memcpy_fast (&s, &sap->spi[0], sizeof (s));
+         proposal->spi = clib_net_to_host_u64 (s);
+       }
 
       for (i = 0; i < sap->num_transforms; i++)
        {