ikev2: remove assert condition
[vpp.git] / src / plugins / ikev2 / ikev2.c
index 745943b..cfc3d9f 100644 (file)
@@ -38,9 +38,9 @@ static int ikev2_delete_tunnel_interface (vnet_main_t * vnm,
                                          ikev2_sa_t * sa,
                                          ikev2_child_sa_t * child);
 
-#define ikev2_set_state(sa, v) do { \
+#define ikev2_set_state(sa, v, ...) do { \
     (sa)->state = v; \
-    ikev2_elog_sa_state("ispi %lx SA state changed to " #v, sa->ispi); \
+    ikev2_elog_sa_state("ispi %lx SA state changed to " #v __VA_ARGS__, sa->ispi); \
   } while(0);
 
 typedef struct
@@ -716,9 +716,8 @@ ikev2_check_payload_length (const ike_payload_header_t * ikep, int rlen,
 }
 
 static int
-ikev2_process_sa_init_req (vlib_main_t * vm,
-                          ikev2_sa_t * sa, ike_header_t * ike,
-                          udp_header_t * udp, u32 len)
+ikev2_process_sa_init_req (vlib_main_t *vm, ikev2_sa_t *sa, ike_header_t *ike,
+                          udp_header_t *udp, u32 len, u32 sw_if_index)
 {
   u8 nonce[IKEV2_NONCE_SIZE];
   int p = 0;
@@ -733,6 +732,7 @@ ikev2_process_sa_init_req (vlib_main_t * vm,
                       ip_addr_version (&sa->iaddr) == AF_IP4);
 
   sa->ispi = clib_net_to_host_u64 (ike->ispi);
+  sa->sw_if_index = sw_if_index;
 
   /* store whole IKE payload - needed for PSK auth */
   vec_reset_length (sa->last_sa_init_req_packet_data);
@@ -1070,14 +1070,14 @@ ikev2_initial_contact_cleanup_internal (ikev2_main_per_thread_data_t * ptd,
 
   /* find old IKE SAs with the same authenticated identity */
   /* *INDENT-OFF* */
-  pool_foreach (tmp, ptd->sas, ({
+  pool_foreach (tmp, ptd->sas)  {
     if (!ikev2_is_id_equal (&tmp->i_id, &sa->i_id)
         || !ikev2_is_id_equal(&tmp->r_id, &sa->r_id))
       continue;
 
     if (sa->rspi != tmp->rspi)
       vec_add1(delete, tmp - ptd->sas);
-  }));
+  }
   /* *INDENT-ON* */
 
   for (i = 0; i < vec_len (delete); i++)
@@ -1280,7 +1280,7 @@ ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa,
   return 1;
 
 malformed:
-  ikev2_set_state (sa, IKEV2_STATE_DELETED);
+  ikev2_set_state (sa, IKEV2_STATE_DELETED, ": malformed IKE_AUTH");
   return 0;
 }
 
@@ -1564,7 +1564,7 @@ ikev2_sa_match_ts (ikev2_sa_t * sa)
   ikev2_id_t *id_rem, *id_loc;
 
   /* *INDENT-OFF* */
-  pool_foreach (p, km->profiles, ({
+  pool_foreach (p, km->profiles)  {
 
     if (sa->is_initiator)
       {
@@ -1607,7 +1607,7 @@ ikev2_sa_match_ts (ikev2_sa_t * sa)
       }
 
     break;
-  }));
+  }
   /* *INDENT-ON* */
 
   if (tsi && tsr)
@@ -1667,7 +1667,7 @@ ikev2_sa_auth (ikev2_sa_t * sa)
     }
 
   /* *INDENT-OFF* */
-  pool_foreach (p, km->profiles, ({
+  pool_foreach (p, km->profiles)  {
 
     /* check id */
     if (!ikev2_is_id_equal (&p->rem_id, id_rem)
@@ -1707,7 +1707,7 @@ ikev2_sa_auth (ikev2_sa_t * sa)
 
     vec_free(auth);
     vec_free(psk);
-  }));
+  }
   /* *INDENT-ON* */
 
   if (sel_p)
@@ -2403,7 +2403,7 @@ ikev2_generate_message (vlib_buffer_t * b, ikev2_sa_t * sa,
        }
       else
        {
-         ikev2_set_state (sa, IKEV2_STATE_DELETED);
+         ikev2_set_state (sa, IKEV2_STATE_DELETED, ": unexpected IKE_AUTH");
          goto done;
        }
     }
@@ -2433,7 +2433,7 @@ ikev2_generate_message (vlib_buffer_t * b, ikev2_sa_t * sa,
       /* received N(AUTHENTICATION_FAILED) */
       else if (sa->state == IKEV2_STATE_AUTH_FAILED)
        {
-         ikev2_set_state (sa, IKEV2_STATE_DELETED);
+         ikev2_set_state (sa, IKEV2_STATE_DELETED, ": auth failed");
          goto done;
        }
       /* received unsupported critical payload */
@@ -2679,11 +2679,11 @@ ikev2_retransmit_sa_init (ike_header_t * ike, ip_address_t iaddr,
   ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
 
   /* *INDENT-OFF* */
-  pool_foreach (sa, ptd->sas, ({
+  pool_foreach (sa, ptd->sas)  {
     res = ikev2_retransmit_sa_init_one (sa, ike, iaddr, raddr, rlen);
     if (res)
       return res;
-  }));
+  }
   /* *INDENT-ON* */
 
   /* req is not retransmit */
@@ -2834,9 +2834,8 @@ ikev2_generate_sa_init_data_and_log (ikev2_sa_t * sa)
 }
 
 static_always_inline uword
-ikev2_node_internal (vlib_main_t * vm,
-                    vlib_node_runtime_t * node, vlib_frame_t * frame,
-                    u8 is_ip4)
+ikev2_node_internal (vlib_main_t *vm, vlib_node_runtime_t *node,
+                    vlib_frame_t *frame, u8 is_ip4, u8 natt)
 {
   u32 n_left = frame->n_vectors, *from;
   ikev2_main_t *km = &ikev2_main;
@@ -2862,15 +2861,9 @@ ikev2_node_internal (vlib_main_t * vm,
       ikev2_sa_t sa;           /* temporary store for SA */
       u32 rlen, slen = 0;
       int ip_hdr_sz = 0;
-      int is_req = 0, has_non_esp_marker = 0;
-
-      ASSERT (0 == b0->punt_reason
-             || (is_ip4
-                 && b0->punt_reason ==
-                 ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0]));
+      int is_req = 0;
 
-      if (is_ip4
-         && b0->punt_reason == ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0])
+      if (natt)
        {
          u8 *ptr = vlib_buffer_get_current (b0);
          ip40 = (ip4_header_t *) ptr;
@@ -2903,12 +2896,12 @@ ikev2_node_internal (vlib_main_t * vm,
       rlen = b0->current_length - ip_hdr_sz - sizeof (*udp0);
 
       /* check for non-esp marker */
-      if (*((u32 *) ike0) == 0)
+      if (natt)
        {
+         ASSERT (*((u32 *) ike0) == 0);
          ike0 =
            (ike_header_t *) ((u8 *) ike0 + sizeof (ikev2_non_esp_marker));
          rlen -= sizeof (ikev2_non_esp_marker);
-         has_non_esp_marker = 1;
        }
 
       if (clib_net_to_host_u32 (ike0->length) != rlen)
@@ -2958,7 +2951,9 @@ ikev2_node_internal (vlib_main_t * vm,
                      goto dispatch0;
                    }
 
-                 res = ikev2_process_sa_init_req (vm, sa0, ike0, udp0, rlen);
+                 res = ikev2_process_sa_init_req (
+                   vm, sa0, ike0, udp0, rlen,
+                   vnet_buffer (b0)->sw_if_index[VLIB_RX]);
                  if (!res)
                    vlib_node_increment_counter (vm, node->node_index,
                                                 IKEV2_ERROR_MALFORMED_PACKET,
@@ -3271,13 +3266,13 @@ ikev2_node_internal (vlib_main_t * vm,
              if (udp0->dst_port == clib_net_to_host_u16 (IKEV2_PORT_NATT)
                  && ikev2_natt_active (sa0))
                {
-                 if (!has_non_esp_marker)
+                 if (!natt)
                    slen = ikev2_insert_non_esp_marker (ike0, slen);
                }
            }
          else
            {
-             if (has_non_esp_marker)
+             if (natt)
                slen += sizeof (ikev2_non_esp_marker);
 
              u16 tp = udp0->dst_port;
@@ -3332,13 +3327,20 @@ ikev2_node_internal (vlib_main_t * vm,
 static uword
 ikev2_ip4 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */ );
+  return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */, 0);
+}
+
+static uword
+ikev2_ip4_natt (vlib_main_t *vm, vlib_node_runtime_t *node,
+               vlib_frame_t *frame)
+{
+  return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */, 1 /* natt */);
 }
 
 static uword
 ikev2_ip6 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ikev2_node_internal (vm, node, frame, 0 /* is_ip4 */ );
+  return ikev2_node_internal (vm, node, frame, 0 /* is_ip4 */, 0);
 }
 
 /* *INDENT-OFF* */
@@ -3359,6 +3361,23 @@ VLIB_REGISTER_NODE (ikev2_node_ip4,static) = {
   },
 };
 
+VLIB_REGISTER_NODE (ikev2_node_ip4_natt,static) = {
+  .function = ikev2_ip4_natt,
+  .name = "ikev2-ip4-natt",
+  .vector_size = sizeof (u32),
+  .format_trace = format_ikev2_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = ARRAY_LEN(ikev2_error_strings),
+  .error_strings = ikev2_error_strings,
+
+  .n_next_nodes = IKEV2_IP4_N_NEXT,
+  .next_nodes = {
+    [IKEV2_NEXT_IP4_LOOKUP] = "ip4-lookup",
+    [IKEV2_NEXT_IP4_ERROR_DROP] = "error-drop",
+  },
+};
+
 VLIB_REGISTER_NODE (ikev2_node_ip6,static) = {
   .function = ikev2_ip6,
   .name = "ikev2-ip6",
@@ -3750,10 +3769,10 @@ ikev2_cleanup_profile_sessions (ikev2_main_t * km, ikev2_profile_t * p)
   u32 *del_sai = 0;
 
   /* *INDENT-OFF* */
-  pool_foreach(sa, km->sais, ({
+  pool_foreach (sa, km->sais)  {
     if (pi == sa->profile_index)
       vec_add1 (del_sai, sa - km->sais);
-  }));
+  }
   /* *INDENT-ON* */
 
   vec_foreach (sai, del_sai)
@@ -3768,10 +3787,10 @@ ikev2_cleanup_profile_sessions (ikev2_main_t * km, ikev2_profile_t * p)
   vec_foreach (tkm, km->per_thread_data)
   {
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       if (sa->profile_index != ~0 && pi == sa->profile_index)
         vec_add1 (del_sai, sa - tkm->sas);
-    }));
+    }
     /* *INDENT-ON* */
 
     vec_foreach (sai, del_sai)
@@ -4403,14 +4422,14 @@ ikev2_initiate_delete_child_sa (vlib_main_t * vm, u32 ispi)
     if (fchild)
       break;
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
       if (fchild)
         {
           fsa = sa;
           break;
         }
-    }));
+    }
     /* *INDENT-ON* */
   }
 
@@ -4443,14 +4462,14 @@ ikev2_initiate_delete_ike_sa (vlib_main_t * vm, u64 ispi)
     if (fsa)
       break;
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       if (sa->ispi == ispi)
         {
           fsa = sa;
           ftkm = tkm;
           break;
         }
-    }));
+    }
     /* *INDENT-ON* */
   }
 
@@ -4526,14 +4545,14 @@ ikev2_initiate_rekey_child_sa (vlib_main_t * vm, u32 ispi)
     if (fchild)
       break;
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
       if (fchild)
         {
           fsa = sa;
           break;
         }
-    }));
+    }
     /* *INDENT-ON* */
   }
 
@@ -4568,10 +4587,10 @@ ikev2_sa_del (ikev2_profile_t * p, u32 sw_if_index)
   vec_foreach (tkm, km->per_thread_data)
   {
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       if (ikev2_sa_sw_if_match (sa, sw_if_index))
         vec_add1 (sa_vec, sa);
-    }));
+    }
     /* *INDENT-ON* */
 
     vec_foreach (sap, sa_vec)
@@ -4583,10 +4602,10 @@ ikev2_sa_del (ikev2_profile_t * p, u32 sw_if_index)
   vec_free (sa_vec);
 
   /* *INDENT-OFF* */
-  pool_foreach (sa, km->sais, ({
+  pool_foreach (sa, km->sais)  {
     if (ikev2_sa_sw_if_match (sa, sw_if_index))
       vec_add1 (ispi_vec, sa->ispi);
-  }));
+  }
   /* *INDENT-ON* */
 
   vec_foreach (ispi, ispi_vec)
@@ -4607,10 +4626,10 @@ ikev2_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
     return 0;
 
   /* *INDENT-OFF* */
-  pool_foreach (p, km->profiles, ({
+  pool_foreach (p, km->profiles)  {
     if (p->responder.sw_if_index == sw_if_index)
       ikev2_sa_del (p, sw_if_index);
-  }));
+  }
   /* *INDENT-ON* */
 
   return 0;
@@ -4664,9 +4683,9 @@ ikev2_init (vlib_main_t * vm)
   udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip4.index, 1);
   udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip6.index, 0);
 
-  vlib_punt_hdl_t punt_hdl = vlib_punt_client_register ("ikev2-ip4");
+  vlib_punt_hdl_t punt_hdl = vlib_punt_client_register ("ikev2-ip4-natt");
   vlib_punt_register (punt_hdl, ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0],
-                     "ikev2-ip4");
+                     "ikev2-ip4-natt");
   ikev2_cli_reference ();
 
   km->log_level = IKEV2_LOG_ERROR;
@@ -4839,14 +4858,14 @@ ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa)
     if (fchild)
       break;
     /* *INDENT-OFF* */
-    pool_foreach (sa, tkm->sas, ({
+    pool_foreach (sa, tkm->sas)  {
       fchild = ikev2_sa_get_child(sa, ipsec_sa->spi, IKEV2_PROTOCOL_ESP, 1);
       if (fchild)
         {
           fsa = sa;
           break;
         }
-    }));
+    }
     /* *INDENT-ON* */
   }
   vlib_get_combined_counter (&ipsec_sa_counters,
@@ -5029,7 +5048,7 @@ ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
        u32 *to_be_deleted = 0;
 
         /* *INDENT-OFF* */
-        pool_foreach (sa, tkm->sas, ({
+        pool_foreach (sa, tkm->sas)  {
           ikev2_child_sa_t *c;
           u8 del_old_ids = 0;
 
@@ -5049,7 +5068,7 @@ ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
 
           if (!km->dpd_disabled && ikev2_mngr_process_responder_sas (sa))
             vec_add1 (to_be_deleted, sa - tkm->sas);
-        }));
+        }
         /* *INDENT-ON* */
 
        vec_foreach (sai, to_be_deleted)
@@ -5085,9 +5104,9 @@ ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
       /* process ipsec sas */
       ipsec_sa_t *sa;
       /* *INDENT-OFF* */
-      pool_foreach (sa, im->sad, ({
+      pool_foreach (sa, im->sad)  {
         ikev2_mngr_process_ipsec_sa(sa);
-      }));
+      }
       /* *INDENT-ON* */
 
       ikev2_process_pending_sa_init (km);