ikev2: cleanup tunnels after subsequent sa-init
[vpp.git] / src / plugins / ikev2 / ikev2.c
index 4bbe554..a647784 100644 (file)
@@ -832,9 +832,6 @@ ikev2_initial_contact_cleanup (ikev2_sa_t * sa)
 
   vec_free (delete);
   sa->initial_contact = 0;
-
-  km->log_level = IKEV2_LOG_ERROR;
-  km->log_class = vlib_log_register_class ("ikev2", 0);
 }
 
 static void
@@ -1409,6 +1406,12 @@ ikev2_sa_auth (ikev2_sa_t * sa)
          sa->childs[0].r_proposals =
            ikev2_select_proposal (sa->childs[0].i_proposals,
                                   IKEV2_PROTOCOL_ESP);
+
+         if (~0 != sel_p->tun_itf)
+           {
+             sa->is_tun_itf_set = 1;
+             sa->tun_itf = sel_p->tun_itf;
+           }
        }
     }
   else
@@ -1519,7 +1522,10 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
       hash_set1 (km->sw_if_indices, sw_if_index);
     }
   else
-    sw_if_index = a->sw_if_index;
+    {
+      sw_if_index = a->sw_if_index;
+      vnet_sw_interface_admin_up (vnet_get_main (), sw_if_index);
+    }
 
   if (rv)
     {
@@ -1544,7 +1550,7 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
 
   u32 *sas_in = NULL;
   vec_add1 (sas_in, a->remote_sa_id);
-  rv |= ipsec_tun_protect_update (sw_if_index, a->local_sa_id, sas_in);
+  rv |= ipsec_tun_protect_update (sw_if_index, NULL, a->local_sa_id, sas_in);
 }
 
 static int
@@ -1791,10 +1797,13 @@ ikev2_del_tunnel_from_main (ikev2_del_ipsec_tunnel_args_t * a)
        sw_if_index = ~0;
     }
   else
-    sw_if_index = a->sw_if_index;
+    {
+      sw_if_index = a->sw_if_index;
+      vnet_sw_interface_admin_down (vnet_get_main (), sw_if_index);
+    }
 
   if (~0 != sw_if_index)
-    ipsec_tun_protect_del (sw_if_index);
+    ipsec_tun_protect_del (sw_if_index, NULL);
 
   ipsec_sa_unlock_id (a->remote_sa_id);
   ipsec_sa_unlock_id (a->local_sa_id);
@@ -1942,6 +1951,8 @@ ikev2_generate_message (ikev2_sa_t * sa, ike_header_t * ike, void *user)
          ikev2_payload_add_sa (chain, sa->childs[0].i_proposals);
          ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
          ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
+         ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_INITIAL_CONTACT,
+                                   0);
        }
       else
        {
@@ -2872,6 +2883,7 @@ ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add)
       clib_memset (p, 0, sizeof (*p));
       p->name = vec_dup (name);
       p->responder.sw_if_index = ~0;
+      p->tun_itf = ~0;
       uword index = p - km->profiles;
       mhash_set_mem (&km->profile_index_by_name, name, &index, 0);
     }
@@ -3174,6 +3186,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
     sa.state = IKEV2_STATE_SA_INIT;
     sa.tun_itf = p->tun_itf;
     sa.is_tun_itf_set = 1;
+    sa.initial_contact = 1;
     ikev2_generate_sa_init_data (&sa);
     ikev2_payload_add_ke (chain, sa.dh_group, sa.i_dh_data);
     ikev2_payload_add_nonce (chain, sa.i_nonce);
@@ -3253,6 +3266,8 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
     vec_add (sa.childs[0].tsi, &p->loc_ts, 1);
     vec_add (sa.childs[0].tsr, &p->rem_ts, 1);
 
+    ikev2_initial_contact_cleanup (&sa);
+
     /* add SA to the pool */
     ikev2_sa_t *sa0 = 0;
     pool_get (km->sais, sa0);
@@ -3518,6 +3533,8 @@ ikev2_init (vlib_main_t * vm)
 
   ikev2_cli_reference ();
 
+  km->log_level = IKEV2_LOG_ERROR;
+  km->log_class = vlib_log_register_class ("ikev2", 0);
   return 0;
 }