LCOV - code coverage report
Current view: top level - plugins/ikev2 - ikev2.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 2097 2744 76.4 %
Date: 2023-07-05 22:20:52 Functions: 122 131 93.1 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vlib/vlib.h>
      17             : #include <vlib/unix/plugin.h>
      18             : #include <vlibmemory/api.h>
      19             : #include <vpp/app/version.h>
      20             : #include <vnet/vnet.h>
      21             : #include <vppinfra/error.h>
      22             : #include <vppinfra/random.h>
      23             : #include <vnet/udp/udp.h>
      24             : #include <vnet/ipsec/ipsec.h>
      25             : #include <vnet/ipsec/ipsec_tun.h>
      26             : #include <vnet/ipip/ipip.h>
      27             : #include <plugins/ikev2/ikev2.h>
      28             : #include <plugins/ikev2/ikev2_priv.h>
      29             : #include <plugins/dns/dns.h>
      30             : #include <openssl/sha.h>
      31             : #include <vnet/ipsec/ipsec_punt.h>
      32             : #include <plugins/ikev2/ikev2.api_enum.h>
      33             : 
      34             : #define IKEV2_LIVENESS_RETRIES 3
      35             : #define IKEV2_LIVENESS_PERIOD_CHECK 30
      36             : 
      37             : ikev2_main_t ikev2_main;
      38             : 
      39             : static int ikev2_delete_tunnel_interface (vnet_main_t * vnm,
      40             :                                           ikev2_sa_t * sa,
      41             :                                           ikev2_child_sa_t * child);
      42             : 
      43             : #define ikev2_set_state(sa, v, ...) do { \
      44             :     (sa)->state = v; \
      45             :     ikev2_elog_sa_state("ispi %lx SA state changed to " #v __VA_ARGS__, sa->ispi); \
      46             :   } while(0);
      47             : 
      48             : typedef struct
      49             : {
      50             :   u32 next_index;
      51             :   u32 sw_if_index;
      52             : } ikev2_trace_t;
      53             : 
      54             : static u8 *
      55         120 : format_ikev2_trace (u8 * s, va_list * args)
      56             : {
      57         120 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      58         120 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      59         120 :   ikev2_trace_t *t = va_arg (*args, ikev2_trace_t *);
      60             : 
      61         120 :   s = format (s, "ikev2: sw_if_index %d, next index %d",
      62             :               t->sw_if_index, t->next_index);
      63         120 :   return s;
      64             : }
      65             : 
      66             : #define IKEV2_GENERATE_SA_INIT_OK_str ""
      67             : #define IKEV2_GENERATE_SA_INIT_OK_ERR_NO_DH_STR \
      68             :   "no DH group configured for IKE proposals!"
      69             : #define IKEV2_GENERATE_SA_INIT_OK_ERR_UNSUPP_STR \
      70             :   "DH group not supported!"
      71             : 
      72             : typedef enum
      73             : {
      74             :   IKEV2_GENERATE_SA_INIT_OK,
      75             :   IKEV2_GENERATE_SA_INIT_ERR_NO_DH,
      76             :   IKEV2_GENERATE_SA_INIT_ERR_UNSUPPORTED_DH,
      77             : } ikev2_generate_sa_error_t;
      78             : 
      79             : static u8 *
      80           0 : format_ikev2_gen_sa_error (u8 * s, va_list * args)
      81             : {
      82           0 :   ikev2_generate_sa_error_t e = va_arg (*args, ikev2_generate_sa_error_t);
      83           0 :   switch (e)
      84             :     {
      85           0 :     case IKEV2_GENERATE_SA_INIT_OK:
      86           0 :       break;
      87           0 :     case IKEV2_GENERATE_SA_INIT_ERR_NO_DH:
      88           0 :       s = format (s, IKEV2_GENERATE_SA_INIT_OK_ERR_NO_DH_STR);
      89           0 :       break;
      90           0 :     case IKEV2_GENERATE_SA_INIT_ERR_UNSUPPORTED_DH:
      91           0 :       s = format (s, IKEV2_GENERATE_SA_INIT_OK_ERR_UNSUPP_STR);
      92           0 :       break;
      93             :     }
      94           0 :   return s;
      95             : }
      96             : 
      97             : typedef enum
      98             : {
      99             :   IKEV2_NEXT_IP4_LOOKUP,
     100             :   IKEV2_NEXT_IP4_ERROR_DROP,
     101             :   IKEV2_IP4_N_NEXT,
     102             : } ikev2_ip4_next_t;
     103             : 
     104             : typedef enum
     105             : {
     106             :   IKEV2_NEXT_IP6_LOOKUP,
     107             :   IKEV2_NEXT_IP6_ERROR_DROP,
     108             :   IKEV2_IP6_N_NEXT,
     109             : } ikev2_ip6_next_t;
     110             : 
     111             : typedef u32 ikev2_non_esp_marker;
     112             : 
     113             : static u16
     114          20 : ikev2_get_port (ikev2_sa_t *sa)
     115             : {
     116          20 :   return ikev2_natt_active (sa) ? IKEV2_PORT_NATT : IKEV2_PORT;
     117             : }
     118             : 
     119             : static int
     120           2 : ikev2_insert_non_esp_marker (ike_header_t *ike, int len)
     121             : {
     122           2 :   memmove ((u8 *) ike + sizeof (ikev2_non_esp_marker), ike, len);
     123           2 :   clib_memset (ike, 0, sizeof (ikev2_non_esp_marker));
     124           2 :   return len + sizeof (ikev2_non_esp_marker);
     125             : }
     126             : 
     127             : static ikev2_sa_transform_t *
     128         886 : ikev2_find_transform_data (ikev2_sa_transform_t * t)
     129             : {
     130         886 :   ikev2_main_t *km = &ikev2_main;
     131             :   ikev2_sa_transform_t *td;
     132             : 
     133       10757 :   vec_foreach (td, km->supported_transforms)
     134             :   {
     135       10707 :     if (td->type != t->type)
     136        7918 :       continue;
     137             : 
     138        2789 :     if (td->transform_id != t->transform_id)
     139        1931 :       continue;
     140             : 
     141         858 :     if (td->type == IKEV2_TRANSFORM_TYPE_ENCR)
     142             :       {
     143         314 :         if (vec_len (t->attrs) != 4 || t->attrs[0] != 0x80
     144         314 :             || t->attrs[1] != 14)
     145           0 :           continue;
     146             : 
     147         314 :         if (((t->attrs[2] << 8 | t->attrs[3]) / 8) != td->key_len)
     148          22 :           continue;
     149             :       }
     150         836 :     return td;
     151             :   }
     152          50 :   return 0;
     153             : }
     154             : 
     155             : static ikev2_sa_proposal_t *
     156          34 : ikev2_select_proposal (ikev2_sa_proposal_t * proposals,
     157             :                        ikev2_protocol_id_t prot_id)
     158             : {
     159          34 :   ikev2_sa_proposal_t *rv = 0;
     160             :   ikev2_sa_proposal_t *proposal;
     161             :   ikev2_sa_transform_t *transform, *new_t;
     162             :   u8 mandatory_bitmap, optional_bitmap;
     163             : 
     164          34 :   if (prot_id == IKEV2_PROTOCOL_IKE)
     165             :     {
     166          13 :       mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) |
     167             :         (1 << IKEV2_TRANSFORM_TYPE_PRF) | (1 << IKEV2_TRANSFORM_TYPE_DH);
     168          13 :       optional_bitmap = mandatory_bitmap | (1 << IKEV2_TRANSFORM_TYPE_INTEG);
     169             :     }
     170          21 :   else if (prot_id == IKEV2_PROTOCOL_ESP)
     171             :     {
     172          21 :       mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) |
     173             :         (1 << IKEV2_TRANSFORM_TYPE_ESN);
     174          21 :       optional_bitmap = mandatory_bitmap |
     175             :         (1 << IKEV2_TRANSFORM_TYPE_INTEG) | (1 << IKEV2_TRANSFORM_TYPE_DH);
     176             :     }
     177           0 :   else if (prot_id == IKEV2_PROTOCOL_AH)
     178             :     {
     179           0 :       mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_INTEG) |
     180             :         (1 << IKEV2_TRANSFORM_TYPE_ESN);
     181           0 :       optional_bitmap = mandatory_bitmap | (1 << IKEV2_TRANSFORM_TYPE_DH);
     182             :     }
     183             :   else
     184           0 :     return 0;
     185             : 
     186          34 :   vec_add2 (rv, proposal, 1);
     187             : 
     188          34 :   vec_foreach (proposal, proposals)
     189             :   {
     190          34 :     u8 bitmap = 0;
     191          34 :     if (proposal->protocol_id != prot_id)
     192           0 :       continue;
     193             : 
     194         173 :     vec_foreach (transform, proposal->transforms)
     195             :     {
     196         139 :       if ((1 << transform->type) & bitmap)
     197          21 :         continue;
     198             : 
     199         118 :       if (ikev2_find_transform_data (transform))
     200             :         {
     201         116 :           bitmap |= 1 << transform->type;
     202         116 :           vec_add2 (rv->transforms, new_t, 1);
     203         116 :           clib_memcpy_fast (new_t, transform, sizeof (*new_t));
     204         116 :           new_t->attrs = vec_dup (transform->attrs);
     205             :         }
     206             :     }
     207             : 
     208          34 :     if ((bitmap & mandatory_bitmap) == mandatory_bitmap &&
     209          34 :         (bitmap & ~optional_bitmap) == 0)
     210             :       {
     211          34 :         rv->proposal_num = proposal->proposal_num;
     212          34 :         rv->protocol_id = proposal->protocol_id;
     213          34 :         RAND_bytes ((u8 *) & rv->spi, sizeof (rv->spi));
     214          34 :         goto done;
     215             :       }
     216             :     else
     217             :       {
     218           0 :         vec_free (rv->transforms);
     219             :       }
     220             :   }
     221             : 
     222           0 :   vec_free (rv);
     223          34 : done:
     224          34 :   return rv;
     225             : }
     226             : 
     227             : ikev2_sa_transform_t *
     228         777 : ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p,
     229             :                           ikev2_transform_type_t type)
     230             : {
     231             :   ikev2_sa_transform_t *t;
     232             : 
     233         777 :   if (!p)
     234           0 :     return 0;
     235             : 
     236        1612 :   vec_foreach (t, p->transforms)
     237             :   {
     238        1603 :     if (t->type == type)
     239         768 :       return ikev2_find_transform_data (t);
     240             :   }
     241           9 :   return 0;
     242             : }
     243             : 
     244             : ikev2_child_sa_t *
     245          52 : ikev2_sa_get_child (ikev2_sa_t * sa, u32 spi, ikev2_protocol_id_t prot_id,
     246             :                     int by_initiator)
     247             : {
     248             :   ikev2_child_sa_t *c;
     249          75 :   vec_foreach (c, sa->childs)
     250             :   {
     251          52 :     ikev2_sa_proposal_t *proposal =
     252          52 :       by_initiator ? &c->i_proposals[0] : &c->r_proposals[0];
     253          52 :     if (proposal && proposal->spi == spi && proposal->protocol_id == prot_id)
     254          29 :       return c;
     255             :   }
     256             : 
     257          23 :   return 0;
     258             : }
     259             : 
     260             : void
     261         712 : ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v)
     262             : {
     263             :   ikev2_sa_proposal_t *p;
     264             :   ikev2_sa_transform_t *t;
     265             : 
     266         712 :   if (!*v)
     267         616 :     return;
     268             : 
     269         192 :   vec_foreach (p, *v)
     270             :   {
     271         445 :     vec_foreach (t, p->transforms)
     272             :     {
     273         349 :       vec_free (t->attrs);
     274             :     }
     275          96 :     vec_free (p->transforms);
     276             :   }
     277          96 :   vec_free (*v);
     278             : }
     279             : 
     280             : static void
     281          27 : ikev2_sa_free_child_sa (ikev2_child_sa_t * c)
     282             : {
     283          27 :   ikev2_sa_free_proposal_vector (&c->r_proposals);
     284          27 :   ikev2_sa_free_proposal_vector (&c->i_proposals);
     285          27 :   vec_free (c->sk_ai);
     286          27 :   vec_free (c->sk_ar);
     287          27 :   vec_free (c->sk_ei);
     288          27 :   vec_free (c->sk_er);
     289          27 :   vec_free (c->tsi);
     290          27 :   vec_free (c->tsr);
     291          27 : }
     292             : 
     293             : static void
     294         311 : ikev2_sa_free_all_child_sa (ikev2_child_sa_t ** childs)
     295             : {
     296             :   ikev2_child_sa_t *c;
     297         337 :   vec_foreach (c, *childs) ikev2_sa_free_child_sa (c);
     298             : 
     299         311 :   vec_free (*childs);
     300         311 : }
     301             : 
     302             : static void
     303           1 : ikev2_sa_del_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * child)
     304             : {
     305           1 :   ikev2_sa_free_child_sa (child);
     306           1 :   vec_del1 (sa->childs, child - sa->childs);
     307           1 : }
     308             : 
     309             : static void
     310         290 : ikev2_sa_free_all_vec (ikev2_sa_t * sa)
     311             : {
     312         290 :   vec_free (sa->i_nonce);
     313         290 :   vec_free (sa->r_nonce);
     314             : 
     315         290 :   vec_free (sa->dh_shared_key);
     316         290 :   vec_free (sa->dh_private_key);
     317         290 :   vec_free (sa->i_dh_data);
     318         290 :   vec_free (sa->r_dh_data);
     319             : 
     320         290 :   ikev2_sa_free_proposal_vector (&sa->r_proposals);
     321         290 :   ikev2_sa_free_proposal_vector (&sa->i_proposals);
     322             : 
     323         290 :   vec_free (sa->sk_d);
     324         290 :   vec_free (sa->sk_ai);
     325         290 :   vec_free (sa->sk_ar);
     326         290 :   vec_free (sa->sk_ei);
     327         290 :   vec_free (sa->sk_er);
     328         290 :   vec_free (sa->sk_pi);
     329         290 :   vec_free (sa->sk_pr);
     330             : 
     331         290 :   vec_free (sa->i_id.data);
     332         290 :   vec_free (sa->r_id.data);
     333             : 
     334         290 :   vec_free (sa->i_auth.data);
     335         290 :   if (sa->i_auth.key)
     336           0 :     EVP_PKEY_free (sa->i_auth.key);
     337         290 :   vec_free (sa->r_auth.data);
     338         290 :   if (sa->r_auth.key)
     339           0 :     EVP_PKEY_free (sa->r_auth.key);
     340             : 
     341         290 :   vec_free (sa->del);
     342             : 
     343         290 :   vec_free (sa->rekey);
     344             : 
     345         290 :   vec_free (sa->last_sa_init_req_packet_data);
     346         290 :   vec_free (sa->last_sa_init_res_packet_data);
     347             : 
     348         290 :   vec_free (sa->last_res_packet_data);
     349             : 
     350         290 :   ikev2_sa_free_all_child_sa (&sa->childs);
     351         290 : }
     352             : 
     353             : static void
     354          12 : ikev2_delete_sa (ikev2_main_per_thread_data_t * ptd, ikev2_sa_t * sa)
     355             : {
     356             :   uword *p;
     357             : 
     358          12 :   ikev2_sa_free_all_vec (sa);
     359             : 
     360          12 :   p = hash_get (ptd->sa_by_rspi, sa->rspi);
     361          12 :   if (p)
     362             :     {
     363          12 :       hash_unset (ptd->sa_by_rspi, sa->rspi);
     364          12 :       pool_put (ptd->sas, sa);
     365             :     }
     366          12 : }
     367             : 
     368             : static ikev2_generate_sa_error_t
     369          19 : ikev2_generate_sa_init_data (ikev2_sa_t * sa)
     370             : {
     371          19 :   ikev2_sa_transform_t *t = 0, *t2;
     372          19 :   ikev2_main_t *km = &ikev2_main;
     373             : 
     374          19 :   if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
     375           0 :     return IKEV2_GENERATE_SA_INIT_ERR_NO_DH;
     376             : 
     377             :   /* check if received DH group is on our list of supported groups */
     378         506 :   vec_foreach (t2, km->supported_transforms)
     379             :   {
     380         506 :     if (t2->type == IKEV2_TRANSFORM_TYPE_DH && sa->dh_group == t2->dh_type)
     381             :       {
     382          19 :         t = t2;
     383          19 :         break;
     384             :       }
     385             :   }
     386             : 
     387          19 :   if (!t)
     388             :     {
     389           0 :       sa->dh_group = IKEV2_TRANSFORM_DH_TYPE_NONE;
     390           0 :       return IKEV2_GENERATE_SA_INIT_ERR_UNSUPPORTED_DH;
     391             :     }
     392             : 
     393          19 :   if (sa->is_initiator)
     394             :     {
     395             :       /* generate rspi */
     396           6 :       RAND_bytes ((u8 *) & sa->ispi, 8);
     397             : 
     398             :       /* generate nonce */
     399           6 :       sa->i_nonce = vec_new (u8, IKEV2_NONCE_SIZE);
     400           6 :       RAND_bytes ((u8 *) sa->i_nonce, IKEV2_NONCE_SIZE);
     401             :     }
     402             :   else
     403             :     {
     404             :       /* generate rspi */
     405          13 :       RAND_bytes ((u8 *) & sa->rspi, 8);
     406             : 
     407             :       /* generate nonce */
     408          13 :       sa->r_nonce = vec_new (u8, vec_len (sa->i_nonce));
     409          13 :       RAND_bytes ((u8 *) sa->r_nonce, vec_len (sa->i_nonce));
     410             :     }
     411             : 
     412             :   /* generate dh keys */
     413          19 :   ikev2_generate_dh (sa, t);
     414             : 
     415          19 :   return IKEV2_GENERATE_SA_INIT_OK;
     416             : }
     417             : 
     418             : static void
     419           6 : ikev2_complete_sa_data (ikev2_sa_t * sa, ikev2_sa_t * sai)
     420             : {
     421           6 :   ikev2_sa_transform_t *t = 0, *t2;
     422           6 :   ikev2_main_t *km = &ikev2_main;
     423             : 
     424             :   /*move some data to the new SA */
     425             : #define _(A) ({void* __tmp__ = (A); (A) = 0; __tmp__;})
     426           6 :   sa->i_nonce = _(sai->i_nonce);
     427           6 :   sa->i_dh_data = _(sai->i_dh_data);
     428           6 :   sa->dh_private_key = _(sai->dh_private_key);
     429           6 :   ip_address_copy (&sa->iaddr, &sai->iaddr);
     430           6 :   ip_address_copy (&sa->raddr, &sai->raddr);
     431           6 :   sa->is_initiator = sai->is_initiator;
     432           6 :   sa->i_id.type = sai->i_id.type;
     433           6 :   sa->r_id.type = sai->r_id.type;
     434           6 :   sa->profile_index = sai->profile_index;
     435           6 :   sa->tun_itf = sai->tun_itf;
     436           6 :   sa->is_tun_itf_set = sai->is_tun_itf_set;
     437           6 :   if (sai->natt_state == IKEV2_NATT_DISABLED)
     438           0 :     sa->natt_state = IKEV2_NATT_DISABLED;
     439           6 :   sa->i_id.data = _(sai->i_id.data);
     440           6 :   sa->r_id.data = _(sai->r_id.data);
     441           6 :   sa->i_auth.method = sai->i_auth.method;
     442           6 :   sa->i_auth.hex = sai->i_auth.hex;
     443           6 :   sa->i_auth.data = _(sai->i_auth.data);
     444           6 :   sa->i_auth.key = _(sai->i_auth.key);
     445           6 :   sa->last_sa_init_req_packet_data = _(sai->last_sa_init_req_packet_data);
     446           6 :   sa->last_init_msg_id = sai->last_init_msg_id;
     447           6 :   sa->childs = _(sai->childs);
     448           6 :   sa->udp_encap = sai->udp_encap;
     449           6 :   sa->ipsec_over_udp_port = sai->ipsec_over_udp_port;
     450           6 :   sa->dst_port = sai->dst_port;
     451           6 :   sa->sw_if_index = sai->sw_if_index;
     452             : #undef _
     453             : 
     454             : 
     455           6 :   if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
     456             :     {
     457           0 :       return;
     458             :     }
     459             : 
     460             :   /* check if received DH group is on our list of supported groups */
     461         156 :   vec_foreach (t2, km->supported_transforms)
     462             :   {
     463         156 :     if (t2->type == IKEV2_TRANSFORM_TYPE_DH && sa->dh_group == t2->dh_type)
     464             :       {
     465           6 :         t = t2;
     466           6 :         break;
     467             :       }
     468             :   }
     469             : 
     470           6 :   if (!t)
     471             :     {
     472           0 :       sa->dh_group = IKEV2_TRANSFORM_DH_TYPE_NONE;
     473           0 :       return;
     474             :     }
     475             : 
     476             : 
     477             :   /* generate dh keys */
     478           6 :   ikev2_complete_dh (sa, t);
     479             : 
     480             : }
     481             : 
     482             : static void
     483          25 : ikev2_calc_keys (ikev2_sa_t * sa)
     484             : {
     485             :   u8 *tmp;
     486             :   /* calculate SKEYSEED = prf(Ni | Nr, g^ir) */
     487          25 :   u8 *skeyseed = 0;
     488          25 :   u8 *s = 0;
     489          25 :   u16 integ_key_len = 0, salt_len = 0;
     490             :   ikev2_sa_transform_t *tr_encr, *tr_prf, *tr_integ;
     491             :   tr_encr =
     492          25 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
     493             :   tr_prf =
     494          25 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
     495             :   tr_integ =
     496          25 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
     497             : 
     498          25 :   if (tr_integ)
     499          12 :     integ_key_len = tr_integ->key_len;
     500             :   else
     501          13 :     salt_len = sizeof (u32);
     502             : 
     503          25 :   vec_append (s, sa->i_nonce);
     504          25 :   vec_append (s, sa->r_nonce);
     505          25 :   skeyseed = ikev2_calc_prf (tr_prf, s, sa->dh_shared_key);
     506             : 
     507             :   /* Calculate S = Ni | Nr | SPIi | SPIr */
     508             :   u64 *spi;
     509          25 :   vec_add2 (s, tmp, 2 * sizeof (*spi));
     510          25 :   spi = (u64 *) tmp;
     511          25 :   spi[0] = clib_host_to_net_u64 (sa->ispi);
     512          25 :   spi[1] = clib_host_to_net_u64 (sa->rspi);
     513             : 
     514             :   /* calculate PRFplus */
     515             :   u8 *keymat;
     516          25 :   int len = tr_prf->key_trunc +      /* SK_d */
     517          25 :     integ_key_len * 2 +         /* SK_ai, SK_ar */
     518          25 :     tr_encr->key_len * 2 +   /* SK_ei, SK_er */
     519          25 :     tr_prf->key_len * 2 +    /* SK_pi, SK_pr */
     520          25 :     salt_len * 2;
     521             : 
     522          25 :   keymat = ikev2_calc_prfplus (tr_prf, skeyseed, s, len);
     523          25 :   vec_free (skeyseed);
     524          25 :   vec_free (s);
     525             : 
     526          25 :   int pos = 0;
     527             : 
     528             :   /* SK_d */
     529          25 :   sa->sk_d = vec_new (u8, tr_prf->key_trunc);
     530          25 :   clib_memcpy_fast (sa->sk_d, keymat + pos, tr_prf->key_trunc);
     531          25 :   pos += tr_prf->key_trunc;
     532             : 
     533          25 :   if (integ_key_len)
     534             :     {
     535             :       /* SK_ai */
     536          12 :       sa->sk_ai = vec_new (u8, integ_key_len);
     537          12 :       clib_memcpy_fast (sa->sk_ai, keymat + pos, integ_key_len);
     538          12 :       pos += integ_key_len;
     539             : 
     540             :       /* SK_ar */
     541          12 :       sa->sk_ar = vec_new (u8, integ_key_len);
     542          12 :       clib_memcpy_fast (sa->sk_ar, keymat + pos, integ_key_len);
     543          12 :       pos += integ_key_len;
     544             :     }
     545             : 
     546             :   /* SK_ei */
     547          25 :   sa->sk_ei = vec_new (u8, tr_encr->key_len + salt_len);
     548          25 :   clib_memcpy_fast (sa->sk_ei, keymat + pos, tr_encr->key_len + salt_len);
     549          25 :   pos += tr_encr->key_len + salt_len;
     550             : 
     551             :   /* SK_er */
     552          25 :   sa->sk_er = vec_new (u8, tr_encr->key_len + salt_len);
     553          25 :   clib_memcpy_fast (sa->sk_er, keymat + pos, tr_encr->key_len + salt_len);
     554          25 :   pos += tr_encr->key_len + salt_len;
     555             : 
     556             :   /* SK_pi */
     557          25 :   sa->sk_pi = vec_new (u8, tr_prf->key_len);
     558          25 :   clib_memcpy_fast (sa->sk_pi, keymat + pos, tr_prf->key_len);
     559          25 :   pos += tr_prf->key_len;
     560             : 
     561             :   /* SK_pr */
     562          25 :   sa->sk_pr = vec_new (u8, tr_prf->key_len);
     563          25 :   clib_memcpy_fast (sa->sk_pr, keymat + pos, tr_prf->key_len);
     564          25 :   pos += tr_prf->key_len;
     565             : 
     566          25 :   vec_free (keymat);
     567          25 :   sa->keys_generated = 1;
     568          25 : }
     569             : 
     570             : static void
     571          27 : ikev2_calc_child_keys (ikev2_sa_t *sa, ikev2_child_sa_t *child, u8 kex)
     572             : {
     573          27 :   u8 *s = 0;
     574          27 :   u16 integ_key_len = 0;
     575          27 :   u8 salt_len = 0;
     576             : 
     577             :   ikev2_sa_transform_t *tr_prf, *ctr_encr, *ctr_integ;
     578             :   tr_prf =
     579          27 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
     580             :   ctr_encr =
     581          27 :     ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
     582             :   ctr_integ =
     583          27 :     ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
     584             : 
     585          27 :   if (ctr_integ)
     586          26 :     integ_key_len = ctr_integ->key_len;
     587             :   else
     588           1 :     salt_len = sizeof (u32);
     589             : 
     590          27 :   if (kex)
     591           3 :     vec_append (s, sa->dh_shared_key);
     592          27 :   vec_append (s, sa->i_nonce);
     593          27 :   vec_append (s, sa->r_nonce);
     594             :   /* calculate PRFplus */
     595             :   u8 *keymat;
     596          27 :   int len = ctr_encr->key_len * 2 + integ_key_len * 2 + salt_len * 2;
     597             : 
     598          27 :   keymat = ikev2_calc_prfplus (tr_prf, sa->sk_d, s, len);
     599             : 
     600          27 :   int pos = 0;
     601             : 
     602             :   /* SK_ei */
     603          27 :   child->sk_ei = vec_new (u8, ctr_encr->key_len);
     604          27 :   clib_memcpy_fast (child->sk_ei, keymat + pos, ctr_encr->key_len);
     605          27 :   pos += ctr_encr->key_len;
     606             : 
     607          27 :   if (ctr_integ)
     608             :     {
     609             :       /* SK_ai */
     610          26 :       child->sk_ai = vec_new (u8, ctr_integ->key_len);
     611          26 :       clib_memcpy_fast (child->sk_ai, keymat + pos, ctr_integ->key_len);
     612          26 :       pos += ctr_integ->key_len;
     613             :     }
     614             :   else
     615             :     {
     616           1 :       clib_memcpy (&child->salt_ei, keymat + pos, salt_len);
     617           1 :       pos += salt_len;
     618             :     }
     619             : 
     620             :   /* SK_er */
     621          27 :   child->sk_er = vec_new (u8, ctr_encr->key_len);
     622          27 :   clib_memcpy_fast (child->sk_er, keymat + pos, ctr_encr->key_len);
     623          27 :   pos += ctr_encr->key_len;
     624             : 
     625          27 :   if (ctr_integ)
     626             :     {
     627             :       /* SK_ar */
     628          26 :       child->sk_ar = vec_new (u8, integ_key_len);
     629          26 :       clib_memcpy_fast (child->sk_ar, keymat + pos, integ_key_len);
     630          26 :       pos += integ_key_len;
     631             :     }
     632             :   else
     633             :     {
     634           1 :       clib_memcpy (&child->salt_er, keymat + pos, salt_len);
     635           1 :       pos += salt_len;
     636             :     }
     637             : 
     638          27 :   ASSERT (pos == len);
     639             : 
     640          27 :   vec_free (keymat);
     641          27 : }
     642             : 
     643             : static u8 *
     644          74 : ikev2_compute_nat_sha1 (u64 ispi, u64 rspi, ip_address_t *ia, u16 port)
     645          74 : {
     646          74 :   const u32 max_buf_size =
     647             :     sizeof (ispi) + sizeof (rspi) + sizeof (ip6_address_t) + sizeof (u16);
     648          74 :   u8 buf[max_buf_size];
     649          74 :   u8 *res = vec_new (u8, 20);
     650             : 
     651          74 :   clib_memcpy_fast (&buf[0], &ispi, sizeof (ispi));
     652          74 :   clib_memcpy_fast (&buf[8], &rspi, sizeof (rspi));
     653          74 :   clib_memcpy_fast (&buf[8 + 8], ip_addr_bytes (ia), ip_address_size (ia));
     654          74 :   clib_memcpy_fast (&buf[8 + 8 + ip_address_size (ia)], &port, sizeof (port));
     655          74 :   SHA1 (buf, 2 * sizeof (ispi) + sizeof (port) + ip_address_size (ia), res);
     656          74 :   return res;
     657             : }
     658             : 
     659             : static int
     660          23 : ikev2_parse_ke_payload (const void *p, u32 rlen, ikev2_sa_t * sa,
     661             :                         u8 ** ke_data)
     662             : {
     663          23 :   const ike_ke_payload_header_t *ke = p;
     664          23 :   u16 plen = clib_net_to_host_u16 (ke->length);
     665          23 :   ASSERT (plen >= sizeof (*ke) && plen <= rlen);
     666          23 :   if (sizeof (*ke) > rlen)
     667             :     {
     668           0 :       ikev2_elog_error ("KE: packet too small");
     669           0 :       return 0;
     670             :     }
     671             : 
     672          23 :   sa->dh_group = clib_net_to_host_u16 (ke->dh_group);
     673          23 :   vec_reset_length (ke_data[0]);
     674          23 :   vec_add (ke_data[0], ke->payload, plen - sizeof (*ke));
     675          23 :   return 1;
     676             : }
     677             : 
     678             : static int
     679          30 : ikev2_parse_nonce_payload (const void *p, u32 rlen, const u8 **nonce)
     680             : {
     681          30 :   const ike_payload_header_t *ikep = p;
     682          30 :   u16 plen = clib_net_to_host_u16 (ikep->length);
     683          30 :   ASSERT (plen >= sizeof (*ikep) && plen <= rlen);
     684          30 :   int len = plen - sizeof (*ikep);
     685          30 :   ASSERT (len >= 16 && len <= 256);
     686          30 :   if (PREDICT_FALSE (len < 16 || len > 256))
     687             :     {
     688           0 :       ikev2_elog_error ("NONCE: bad size");
     689           0 :       return 0;
     690             :     }
     691          30 :   *nonce = ikep->payload;
     692          30 :   return len;
     693             : }
     694             : 
     695             : static int
     696         597 : ikev2_check_payload_length (const ike_payload_header_t * ikep, int rlen,
     697             :                             u16 * plen)
     698             : {
     699         597 :   if (sizeof (*ikep) > rlen)
     700             :     {
     701           0 :       ikev2_elog_error ("payload: packet too small");
     702           0 :       return 0;
     703             :     }
     704         597 :   *plen = clib_net_to_host_u16 (ikep->length);
     705         597 :   if (*plen < sizeof (*ikep) || *plen > rlen)
     706             :     {
     707         254 :       ikev2_elog_error ("payload: bad size");
     708         254 :       return 0;
     709             :     }
     710         343 :   return 1;
     711             : }
     712             : 
     713             : static int
     714         267 : ikev2_process_sa_init_req (vlib_main_t *vm, ikev2_sa_t *sa, ike_header_t *ike,
     715             :                            udp_header_t *udp, u32 len, u32 sw_if_index)
     716             : {
     717         267 :   int p = 0;
     718         267 :   u8 payload = ike->nextpayload;
     719             :   ike_payload_header_t *ikep;
     720             :   u16 plen;
     721             : 
     722         267 :   ikev2_elog_exchange ("ispi %lx rspi %lx IKE_INIT request received "
     723             :                        "from ", clib_net_to_host_u64 (ike->ispi),
     724             :                        clib_net_to_host_u64 (ike->rspi),
     725             :                        ip_addr_v4 (&sa->iaddr).as_u32,
     726             :                        ip_addr_version (&sa->iaddr) == AF_IP4);
     727             : 
     728         267 :   sa->ispi = clib_net_to_host_u64 (ike->ispi);
     729         267 :   sa->sw_if_index = sw_if_index;
     730             : 
     731             :   /* store whole IKE payload - needed for PSK auth */
     732         267 :   vec_reset_length (sa->last_sa_init_req_packet_data);
     733         267 :   vec_add (sa->last_sa_init_req_packet_data, ike, len);
     734             : 
     735         267 :   if (len < sizeof (*ike))
     736             :     {
     737           0 :       ikev2_elog_error ("IKE_INIT request too small");
     738           0 :       return 0;
     739             :     }
     740             : 
     741         267 :   len -= sizeof (*ike);
     742         330 :   while (p < len && payload != IKEV2_PAYLOAD_NONE)
     743             :     {
     744         317 :       ikep = (ike_payload_header_t *) & ike->payload[p];
     745         317 :       int current_length = len - p;
     746         317 :       if (!ikev2_check_payload_length (ikep, current_length, &plen))
     747         254 :         return 0;
     748             : 
     749          63 :       if (payload == IKEV2_PAYLOAD_SA)
     750             :         {
     751          13 :           ikev2_sa_free_proposal_vector (&sa->i_proposals);
     752          13 :           sa->i_proposals = ikev2_parse_sa_payload (ikep, current_length);
     753             :         }
     754          50 :       else if (payload == IKEV2_PAYLOAD_KE)
     755             :         {
     756          13 :           if (!ikev2_parse_ke_payload (ikep, current_length, sa,
     757             :                                        &sa->i_dh_data))
     758           0 :             return 0;
     759             :         }
     760          37 :       else if (payload == IKEV2_PAYLOAD_NONCE)
     761             :         {
     762             :           const u8 *nonce;
     763             :           int nonce_len;
     764          13 :           vec_reset_length (sa->i_nonce);
     765          13 :           if ((nonce_len = ikev2_parse_nonce_payload (ikep, current_length,
     766             :                                                       &nonce)) <= 0)
     767           0 :             return 0;
     768          13 :           vec_add (sa->i_nonce, nonce, nonce_len);
     769             :         }
     770          24 :       else if (payload == IKEV2_PAYLOAD_NOTIFY)
     771             :         {
     772          24 :           ikev2_notify_t *n =
     773          24 :             ikev2_parse_notify_payload (ikep, current_length);
     774          24 :           if (n->msg_type == IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP)
     775             :             {
     776          24 :               u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi, 0, &sa->iaddr,
     777          12 :                                                     udp->src_port);
     778          12 :               if (clib_memcmp (src_sha, n->data, vec_len (src_sha)))
     779             :                 {
     780           1 :                   if (sa->natt_state == IKEV2_NATT_ENABLED)
     781           1 :                     sa->natt_state = IKEV2_NATT_ACTIVE;
     782           1 :                   ikev2_elog_uint (IKEV2_LOG_DEBUG, "ispi %lx initiator"
     783             :                                    " behind NAT", sa->ispi);
     784             :                 }
     785          12 :               vec_free (src_sha);
     786             :             }
     787          12 :           else if (n->msg_type ==
     788             :                    IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP)
     789             :             {
     790          24 :               u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi, 0, &sa->raddr,
     791          12 :                                                     udp->dst_port);
     792          12 :               if (clib_memcmp (dst_sha, n->data, vec_len (dst_sha)))
     793             :                 {
     794           1 :                   if (sa->natt_state == IKEV2_NATT_ENABLED)
     795           1 :                     sa->natt_state = IKEV2_NATT_ACTIVE;
     796           1 :                   ikev2_elog_uint (IKEV2_LOG_DEBUG, "ispi %lx responder"
     797             :                                    " (self) behind NAT", sa->ispi);
     798             :                 }
     799          12 :               vec_free (dst_sha);
     800             :             }
     801          24 :           vec_free (n);
     802             :         }
     803           0 :       else if (payload == IKEV2_PAYLOAD_VENDOR)
     804             :         {
     805           0 :           ikev2_parse_vendor_payload (ikep);
     806             :         }
     807             :       else
     808             :         {
     809           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
     810             :                            payload);
     811           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
     812             :             {
     813           0 :               ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
     814           0 :               sa->unsupported_cp = payload;
     815           0 :               return 0;
     816             :             }
     817             :         }
     818             : 
     819          63 :       payload = ikep->nextpayload;
     820          63 :       p += plen;
     821             :     }
     822             : 
     823          13 :   ikev2_set_state (sa, IKEV2_STATE_SA_INIT);
     824          13 :   return 1;
     825             : }
     826             : 
     827             : static void
     828           6 : ikev2_process_sa_init_resp (vlib_main_t * vm,
     829             :                             ikev2_sa_t * sa, ike_header_t * ike,
     830             :                             udp_header_t * udp, u32 len)
     831             : {
     832           6 :   int p = 0;
     833           6 :   u8 payload = ike->nextpayload;
     834             :   ike_payload_header_t *ikep;
     835             :   u16 plen;
     836             : 
     837           6 :   sa->ispi = clib_net_to_host_u64 (ike->ispi);
     838           6 :   sa->rspi = clib_net_to_host_u64 (ike->rspi);
     839             : 
     840           6 :   ikev2_elog_exchange ("ispi %lx rspi %lx IKE_INIT response received "
     841             :                        "from ", sa->ispi, sa->rspi,
     842             :                        ip_addr_v4 (&sa->raddr).as_u32,
     843             :                        ip_addr_version (&sa->raddr) == AF_IP4);
     844             : 
     845             :   /* store whole IKE payload - needed for PSK auth */
     846           6 :   vec_reset_length (sa->last_sa_init_res_packet_data);
     847           6 :   vec_add (sa->last_sa_init_res_packet_data, ike, len);
     848             : 
     849           6 :   if (sizeof (*ike) > len)
     850             :     {
     851           0 :       ikev2_elog_error ("IKE_INIT response too small");
     852           0 :       return;
     853             :     }
     854             : 
     855           6 :   len -= sizeof (*ike);
     856          36 :   while (p < len && payload != IKEV2_PAYLOAD_NONE)
     857             :     {
     858          30 :       int current_length = len - p;
     859          30 :       ikep = (ike_payload_header_t *) & ike->payload[p];
     860          30 :       if (!ikev2_check_payload_length (ikep, current_length, &plen))
     861           0 :         return;
     862             : 
     863          30 :       if (payload == IKEV2_PAYLOAD_SA)
     864             :         {
     865           6 :           ikev2_sa_free_proposal_vector (&sa->r_proposals);
     866           6 :           sa->r_proposals = ikev2_parse_sa_payload (ikep, current_length);
     867           6 :           if (sa->r_proposals)
     868             :             {
     869           6 :               ikev2_set_state (sa, IKEV2_STATE_SA_INIT);
     870           6 :               ike->msgid =
     871           6 :                 clib_host_to_net_u32 (clib_net_to_host_u32 (ike->msgid) + 1);
     872             :             }
     873             :         }
     874          24 :       else if (payload == IKEV2_PAYLOAD_KE)
     875             :         {
     876           6 :           if (!ikev2_parse_ke_payload (ikep, current_length, sa,
     877             :                                        &sa->r_dh_data))
     878           0 :             return;
     879             :         }
     880          18 :       else if (payload == IKEV2_PAYLOAD_NONCE)
     881             :         {
     882             :           const u8 *nonce;
     883             :           int nonce_len;
     884           6 :           vec_reset_length (sa->r_nonce);
     885           6 :           if ((nonce_len = ikev2_parse_nonce_payload (ikep, current_length,
     886             :                                                       &nonce)) <= 0)
     887           0 :             return;
     888           6 :           vec_add (sa->r_nonce, nonce, nonce_len);
     889             :         }
     890          12 :       else if (payload == IKEV2_PAYLOAD_NOTIFY)
     891             :         {
     892          12 :           ikev2_notify_t *n =
     893          12 :             ikev2_parse_notify_payload (ikep, current_length);
     894          12 :           if (n->msg_type == IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP)
     895             :             {
     896          12 :               u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi, ike->rspi,
     897             :                                                     &sa->raddr,
     898           6 :                                                     udp->src_port);
     899           6 :               if (clib_memcmp (src_sha, n->data, vec_len (src_sha)))
     900             :                 {
     901           0 :                   ikev2_elog_uint (IKEV2_LOG_DEBUG, "ispi %lx responder"
     902             :                                    " behind NAT, unsupported", sa->ispi);
     903             :                 }
     904           6 :               vec_free (src_sha);
     905             :             }
     906           6 :           else if (n->msg_type ==
     907             :                    IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP)
     908             :             {
     909          12 :               u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi, ike->rspi,
     910             :                                                     &sa->iaddr,
     911           6 :                                                     udp->dst_port);
     912           6 :               if (clib_memcmp (dst_sha, n->data, vec_len (dst_sha)))
     913             :                 {
     914           1 :                   if (sa->natt_state == IKEV2_NATT_ENABLED)
     915           1 :                     sa->natt_state = IKEV2_NATT_ACTIVE;
     916           1 :                   ikev2_elog_uint (IKEV2_LOG_DEBUG, "ispi %lx initiator"
     917             :                                    " (self) behind NAT", sa->ispi);
     918             :                 }
     919           6 :               vec_free (dst_sha);
     920             :             }
     921          12 :           vec_free (n);
     922             :         }
     923           0 :       else if (payload == IKEV2_PAYLOAD_VENDOR)
     924             :         {
     925           0 :           ikev2_parse_vendor_payload (ikep);
     926             :         }
     927             :       else
     928             :         {
     929           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
     930             :                            payload);
     931           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
     932             :             {
     933           0 :               ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
     934           0 :               sa->unsupported_cp = payload;
     935           0 :               return;
     936             :             }
     937             :         }
     938             : 
     939          30 :       payload = ikep->nextpayload;
     940          30 :       p += plen;
     941             :     }
     942             : }
     943             : 
     944             : static u8 *
     945          43 : ikev2_decrypt_sk_payload (ikev2_sa_t * sa, ike_header_t * ike,
     946             :                           u8 * payload, u32 rlen, u32 * out_len)
     947             : {
     948          43 :   ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
     949          43 :   int p = 0;
     950          43 :   u8 last_payload = 0, *hmac = 0, *plaintext = 0;
     951          43 :   ike_payload_header_t *ikep = 0;
     952          43 :   u16 plen = 0;
     953          43 :   u32 dlen = 0;
     954             :   ikev2_sa_transform_t *tr_integ;
     955             :   ikev2_sa_transform_t *tr_encr;
     956             :   tr_integ =
     957          43 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
     958             :   tr_encr =
     959          43 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
     960          43 :   int is_aead = tr_encr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_GCM_16;
     961             : 
     962          43 :   if (((!sa->sk_ar || !sa->sk_ai) && !is_aead) || (!sa->sk_ei || !sa->sk_er))
     963           0 :     return 0;
     964             : 
     965          43 :   if (rlen <= sizeof (*ike))
     966           0 :     return 0;
     967             : 
     968          43 :   int len = rlen - sizeof (*ike);
     969          86 :   while (p < len &&
     970          43 :          *payload != IKEV2_PAYLOAD_NONE && last_payload != IKEV2_PAYLOAD_SK)
     971             :     {
     972          43 :       ikep = (ike_payload_header_t *) & ike->payload[p];
     973          43 :       int current_length = len - p;
     974          43 :       if (!ikev2_check_payload_length (ikep, current_length, &plen))
     975           0 :         return 0;
     976             : 
     977          43 :       if (*payload == IKEV2_PAYLOAD_SK)
     978             :         {
     979          43 :           last_payload = *payload;
     980             :         }
     981             :       else
     982             :         {
     983           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
     984             :                            *payload);
     985           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
     986             :             {
     987           0 :               sa->unsupported_cp = *payload;
     988           0 :               return 0;
     989             :             }
     990             :         }
     991             : 
     992          43 :       *payload = ikep->nextpayload;
     993          43 :       p += plen;
     994             :     }
     995             : 
     996          43 :   if (last_payload != IKEV2_PAYLOAD_SK)
     997             :     {
     998           0 :       ikev2_elog_error ("Last payload must be SK");
     999           0 :       return 0;
    1000             :     }
    1001             : 
    1002          43 :   if (is_aead)
    1003             :     {
    1004          12 :       if (plen < sizeof (*ikep) + IKEV2_GCM_ICV_SIZE)
    1005           0 :         return 0;
    1006             : 
    1007          12 :       plen -= sizeof (*ikep) + IKEV2_GCM_ICV_SIZE;
    1008          12 :       u8 *aad = (u8 *) ike;
    1009          12 :       u32 aad_len = ikep->payload - aad;
    1010          12 :       u8 *tag = ikep->payload + plen;
    1011             : 
    1012          12 :       int rc = ikev2_decrypt_aead_data (ptd, sa, tr_encr, ikep->payload,
    1013             :                                         plen, aad, aad_len, tag, &dlen);
    1014          12 :       if (rc)
    1015             :         {
    1016          12 :           *out_len = dlen;
    1017          12 :           plaintext = ikep->payload + IKEV2_GCM_IV_SIZE;
    1018             :         }
    1019             :     }
    1020             :   else
    1021             :     {
    1022          31 :       if (rlen < tr_integ->key_trunc)
    1023           0 :         return 0;
    1024             : 
    1025          31 :       hmac =
    1026          31 :         ikev2_calc_integr (tr_integ, sa->is_initiator ? sa->sk_ar : sa->sk_ai,
    1027          31 :                            (u8 *) ike, rlen - tr_integ->key_trunc);
    1028             : 
    1029          31 :       if (plen < sizeof (*ikep) + tr_integ->key_trunc)
    1030           0 :         return 0;
    1031             : 
    1032          31 :       plen = plen - sizeof (*ikep) - tr_integ->key_trunc;
    1033             : 
    1034          31 :       if (clib_memcmp (hmac, &ikep->payload[plen], tr_integ->key_trunc))
    1035             :         {
    1036           0 :           ikev2_elog_error ("message integrity check failed");
    1037           0 :           vec_free (hmac);
    1038           0 :           return 0;
    1039             :         }
    1040          31 :       vec_free (hmac);
    1041             : 
    1042          31 :       int rc = ikev2_decrypt_data (ptd, sa, tr_encr, ikep->payload, plen,
    1043             :                                    &dlen);
    1044          31 :       if (rc)
    1045             :         {
    1046          31 :           *out_len = dlen;
    1047          31 :           plaintext = ikep->payload + tr_encr->block_size;
    1048             :         }
    1049             :     }
    1050             : 
    1051          43 :   return plaintext;
    1052             : }
    1053             : 
    1054             : static int
    1055         111 : ikev2_is_id_equal (const ikev2_id_t *i1, const ikev2_id_t *i2)
    1056             : {
    1057         111 :   if (i1->type != i2->type)
    1058           0 :     return 0;
    1059             : 
    1060         111 :   if (vec_len (i1->data) != vec_len (i2->data))
    1061           0 :     return 0;
    1062             : 
    1063         111 :   if (clib_memcmp (i1->data, i2->data, vec_len (i1->data)))
    1064           0 :     return 0;
    1065             : 
    1066         111 :   return 1;
    1067             : }
    1068             : 
    1069             : static void
    1070          25 : ikev2_initial_contact_cleanup_internal (ikev2_main_per_thread_data_t * ptd,
    1071             :                                         ikev2_sa_t * sa)
    1072             : {
    1073          25 :   ikev2_main_t *km = &ikev2_main;
    1074             :   ikev2_sa_t *tmp;
    1075          25 :   u32 i, *delete = 0;
    1076             :   ikev2_child_sa_t *c;
    1077             : 
    1078             :   /* find old IKE SAs with the same authenticated identity */
    1079             :   /* *INDENT-OFF* */
    1080          44 :   pool_foreach (tmp, ptd->sas)  {
    1081          19 :     if (!ikev2_is_id_equal (&tmp->i_id, &sa->i_id)
    1082          19 :         || !ikev2_is_id_equal(&tmp->r_id, &sa->r_id))
    1083           0 :       continue;
    1084             : 
    1085          19 :     if (sa->rspi != tmp->rspi)
    1086           0 :       vec_add1(delete, tmp - ptd->sas);
    1087             :   }
    1088             :   /* *INDENT-ON* */
    1089             : 
    1090          25 :   for (i = 0; i < vec_len (delete); i++)
    1091             :     {
    1092           0 :       tmp = pool_elt_at_index (ptd->sas, delete[i]);
    1093           0 :       vec_foreach (c, tmp->childs)
    1094             :       {
    1095           0 :         ikev2_delete_tunnel_interface (km->vnet_main, tmp, c);
    1096             :       }
    1097           0 :       ikev2_delete_sa (ptd, tmp);
    1098             :     }
    1099             : 
    1100          25 :   vec_free (delete);
    1101          25 :   sa->initial_contact = 0;
    1102          25 : }
    1103             : 
    1104             : static void
    1105          25 : ikev2_initial_contact_cleanup (ikev2_main_per_thread_data_t * ptd,
    1106             :                                ikev2_sa_t * sa)
    1107             : {
    1108          25 :   ikev2_main_t *km = &ikev2_main;
    1109             : 
    1110          25 :   if (!sa->initial_contact)
    1111           0 :     return;
    1112             : 
    1113          25 :   if (ptd)
    1114             :     {
    1115          19 :       ikev2_initial_contact_cleanup_internal (ptd, sa);
    1116             :     }
    1117             :   else
    1118             :     {
    1119          12 :       vec_foreach (ptd, km->per_thread_data)
    1120           6 :         ikev2_initial_contact_cleanup_internal (ptd, sa);
    1121             :     }
    1122          25 :   sa->initial_contact = 0;
    1123             : }
    1124             : 
    1125             : static int
    1126          37 : ikev2_parse_id_payload (const void *p, u16 rlen, ikev2_id_t * sa_id)
    1127             : {
    1128          37 :   const ike_id_payload_header_t *id = p;
    1129          37 :   u16 plen = clib_net_to_host_u16 (id->length);
    1130          37 :   if (plen < sizeof (*id) || plen > rlen)
    1131           0 :     return 0;
    1132             : 
    1133          37 :   sa_id->type = id->id_type;
    1134          37 :   vec_reset_length (sa_id->data);
    1135          37 :   vec_add (sa_id->data, id->payload, plen - sizeof (*id));
    1136             : 
    1137          37 :   return 1;
    1138             : }
    1139             : 
    1140             : static int
    1141          19 : ikev2_parse_auth_payload (const void *p, u32 rlen, ikev2_auth_t * a)
    1142             : {
    1143          19 :   const ike_auth_payload_header_t *ah = p;
    1144          19 :   u16 plen = clib_net_to_host_u16 (ah->length);
    1145             : 
    1146          19 :   a->method = ah->auth_method;
    1147          19 :   vec_reset_length (a->data);
    1148          19 :   vec_add (a->data, ah->payload, plen - sizeof (*ah));
    1149          19 :   return 1;
    1150             : }
    1151             : 
    1152             : static int
    1153          19 : ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa,
    1154             :                         ike_header_t * ike, u32 len)
    1155             : {
    1156          19 :   int p = 0;
    1157             :   ikev2_child_sa_t *first_child_sa;
    1158          19 :   u8 payload = ike->nextpayload;
    1159          19 :   u8 *plaintext = 0;
    1160             :   ike_payload_header_t *ikep;
    1161             :   u16 plen;
    1162          19 :   u32 dlen = 0;
    1163             : 
    1164          19 :   ikev2_elog_exchange ("ispi %lx rspi %lx EXCHANGE_IKE_AUTH received "
    1165             :                        "from ", clib_host_to_net_u64 (ike->ispi),
    1166             :                        clib_host_to_net_u64 (ike->rspi),
    1167             :                        sa->is_initiator ?
    1168             :                        ip_addr_v4 (&sa->raddr).as_u32 :
    1169             :                        ip_addr_v4 (&sa->iaddr).as_u32,
    1170             :                        ip_addr_version (&sa->raddr) == AF_IP4);
    1171             : 
    1172          19 :   ikev2_calc_keys (sa);
    1173             : 
    1174          19 :   plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload, len, &dlen);
    1175             : 
    1176          19 :   if (!plaintext)
    1177             :     {
    1178           0 :       if (sa->unsupported_cp)
    1179             :         {
    1180           0 :           ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    1181           0 :           return 0;
    1182             :         }
    1183           0 :       goto malformed;
    1184             :     }
    1185             : 
    1186             :   /* select or create 1st child SA */
    1187          19 :   if (sa->is_initiator)
    1188             :     {
    1189           6 :       first_child_sa = &sa->childs[0];
    1190             :     }
    1191             :   else
    1192             :     {
    1193          13 :       ikev2_sa_free_all_child_sa (&sa->childs);
    1194          13 :       vec_add2 (sa->childs, first_child_sa, 1);
    1195             :     }
    1196             : 
    1197             : 
    1198             :   /* process encrypted payload */
    1199         151 :   while (p < dlen && payload != IKEV2_PAYLOAD_NONE)
    1200             :     {
    1201         132 :       ikep = (ike_payload_header_t *) & plaintext[p];
    1202         132 :       int current_length = dlen - p;
    1203         132 :       if (!ikev2_check_payload_length (ikep, current_length, &plen))
    1204           0 :         goto malformed;
    1205             : 
    1206         132 :       if (payload == IKEV2_PAYLOAD_SA)  /* 33 */
    1207             :         {
    1208          19 :           if (sa->is_initiator)
    1209             :             {
    1210           6 :               ikev2_sa_free_proposal_vector (&first_child_sa->r_proposals);
    1211           6 :               first_child_sa->r_proposals = ikev2_parse_sa_payload (ikep,
    1212             :                                                                     current_length);
    1213             :             }
    1214             :           else
    1215             :             {
    1216          13 :               ikev2_sa_free_proposal_vector (&first_child_sa->i_proposals);
    1217          13 :               first_child_sa->i_proposals = ikev2_parse_sa_payload (ikep,
    1218             :                                                                     current_length);
    1219             :             }
    1220             :         }
    1221         113 :       else if (payload == IKEV2_PAYLOAD_IDI)    /* 35 */
    1222             :         {
    1223          19 :           if (!ikev2_parse_id_payload (ikep, current_length, &sa->i_id))
    1224           0 :             goto malformed;
    1225             :         }
    1226          94 :       else if (payload == IKEV2_PAYLOAD_IDR)    /* 36 */
    1227             :         {
    1228          18 :           if (!ikev2_parse_id_payload (ikep, current_length, &sa->r_id))
    1229           0 :             goto malformed;
    1230             :         }
    1231          76 :       else if (payload == IKEV2_PAYLOAD_AUTH)   /* 39 */
    1232             :         {
    1233          19 :           if (sa->is_initiator)
    1234             :             {
    1235           6 :               if (!ikev2_parse_auth_payload (ikep, current_length,
    1236             :                                              &sa->r_auth))
    1237           0 :                 goto malformed;
    1238             :             }
    1239             :           else
    1240             :             {
    1241          13 :               if (!ikev2_parse_auth_payload (ikep, current_length,
    1242             :                                              &sa->i_auth))
    1243           0 :                 goto malformed;
    1244             :             }
    1245             :         }
    1246          57 :       else if (payload == IKEV2_PAYLOAD_NOTIFY) /* 41 */
    1247             :         {
    1248          19 :           ikev2_notify_t *n =
    1249          19 :             ikev2_parse_notify_payload (ikep, current_length);
    1250          19 :           if (n->msg_type == IKEV2_NOTIFY_MSG_INITIAL_CONTACT)
    1251             :             {
    1252          19 :               sa->initial_contact = 1;
    1253             :             }
    1254          19 :           vec_free (n);
    1255             :         }
    1256          38 :       else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */
    1257             :         {
    1258           0 :           ikev2_parse_vendor_payload (ikep);
    1259             :         }
    1260          38 :       else if (payload == IKEV2_PAYLOAD_TSI)    /* 44 */
    1261             :         {
    1262          19 :           vec_free (first_child_sa->tsi);
    1263          19 :           first_child_sa->tsi = ikev2_parse_ts_payload (ikep, current_length);
    1264             :         }
    1265          19 :       else if (payload == IKEV2_PAYLOAD_TSR)    /* 45 */
    1266             :         {
    1267          19 :           vec_free (first_child_sa->tsr);
    1268          19 :           first_child_sa->tsr = ikev2_parse_ts_payload (ikep, current_length);
    1269             :         }
    1270             :       else
    1271             :         {
    1272           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
    1273             :                            payload);
    1274             : 
    1275           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
    1276             :             {
    1277           0 :               ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    1278           0 :               sa->unsupported_cp = payload;
    1279           0 :               return 0;
    1280             :             }
    1281             :         }
    1282             : 
    1283         132 :       payload = ikep->nextpayload;
    1284         132 :       p += plen;
    1285             :     }
    1286             : 
    1287          19 :   return 1;
    1288             : 
    1289           0 : malformed:
    1290           0 :   ikev2_set_state (sa, IKEV2_STATE_DELETED, ": malformed IKE_AUTH");
    1291           0 :   return 0;
    1292             : }
    1293             : 
    1294             : static int
    1295          13 : ikev2_process_informational_req (vlib_main_t * vm,
    1296             :                                  ikev2_sa_t * sa, ike_header_t * ike, u32 len)
    1297             : {
    1298          13 :   int p = 0;
    1299          13 :   u8 payload = ike->nextpayload;
    1300          13 :   u8 *plaintext = 0;
    1301             :   ike_payload_header_t *ikep;
    1302          13 :   u32 dlen = 0;
    1303          13 :   ikev2_notify_t *n = 0;
    1304             : 
    1305          13 :   sa->liveness_retries = 0;
    1306          13 :   ikev2_elog_exchange ("ispi %lx rspi %lx INFORMATIONAL received "
    1307             :                        "from ", clib_host_to_net_u64 (ike->ispi),
    1308             :                        clib_host_to_net_u64 (ike->rspi),
    1309             :                        ip_addr_v4 (&sa->iaddr).as_u32,
    1310             :                        ip_addr_version (&sa->iaddr) == AF_IP4);
    1311             : 
    1312          13 :   plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload, len, &dlen);
    1313             : 
    1314          13 :   if (!plaintext)
    1315           0 :     return 0;
    1316             : 
    1317             :   /* process encrypted payload */
    1318          13 :   p = 0;
    1319          25 :   while (p < dlen && payload != IKEV2_PAYLOAD_NONE)
    1320             :     {
    1321          12 :       u32 current_length = dlen - p;
    1322          12 :       if (p + sizeof (*ikep) > dlen)
    1323           0 :         return 0;
    1324             : 
    1325          12 :       ikep = (ike_payload_header_t *) & plaintext[p];
    1326          12 :       u16 plen = clib_net_to_host_u16 (ikep->length);
    1327             : 
    1328          12 :       if (plen < sizeof (*ikep) || plen > current_length)
    1329           0 :         return 0;
    1330             : 
    1331          12 :       if (payload == IKEV2_PAYLOAD_NOTIFY)      /* 41 */
    1332             :         {
    1333           0 :           n = ikev2_parse_notify_payload (ikep, current_length);
    1334           0 :           if (!n)
    1335           0 :             return 0;
    1336           0 :           if (n->msg_type == IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED)
    1337           0 :             ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
    1338           0 :           vec_free (n);
    1339             :         }
    1340          12 :       else if (payload == IKEV2_PAYLOAD_DELETE) /* 42 */
    1341             :         {
    1342          12 :           sa->del = ikev2_parse_delete_payload (ikep, current_length);
    1343             :         }
    1344           0 :       else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */
    1345             :         {
    1346           0 :           ikev2_parse_vendor_payload (ikep);
    1347             :         }
    1348             :       else
    1349             :         {
    1350           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
    1351             :                            payload);
    1352           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
    1353             :             {
    1354           0 :               sa->unsupported_cp = payload;
    1355           0 :               return 0;
    1356             :             }
    1357             :         }
    1358          12 :       payload = ikep->nextpayload;
    1359          12 :       p += plen;
    1360             :     }
    1361          13 :   return 1;
    1362             : }
    1363             : 
    1364             : static int
    1365           6 : ikev2_process_create_child_sa_rekey (ikev2_sa_t *sa, ikev2_sa_t *sar,
    1366             :                                      ikev2_rekey_t *rekey,
    1367             :                                      ikev2_sa_proposal_t *proposal,
    1368             :                                      ikev2_ts_t *tsi, ikev2_ts_t *tsr,
    1369             :                                      const u8 *nonce, int nonce_len)
    1370             : {
    1371             :   ikev2_sa_transform_t *tr;
    1372             : 
    1373           6 :   rekey->i_proposal = proposal;
    1374           6 :   rekey->r_proposal = ikev2_select_proposal (proposal, IKEV2_PROTOCOL_ESP);
    1375             : 
    1376           6 :   if (sar->dh_group)
    1377             :     {
    1378             :       tr =
    1379           3 :         ikev2_sa_get_td_for_type (rekey->r_proposal, IKEV2_TRANSFORM_TYPE_DH);
    1380             : 
    1381           3 :       if (!tr || tr->dh_type != sar->dh_group)
    1382             :         {
    1383           0 :           rekey->notify_type = IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD;
    1384           0 :           ikev2_sa_free_proposal_vector (&rekey->r_proposal);
    1385           0 :           return 0;
    1386             :         }
    1387             : 
    1388           3 :       vec_free (sa->dh_shared_key);
    1389           3 :       vec_free (sa->dh_private_key);
    1390           3 :       vec_free (sa->i_dh_data);
    1391           3 :       vec_free (sa->r_dh_data);
    1392             : 
    1393           3 :       sa->dh_group = sar->dh_group;
    1394           3 :       sa->i_dh_data = sar->i_dh_data;
    1395           3 :       sar->i_dh_data = 0;
    1396             : 
    1397           3 :       ikev2_generate_dh (sa, tr);
    1398           3 :       rekey->kex = 1;
    1399             :     }
    1400             : 
    1401           6 :   vec_reset_length (sa->i_nonce);
    1402           6 :   vec_add (sa->i_nonce, nonce, nonce_len);
    1403             : 
    1404           6 :   vec_validate (sa->r_nonce, nonce_len - 1);
    1405           6 :   RAND_bytes ((u8 *) sa->r_nonce, nonce_len);
    1406             : 
    1407           6 :   rekey->tsi = tsi;
    1408           6 :   rekey->tsr = tsr;
    1409             : 
    1410           6 :   return 1;
    1411             : }
    1412             : 
    1413             : static int
    1414          11 : ikev2_process_create_child_sa_req (vlib_main_t * vm,
    1415             :                                    ikev2_sa_t * sa, ike_header_t * ike,
    1416             :                                    u32 len)
    1417             : {
    1418          11 :   int p = 0;
    1419          11 :   u8 payload = ike->nextpayload;
    1420          11 :   u8 *plaintext = 0;
    1421             :   ikev2_rekey_t *rekey;
    1422             :   ike_payload_header_t *ikep;
    1423          11 :   ikev2_notify_t *n = 0;
    1424          11 :   ikev2_ts_t *tsi = 0;
    1425          11 :   ikev2_ts_t *tsr = 0;
    1426          11 :   ikev2_sa_proposal_t *proposal = 0;
    1427             :   ikev2_child_sa_t *child_sa;
    1428          11 :   u32 dlen = 0, src;
    1429             :   u16 plen;
    1430          11 :   const u8 *nonce = 0;
    1431          11 :   int nonce_len = 0;
    1432             :   ikev2_sa_t sar;
    1433             : 
    1434          11 :   clib_memset (&sar, 0, sizeof (sar));
    1435             : 
    1436          11 :   if (sa->is_initiator)
    1437           3 :     src = ip_addr_v4 (&sa->raddr).as_u32;
    1438             :   else
    1439           8 :     src = ip_addr_v4 (&sa->iaddr).as_u32;
    1440             : 
    1441          11 :   ikev2_elog_exchange ("ispi %lx rspi %lx CREATE_CHILD_SA received from",
    1442             :                        clib_host_to_net_u64 (ike->ispi),
    1443             :                        clib_host_to_net_u64 (ike->rspi), src,
    1444             :                        ip_addr_version (&sa->raddr) == AF_IP4);
    1445             : 
    1446          11 :   plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload, len, &dlen);
    1447             : 
    1448          11 :   if (!plaintext)
    1449           0 :     goto cleanup_and_exit;
    1450             : 
    1451             :   /* process encrypted payload */
    1452          11 :   p = 0;
    1453          86 :   while (payload != IKEV2_PAYLOAD_NONE)
    1454             :     {
    1455          75 :       ikep = (ike_payload_header_t *) & plaintext[p];
    1456          75 :       int current_length = dlen - p;
    1457          75 :       if (!ikev2_check_payload_length (ikep, current_length, &plen))
    1458           0 :         goto cleanup_and_exit;
    1459             : 
    1460          75 :       if (payload == IKEV2_PAYLOAD_SA)
    1461             :         {
    1462          19 :           proposal = ikev2_parse_sa_payload (ikep, current_length);
    1463             :         }
    1464          56 :       else if (payload == IKEV2_PAYLOAD_KE)
    1465             :         {
    1466           4 :           if (!ikev2_parse_ke_payload (ikep, current_length, &sar,
    1467             :                                        &sar.i_dh_data))
    1468           0 :             goto cleanup_and_exit;
    1469             :         }
    1470          52 :       else if (payload == IKEV2_PAYLOAD_NOTIFY)
    1471             :         {
    1472             :           ikev2_notify_t *n0;
    1473          19 :           n0 = ikev2_parse_notify_payload (ikep, current_length);
    1474          19 :           if (n0->msg_type == IKEV2_NOTIFY_MSG_REKEY_SA)
    1475             :             {
    1476          11 :               vec_free (n);
    1477          11 :               n = n0;
    1478             :             }
    1479             :           else
    1480           8 :             vec_free (n0);
    1481             :         }
    1482          33 :       else if (payload == IKEV2_PAYLOAD_DELETE)
    1483             :         {
    1484           0 :           sa->del = ikev2_parse_delete_payload (ikep, current_length);
    1485             :         }
    1486          33 :       else if (payload == IKEV2_PAYLOAD_VENDOR)
    1487             :         {
    1488           0 :           ikev2_parse_vendor_payload (ikep);
    1489             :         }
    1490          33 :       else if (payload == IKEV2_PAYLOAD_NONCE)
    1491             :         {
    1492          11 :           nonce_len = ikev2_parse_nonce_payload (ikep, current_length, &nonce);
    1493          11 :           if (nonce_len <= 0)
    1494           0 :             goto cleanup_and_exit;
    1495             :         }
    1496          22 :       else if (payload == IKEV2_PAYLOAD_TSI)
    1497             :         {
    1498          11 :           tsi = ikev2_parse_ts_payload (ikep, current_length);
    1499             :         }
    1500          11 :       else if (payload == IKEV2_PAYLOAD_TSR)
    1501             :         {
    1502          11 :           tsr = ikev2_parse_ts_payload (ikep, current_length);
    1503             :         }
    1504             :       else
    1505             :         {
    1506           0 :           ikev2_elog_uint (IKEV2_LOG_ERROR, "Unknown payload! type=%d",
    1507             :                            payload);
    1508           0 :           if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
    1509             :             {
    1510           0 :               sa->unsupported_cp = payload;
    1511           0 :               goto cleanup_and_exit;
    1512             :             }
    1513             :         }
    1514          75 :       payload = ikep->nextpayload;
    1515          75 :       p += plen;
    1516             :     }
    1517             : 
    1518          11 :   if (!proposal || proposal->protocol_id != IKEV2_PROTOCOL_ESP || !nonce)
    1519           0 :     goto cleanup_and_exit;
    1520             : 
    1521          11 :   if (sa->is_initiator)
    1522             :     {
    1523           3 :       rekey = sa->rekey;
    1524           3 :       if (vec_len (rekey) == 0)
    1525           1 :         goto cleanup_and_exit;
    1526           2 :       rekey->notify_type = 0;
    1527           2 :       rekey->protocol_id = proposal->protocol_id;
    1528           4 :       rekey->i_proposal =
    1529           2 :         ikev2_select_proposal (proposal, IKEV2_PROTOCOL_ESP);
    1530           2 :       rekey->i_proposal->spi = rekey->spi;
    1531           2 :       rekey->r_proposal = proposal;
    1532           2 :       rekey->tsi = tsi;
    1533           2 :       rekey->tsr = tsr;
    1534             :       /* update Nr */
    1535           2 :       vec_reset_length (sa->r_nonce);
    1536           2 :       vec_add (sa->r_nonce, nonce, nonce_len);
    1537           2 :       child_sa = ikev2_sa_get_child (sa, rekey->ispi, IKEV2_PROTOCOL_ESP, 1);
    1538           2 :       if (child_sa)
    1539             :         {
    1540           2 :           child_sa->rekey_retries = 0;
    1541             :         }
    1542             :     }
    1543             :   else
    1544             :     {
    1545           8 :       if (n)
    1546             :         {
    1547           8 :           child_sa = ikev2_sa_get_child (sa, n->spi, n->protocol_id, 1);
    1548           8 :           if (!child_sa)
    1549             :             {
    1550           0 :               ikev2_elog_uint (IKEV2_LOG_ERROR, "child SA spi %lx not found",
    1551             :                                n->spi);
    1552           0 :               goto cleanup_and_exit;
    1553             :             }
    1554           8 :           vec_add2 (sa->rekey, rekey, 1);
    1555           8 :           rekey->notify_type = 0;
    1556           8 :           rekey->kex = 0;
    1557           8 :           rekey->protocol_id = n->protocol_id;
    1558           8 :           rekey->spi = n->spi;
    1559           8 :           if (sa->old_remote_id_present)
    1560             :             {
    1561           2 :               rekey->notify_type = IKEV2_NOTIFY_MSG_TEMPORARY_FAILURE;
    1562           2 :               vec_free (proposal);
    1563           2 :               vec_free (tsr);
    1564           2 :               vec_free (tsi);
    1565             :             }
    1566           6 :           else if (!ikev2_process_create_child_sa_rekey (
    1567             :                      sa, &sar, rekey, proposal, tsi, tsr, nonce, nonce_len))
    1568             :             {
    1569           0 :               vec_free (proposal);
    1570           0 :               vec_free (tsr);
    1571           0 :               vec_free (tsi);
    1572             :             }
    1573             :         }
    1574             :       else
    1575             :         {
    1576             :           /* create new child SA */
    1577           0 :           vec_add2 (sa->new_child, rekey, 1);
    1578           0 :           rekey->notify_type = 0;
    1579           0 :           rekey->kex = 0;
    1580           0 :           if (!ikev2_process_create_child_sa_rekey (
    1581             :                 sa, &sar, rekey, proposal, tsi, tsr, nonce, nonce_len))
    1582             :             {
    1583           0 :               vec_free (proposal);
    1584           0 :               vec_free (tsr);
    1585           0 :               vec_free (tsi);
    1586             :             }
    1587             :         }
    1588             :     }
    1589          10 :   vec_free (n);
    1590          10 :   ikev2_sa_free_all_vec (&sar);
    1591          10 :   return 1;
    1592             : 
    1593           1 : cleanup_and_exit:
    1594           1 :   vec_free (n);
    1595           1 :   vec_free (proposal);
    1596           1 :   vec_free (tsr);
    1597           1 :   vec_free (tsi);
    1598           1 :   ikev2_sa_free_all_vec (&sar);
    1599           1 :   return 0;
    1600             : }
    1601             : 
    1602             : static u8 *
    1603          38 : ikev2_sa_generate_authmsg (ikev2_sa_t * sa, int is_responder)
    1604             : {
    1605          38 :   u8 *authmsg = 0;
    1606             :   u8 *data;
    1607             :   u8 *nonce;
    1608             :   ikev2_id_t *id;
    1609             :   u8 *key;
    1610             :   u8 *packet_data;
    1611             :   ikev2_sa_transform_t *tr_prf;
    1612             : 
    1613             :   tr_prf =
    1614          38 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
    1615             : 
    1616          38 :   if (is_responder)
    1617             :     {
    1618          19 :       id = &sa->r_id;
    1619          19 :       key = sa->sk_pr;
    1620          19 :       nonce = sa->i_nonce;
    1621          19 :       packet_data = sa->last_sa_init_res_packet_data;
    1622             :     }
    1623             :   else
    1624             :     {
    1625          19 :       id = &sa->i_id;
    1626          19 :       key = sa->sk_pi;
    1627          19 :       nonce = sa->r_nonce;
    1628          19 :       packet_data = sa->last_sa_init_req_packet_data;
    1629             :     }
    1630             : 
    1631          38 :   data = vec_new (u8, 4);
    1632          38 :   data[0] = id->type;
    1633          38 :   vec_append (data, id->data);
    1634             : 
    1635          38 :   u8 *id_hash = ikev2_calc_prf (tr_prf, key, data);
    1636          38 :   vec_append (authmsg, packet_data);
    1637          38 :   vec_append (authmsg, nonce);
    1638          38 :   vec_append (authmsg, id_hash);
    1639          38 :   vec_free (id_hash);
    1640          38 :   vec_free (data);
    1641             : 
    1642          38 :   return authmsg;
    1643             : }
    1644             : 
    1645             : static int
    1646          38 : ikev2_match_profile (const ikev2_profile_t *p, const ikev2_id_t *id_loc,
    1647             :                      const ikev2_id_t *id_rem, int is_initiator)
    1648             : {
    1649             :   /* on the initiator, IDi is always present and must match
    1650             :    * however on the responder, IDr (which is our local id) is optional */
    1651          75 :   if ((is_initiator || id_loc->type != 0) &&
    1652          37 :       !ikev2_is_id_equal (&p->loc_id, id_loc))
    1653           0 :     return 0;
    1654             : 
    1655             :   /* on the initiator, we might not have configured a specific remote id
    1656             :    * however on the responder, the remote id should always be configured */
    1657          74 :   if ((!is_initiator || p->rem_id.type != 0) &&
    1658          36 :       !ikev2_is_id_equal (&p->rem_id, id_rem))
    1659           0 :     return 0;
    1660             : 
    1661          38 :   return 1;
    1662             : }
    1663             : 
    1664             : static int
    1665          38 : ikev2_ts_cmp (ikev2_ts_t * ts1, ikev2_ts_t * ts2)
    1666             : {
    1667          38 :   if (ts1->ts_type == ts2->ts_type && ts1->protocol_id == ts2->protocol_id &&
    1668          76 :       ts1->start_port == ts2->start_port && ts1->end_port == ts2->end_port &&
    1669          76 :       !ip_address_cmp (&ts1->start_addr, &ts2->start_addr) &&
    1670          38 :       !ip_address_cmp (&ts1->end_addr, &ts2->end_addr))
    1671          38 :     return 1;
    1672             : 
    1673           0 :   return 0;
    1674             : }
    1675             : 
    1676             : static void
    1677          19 : ikev2_sa_match_ts (ikev2_sa_t * sa)
    1678             : {
    1679          19 :   ikev2_main_t *km = &ikev2_main;
    1680             :   ikev2_profile_t *p;
    1681          19 :   ikev2_ts_t *ts, *p_tsi, *p_tsr, *tsi = 0, *tsr = 0;
    1682             :   ikev2_id_t *id_rem, *id_loc;
    1683             : 
    1684             :   /* *INDENT-OFF* */
    1685          19 :   pool_foreach (p, km->profiles)  {
    1686             : 
    1687          19 :     if (sa->is_initiator)
    1688             :       {
    1689           6 :         p_tsi = &p->loc_ts;
    1690           6 :         p_tsr = &p->rem_ts;
    1691           6 :         id_rem = &sa->r_id;
    1692           6 :         id_loc = &sa->i_id;
    1693             :       }
    1694             :     else
    1695             :       {
    1696          13 :         p_tsi = &p->rem_ts;
    1697          13 :         p_tsr = &p->loc_ts;
    1698          13 :         id_rem = &sa->i_id;
    1699          13 :         id_loc = &sa->r_id;
    1700             :       }
    1701             : 
    1702          19 :     if (!ikev2_match_profile (p, id_loc, id_rem, sa->is_initiator))
    1703           0 :       continue;
    1704             : 
    1705          19 :     sa->profile_index = p - km->profiles;
    1706             : 
    1707          19 :     vec_foreach(ts, sa->childs[0].tsi)
    1708             :       {
    1709          19 :         if (ikev2_ts_cmp(p_tsi, ts))
    1710             :           {
    1711          19 :             vec_add1 (tsi, ts[0]);
    1712          19 :             break;
    1713             :           }
    1714             :       }
    1715             : 
    1716          19 :     vec_foreach(ts, sa->childs[0].tsr)
    1717             :       {
    1718          19 :         if (ikev2_ts_cmp(p_tsr, ts))
    1719             :           {
    1720          19 :             vec_add1 (tsr, ts[0]);
    1721          19 :             break;
    1722             :           }
    1723             :       }
    1724             : 
    1725          19 :     break;
    1726             :   }
    1727             :   /* *INDENT-ON* */
    1728             : 
    1729          19 :   if (tsi && tsr)
    1730             :     {
    1731          19 :       vec_free (sa->childs[0].tsi);
    1732          19 :       vec_free (sa->childs[0].tsr);
    1733          19 :       sa->childs[0].tsi = tsi;
    1734          19 :       sa->childs[0].tsr = tsr;
    1735             :     }
    1736             :   else
    1737             :     {
    1738           0 :       vec_free (tsi);
    1739           0 :       vec_free (tsr);
    1740           0 :       ikev2_set_state (sa, IKEV2_STATE_TS_UNACCEPTABLE);
    1741             :     }
    1742          19 : }
    1743             : 
    1744             : static ikev2_profile_t *
    1745          19 : ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa,
    1746             :                       ikev2_sa_transform_t *tr_prf, u8 *key_pad)
    1747             : {
    1748          19 :   ikev2_profile_t *ret = 0, *p;
    1749             :   ikev2_id_t *id_rem, *id_loc;
    1750             :   ikev2_auth_t *sa_auth;
    1751          19 :   u8 *authmsg, *psk = 0, *auth = 0;
    1752             : 
    1753          19 :   authmsg = ikev2_sa_generate_authmsg (sa, sa->is_initiator);
    1754             : 
    1755          19 :   if (sa->is_initiator)
    1756             :     {
    1757           6 :       id_rem = &sa->r_id;
    1758           6 :       id_loc = &sa->i_id;
    1759           6 :       sa_auth = &sa->r_auth;
    1760             :     }
    1761             :   else
    1762             :     {
    1763          13 :       id_rem = &sa->i_id;
    1764          13 :       id_loc = &sa->r_id;
    1765          13 :       sa_auth = &sa->i_auth;
    1766             :     }
    1767             : 
    1768          19 :   pool_foreach (p, km->profiles)
    1769             :     {
    1770          19 :       if (!ikev2_match_profile (p, id_loc, id_rem, sa->is_initiator))
    1771           0 :         continue;
    1772             : 
    1773          19 :       if (sa_auth->method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
    1774             :         {
    1775          18 :           if (!p->auth.data ||
    1776          18 :               p->auth.method != IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
    1777           0 :             continue;
    1778             : 
    1779          18 :           psk = ikev2_calc_prf (tr_prf, p->auth.data, key_pad);
    1780          18 :           auth = ikev2_calc_prf (tr_prf, psk, authmsg);
    1781             : 
    1782          18 :           if (!clib_memcmp (auth, sa_auth->data, vec_len (sa_auth->data)))
    1783             :             {
    1784          18 :               ikev2_set_state (sa, IKEV2_STATE_AUTHENTICATED);
    1785          18 :               vec_free (auth);
    1786          18 :               ret = p;
    1787          18 :               break;
    1788             :             }
    1789             :           else
    1790             :             {
    1791           0 :               ikev2_elog_uint (IKEV2_LOG_ERROR,
    1792             :                                "shared key mismatch! ispi %lx", sa->ispi);
    1793             :             }
    1794             :         }
    1795           1 :       else if (sa_auth->method == IKEV2_AUTH_METHOD_RSA_SIG)
    1796             :         {
    1797           1 :           if (p->auth.method != IKEV2_AUTH_METHOD_RSA_SIG)
    1798           0 :             continue;
    1799             : 
    1800           1 :           if (ikev2_verify_sign (p->auth.key, sa_auth->data, authmsg) == 1)
    1801             :             {
    1802           1 :               ikev2_set_state (sa, IKEV2_STATE_AUTHENTICATED);
    1803           1 :               ret = p;
    1804           1 :               break;
    1805             :             }
    1806             :           else
    1807             :             {
    1808           0 :               ikev2_elog_uint (IKEV2_LOG_ERROR,
    1809             :                                "cert verification failed! ispi %lx", sa->ispi);
    1810             :             }
    1811             :         }
    1812             :     }
    1813          19 :   vec_free (authmsg);
    1814          19 :   return ret;
    1815             : }
    1816             : 
    1817             : static void
    1818          19 : ikev2_sa_auth (ikev2_sa_t *sa)
    1819             : {
    1820          19 :   ikev2_main_t *km = &ikev2_main;
    1821          19 :   ikev2_profile_t *sel_p = 0;
    1822             :   ikev2_sa_transform_t *tr_prf;
    1823             :   u8 *psk, *authmsg, *key_pad;
    1824             : 
    1825             :   tr_prf =
    1826          19 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
    1827             : 
    1828             :   /* only shared key and rsa signature */
    1829          19 :   if (!(sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC ||
    1830           1 :         sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG))
    1831             :     {
    1832           0 :       ikev2_elog_uint (IKEV2_LOG_ERROR, "unsupported authentication method %u",
    1833             :                        sa->i_auth.method);
    1834           0 :       ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
    1835           0 :       return;
    1836             :     }
    1837             : 
    1838          19 :   key_pad = format (0, "%s", IKEV2_KEY_PAD);
    1839          19 :   sel_p = ikev2_select_profile (km, sa, tr_prf, key_pad);
    1840             : 
    1841          19 :   if (sel_p)
    1842             :     {
    1843          19 :       ASSERT (sa->state == IKEV2_STATE_AUTHENTICATED);
    1844          19 :       sa->udp_encap = sel_p->udp_encap;
    1845          19 :       sa->ipsec_over_udp_port = sel_p->ipsec_over_udp_port;
    1846             : 
    1847          19 :       if (!sa->is_initiator)
    1848             :         {
    1849          13 :           vec_free (sa->r_id.data);
    1850          13 :           sa->r_id.data = vec_dup (sel_p->loc_id.data);
    1851          13 :           sa->r_id.type = sel_p->loc_id.type;
    1852          13 :           sa->i_id.data = vec_dup (sel_p->rem_id.data);
    1853          13 :           sa->i_id.type = sel_p->rem_id.type;
    1854             : 
    1855             :           /* generate our auth data */
    1856          13 :           authmsg = ikev2_sa_generate_authmsg (sa, 1);
    1857          13 :           if (sel_p->auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
    1858             :             {
    1859          12 :               vec_free (sa->r_auth.data);
    1860          12 :               psk = ikev2_calc_prf (tr_prf, sel_p->auth.data, key_pad);
    1861          12 :               sa->r_auth.data = ikev2_calc_prf (tr_prf, psk, authmsg);
    1862          12 :               sa->r_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC;
    1863          12 :               vec_free (psk);
    1864             :             }
    1865           1 :           else if (sel_p->auth.method == IKEV2_AUTH_METHOD_RSA_SIG)
    1866             :             {
    1867           1 :               vec_free (sa->r_auth.data);
    1868           1 :               sa->r_auth.data = ikev2_calc_sign (km->pkey, authmsg);
    1869           1 :               sa->r_auth.method = IKEV2_AUTH_METHOD_RSA_SIG;
    1870             :             }
    1871          13 :           vec_free (authmsg);
    1872             : 
    1873             :           /* select transforms for 1st child sa */
    1874          13 :           ikev2_sa_free_proposal_vector (&sa->childs[0].r_proposals);
    1875          26 :           sa->childs[0].r_proposals =
    1876          13 :             ikev2_select_proposal (sa->childs[0].i_proposals,
    1877             :                                    IKEV2_PROTOCOL_ESP);
    1878             : 
    1879          13 :           if (~0 != sel_p->tun_itf)
    1880             :             {
    1881           0 :               sa->is_tun_itf_set = 1;
    1882           0 :               sa->tun_itf = sel_p->tun_itf;
    1883             :             }
    1884             :         }
    1885             :     }
    1886             :   else
    1887             :     {
    1888           0 :       ikev2_elog_uint (IKEV2_LOG_ERROR, "authentication failed, no matching "
    1889             :                        "profile found! ispi %lx", sa->ispi);
    1890           0 :       ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
    1891             :     }
    1892          19 :   vec_free (key_pad);
    1893             : }
    1894             : 
    1895             : static void
    1896           6 : ikev2_sa_auth_init (ikev2_sa_t * sa)
    1897             : {
    1898           6 :   ikev2_main_t *km = &ikev2_main;
    1899           6 :   u8 *authmsg, *key_pad, *psk = 0;
    1900             :   ikev2_sa_transform_t *tr_prf;
    1901             : 
    1902             :   tr_prf =
    1903           6 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
    1904             : 
    1905             :   /* only shared key and rsa signature */
    1906           6 :   if (!(sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC ||
    1907           0 :         sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG))
    1908             :     {
    1909           0 :       ikev2_elog_uint (IKEV2_LOG_ERROR,
    1910             :                        "unsupported authentication method %u",
    1911             :                        sa->i_auth.method);
    1912           0 :       ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
    1913           0 :       return;
    1914             :     }
    1915             : 
    1916           6 :   authmsg = ikev2_sa_generate_authmsg (sa, 0);
    1917             : 
    1918           6 :   if (sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
    1919             :     {
    1920           6 :       key_pad = format (0, "%s", IKEV2_KEY_PAD);
    1921           6 :       psk = ikev2_calc_prf (tr_prf, sa->i_auth.data, key_pad);
    1922           6 :       vec_free (sa->i_auth.data);
    1923           6 :       sa->i_auth.data = ikev2_calc_prf (tr_prf, psk, authmsg);
    1924           6 :       sa->i_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC;
    1925           6 :       vec_free (psk);
    1926           6 :       vec_free (key_pad);
    1927             :     }
    1928           0 :   else if (sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG)
    1929             :     {
    1930           0 :       vec_free (sa->i_auth.data);
    1931           0 :       sa->i_auth.data = ikev2_calc_sign (km->pkey, authmsg);
    1932           0 :       sa->i_auth.method = IKEV2_AUTH_METHOD_RSA_SIG;
    1933             :     }
    1934           6 :   vec_free (authmsg);
    1935             : }
    1936             : 
    1937             : static u32
    1938          27 : ikev2_mk_local_sa_id (u32 sai, u32 ci, u32 ti)
    1939             : {
    1940          27 :   return (0x80000000 | (ti << 24) | (sai << 12) | ci);
    1941             : }
    1942             : 
    1943             : static u32
    1944          27 : ikev2_mk_remote_sa_id (u32 sai, u32 ci, u32 ti)
    1945             : {
    1946          27 :   return (0xc0000000 | (ti << 24) | (sai << 12) | ci);
    1947             : }
    1948             : 
    1949             : typedef struct
    1950             : {
    1951             :   u32 sw_if_index;
    1952             :   u32 salt_local;
    1953             :   u32 salt_remote;
    1954             :   u32 local_sa_id;
    1955             :   u32 remote_sa_id;
    1956             :   ipsec_sa_flags_t flags;
    1957             :   u32 local_spi;
    1958             :   u32 remote_spi;
    1959             :   ipsec_crypto_alg_t encr_type;
    1960             :   ipsec_integ_alg_t integ_type;
    1961             :   ip_address_t local_ip;
    1962             :   ip_address_t remote_ip;
    1963             :   ipsec_key_t loc_ckey, rem_ckey, loc_ikey, rem_ikey;
    1964             :   u8 is_rekey;
    1965             :   u32 old_remote_sa_id;
    1966             :   u16 ipsec_over_udp_port;
    1967             :   u16 src_port;
    1968             :   u16 dst_port;
    1969             : } ikev2_add_ipsec_tunnel_args_t;
    1970             : 
    1971             : static void
    1972          27 : ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
    1973             : {
    1974          27 :   ikev2_main_t *km = &ikev2_main;
    1975             :   u32 sw_if_index;
    1976          27 :   int rv = 0;
    1977          27 :   tunnel_t tun_in = {
    1978             :     .t_flags = TUNNEL_FLAG_NONE,
    1979             :     .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
    1980             :     .t_dscp = 0,
    1981             :     .t_mode = TUNNEL_MODE_P2P,
    1982             :     .t_table_id = 0,
    1983             :     .t_hop_limit = 255,
    1984             :     .t_src = a->remote_ip,
    1985             :     .t_dst = a->local_ip,
    1986             :   };
    1987          27 :   tunnel_t tun_out = {
    1988             :     .t_flags = TUNNEL_FLAG_NONE,
    1989             :     .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
    1990             :     .t_dscp = 0,
    1991             :     .t_mode = TUNNEL_MODE_P2P,
    1992             :     .t_table_id = 0,
    1993             :     .t_hop_limit = 255,
    1994             :     .t_src = a->local_ip,
    1995             :     .t_dst = a->remote_ip,
    1996             :   };
    1997             : 
    1998          27 :   if (~0 == a->sw_if_index)
    1999             :     {
    2000             :       /* no tunnel associated with the SA/profile - create a new one */
    2001          27 :       rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0, &ip_addr_46 (&a->local_ip),
    2002             :                             &ip_addr_46 (&a->remote_ip), 0,
    2003             :                             TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
    2004             :                             TUNNEL_MODE_P2P, &sw_if_index);
    2005             : 
    2006          27 :       if (rv == VNET_API_ERROR_IF_ALREADY_EXISTS)
    2007             :         {
    2008           8 :           if (hash_get (km->sw_if_indices, sw_if_index))
    2009             :             /* interface is managed by IKE; proceed with updating SAs */
    2010           8 :             rv = 0;
    2011             :         }
    2012          27 :       hash_set1 (km->sw_if_indices, sw_if_index);
    2013             :     }
    2014             :   else
    2015             :     {
    2016           0 :       sw_if_index = a->sw_if_index;
    2017           0 :       vnet_sw_interface_admin_up (vnet_get_main (), sw_if_index);
    2018             :     }
    2019             : 
    2020          27 :   if (rv)
    2021             :     {
    2022           0 :       ikev2_elog_uint (IKEV2_LOG_ERROR,
    2023             :                        "installing ipip tunnel failed! local spi: %x",
    2024             :                        a->local_spi);
    2025          27 :       return;
    2026             :     }
    2027             : 
    2028          27 :   u32 *sas_in = NULL;
    2029          27 :   vec_add1 (sas_in, a->remote_sa_id);
    2030          27 :   if (a->is_rekey)
    2031             :     {
    2032           8 :       ipsec_tun_protect_del (sw_if_index, NULL);
    2033             : 
    2034             :       /* replace local SA immediately */
    2035           8 :       ipsec_sa_unlock_id (a->local_sa_id);
    2036             : 
    2037             :       /* keep the old sa */
    2038           8 :       vec_add1 (sas_in, a->old_remote_sa_id);
    2039             :     }
    2040             : 
    2041          27 :   rv = ipsec_sa_add_and_lock (a->local_sa_id, a->local_spi, IPSEC_PROTOCOL_ESP,
    2042          27 :                               a->encr_type, &a->loc_ckey, a->integ_type,
    2043          27 :                               &a->loc_ikey, a->flags, a->salt_local,
    2044          27 :                               a->src_port, a->dst_port, &tun_out, NULL);
    2045          27 :   if (rv)
    2046           0 :     goto err0;
    2047             : 
    2048          27 :   rv = ipsec_sa_add_and_lock (
    2049          27 :     a->remote_sa_id, a->remote_spi, IPSEC_PROTOCOL_ESP, a->encr_type,
    2050          27 :     &a->rem_ckey, a->integ_type, &a->rem_ikey,
    2051          27 :     (a->flags | IPSEC_SA_FLAG_IS_INBOUND), a->salt_remote,
    2052          27 :     a->ipsec_over_udp_port, a->ipsec_over_udp_port, &tun_in, NULL);
    2053          27 :   if (rv)
    2054           0 :     goto err1;
    2055             : 
    2056          27 :   rv = ipsec_tun_protect_update (sw_if_index, NULL, a->local_sa_id, sas_in);
    2057          27 :   if (rv)
    2058           0 :     goto err2;
    2059             : 
    2060          27 :   return;
    2061             : 
    2062           0 : err2:
    2063           0 :   ipsec_sa_unlock_id (a->remote_sa_id);
    2064           0 : err1:
    2065           0 :   ipsec_sa_unlock_id (a->local_sa_id);
    2066           0 : err0:
    2067           0 :   vec_free (sas_in);
    2068             : }
    2069             : 
    2070             : static int
    2071          27 : ikev2_create_tunnel_interface (vlib_main_t *vm, ikev2_sa_t *sa,
    2072             :                                ikev2_child_sa_t *child, u32 sa_index,
    2073             :                                u32 child_index, u8 is_rekey, u8 kex)
    2074             : {
    2075          27 :   u32 thread_index = vlib_get_thread_index ();
    2076          27 :   ikev2_main_t *km = &ikev2_main;
    2077             :   ipsec_crypto_alg_t encr_type;
    2078             :   ipsec_integ_alg_t integ_type;
    2079          27 :   ikev2_profile_t *p = 0;
    2080             :   ikev2_sa_transform_t *tr;
    2081             :   ikev2_sa_proposal_t *proposals;
    2082          27 :   u8 is_aead = 0;
    2083             :   ikev2_add_ipsec_tunnel_args_t a;
    2084             : 
    2085          27 :   clib_memset (&a, 0, sizeof (a));
    2086             : 
    2087          27 :   if (!child->r_proposals)
    2088             :     {
    2089           0 :       ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2090           0 :       return 1;
    2091             :     }
    2092             : 
    2093          27 :   if (sa->is_initiator)
    2094             :     {
    2095           8 :       ip_address_copy (&a.local_ip, &sa->iaddr);
    2096           8 :       ip_address_copy (&a.remote_ip, &sa->raddr);
    2097           8 :       proposals = child->r_proposals;
    2098           8 :       a.local_spi = child->r_proposals[0].spi;
    2099           8 :       a.remote_spi = child->i_proposals[0].spi;
    2100             :     }
    2101             :   else
    2102             :     {
    2103          19 :       ip_address_copy (&a.local_ip, &sa->raddr);
    2104          19 :       ip_address_copy (&a.remote_ip, &sa->iaddr);
    2105          19 :       proposals = child->i_proposals;
    2106          19 :       a.local_spi = child->i_proposals[0].spi;
    2107          19 :       a.remote_spi = child->r_proposals[0].spi;
    2108             :     }
    2109             : 
    2110          27 :   a.flags = IPSEC_SA_FLAG_USE_ANTI_REPLAY;
    2111          27 :   if (sa->udp_encap)
    2112             :     {
    2113           1 :       a.flags |= IPSEC_SA_FLAG_IS_TUNNEL;
    2114           1 :       a.flags |= IPSEC_SA_FLAG_UDP_ENCAP;
    2115             :     }
    2116          27 :   if (ikev2_natt_active (sa))
    2117           3 :     a.flags |= IPSEC_SA_FLAG_UDP_ENCAP;
    2118          27 :   a.is_rekey = is_rekey;
    2119             : 
    2120          27 :   tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_ESN);
    2121          27 :   if (tr && tr->esn_type)
    2122           2 :     a.flags |= IPSEC_SA_FLAG_USE_ESN;
    2123             : 
    2124          27 :   tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_ENCR);
    2125          27 :   if (tr)
    2126             :     {
    2127          27 :       if (tr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC && tr->key_len)
    2128             :         {
    2129          26 :           switch (tr->key_len)
    2130             :             {
    2131           0 :             case 16:
    2132           0 :               encr_type = IPSEC_CRYPTO_ALG_AES_CBC_128;
    2133           0 :               break;
    2134           1 :             case 24:
    2135           1 :               encr_type = IPSEC_CRYPTO_ALG_AES_CBC_192;
    2136           1 :               break;
    2137          25 :             case 32:
    2138          25 :               encr_type = IPSEC_CRYPTO_ALG_AES_CBC_256;
    2139          25 :               break;
    2140           0 :             default:
    2141           0 :               ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2142           0 :               return 1;
    2143             :               break;
    2144             :             }
    2145             :         }
    2146           1 :       else if (tr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_GCM_16
    2147           1 :                && tr->key_len)
    2148             :         {
    2149           1 :           switch (tr->key_len)
    2150             :             {
    2151           0 :             case 16:
    2152           0 :               encr_type = IPSEC_CRYPTO_ALG_AES_GCM_128;
    2153           0 :               break;
    2154           0 :             case 24:
    2155           0 :               encr_type = IPSEC_CRYPTO_ALG_AES_GCM_192;
    2156           0 :               break;
    2157           1 :             case 32:
    2158           1 :               encr_type = IPSEC_CRYPTO_ALG_AES_GCM_256;
    2159           1 :               break;
    2160           0 :             default:
    2161           0 :               ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2162           0 :               return 1;
    2163             :               break;
    2164             :             }
    2165           1 :           is_aead = 1;
    2166             :         }
    2167             :       else
    2168             :         {
    2169           0 :           ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2170           0 :           return 1;
    2171             :         }
    2172             :     }
    2173             :   else
    2174             :     {
    2175           0 :       ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2176           0 :       return 1;
    2177             :     }
    2178          27 :   a.encr_type = encr_type;
    2179             : 
    2180          27 :   if (!is_aead)
    2181             :     {
    2182          26 :       tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_INTEG);
    2183          26 :       if (tr)
    2184             :         {
    2185          26 :           switch (tr->integ_type)
    2186             :             {
    2187           8 :             case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_256_128:
    2188           8 :               integ_type = IPSEC_INTEG_ALG_SHA_256_128;
    2189           8 :               break;
    2190           1 :             case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_384_192:
    2191           1 :               integ_type = IPSEC_INTEG_ALG_SHA_384_192;
    2192           1 :               break;
    2193           0 :             case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_512_256:
    2194           0 :               integ_type = IPSEC_INTEG_ALG_SHA_512_256;
    2195           0 :               break;
    2196          17 :             case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96:
    2197          17 :               integ_type = IPSEC_INTEG_ALG_SHA1_96;
    2198          17 :               break;
    2199           0 :             default:
    2200           0 :               ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2201           0 :               return 1;
    2202             :             }
    2203             :         }
    2204             :       else
    2205             :         {
    2206           0 :           ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
    2207           0 :           return 1;
    2208             :         }
    2209             :     }
    2210             :   else
    2211             :     {
    2212           1 :       integ_type = IPSEC_INTEG_ALG_NONE;
    2213             :     }
    2214             : 
    2215          27 :   a.integ_type = integ_type;
    2216          27 :   ikev2_calc_child_keys (sa, child, kex);
    2217             : 
    2218          27 :   if (sa->is_initiator)
    2219             :     {
    2220           8 :       ipsec_mk_key (&a.loc_ikey, child->sk_ai, vec_len (child->sk_ai));
    2221           8 :       ipsec_mk_key (&a.rem_ikey, child->sk_ar, vec_len (child->sk_ar));
    2222           8 :       ipsec_mk_key (&a.loc_ckey, child->sk_ei, vec_len (child->sk_ei));
    2223           8 :       ipsec_mk_key (&a.rem_ckey, child->sk_er, vec_len (child->sk_er));
    2224           8 :       if (is_aead)
    2225             :         {
    2226           0 :           a.salt_remote = child->salt_er;
    2227           0 :           a.salt_local = child->salt_ei;
    2228             :         }
    2229           8 :       a.dst_port = a.src_port = sa->ipsec_over_udp_port;
    2230             :     }
    2231             :   else
    2232             :     {
    2233          19 :       ipsec_mk_key (&a.loc_ikey, child->sk_ar, vec_len (child->sk_ar));
    2234          19 :       ipsec_mk_key (&a.rem_ikey, child->sk_ai, vec_len (child->sk_ai));
    2235          19 :       ipsec_mk_key (&a.loc_ckey, child->sk_er, vec_len (child->sk_er));
    2236          19 :       ipsec_mk_key (&a.rem_ckey, child->sk_ei, vec_len (child->sk_ei));
    2237          19 :       if (is_aead)
    2238             :         {
    2239           1 :           a.salt_remote = child->salt_ei;
    2240           1 :           a.salt_local = child->salt_er;
    2241             :         }
    2242          19 :       a.dst_port =
    2243          19 :         ikev2_natt_active (sa) ? sa->dst_port : sa->ipsec_over_udp_port;
    2244          19 :       a.src_port = sa->ipsec_over_udp_port;
    2245             :     }
    2246             : 
    2247          27 :   if (sa->is_initiator && sa->profile_index != ~0)
    2248           8 :     p = pool_elt_at_index (km->profiles, sa->profile_index);
    2249             : 
    2250          27 :   if (p && p->lifetime)
    2251             :     {
    2252           0 :       child->time_to_expiration = vlib_time_now (vm) + p->lifetime;
    2253           0 :       if (p->lifetime_jitter)
    2254             :         {
    2255             :           // This is not much better than rand(3), which Coverity warns
    2256             :           // is unsuitable for security applications; random_u32 is
    2257             :           // however fast. If this perturbance to the expiration time
    2258             :           // needs to use a better RNG then we may need to use something
    2259             :           // like /dev/urandom which has significant overhead.
    2260           0 :           u32 rnd = (u32) (vlib_time_now (vm) * 1e6);
    2261           0 :           rnd = random_u32 (&rnd);
    2262             : 
    2263           0 :           child->time_to_expiration += 1 + (rnd % p->lifetime_jitter);
    2264             :         }
    2265             :     }
    2266             : 
    2267          27 :   if (thread_index & 0xffffffc0)
    2268           0 :     ikev2_elog_error ("error: thread index exceeds max range 0x3f!");
    2269             : 
    2270          27 :   if (child_index & 0xfffff000 || sa_index & 0xfffff000)
    2271           0 :     ikev2_elog_error ("error: sa/child index exceeds max range 0xfff!");
    2272             : 
    2273          27 :   child->local_sa_id =
    2274          27 :     a.local_sa_id =
    2275          27 :     ikev2_mk_local_sa_id (sa_index, child_index, thread_index);
    2276             : 
    2277          27 :   u32 remote_sa_id = ikev2_mk_remote_sa_id (sa_index, child_index,
    2278             :                                             thread_index);
    2279             : 
    2280          27 :   if (is_rekey)
    2281             :     {
    2282             :       /* create a new remote SA ID to keep the old SA for a bit longer
    2283             :        * so the peer has some time to swap their SAs */
    2284             : 
    2285             :       /* use most significat bit of child index part in id */
    2286           8 :       u32 mask = 0x800;
    2287           8 :       if (sa->current_remote_id_mask)
    2288             :         {
    2289           2 :           sa->old_remote_id = a.old_remote_sa_id = remote_sa_id | mask;
    2290           2 :           sa->current_remote_id_mask = 0;
    2291             :         }
    2292             :       else
    2293             :         {
    2294           6 :           sa->old_remote_id = a.old_remote_sa_id = remote_sa_id;
    2295           6 :           sa->current_remote_id_mask = mask;
    2296           6 :           remote_sa_id |= mask;
    2297             :         }
    2298           8 :       sa->old_id_expiration = 3.0;
    2299           8 :       sa->old_remote_id_present = 1;
    2300             :     }
    2301             : 
    2302          27 :   child->remote_sa_id = a.remote_sa_id = remote_sa_id;
    2303             : 
    2304          27 :   a.sw_if_index = (sa->is_tun_itf_set ? sa->tun_itf : ~0);
    2305          27 :   a.ipsec_over_udp_port = sa->ipsec_over_udp_port;
    2306             : 
    2307          27 :   vl_api_rpc_call_main_thread (ikev2_add_tunnel_from_main,
    2308             :                                (u8 *) & a, sizeof (a));
    2309          27 :   return 0;
    2310             : }
    2311             : 
    2312             : typedef struct
    2313             : {
    2314             :   ip46_address_t local_ip;
    2315             :   ip46_address_t remote_ip;
    2316             :   u32 remote_sa_id;
    2317             :   u32 local_sa_id;
    2318             :   u32 sw_if_index;
    2319             : } ikev2_del_ipsec_tunnel_args_t;
    2320             : 
    2321             : static u32
    2322          21 : ikev2_flip_alternate_sa_bit (u32 id)
    2323             : {
    2324          21 :   u32 mask = 0x800;
    2325          21 :   if (mask & id)
    2326           6 :     return id & ~mask;
    2327          15 :   return id | mask;
    2328             : }
    2329             : 
    2330             : static void
    2331          19 : ikev2_del_tunnel_from_main (ikev2_del_ipsec_tunnel_args_t * a)
    2332             : {
    2333          19 :   ikev2_main_t *km = &ikev2_main;
    2334          19 :   ipip_tunnel_t *ipip = NULL;
    2335             :   u32 sw_if_index;
    2336             : 
    2337          19 :   if (~0 == a->sw_if_index)
    2338             :     {
    2339             :     /* *INDENT-OFF* */
    2340          19 :     ipip_tunnel_key_t key = {
    2341             :       .src = a->local_ip,
    2342             :       .dst = a->remote_ip,
    2343             :       .transport = IPIP_TRANSPORT_IP4,
    2344             :       .fib_index = 0,
    2345             :     };
    2346             :     /* *INDENT-ON* */
    2347             : 
    2348          19 :       ipip = ipip_tunnel_db_find (&key);
    2349             : 
    2350          19 :       if (ipip)
    2351             :         {
    2352          19 :           sw_if_index = ipip->sw_if_index;
    2353          19 :           hash_unset (km->sw_if_indices, ipip->sw_if_index);
    2354             :         }
    2355             :       else
    2356           0 :         sw_if_index = ~0;
    2357             :     }
    2358             :   else
    2359             :     {
    2360           0 :       sw_if_index = a->sw_if_index;
    2361           0 :       vnet_sw_interface_admin_down (vnet_get_main (), sw_if_index);
    2362             :     }
    2363             : 
    2364          19 :   if (~0 != sw_if_index)
    2365          19 :     ipsec_tun_protect_del (sw_if_index, NULL);
    2366             : 
    2367          19 :   ipsec_sa_unlock_id (a->remote_sa_id);
    2368          19 :   ipsec_sa_unlock_id (a->local_sa_id);
    2369          19 :   ipsec_sa_unlock_id (ikev2_flip_alternate_sa_bit (a->remote_sa_id));
    2370             : 
    2371          19 :   if (ipip)
    2372          19 :     ipip_del_tunnel (ipip->sw_if_index);
    2373          19 : }
    2374             : 
    2375             : static int
    2376          19 : ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa,
    2377             :                                ikev2_child_sa_t * child)
    2378             : {
    2379             :   ikev2_del_ipsec_tunnel_args_t a;
    2380             : 
    2381          19 :   clib_memset (&a, 0, sizeof (a));
    2382             : 
    2383          19 :   if (sa->is_initiator)
    2384             :     {
    2385           6 :       ip_address_to_46 (&sa->iaddr, &a.local_ip);
    2386           6 :       ip_address_to_46 (&sa->raddr, &a.remote_ip);
    2387             :     }
    2388             :   else
    2389             :     {
    2390          13 :       ip_address_to_46 (&sa->raddr, &a.local_ip);
    2391          13 :       ip_address_to_46 (&sa->iaddr, &a.remote_ip);
    2392             :     }
    2393             : 
    2394          19 :   a.remote_sa_id = child->remote_sa_id;
    2395          19 :   a.local_sa_id = child->local_sa_id;
    2396          19 :   a.sw_if_index = (sa->is_tun_itf_set ? sa->tun_itf : ~0);
    2397             : 
    2398          19 :   vl_api_rpc_call_main_thread (ikev2_del_tunnel_from_main, (u8 *) & a,
    2399             :                                sizeof (a));
    2400          19 :   return 0;
    2401             : }
    2402             : 
    2403             : static void
    2404           0 : ikev2_add_invalid_ke_payload (ikev2_sa_t *sa, ikev2_payload_chain_t *chain)
    2405             : {
    2406           0 :   u8 *data = vec_new (u8, 2);
    2407             :   ikev2_sa_transform_t *tr_dh =
    2408           0 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
    2409           0 :   ASSERT (tr_dh && tr_dh->dh_type);
    2410           0 :   data[0] = (tr_dh->dh_type >> 8) & 0xff;
    2411           0 :   data[1] = (tr_dh->dh_type) & 0xff;
    2412           0 :   ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD, data);
    2413           0 :   vec_free (data);
    2414           0 : }
    2415             : 
    2416             : static void
    2417           8 : ikev2_add_create_child_resp (ikev2_sa_t *sa, ikev2_rekey_t *rekey,
    2418             :                              ikev2_payload_chain_t *chain)
    2419             : {
    2420           8 :   if (rekey->notify_type)
    2421             :     {
    2422           2 :       if (rekey->notify_type == IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD)
    2423           0 :         ikev2_add_invalid_ke_payload (sa, chain);
    2424             :       else
    2425           2 :         ikev2_payload_add_notify (chain, rekey->notify_type, 0);
    2426           2 :       return;
    2427             :     }
    2428             : 
    2429           6 :   ikev2_payload_add_sa (chain, rekey->r_proposal);
    2430           6 :   ikev2_payload_add_nonce (chain, sa->r_nonce);
    2431           6 :   if (rekey->kex)
    2432           3 :     ikev2_payload_add_ke (chain, sa->dh_group, sa->r_dh_data);
    2433           6 :   ikev2_payload_add_ts (chain, rekey->tsi, IKEV2_PAYLOAD_TSI);
    2434           6 :   ikev2_payload_add_ts (chain, rekey->tsr, IKEV2_PAYLOAD_TSR);
    2435             : }
    2436             : 
    2437             : static u32
    2438          64 : ikev2_generate_message (vlib_buffer_t *b, ikev2_sa_t *sa, ike_header_t *ike,
    2439             :                         void *user, udp_header_t *udp, ikev2_stats_t *stats)
    2440             : {
    2441          64 :   ikev2_main_t *km = &ikev2_main;
    2442          64 :   u16 buffer_data_size = vlib_buffer_get_default_data_size (km->vlib_main);
    2443          64 :   v8 *integ = 0;
    2444             :   ike_payload_header_t *ph;
    2445             :   u16 plen;
    2446          64 :   u32 tlen = 0;
    2447             : 
    2448             :   ikev2_sa_transform_t *tr_encr, *tr_integ;
    2449             :   tr_encr =
    2450          64 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
    2451             :   tr_integ =
    2452          64 :     ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
    2453             : 
    2454          64 :   ikev2_payload_chain_t *chain = 0;
    2455          64 :   ikev2_payload_new_chain (chain);
    2456             : 
    2457          64 :   if (ike->exchange == IKEV2_EXCHANGE_SA_INIT)
    2458             :     {
    2459          13 :       if (sa->r_proposals == 0)
    2460             :         {
    2461           0 :           ikev2_payload_add_notify (chain,
    2462             :                                     IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0);
    2463           0 :           ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    2464             :         }
    2465          13 :       else if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
    2466             :         {
    2467           0 :           ikev2_add_invalid_ke_payload (sa, chain);
    2468           0 :           ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    2469             :         }
    2470          13 :       else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE)
    2471             :         {
    2472           0 :           u8 *data = vec_new (u8, 1);
    2473             : 
    2474           0 :           data[0] = sa->unsupported_cp;
    2475           0 :           ikev2_payload_add_notify (chain,
    2476             :                                     IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
    2477             :                                     data);
    2478           0 :           vec_free (data);
    2479             :         }
    2480             :       else
    2481             :         {
    2482          13 :           ASSERT (udp);
    2483             : 
    2484          13 :           ike->rspi = clib_host_to_net_u64 (sa->rspi);
    2485          13 :           ikev2_payload_add_sa (chain, sa->r_proposals);
    2486          13 :           ikev2_payload_add_ke (chain, sa->dh_group, sa->r_dh_data);
    2487          13 :           ikev2_payload_add_nonce (chain, sa->r_nonce);
    2488             : 
    2489          13 :           u8 *nat_detection_sha1 =
    2490          13 :             ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa->ispi),
    2491             :                                     clib_host_to_net_u64 (sa->rspi),
    2492          13 :                                     &sa->raddr, udp->dst_port);
    2493          13 :           ikev2_payload_add_notify (chain,
    2494             :                                     IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
    2495             :                                     nat_detection_sha1);
    2496          13 :           vec_free (nat_detection_sha1);
    2497          13 :           nat_detection_sha1 =
    2498          13 :             ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa->ispi),
    2499             :                                     clib_host_to_net_u64 (sa->rspi),
    2500          13 :                                     &sa->iaddr, udp->src_port);
    2501          13 :           ikev2_payload_add_notify (chain,
    2502             :                                     IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
    2503             :                                     nat_detection_sha1);
    2504          13 :           vec_free (nat_detection_sha1);
    2505             :         }
    2506             :     }
    2507          51 :   else if (ike->exchange == IKEV2_EXCHANGE_IKE_AUTH)
    2508             :     {
    2509          19 :       if (sa->state == IKEV2_STATE_AUTHENTICATED)
    2510             :         {
    2511          13 :           ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
    2512          13 :           ikev2_payload_add_auth (chain, &sa->r_auth);
    2513          13 :           ikev2_payload_add_sa (chain, sa->childs[0].r_proposals);
    2514          13 :           ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
    2515          13 :           ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
    2516             :         }
    2517           6 :       else if (sa->state == IKEV2_STATE_AUTH_FAILED)
    2518             :         {
    2519           0 :           ikev2_payload_add_notify (chain,
    2520             :                                     IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED,
    2521             :                                     0);
    2522           0 :           ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    2523             :         }
    2524           6 :       else if (sa->state == IKEV2_STATE_TS_UNACCEPTABLE)
    2525             :         {
    2526           0 :           ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_TS_UNACCEPTABLE,
    2527             :                                     0);
    2528           0 :           ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
    2529           0 :           ikev2_payload_add_auth (chain, &sa->r_auth);
    2530             :         }
    2531           6 :       else if (sa->state == IKEV2_STATE_NO_PROPOSAL_CHOSEN)
    2532             :         {
    2533           0 :           ikev2_payload_add_notify (chain,
    2534             :                                     IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0);
    2535           0 :           ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
    2536           0 :           ikev2_payload_add_auth (chain, &sa->r_auth);
    2537           0 :           ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
    2538           0 :           ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
    2539             :         }
    2540           6 :       else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE)
    2541             :         {
    2542           0 :           u8 *data = vec_new (u8, 1);
    2543             : 
    2544           0 :           data[0] = sa->unsupported_cp;
    2545           0 :           ikev2_payload_add_notify (chain,
    2546             :                                     IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
    2547             :                                     data);
    2548           0 :           vec_free (data);
    2549             :         }
    2550           6 :       else if (sa->state == IKEV2_STATE_SA_INIT)
    2551             :         {
    2552           6 :           ikev2_payload_add_id (chain, &sa->i_id, IKEV2_PAYLOAD_IDI);
    2553             :           /* IDr is optional when sending INIT from the initiator */
    2554           6 :           ASSERT (sa->r_id.type != 0 || sa->is_initiator);
    2555           6 :           if (sa->r_id.type != 0)
    2556           5 :             ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
    2557           6 :           ikev2_payload_add_auth (chain, &sa->i_auth);
    2558           6 :           ikev2_payload_add_sa (chain, sa->childs[0].i_proposals);
    2559           6 :           ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
    2560           6 :           ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
    2561           6 :           ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_INITIAL_CONTACT,
    2562             :                                     0);
    2563             :         }
    2564             :       else
    2565             :         {
    2566           0 :           ikev2_set_state (sa, IKEV2_STATE_DELETED, ": unexpected IKE_AUTH");
    2567           0 :           goto done;
    2568             :         }
    2569             :     }
    2570          32 :   else if (ike->exchange == IKEV2_EXCHANGE_INFORMATIONAL)
    2571             :     {
    2572             :       /* if pending delete */
    2573          21 :       if (sa->del)
    2574             :         {
    2575          18 :           if (sa->del[0].protocol_id == IKEV2_PROTOCOL_IKE)
    2576             :             {
    2577          18 :               if (ike_hdr_is_request (ike))
    2578           6 :                 ikev2_payload_add_delete (chain, sa->del);
    2579             : 
    2580             :               /* The response to a request that deletes the IKE SA is an empty
    2581             :                  INFORMATIONAL response. */
    2582          18 :               ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
    2583             :             }
    2584             :           /* The response to a request that deletes ESP or AH SAs will contain
    2585             :              delete payloads for the paired SAs going in the other direction. */
    2586             :           else
    2587             :             {
    2588           0 :               ikev2_payload_add_delete (chain, sa->del);
    2589             :             }
    2590          18 :           vec_free (sa->del);
    2591          18 :           sa->del = 0;
    2592             :         }
    2593             :       /* received N(AUTHENTICATION_FAILED) */
    2594           3 :       else if (sa->state == IKEV2_STATE_AUTH_FAILED)
    2595             :         {
    2596           0 :           ikev2_set_state (sa, IKEV2_STATE_DELETED, ": auth failed");
    2597           0 :           goto done;
    2598             :         }
    2599             :       /* received unsupported critical payload */
    2600           3 :       else if (sa->unsupported_cp)
    2601             :         {
    2602           0 :           u8 *data = vec_new (u8, 1);
    2603             : 
    2604           0 :           data[0] = sa->unsupported_cp;
    2605           0 :           ikev2_payload_add_notify (chain,
    2606             :                                     IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
    2607             :                                     data);
    2608           0 :           vec_free (data);
    2609           0 :           sa->unsupported_cp = 0;
    2610             :         }
    2611             :       else
    2612             :         /* else send empty response */
    2613             :         {
    2614           3 :           if (ike_hdr_is_response (ike))
    2615             :             {
    2616           1 :               ASSERT (stats != 0);
    2617           1 :               stats->n_keepalives++;
    2618           1 :               sa->stats.n_keepalives++;
    2619             :             }
    2620             :         }
    2621             :     }
    2622          11 :   else if (ike->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA)
    2623             :     {
    2624          11 :       if (sa->is_initiator)
    2625             :         {
    2626             : 
    2627           3 :           ikev2_sa_proposal_t *proposals = (ikev2_sa_proposal_t *) user;
    2628             :           ikev2_notify_t notify;
    2629           3 :           u8 *data = vec_new (u8, 4);
    2630           3 :           clib_memset (&notify, 0, sizeof (notify));
    2631           3 :           notify.protocol_id = IKEV2_PROTOCOL_ESP;
    2632           3 :           notify.spi = sa->childs[0].i_proposals->spi;
    2633           3 :           *(u32 *) data = clib_host_to_net_u32 (notify.spi);
    2634             : 
    2635           3 :           ikev2_payload_add_sa (chain, proposals);
    2636           3 :           ikev2_payload_add_nonce (chain, sa->i_nonce);
    2637           3 :           ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
    2638           3 :           ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
    2639           3 :           ikev2_payload_add_notify_2 (chain, IKEV2_NOTIFY_MSG_REKEY_SA, data,
    2640             :                                       &notify);
    2641             : 
    2642           3 :           vec_free (data);
    2643             :         }
    2644           8 :       else if (vec_len (sa->rekey) > 0)
    2645             :         {
    2646           8 :           ikev2_add_create_child_resp (sa, &sa->rekey[0], chain);
    2647           8 :           vec_del1 (sa->rekey, 0);
    2648             :         }
    2649           0 :       else if (vec_len (sa->new_child) > 0)
    2650             :         {
    2651           0 :           ikev2_add_create_child_resp (sa, &sa->new_child[0], chain);
    2652           0 :           vec_del1 (sa->new_child, 0);
    2653             :         }
    2654           0 :       else if (sa->unsupported_cp)
    2655             :         {
    2656           0 :           u8 *data = vec_new (u8, 1);
    2657             : 
    2658           0 :           data[0] = sa->unsupported_cp;
    2659           0 :           ikev2_payload_add_notify (
    2660             :             chain, IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, data);
    2661           0 :           vec_free (data);
    2662           0 :           sa->unsupported_cp = 0;
    2663             :         }
    2664             :       else
    2665             :         {
    2666           0 :           ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NO_ADDITIONAL_SAS,
    2667             :                                     0);
    2668             :         }
    2669             :     }
    2670             : 
    2671             :   /* IKEv2 header */
    2672          64 :   ike->version = IKE_VERSION_2;
    2673          64 :   ike->nextpayload = IKEV2_PAYLOAD_SK;
    2674          64 :   tlen = sizeof (*ike);
    2675             : 
    2676          64 :   if (sa->is_initiator)
    2677          16 :     ike->flags |= IKEV2_HDR_FLAG_INITIATOR;
    2678             : 
    2679          64 :   if (ike->exchange == IKEV2_EXCHANGE_SA_INIT)
    2680             :     {
    2681          13 :       tlen += vec_len (chain->data);
    2682          13 :       ike->nextpayload = chain->first_payload_type;
    2683          13 :       ike->length = clib_host_to_net_u32 (tlen);
    2684             : 
    2685          13 :       if (tlen + b->current_length + b->current_data > buffer_data_size)
    2686             :         {
    2687           0 :           tlen = ~0;
    2688           0 :           goto done;
    2689             :         }
    2690             : 
    2691          13 :       clib_memcpy_fast (ike->payload, chain->data, vec_len (chain->data));
    2692             : 
    2693             :       /* store whole IKE payload - needed for PSK auth */
    2694          13 :       vec_reset_length (sa->last_sa_init_res_packet_data);
    2695          13 :       vec_add (sa->last_sa_init_res_packet_data, ike, tlen);
    2696             :     }
    2697             :   else
    2698             :     {
    2699          51 :       ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
    2700          51 :       ikev2_payload_chain_add_padding (chain, tr_encr->block_size);
    2701             : 
    2702             :       /* SK payload */
    2703          51 :       plen = sizeof (*ph);
    2704          51 :       ph = (ike_payload_header_t *) & ike->payload[0];
    2705          51 :       ph->nextpayload = chain->first_payload_type;
    2706          51 :       ph->flags = 0;
    2707          51 :       int is_aead =
    2708          51 :         tr_encr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_GCM_16;
    2709          51 :       int iv_len = is_aead ? IKEV2_GCM_IV_SIZE : tr_encr->block_size;
    2710          51 :       plen += vec_len (chain->data) + iv_len;
    2711             : 
    2712             :       /* add space for hmac/tag */
    2713          51 :       if (tr_integ)
    2714          33 :         plen += tr_integ->key_trunc;
    2715             :       else
    2716          18 :         plen += IKEV2_GCM_ICV_SIZE;
    2717          51 :       tlen += plen;
    2718             : 
    2719          51 :       if (tlen + b->current_length + b->current_data > buffer_data_size)
    2720             :         {
    2721           0 :           tlen = ~0;
    2722           0 :           goto done;
    2723             :         }
    2724             : 
    2725             :       /* payload and total length */
    2726          51 :       ph->length = clib_host_to_net_u16 (plen);
    2727          51 :       ike->length = clib_host_to_net_u32 (tlen);
    2728             : 
    2729          51 :       if (is_aead)
    2730             :         {
    2731          18 :           if (!ikev2_encrypt_aead_data (ptd, sa, tr_encr, chain->data,
    2732          18 :                                         ph->payload, (u8 *) ike,
    2733             :                                         sizeof (*ike) + sizeof (*ph),
    2734          18 :                                         ph->payload + plen - sizeof (*ph) -
    2735             :                                         IKEV2_GCM_ICV_SIZE))
    2736             :             {
    2737           0 :               tlen = ~0;
    2738           0 :               goto done;
    2739             :             }
    2740             :         }
    2741             :       else
    2742             :         {
    2743          33 :           if (!ikev2_encrypt_data
    2744          33 :               (ptd, sa, tr_encr, chain->data, ph->payload))
    2745             :             {
    2746           0 :               tlen = ~0;
    2747           0 :               goto done;
    2748             :             }
    2749          33 :           integ =
    2750          33 :             ikev2_calc_integr (tr_integ,
    2751          33 :                                sa->is_initiator ? sa->sk_ai : sa->sk_ar,
    2752          33 :                                (u8 *) ike, tlen - tr_integ->key_trunc);
    2753          33 :           clib_memcpy_fast (ike->payload + tlen - tr_integ->key_trunc -
    2754          33 :                             sizeof (*ike), integ, tr_integ->key_trunc);
    2755             :         }
    2756             : 
    2757             :       /* store whole IKE payload - needed for retransmit */
    2758          51 :       vec_reset_length (sa->last_res_packet_data);
    2759          51 :       vec_add (sa->last_res_packet_data, ike, tlen);
    2760             :     }
    2761             : 
    2762          64 : done:
    2763          64 :   ikev2_payload_destroy_chain (chain);
    2764          64 :   vec_free (integ);
    2765          64 :   return tlen;
    2766             : }
    2767             : 
    2768             : static u32
    2769           0 : ikev2_retransmit_sa_init_one (ikev2_sa_t * sa, ike_header_t * ike,
    2770             :                               ip_address_t iaddr, ip_address_t raddr,
    2771             :                               u32 rlen)
    2772             : {
    2773           0 :   int p = 0;
    2774             :   ike_header_t *tmp;
    2775           0 :   u8 payload = ike->nextpayload;
    2776             : 
    2777           0 :   if (sa->ispi != clib_net_to_host_u64 (ike->ispi) ||
    2778           0 :       ip_address_cmp (&sa->iaddr, &iaddr) ||
    2779           0 :       ip_address_cmp (&sa->raddr, &raddr))
    2780             :     {
    2781           0 :       return 0;
    2782             :     }
    2783             : 
    2784           0 :   while (p < rlen && payload != IKEV2_PAYLOAD_NONE)
    2785             :     {
    2786           0 :       ike_payload_header_t *ikep = (ike_payload_header_t *) & ike->payload[p];
    2787           0 :       u32 plen = clib_net_to_host_u16 (ikep->length);
    2788             : 
    2789           0 :       if (plen < sizeof (ike_payload_header_t))
    2790           0 :         return ~0;
    2791             : 
    2792           0 :       if (payload == IKEV2_PAYLOAD_NONCE &&
    2793           0 :           !clib_memcmp (sa->i_nonce, ikep->payload, plen - sizeof (*ikep)))
    2794             :         {
    2795             :           /* req is retransmit */
    2796           0 :           if (sa->state == IKEV2_STATE_SA_INIT)
    2797             :             {
    2798           0 :               sa->stats.n_init_retransmit++;
    2799           0 :               tmp = (ike_header_t *) sa->last_sa_init_res_packet_data;
    2800           0 :               u32 slen = clib_net_to_host_u32 (tmp->length);
    2801           0 :               ike->ispi = tmp->ispi;
    2802           0 :               ike->rspi = tmp->rspi;
    2803           0 :               ike->nextpayload = tmp->nextpayload;
    2804           0 :               ike->version = tmp->version;
    2805           0 :               ike->exchange = tmp->exchange;
    2806           0 :               ike->flags = tmp->flags;
    2807           0 :               ike->msgid = tmp->msgid;
    2808           0 :               ike->length = tmp->length;
    2809           0 :               clib_memcpy_fast (ike->payload, tmp->payload,
    2810             :                                 slen - sizeof (*ike));
    2811           0 :               ikev2_elog_uint_peers (IKEV2_LOG_DEBUG,
    2812             :                                      "ispi %lx IKE_SA_INIT retransmit "
    2813             :                                      "from %d.%d.%d.%d to %d.%d.%d.%d",
    2814             :                                      ike->ispi,
    2815             :                                      ip_addr_v4 (&raddr).as_u32,
    2816             :                                      ip_addr_v4 (&iaddr).as_u32);
    2817           0 :               return slen;
    2818             :             }
    2819             :           /* else ignore req */
    2820             :           else
    2821             :             {
    2822           0 :               ikev2_elog_uint_peers (IKEV2_LOG_DEBUG,
    2823             :                                      "ispi %lx IKE_SA_INIT ignore "
    2824             :                                      "from %d.%d.%d.%d to %d.%d.%d.%d",
    2825             :                                      ike->ispi,
    2826             :                                      ip_addr_v4 (&raddr).as_u32,
    2827             :                                      ip_addr_v4 (&iaddr).as_u32);
    2828           0 :               return ~0;
    2829             :             }
    2830             :         }
    2831           0 :       payload = ikep->nextpayload;
    2832           0 :       p += plen;
    2833             :     }
    2834             : 
    2835           0 :   return 0;
    2836             : }
    2837             : 
    2838             : static u32
    2839         267 : ikev2_retransmit_sa_init (ike_header_t * ike, ip_address_t iaddr,
    2840             :                           ip_address_t raddr, u32 rlen)
    2841             : {
    2842             :   ikev2_sa_t *sa;
    2843             :   u32 res;
    2844         267 :   ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
    2845             : 
    2846             :   /* *INDENT-OFF* */
    2847         267 :   pool_foreach (sa, ptd->sas)  {
    2848           0 :     res = ikev2_retransmit_sa_init_one (sa, ike, iaddr, raddr, rlen);
    2849           0 :     if (res)
    2850           0 :       return res;
    2851             :   }
    2852             :   /* *INDENT-ON* */
    2853             : 
    2854             :   /* req is not retransmit */
    2855         267 :   return 0;
    2856             : }
    2857             : 
    2858             : static u32
    2859          43 : ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike)
    2860             : {
    2861          43 :   if (ike_hdr_is_response (ike))
    2862           9 :     return 0;
    2863             : 
    2864          34 :   u32 msg_id = clib_net_to_host_u32 (ike->msgid);
    2865             : 
    2866             :   /* new req */
    2867          34 :   if (msg_id > sa->last_msg_id || sa->last_msg_id == ~0)
    2868             :     {
    2869          34 :       sa->last_msg_id = msg_id;
    2870          34 :       return 0;
    2871             :     }
    2872             : 
    2873             :   /* retransmitted req */
    2874           0 :   if (msg_id == sa->last_msg_id)
    2875             :     {
    2876           0 :       sa->stats.n_retransmit++;
    2877           0 :       ike_header_t *tmp = (ike_header_t *) sa->last_res_packet_data;
    2878           0 :       u32 slen = clib_net_to_host_u32 (tmp->length);
    2879           0 :       ike->ispi = tmp->ispi;
    2880           0 :       ike->rspi = tmp->rspi;
    2881           0 :       ike->nextpayload = tmp->nextpayload;
    2882           0 :       ike->version = tmp->version;
    2883           0 :       ike->exchange = tmp->exchange;
    2884           0 :       ike->flags = tmp->flags;
    2885           0 :       ike->msgid = tmp->msgid;
    2886           0 :       ike->length = tmp->length;
    2887           0 :       clib_memcpy_fast (ike->payload, tmp->payload, slen - sizeof (*ike));
    2888           0 :       ikev2_elog_uint_peers (IKEV2_LOG_DEBUG, "IKE retransmit msgid %d",
    2889             :                              msg_id, ip_addr_v4 (&sa->raddr).as_u32,
    2890             :                              ip_addr_v4 (&sa->iaddr).as_u32);
    2891           0 :       return slen;
    2892             :     }
    2893             : 
    2894             :   /* old req ignore */
    2895           0 :   ikev2_elog_uint_peers (IKEV2_LOG_DEBUG, "IKE req ignore msgid %d",
    2896             :                          msg_id, ip_addr_v4 (&sa->raddr).as_u32,
    2897             :                          ip_addr_v4 (&sa->iaddr).as_u32);
    2898           0 :   return ~0;
    2899             : }
    2900             : 
    2901             : static void
    2902          13 : ikev2_init_sa (vlib_main_t * vm, ikev2_sa_t * sa)
    2903             : {
    2904          13 :   ikev2_main_t *km = &ikev2_main;
    2905          13 :   sa->liveness_period_check = vlib_time_now (vm) + km->liveness_period;
    2906          13 :   sa->profile_index = ~0;
    2907          13 : }
    2908             : 
    2909             : static void
    2910           6 : ikev2_del_sa_init_from_main (u64 * ispi)
    2911             : {
    2912           6 :   ikev2_main_t *km = &ikev2_main;
    2913           6 :   uword *p = hash_get (km->sa_by_ispi, *ispi);
    2914           6 :   if (p)
    2915             :     {
    2916           6 :       ikev2_sa_t *sai = pool_elt_at_index (km->sais, p[0]);
    2917           6 :       hash_unset (km->sa_by_ispi, sai->ispi);
    2918           6 :       ikev2_sa_free_all_vec (sai);
    2919           6 :       pool_put (km->sais, sai);
    2920             :     }
    2921           6 : }
    2922             : 
    2923             : static void
    2924           6 : ikev2_del_sa_init (u64 ispi)
    2925             : {
    2926           6 :   vl_api_rpc_call_main_thread (ikev2_del_sa_init_from_main, (u8 *) & ispi,
    2927             :                                sizeof (ispi));
    2928           6 : }
    2929             : 
    2930             : static void
    2931           2 : ikev2_rewrite_v6_addrs (ikev2_sa_t *sa, ip6_header_t *ih)
    2932             : {
    2933           2 :   if (sa->is_initiator)
    2934             :     {
    2935           0 :       ip_address_copy_addr (&ih->dst_address, &sa->raddr);
    2936           0 :       ip_address_copy_addr (&ih->src_address, &sa->iaddr);
    2937             :     }
    2938             :   else
    2939             :     {
    2940           2 :       ip_address_copy_addr (&ih->dst_address, &sa->iaddr);
    2941           2 :       ip_address_copy_addr (&ih->src_address, &sa->raddr);
    2942             :     }
    2943           2 : }
    2944             : 
    2945             : static void
    2946          51 : ikev2_rewrite_v4_addrs (ikev2_sa_t *sa, ip4_header_t *ih)
    2947             : {
    2948          51 :   if (sa->is_initiator)
    2949             :     {
    2950           8 :       ip_address_copy_addr (&ih->dst_address, &sa->raddr);
    2951           8 :       ip_address_copy_addr (&ih->src_address, &sa->iaddr);
    2952             :     }
    2953             :   else
    2954             :     {
    2955          43 :       ip_address_copy_addr (&ih->dst_address, &sa->iaddr);
    2956          43 :       ip_address_copy_addr (&ih->src_address, &sa->raddr);
    2957             :     }
    2958          51 : }
    2959             : 
    2960             : static void
    2961         273 : ikev2_set_ip_address (ikev2_sa_t *sa, const void *iaddr, const void *raddr,
    2962             :                       const ip_address_family_t af)
    2963             : {
    2964         273 :   ip_address_set (&sa->raddr, raddr, af);
    2965         273 :   ip_address_set (&sa->iaddr, iaddr, af);
    2966         273 : }
    2967             : 
    2968             : static void
    2969           0 : ikev2_elog_uint_peers_addr (u32 exchange, ip4_header_t * ip4,
    2970             :                             ip6_header_t * ip6, u8 is_ip4)
    2971             : {
    2972             :   u32 src, dst;
    2973           0 :   if (is_ip4)
    2974             :     {
    2975           0 :       src = ip4->src_address.as_u32;
    2976           0 :       dst = ip4->dst_address.as_u32;
    2977             :     }
    2978             :   else
    2979             :     {
    2980           0 :       src = ip6->src_address.as_u32[3];
    2981           0 :       dst = ip6->dst_address.as_u32[3];
    2982             :     }
    2983           0 :   ikev2_elog_uint_peers (IKEV2_LOG_WARNING, "IKEv2 exchange %d "
    2984             :                          "received from %d.%d.%d.%d to %d.%d.%d.%d",
    2985             :                          exchange, src, dst);
    2986           0 : }
    2987             : 
    2988             : static void
    2989          13 : ikev2_generate_sa_init_data_and_log (ikev2_sa_t * sa)
    2990             : {
    2991          13 :   ikev2_generate_sa_error_t rc = ikev2_generate_sa_init_data (sa);
    2992             : 
    2993          13 :   if (PREDICT_TRUE (rc == IKEV2_GENERATE_SA_INIT_OK))
    2994          13 :     return;
    2995             : 
    2996           0 :   if (rc == IKEV2_GENERATE_SA_INIT_ERR_NO_DH)
    2997           0 :     ikev2_elog_error (IKEV2_GENERATE_SA_INIT_OK_ERR_NO_DH_STR);
    2998           0 :   else if (rc == IKEV2_GENERATE_SA_INIT_ERR_UNSUPPORTED_DH)
    2999           0 :     ikev2_elog_error (IKEV2_GENERATE_SA_INIT_OK_ERR_UNSUPP_STR);
    3000             : }
    3001             : 
    3002             : static void
    3003          64 : ikev2_update_stats (vlib_main_t *vm, u32 node_index, ikev2_stats_t *s)
    3004             : {
    3005          64 :   vlib_node_increment_counter (vm, node_index, IKEV2_ERROR_KEEPALIVE,
    3006          64 :                                s->n_keepalives);
    3007          64 :   vlib_node_increment_counter (vm, node_index, IKEV2_ERROR_REKEY_REQ,
    3008          64 :                                s->n_rekey_req);
    3009          64 :   vlib_node_increment_counter (vm, node_index, IKEV2_ERROR_INIT_SA_REQ,
    3010          64 :                                s->n_sa_init_req);
    3011          64 :   vlib_node_increment_counter (vm, node_index, IKEV2_ERROR_IKE_AUTH_REQ,
    3012          64 :                                s->n_sa_auth_req);
    3013          64 : }
    3014             : 
    3015             : static uword
    3016          64 : ikev2_node_internal (vlib_main_t *vm, vlib_node_runtime_t *node,
    3017             :                      vlib_frame_t *frame, u8 is_ip4, u8 natt)
    3018             : {
    3019          64 :   u32 n_left = frame->n_vectors, *from;
    3020          64 :   ikev2_main_t *km = &ikev2_main;
    3021             :   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
    3022          64 :   u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
    3023          64 :   ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
    3024          64 :   ikev2_stats_t _stats, *stats = &_stats;
    3025             :   int res;
    3026             : 
    3027             :   /* no NAT traversal for ip6 */
    3028          64 :   ASSERT (!natt || is_ip4);
    3029             : 
    3030          64 :   clib_memset_u16 (stats, 0, sizeof (stats[0]) / sizeof (u16));
    3031          64 :   from = vlib_frame_vector_args (frame);
    3032          64 :   vlib_get_buffers (vm, from, bufs, n_left);
    3033          64 :   b = bufs;
    3034             : 
    3035         634 :   while (n_left > 0)
    3036             :     {
    3037         570 :       vlib_buffer_t *b0 = b[0];
    3038         570 :       next[0] = is_ip4 ? IKEV2_NEXT_IP4_ERROR_DROP
    3039             :         : IKEV2_NEXT_IP6_ERROR_DROP;
    3040         570 :       ip4_header_t *ip40 = 0;
    3041         570 :       ip6_header_t *ip60 = 0;
    3042             :       udp_header_t *udp0;
    3043             :       ike_header_t *ike0;
    3044         570 :       ikev2_sa_t *sa0 = 0;
    3045             :       ikev2_sa_t sa;            /* temporary store for SA */
    3046         570 :       u32 rlen, slen = 0;
    3047         570 :       int ip_hdr_sz = 0;
    3048         570 :       int is_req = 0;
    3049             : 
    3050         570 :       if (natt)
    3051             :         {
    3052           7 :           u8 *ptr = vlib_buffer_get_current (b0);
    3053           7 :           ip40 = (ip4_header_t *) ptr;
    3054           7 :           ptr += sizeof (*ip40);
    3055           7 :           udp0 = (udp_header_t *) ptr;
    3056           7 :           ptr += sizeof (*udp0);
    3057           7 :           ike0 = (ike_header_t *) ptr;
    3058           7 :           ip_hdr_sz = sizeof (*ip40);
    3059             :         }
    3060             :       else
    3061             :         {
    3062         563 :           u8 *ipx_hdr = b0->data + vnet_buffer (b0)->l3_hdr_offset;
    3063         563 :           ike0 = vlib_buffer_get_current (b0);
    3064         563 :           vlib_buffer_advance (b0, -sizeof (*udp0));
    3065         563 :           udp0 = vlib_buffer_get_current (b0);
    3066             : 
    3067         563 :           if (is_ip4)
    3068             :             {
    3069         561 :               ip40 = (ip4_header_t *) ipx_hdr;
    3070         561 :               ip_hdr_sz = sizeof (*ip40);
    3071             :             }
    3072             :           else
    3073             :             {
    3074           2 :               ip60 = (ip6_header_t *) ipx_hdr;
    3075           2 :               ip_hdr_sz = sizeof (*ip60);
    3076             :             }
    3077         563 :           vlib_buffer_advance (b0, -ip_hdr_sz);
    3078             :         }
    3079             : 
    3080         570 :       rlen = b0->current_length - ip_hdr_sz - sizeof (*udp0);
    3081             : 
    3082             :       /* check for non-esp marker */
    3083         570 :       if (natt)
    3084             :         {
    3085           7 :           ASSERT (*((u32 *) ike0) == 0);
    3086           7 :           ike0 =
    3087             :             (ike_header_t *) ((u8 *) ike0 + sizeof (ikev2_non_esp_marker));
    3088           7 :           rlen -= sizeof (ikev2_non_esp_marker);
    3089             :         }
    3090             : 
    3091         570 :       if (clib_net_to_host_u32 (ike0->length) != rlen)
    3092             :         {
    3093         254 :           vlib_node_increment_counter (vm, node->node_index,
    3094             :                                        IKEV2_ERROR_BAD_LENGTH, 1);
    3095         254 :           goto dispatch0;
    3096             :         }
    3097             : 
    3098         316 :       if (ike0->version != IKE_VERSION_2)
    3099             :         {
    3100           0 :           vlib_node_increment_counter (vm, node->node_index,
    3101             :                                        IKEV2_ERROR_NOT_IKEV2, 1);
    3102           0 :           goto dispatch0;
    3103             :         }
    3104             : 
    3105         316 :       if (ike0->exchange == IKEV2_EXCHANGE_SA_INIT)
    3106             :         {
    3107         273 :           sa0 = &sa;
    3108         273 :           clib_memset (sa0, 0, sizeof (*sa0));
    3109             : 
    3110         273 :           if (ike_hdr_is_initiator (ike0))
    3111             :             {
    3112         267 :               sa0->stats.n_sa_init_req++;
    3113         267 :               stats->n_sa_init_req++;
    3114         267 :               if (ike0->rspi == 0)
    3115             :                 {
    3116         267 :                   if (is_ip4)
    3117         266 :                     ikev2_set_ip_address (sa0, &ip40->src_address,
    3118         266 :                                           &ip40->dst_address, AF_IP4);
    3119             :                   else
    3120           1 :                     ikev2_set_ip_address (sa0, &ip60->src_address,
    3121           1 :                                           &ip60->dst_address, AF_IP6);
    3122             : 
    3123         267 :                   sa0->dst_port = clib_net_to_host_u16 (udp0->src_port);
    3124             : 
    3125             :                   slen =
    3126         267 :                     ikev2_retransmit_sa_init (ike0, sa0->iaddr,
    3127         267 :                                               sa0->raddr, rlen);
    3128         267 :                   if (slen)
    3129             :                     {
    3130           0 :                       vlib_node_increment_counter (vm, node->node_index,
    3131             :                                                    ~0 ==
    3132             :                                                    slen ?
    3133             :                                                    IKEV2_ERROR_IKE_SA_INIT_IGNORE
    3134             :                                                    :
    3135             :                                                    IKEV2_ERROR_IKE_SA_INIT_RETRANSMIT,
    3136             :                                                    1);
    3137           0 :                       goto dispatch0;
    3138             :                     }
    3139             : 
    3140         267 :                   res = ikev2_process_sa_init_req (
    3141             :                     vm, sa0, ike0, udp0, rlen,
    3142         267 :                     vnet_buffer (b0)->sw_if_index[VLIB_RX]);
    3143         267 :                   if (!res)
    3144         254 :                     vlib_node_increment_counter (vm, node->node_index,
    3145             :                                                  IKEV2_ERROR_MALFORMED_PACKET,
    3146             :                                                  1);
    3147             : 
    3148         267 :                   if (sa0->state == IKEV2_STATE_SA_INIT)
    3149             :                     {
    3150          13 :                       ikev2_sa_free_proposal_vector (&sa0->r_proposals);
    3151          26 :                       sa0->r_proposals =
    3152          13 :                         ikev2_select_proposal (sa0->i_proposals,
    3153             :                                                IKEV2_PROTOCOL_IKE);
    3154          13 :                       ikev2_generate_sa_init_data_and_log (sa0);
    3155             :                     }
    3156             : 
    3157         267 :                   if (sa0->state == IKEV2_STATE_SA_INIT
    3158         254 :                       || sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE)
    3159             :                     {
    3160          13 :                       ike0->flags = IKEV2_HDR_FLAG_RESPONSE;
    3161             :                       slen =
    3162          13 :                         ikev2_generate_message (b0, sa0, ike0, 0, udp0, stats);
    3163          13 :                       if (~0 == slen)
    3164           0 :                         vlib_node_increment_counter (vm, node->node_index,
    3165             :                                                      IKEV2_ERROR_NO_BUFF_SPACE,
    3166             :                                                      1);
    3167             :                     }
    3168             : 
    3169         267 :                   if (sa0->state == IKEV2_STATE_SA_INIT)
    3170             :                     {
    3171             :                       /* add SA to the pool */
    3172          13 :                       pool_get (ptd->sas, sa0);
    3173          13 :                       clib_memcpy_fast (sa0, &sa, sizeof (*sa0));
    3174          13 :                       ikev2_init_sa (vm, sa0);
    3175          13 :                       hash_set (ptd->sa_by_rspi, sa0->rspi, sa0 - ptd->sas);
    3176             :                     }
    3177             :                   else
    3178             :                     {
    3179         254 :                       ikev2_sa_free_all_vec (sa0);
    3180             :                     }
    3181             :                 }
    3182             :             }
    3183             :           else                  //received sa_init without initiator flag
    3184             :             {
    3185           6 :               if (is_ip4)
    3186           6 :                 ikev2_set_ip_address (sa0, &ip40->dst_address,
    3187           6 :                                       &ip40->src_address, AF_IP4);
    3188             :               else
    3189           0 :                 ikev2_set_ip_address (sa0, &ip60->dst_address,
    3190           0 :                                       &ip60->src_address, AF_IP6);
    3191             : 
    3192           6 :               ikev2_process_sa_init_resp (vm, sa0, ike0, udp0, rlen);
    3193             : 
    3194           6 :               if (sa0->state == IKEV2_STATE_SA_INIT)
    3195             :                 {
    3196           6 :                   is_req = 1;
    3197           6 :                   ike0->exchange = IKEV2_EXCHANGE_IKE_AUTH;
    3198           6 :                   uword *p = hash_get (km->sa_by_ispi, sa0->ispi);
    3199           6 :                   if (p)
    3200             :                     {
    3201           6 :                       ikev2_sa_t *sai = pool_elt_at_index (km->sais, p[0]);
    3202             : 
    3203           6 :                       if (clib_atomic_bool_cmp_and_swap
    3204             :                           (&sai->init_response_received, 0, 1))
    3205             :                         {
    3206           6 :                           ikev2_complete_sa_data (sa0, sai);
    3207           6 :                           ikev2_calc_keys (sa0);
    3208           6 :                           ikev2_sa_auth_init (sa0);
    3209           6 :                           ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
    3210           6 :                           ike0->msgid =
    3211           6 :                             clib_net_to_host_u32 (sai->last_init_msg_id);
    3212           6 :                           sa0->last_init_msg_id = sai->last_init_msg_id + 1;
    3213           6 :                           slen = ikev2_generate_message (b0, sa0, ike0, 0,
    3214             :                                                          udp0, stats);
    3215           6 :                           if (~0 == slen)
    3216           0 :                             vlib_node_increment_counter (vm,
    3217             :                                                          node->node_index,
    3218             :                                                          IKEV2_ERROR_NO_BUFF_SPACE,
    3219             :                                                          1);
    3220             :                         }
    3221             :                       else
    3222             :                         {
    3223             :                           /* we've already processed sa-init response */
    3224           0 :                           sa0->state = IKEV2_STATE_UNKNOWN;
    3225             :                         }
    3226             :                     }
    3227             :                 }
    3228             : 
    3229           6 :               if (sa0->state == IKEV2_STATE_SA_INIT)
    3230             :                 {
    3231             :                   /* add SA to the pool */
    3232           6 :                   pool_get (ptd->sas, sa0);
    3233           6 :                   clib_memcpy_fast (sa0, &sa, sizeof (*sa0));
    3234           6 :                   hash_set (ptd->sa_by_rspi, sa0->rspi, sa0 - ptd->sas);
    3235             :                 }
    3236             :               else
    3237             :                 {
    3238           0 :                   ikev2_sa_free_all_vec (sa0);
    3239             :                 }
    3240             :             }
    3241             :         }
    3242          43 :       else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH)
    3243             :         {
    3244             :           uword *p;
    3245          19 :           p = hash_get (ptd->sa_by_rspi, clib_net_to_host_u64 (ike0->rspi));
    3246          19 :           if (p)
    3247             :             {
    3248          19 :               sa0 = pool_elt_at_index (ptd->sas, p[0]);
    3249          19 :               slen = ikev2_retransmit_resp (sa0, ike0);
    3250          19 :               if (slen)
    3251             :                 {
    3252           0 :                   vlib_node_increment_counter (vm, node->node_index,
    3253             :                                                ~0 ==
    3254             :                                                slen ?
    3255             :                                                IKEV2_ERROR_IKE_REQ_IGNORE
    3256             :                                                :
    3257             :                                                IKEV2_ERROR_IKE_REQ_RETRANSMIT,
    3258             :                                                1);
    3259           0 :                   goto dispatch0;
    3260             :                 }
    3261             : 
    3262          19 :               sa0->dst_port = clib_net_to_host_u16 (udp0->src_port);
    3263          19 :               res = ikev2_process_auth_req (vm, sa0, ike0, rlen);
    3264          19 :               if (res)
    3265          19 :                 ikev2_sa_auth (sa0);
    3266             :               else
    3267           0 :                 vlib_node_increment_counter (vm, node->node_index,
    3268             :                                              IKEV2_ERROR_MALFORMED_PACKET, 1);
    3269          19 :               if (sa0->state == IKEV2_STATE_AUTHENTICATED)
    3270             :                 {
    3271          19 :                   ikev2_initial_contact_cleanup (ptd, sa0);
    3272          19 :                   ikev2_sa_match_ts (sa0);
    3273          19 :                   if (sa0->state != IKEV2_STATE_TS_UNACCEPTABLE)
    3274          19 :                     ikev2_create_tunnel_interface (vm, sa0, &sa0->childs[0],
    3275          19 :                                                    p[0], 0, 0, 0);
    3276             :                 }
    3277             : 
    3278          19 :               if (sa0->is_initiator)
    3279             :                 {
    3280           6 :                   sa0->last_msg_id = ~0;
    3281           6 :                   ikev2_del_sa_init (sa0->ispi);
    3282             :                 }
    3283             :               else
    3284             :                 {
    3285          13 :                   sa0->stats.n_sa_auth_req++;
    3286          13 :                   stats->n_sa_auth_req++;
    3287          13 :                   ike0->flags = IKEV2_HDR_FLAG_RESPONSE;
    3288             :                   slen =
    3289          13 :                     ikev2_generate_message (b0, sa0, ike0, 0, udp0, stats);
    3290          13 :                   if (~0 == slen)
    3291           0 :                     vlib_node_increment_counter (vm, node->node_index,
    3292             :                                                  IKEV2_ERROR_NO_BUFF_SPACE,
    3293             :                                                  1);
    3294             :                 }
    3295             :             }
    3296             :         }
    3297          24 :       else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL)
    3298             :         {
    3299             :           uword *p;
    3300          13 :           p = hash_get (ptd->sa_by_rspi, clib_net_to_host_u64 (ike0->rspi));
    3301          13 :           if (p)
    3302             :             {
    3303          13 :               sa0 = pool_elt_at_index (ptd->sas, p[0]);
    3304          13 :               slen = ikev2_retransmit_resp (sa0, ike0);
    3305          13 :               if (slen)
    3306             :                 {
    3307           0 :                   vlib_node_increment_counter (vm, node->node_index,
    3308             :                                                ~0 ==
    3309             :                                                slen ?
    3310             :                                                IKEV2_ERROR_IKE_REQ_IGNORE
    3311             :                                                :
    3312             :                                                IKEV2_ERROR_IKE_REQ_RETRANSMIT,
    3313             :                                                1);
    3314           0 :                   goto dispatch0;
    3315             :                 }
    3316             : 
    3317          13 :               res = ikev2_process_informational_req (vm, sa0, ike0, rlen);
    3318          13 :               if (!res)
    3319             :                 {
    3320           0 :                   vlib_node_increment_counter (vm, node->node_index,
    3321             :                                                IKEV2_ERROR_MALFORMED_PACKET,
    3322             :                                                1);
    3323           0 :                   slen = ~0;
    3324           0 :                   goto dispatch0;
    3325             :                 }
    3326             : 
    3327          13 :               if (sa0->del)
    3328             :                 {
    3329          12 :                   if (sa0->del[0].protocol_id != IKEV2_PROTOCOL_IKE)
    3330             :                     {
    3331           0 :                       ikev2_delete_t *d, *tmp, *resp = 0;
    3332           0 :                       vec_foreach (d, sa0->del)
    3333             :                       {
    3334             :                         ikev2_child_sa_t *ch_sa;
    3335           0 :                         ch_sa = ikev2_sa_get_child (sa0, d->spi,
    3336           0 :                                                     d->protocol_id,
    3337           0 :                                                     !sa0->is_initiator);
    3338           0 :                         if (ch_sa)
    3339             :                           {
    3340           0 :                             ikev2_delete_tunnel_interface (km->vnet_main,
    3341             :                                                            sa0, ch_sa);
    3342           0 :                             if (!sa0->is_initiator)
    3343             :                               {
    3344           0 :                                 vec_add2 (resp, tmp, 1);
    3345           0 :                                 tmp->protocol_id = d->protocol_id;
    3346           0 :                                 tmp->spi = ch_sa->r_proposals[0].spi;
    3347             :                               }
    3348           0 :                             ikev2_sa_del_child_sa (sa0, ch_sa);
    3349             :                           }
    3350             :                       }
    3351           0 :                       if (!sa0->is_initiator)
    3352             :                         {
    3353           0 :                           vec_free (sa0->del);
    3354           0 :                           sa0->del = resp;
    3355             :                         }
    3356             :                     }
    3357             :                 }
    3358          13 :               if (ike_hdr_is_request (ike0))
    3359             :                 {
    3360          13 :                   ike0->flags = IKEV2_HDR_FLAG_RESPONSE;
    3361             :                   slen =
    3362          13 :                     ikev2_generate_message (b0, sa0, ike0, 0, udp0, stats);
    3363          13 :                   if (~0 == slen)
    3364           0 :                     vlib_node_increment_counter (vm, node->node_index,
    3365             :                                                  IKEV2_ERROR_NO_BUFF_SPACE,
    3366             :                                                  1);
    3367             :                 }
    3368             :             }
    3369             :         }
    3370          11 :       else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA)
    3371             :         {
    3372             :           uword *p;
    3373          11 :           p = hash_get (ptd->sa_by_rspi, clib_net_to_host_u64 (ike0->rspi));
    3374          11 :           if (p)
    3375             :             {
    3376          11 :               sa0 = pool_elt_at_index (ptd->sas, p[0]);
    3377          11 :               slen = ikev2_retransmit_resp (sa0, ike0);
    3378          11 :               if (slen)
    3379             :                 {
    3380           0 :                   vlib_node_increment_counter (vm, node->node_index,
    3381             :                                                ~0 ==
    3382             :                                                slen ?
    3383             :                                                IKEV2_ERROR_IKE_REQ_IGNORE
    3384             :                                                :
    3385             :                                                IKEV2_ERROR_IKE_REQ_RETRANSMIT,
    3386             :                                                1);
    3387           0 :                   goto dispatch0;
    3388             :                 }
    3389             : 
    3390          11 :               res = ikev2_process_create_child_sa_req (vm, sa0, ike0, rlen);
    3391          11 :               if (!res)
    3392             :                 {
    3393           1 :                   vlib_node_increment_counter (vm, node->node_index,
    3394             :                                                IKEV2_ERROR_MALFORMED_PACKET,
    3395             :                                                1);
    3396           1 :                   slen = ~0;
    3397           1 :                   goto dispatch0;
    3398             :                 }
    3399             : 
    3400          10 :               if (vec_len (sa0->rekey) > 0)
    3401             :                 {
    3402          10 :                   if (!sa0->rekey[0].notify_type &&
    3403           8 :                       sa0->rekey[0].protocol_id != IKEV2_PROTOCOL_IKE)
    3404             :                     {
    3405           8 :                       if (vec_len (sa0->childs) > 0)
    3406           8 :                         ikev2_sa_free_all_child_sa (&sa0->childs);
    3407             :                       ikev2_child_sa_t *child;
    3408           8 :                       vec_add2 (sa0->childs, child, 1);
    3409           8 :                       clib_memset (child, 0, sizeof (*child));
    3410           8 :                       child->r_proposals = sa0->rekey[0].r_proposal;
    3411           8 :                       child->i_proposals = sa0->rekey[0].i_proposal;
    3412           8 :                       child->tsi = sa0->rekey[0].tsi;
    3413           8 :                       child->tsr = sa0->rekey[0].tsr;
    3414           8 :                       ikev2_create_tunnel_interface (vm, sa0, child, p[0],
    3415           8 :                                                      child - sa0->childs, 1,
    3416           8 :                                                      sa0->rekey[0].kex);
    3417             :                     }
    3418          10 :                   if (ike_hdr_is_response (ike0))
    3419             :                     {
    3420           2 :                       vec_free (sa0->rekey);
    3421             :                     }
    3422             :                   else
    3423             :                     {
    3424           8 :                       stats->n_rekey_req++;
    3425           8 :                       sa0->stats.n_rekey_req++;
    3426           8 :                       ike0->flags = IKEV2_HDR_FLAG_RESPONSE;
    3427             :                       slen =
    3428           8 :                         ikev2_generate_message (b0, sa0, ike0, 0, udp0, stats);
    3429           8 :                       if (~0 == slen)
    3430           0 :                         vlib_node_increment_counter (vm, node->node_index,
    3431             :                                                      IKEV2_ERROR_NO_BUFF_SPACE,
    3432             :                                                      1);
    3433             :                     }
    3434             :                 }
    3435           0 :               else if (vec_len (sa0->new_child) > 0)
    3436             :                 {
    3437             :                   ikev2_child_sa_t *c;
    3438           0 :                   vec_add2 (sa0->childs, c, 1);
    3439           0 :                   memset (c, 0, sizeof (*c));
    3440           0 :                   c->r_proposals = sa0->new_child[0].r_proposal;
    3441           0 :                   c->i_proposals = sa0->new_child[0].i_proposal;
    3442           0 :                   c->tsi = sa0->new_child[0].tsi;
    3443           0 :                   c->tsr = sa0->new_child[0].tsr;
    3444           0 :                   ikev2_create_tunnel_interface (vm, sa0, c, p[0],
    3445           0 :                                                  c - sa0->childs, 0,
    3446           0 :                                                  sa0->new_child[0].kex);
    3447           0 :                   if (ike_hdr_is_request (ike0))
    3448             :                     {
    3449           0 :                       ike0->flags = IKEV2_HDR_FLAG_RESPONSE;
    3450             :                       slen =
    3451           0 :                         ikev2_generate_message (b0, sa0, ike0, 0, udp0, 0);
    3452           0 :                       if (~0 == slen)
    3453           0 :                         vlib_node_increment_counter (
    3454             :                           vm, node->node_index, IKEV2_ERROR_NO_BUFF_SPACE, 1);
    3455             :                     }
    3456             :                 }
    3457             :             }
    3458             :         }
    3459             :       else
    3460             :         {
    3461           0 :           ikev2_elog_uint_peers_addr (ike0->exchange, ip40, ip60, is_ip4);
    3462             :         }
    3463             : 
    3464         570 :     dispatch0:
    3465             :       /* if we are sending packet back, rewrite headers */
    3466         570 :       if (slen && ~0 != slen)
    3467             :         {
    3468          53 :           if (is_ip4)
    3469             :             {
    3470          51 :               next[0] = IKEV2_NEXT_IP4_LOOKUP;
    3471          51 :               ikev2_rewrite_v4_addrs (sa0, ip40);
    3472             :             }
    3473             :           else
    3474             :             {
    3475           2 :               next[0] = IKEV2_NEXT_IP6_LOOKUP;
    3476           2 :               ikev2_rewrite_v6_addrs (sa0, ip60);
    3477             :             }
    3478             : 
    3479          53 :           if (is_req)
    3480             :             {
    3481           6 :               udp0->dst_port = udp0->src_port =
    3482           6 :                 clib_net_to_host_u16 (ikev2_get_port (sa0));
    3483             : 
    3484           6 :               if (udp0->dst_port == clib_net_to_host_u16 (IKEV2_PORT_NATT)
    3485           1 :                   && ikev2_natt_active (sa0))
    3486             :                 {
    3487           1 :                   if (!natt)
    3488           1 :                     slen = ikev2_insert_non_esp_marker (ike0, slen);
    3489             :                 }
    3490             :             }
    3491             :           else
    3492             :             {
    3493          47 :               if (natt)
    3494           6 :                 slen += sizeof (ikev2_non_esp_marker);
    3495             : 
    3496          47 :               u16 tp = udp0->dst_port;
    3497          47 :               udp0->dst_port = udp0->src_port;
    3498          47 :               udp0->src_port = tp;
    3499             :             }
    3500             : 
    3501          53 :           udp0->length = clib_host_to_net_u16 (slen + sizeof (udp_header_t));
    3502          53 :           udp0->checksum = 0;
    3503          53 :           b0->current_length = slen + ip_hdr_sz + sizeof (udp_header_t);
    3504          53 :           if (is_ip4)
    3505             :             {
    3506          51 :               ip40->length = clib_host_to_net_u16 (b0->current_length);
    3507          51 :               ip40->checksum = ip4_header_checksum (ip40);
    3508             :             }
    3509             :           else
    3510             :             {
    3511           2 :               ip60->payload_length =
    3512           2 :                 clib_host_to_net_u16 (b0->current_length - sizeof (*ip60));
    3513             :             }
    3514             :         }
    3515             :       /* delete sa */
    3516         570 :       if (sa0 && (sa0->state == IKEV2_STATE_DELETED ||
    3517         316 :                   sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE))
    3518             :         {
    3519             :           ikev2_child_sa_t *c;
    3520             : 
    3521          24 :           vec_foreach (c, sa0->childs)
    3522          12 :             ikev2_delete_tunnel_interface (km->vnet_main, sa0, c);
    3523             : 
    3524          12 :           ikev2_delete_sa (ptd, sa0);
    3525             :         }
    3526         570 :       if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
    3527             :                          && (b0->flags & VLIB_BUFFER_IS_TRACED)))
    3528             :         {
    3529             : 
    3530         570 :           ikev2_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
    3531         570 :           t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
    3532         570 :           t->next_index = next[0];
    3533             :         }
    3534         570 :       n_left -= 1;
    3535         570 :       next += 1;
    3536         570 :       b += 1;
    3537             :     }
    3538             : 
    3539          64 :   ikev2_update_stats (vm, node->node_index, stats);
    3540          64 :   vlib_node_increment_counter (vm, node->node_index,
    3541          64 :                                IKEV2_ERROR_PROCESSED, frame->n_vectors);
    3542          64 :   vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
    3543          64 :   return frame->n_vectors;
    3544             : }
    3545             : 
    3546             : static uword
    3547          55 : ikev2_ip4 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
    3548             : {
    3549          55 :   return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */, 0);
    3550             : }
    3551             : 
    3552             : static uword
    3553           7 : ikev2_ip4_natt (vlib_main_t *vm, vlib_node_runtime_t *node,
    3554             :                 vlib_frame_t *frame)
    3555             : {
    3556           7 :   return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */, 1 /* natt */);
    3557             : }
    3558             : 
    3559             : static uword
    3560           2 : ikev2_ip6 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
    3561             : {
    3562           2 :   return ikev2_node_internal (vm, node, frame, 0 /* is_ip4 */, 0);
    3563             : }
    3564             : 
    3565             : /* *INDENT-OFF* */
    3566      122120 : VLIB_REGISTER_NODE (ikev2_node_ip4,static) = {
    3567             :   .function = ikev2_ip4,
    3568             :   .name = "ikev2-ip4",
    3569             :   .vector_size = sizeof (u32),
    3570             :   .format_trace = format_ikev2_trace,
    3571             :   .type = VLIB_NODE_TYPE_INTERNAL,
    3572             : 
    3573             :   .n_errors = IKEV2_N_ERROR,
    3574             :   .error_counters = ikev2_error_counters,
    3575             : 
    3576             :   .n_next_nodes = IKEV2_IP4_N_NEXT,
    3577             :   .next_nodes = {
    3578             :     [IKEV2_NEXT_IP4_LOOKUP] = "ip4-lookup",
    3579             :     [IKEV2_NEXT_IP4_ERROR_DROP] = "error-drop",
    3580             :   },
    3581             : };
    3582             : 
    3583      122120 : VLIB_REGISTER_NODE (ikev2_node_ip4_natt,static) = {
    3584             :   .function = ikev2_ip4_natt,
    3585             :   .name = "ikev2-ip4-natt",
    3586             :   .vector_size = sizeof (u32),
    3587             :   .format_trace = format_ikev2_trace,
    3588             :   .type = VLIB_NODE_TYPE_INTERNAL,
    3589             : 
    3590             :   .n_errors = IKEV2_N_ERROR,
    3591             :   .error_counters = ikev2_error_counters,
    3592             : 
    3593             :   .n_next_nodes = IKEV2_IP4_N_NEXT,
    3594             :   .next_nodes = {
    3595             :     [IKEV2_NEXT_IP4_LOOKUP] = "ip4-lookup",
    3596             :     [IKEV2_NEXT_IP4_ERROR_DROP] = "error-drop",
    3597             :   },
    3598             : };
    3599             : 
    3600      122120 : VLIB_REGISTER_NODE (ikev2_node_ip6,static) = {
    3601             :   .function = ikev2_ip6,
    3602             :   .name = "ikev2-ip6",
    3603             :   .vector_size = sizeof (u32),
    3604             :   .format_trace = format_ikev2_trace,
    3605             :   .type = VLIB_NODE_TYPE_INTERNAL,
    3606             : 
    3607             :   .n_errors = IKEV2_N_ERROR,
    3608             :   .error_counters = ikev2_error_counters,
    3609             : 
    3610             :   .n_next_nodes = IKEV2_IP6_N_NEXT,
    3611             :   .next_nodes = {
    3612             :     [IKEV2_NEXT_IP6_LOOKUP] = "ip6-lookup",
    3613             :     [IKEV2_NEXT_IP6_ERROR_DROP] = "error-drop",
    3614             :   },
    3615             : };
    3616             : /* *INDENT-ON* */
    3617             : 
    3618             : // set ikev2 proposals when vpp is used as initiator
    3619             : static clib_error_t *
    3620          12 : ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa,
    3621             :                                ikev2_transforms_set * ts,
    3622             :                                ikev2_sa_proposal_t ** proposals, int is_ike)
    3623             : {
    3624             :   clib_error_t *r;
    3625          12 :   ikev2_main_t *km = &ikev2_main;
    3626             :   ikev2_sa_proposal_t *proposal;
    3627          12 :   vec_add2 (*proposals, proposal, 1);
    3628             :   ikev2_sa_transform_t *td;
    3629             :   int error;
    3630             : 
    3631             :   /* Encryption */
    3632          12 :   error = 1;
    3633          30 :   vec_foreach (td, km->supported_transforms)
    3634             :   {
    3635          30 :     if (td->type == IKEV2_TRANSFORM_TYPE_ENCR
    3636          30 :         && td->encr_type == ts->crypto_alg
    3637          12 :         && td->key_len == ts->crypto_key_size / 8)
    3638             :       {
    3639             :         u16 attr[2];
    3640          12 :         attr[0] = clib_host_to_net_u16 (14 | (1 << 15));
    3641          12 :         attr[1] = clib_host_to_net_u16 (td->key_len << 3);
    3642          12 :         vec_add (td->attrs, (u8 *) attr, 4);
    3643          12 :         vec_add1 (proposal->transforms, *td);
    3644          12 :         td->attrs = 0;
    3645             : 
    3646          12 :         error = 0;
    3647          12 :         break;
    3648             :       }
    3649             :   }
    3650          12 :   if (error)
    3651             :     {
    3652           0 :       r = clib_error_return (0, "Unsupported algorithm");
    3653           0 :       return r;
    3654             :     }
    3655             : 
    3656          12 :   if (IKEV2_TRANSFORM_INTEG_TYPE_NONE != ts->integ_alg)
    3657             :     {
    3658             :       /* Integrity */
    3659           6 :       error = 1;
    3660          66 :       vec_foreach (td, km->supported_transforms)
    3661             :       {
    3662          66 :         if (td->type == IKEV2_TRANSFORM_TYPE_INTEG
    3663           6 :             && td->integ_type == ts->integ_alg)
    3664             :           {
    3665           6 :             vec_add1 (proposal->transforms, *td);
    3666           6 :             error = 0;
    3667           6 :             break;
    3668             :           }
    3669             :       }
    3670           6 :       if (error)
    3671             :         {
    3672           0 :           ikev2_elog_error
    3673             :             ("Didn't find any supported algorithm for IKEV2_TRANSFORM_TYPE_INTEG");
    3674           0 :           r = clib_error_return (0, "Unsupported algorithm");
    3675           0 :           return r;
    3676             :         }
    3677             :     }
    3678             : 
    3679             :   /* PRF */
    3680          12 :   if (is_ike)
    3681             :     {
    3682           6 :       error = 1;
    3683          42 :       vec_foreach (td, km->supported_transforms)
    3684             :       {
    3685          42 :         if (td->type == IKEV2_TRANSFORM_TYPE_PRF
    3686           6 :             && td->prf_type == IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA2_256)
    3687             :           {
    3688           6 :             vec_add1 (proposal->transforms, *td);
    3689           6 :             error = 0;
    3690           6 :             break;
    3691             :           }
    3692             :       }
    3693           6 :       if (error)
    3694             :         {
    3695           0 :           r = clib_error_return (0, "Unsupported algorithm");
    3696           0 :           return r;
    3697             :         }
    3698             :     }
    3699             : 
    3700             :   /* DH */
    3701          12 :   if (is_ike)
    3702             :     {
    3703           6 :       error = 1;
    3704         156 :       vec_foreach (td, km->supported_transforms)
    3705             :       {
    3706         156 :         if (td->type == IKEV2_TRANSFORM_TYPE_DH && td->dh_type == ts->dh_type)
    3707             :           {
    3708           6 :             vec_add1 (proposal->transforms, *td);
    3709           6 :             if (is_ike)
    3710             :               {
    3711           6 :                 sa->dh_group = td->dh_type;
    3712             :               }
    3713           6 :             error = 0;
    3714           6 :             break;
    3715             :           }
    3716             :       }
    3717           6 :       if (error)
    3718             :         {
    3719           0 :           r = clib_error_return (0, "Unsupported algorithm");
    3720           0 :           return r;
    3721             :         }
    3722             :     }
    3723             : 
    3724          12 :   if (!is_ike)
    3725             :     {
    3726           6 :       error = 1;
    3727         198 :       vec_foreach (td, km->supported_transforms)
    3728             :       {
    3729         192 :         if (td->type == IKEV2_TRANSFORM_TYPE_ESN)
    3730             :           {
    3731          12 :             vec_add1 (proposal->transforms, *td);
    3732          12 :             error = 0;
    3733             :           }
    3734             :       }
    3735           6 :       if (error)
    3736             :         {
    3737           0 :           r = clib_error_return (0, "Unsupported algorithm");
    3738           0 :           return r;
    3739             :         }
    3740             :     }
    3741             : 
    3742             : 
    3743          12 :   return 0;
    3744             : }
    3745             : 
    3746             : static ikev2_profile_t *
    3747         188 : ikev2_profile_index_by_name (u8 * name)
    3748             : {
    3749         188 :   ikev2_main_t *km = &ikev2_main;
    3750             :   uword *p;
    3751             : 
    3752         188 :   p = mhash_get (&km->profile_index_by_name, name);
    3753         188 :   if (!p)
    3754          22 :     return 0;
    3755             : 
    3756         166 :   return pool_elt_at_index (km->profiles, p[0]);
    3757             : }
    3758             : 
    3759             : 
    3760             : static void
    3761          17 : ikev2_send_ike (vlib_main_t * vm, ip_address_t * src, ip_address_t * dst,
    3762             :                 u32 bi0, u32 len, u16 src_port, u16 dst_port, u32 sw_if_index)
    3763             : {
    3764             :   ip4_header_t *ip40;
    3765             :   ip6_header_t *ip60;
    3766             :   udp_header_t *udp0;
    3767             :   vlib_buffer_t *b0;
    3768             :   vlib_frame_t *f;
    3769             :   u32 *to_next;
    3770             : 
    3771          17 :   b0 = vlib_get_buffer (vm, bi0);
    3772          17 :   vlib_buffer_advance (b0, -sizeof (udp_header_t));
    3773          17 :   udp0 = vlib_buffer_get_current (b0);
    3774          17 :   udp0->dst_port = clib_host_to_net_u16 (dst_port);
    3775          17 :   udp0->src_port = clib_host_to_net_u16 (src_port);
    3776          17 :   udp0->length = clib_host_to_net_u16 (len + sizeof (udp_header_t));
    3777          17 :   udp0->checksum = 0;
    3778             : 
    3779          17 :   if (ip_addr_version (dst) == AF_IP4)
    3780             :     {
    3781          16 :       vlib_buffer_advance (b0, -sizeof (ip4_header_t));
    3782          16 :       ip40 = vlib_buffer_get_current (b0);
    3783          16 :       ip40->ip_version_and_header_length = 0x45;
    3784          16 :       ip40->tos = 0;
    3785          16 :       ip40->fragment_id = 0;
    3786          16 :       ip40->flags_and_fragment_offset = 0;
    3787          16 :       ip40->ttl = 0xff;
    3788          16 :       ip40->protocol = IP_PROTOCOL_UDP;
    3789          16 :       ip40->dst_address.as_u32 = ip_addr_v4 (dst).as_u32;
    3790          16 :       ip40->src_address.as_u32 = ip_addr_v4 (src).as_u32;
    3791          16 :       b0->current_length =
    3792          16 :         len + sizeof (ip4_header_t) + sizeof (udp_header_t);
    3793          16 :       ip40->length = clib_host_to_net_u16 (b0->current_length);
    3794          16 :       ip40->checksum = ip4_header_checksum (ip40);
    3795             :     }
    3796             :   else
    3797             :     {
    3798           1 :       vlib_buffer_advance (b0, -sizeof (ip6_header_t));
    3799           1 :       ip60 = vlib_buffer_get_current (b0);
    3800             : 
    3801           1 :       b0->current_length = len + sizeof (*ip60) + sizeof (udp_header_t);
    3802           1 :       ip60->ip_version_traffic_class_and_flow_label =
    3803           1 :         clib_host_to_net_u32 (0x6 << 28);
    3804           1 :       ip60->payload_length =
    3805           1 :         clib_host_to_net_u16 (b0->current_length - sizeof (*ip60));
    3806           1 :       ip60->protocol = IP_PROTOCOL_UDP;
    3807           1 :       ip60->hop_limit = 0xff;
    3808           1 :       clib_memcpy_fast (ip60->src_address.as_u8, ip_addr_v6 (src).as_u8,
    3809             :                         sizeof (ip60->src_address));
    3810           1 :       clib_memcpy_fast (ip60->dst_address.as_u8, ip_addr_v6 (dst).as_u8,
    3811             :                         sizeof (ip60->src_address));
    3812             :     }
    3813             : 
    3814          17 :   b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
    3815          17 :   vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index;
    3816          17 :   vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
    3817             : 
    3818          34 :   u32 next_index = (ip_addr_version (dst) == AF_IP4) ?
    3819          17 :     ip4_lookup_node.index : ip6_lookup_node.index;
    3820             : 
    3821             :   /* send the request */
    3822          17 :   f = vlib_get_frame_to_node (vm, next_index);
    3823          17 :   to_next = vlib_frame_vector_args (f);
    3824          17 :   to_next[0] = bi0;
    3825          17 :   f->n_vectors = 1;
    3826          17 :   vlib_put_frame_to_node (vm, next_index, f);
    3827             : 
    3828          17 : }
    3829             : 
    3830             : static u32
    3831          17 : ikev2_get_new_ike_header_buff (vlib_main_t * vm, vlib_buffer_t ** b)
    3832             : {
    3833             :   u32 bi0;
    3834          17 :   if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
    3835             :     {
    3836           0 :       *b = 0;
    3837           0 :       return 0;
    3838             :     }
    3839          17 :   *b = vlib_get_buffer (vm, bi0);
    3840          17 :   return bi0;
    3841             : }
    3842             : 
    3843             : clib_error_t *
    3844           1 : ikev2_set_local_key (vlib_main_t * vm, u8 * file)
    3845             : {
    3846           1 :   ikev2_main_t *km = &ikev2_main;
    3847             : 
    3848           1 :   if (km->pkey)
    3849           0 :     EVP_PKEY_free (km->pkey);
    3850           1 :   km->pkey = ikev2_load_key_file (file);
    3851           1 :   if (km->pkey == NULL)
    3852           0 :     return clib_error_return (0, "load key '%s' failed", file);
    3853             : 
    3854           1 :   return 0;
    3855             : }
    3856             : 
    3857             : static vnet_api_error_t
    3858           2 : ikev2_register_udp_port (ikev2_profile_t *p, u16 port)
    3859             : {
    3860           2 :   ipsec_register_udp_port (port, 0 /* is_ip4 */);
    3861           2 :   ipsec_register_udp_port (port, 1 /* is_ip4 */);
    3862           2 :   p->ipsec_over_udp_port = port;
    3863           2 :   return 0;
    3864             : }
    3865             : 
    3866             : static void
    3867          20 : ikev2_unregister_udp_port (ikev2_profile_t *p)
    3868             : {
    3869          20 :   if (p->ipsec_over_udp_port == IPSEC_UDP_PORT_NONE)
    3870          18 :     return;
    3871             : 
    3872           2 :   ipsec_unregister_udp_port (p->ipsec_over_udp_port, 0 /* is_ip4 */);
    3873           2 :   ipsec_unregister_udp_port (p->ipsec_over_udp_port, 1 /* is_ip4 */);
    3874           2 :   p->ipsec_over_udp_port = IPSEC_UDP_PORT_NONE;
    3875             : }
    3876             : 
    3877             : static void
    3878           6 : ikev2_initiate_delete_ike_sa_internal (vlib_main_t * vm,
    3879             :                                        ikev2_main_per_thread_data_t * tkm,
    3880             :                                        ikev2_sa_t * sa, u8 send_notification)
    3881             : {
    3882           6 :   ikev2_main_t *km = &ikev2_main;
    3883             :   ip_address_t *src, *dst;
    3884             :   vlib_buffer_t *b0;
    3885             :   ikev2_child_sa_t *c;
    3886             : 
    3887             :   /* Create the Initiator notification for IKE SA removal */
    3888             :   ike_header_t *ike0;
    3889           6 :   u32 bi0 = 0;
    3890             :   int len;
    3891             : 
    3892           6 :   vec_resize (sa->del, 1);
    3893           6 :   sa->del->protocol_id = IKEV2_PROTOCOL_IKE;
    3894           6 :   sa->del->spi = sa->ispi;
    3895             : 
    3896           6 :   if (send_notification)
    3897             :     {
    3898           6 :       bi0 = ikev2_get_new_ike_header_buff (vm, &b0);
    3899           6 :       if (!bi0)
    3900             :         {
    3901           0 :           ikev2_log_error ("buffer alloc failure");
    3902           0 :           goto delete_sa;
    3903             :         }
    3904             : 
    3905           6 :       ike0 = vlib_buffer_get_current (b0);
    3906           6 :       ike0->exchange = IKEV2_EXCHANGE_INFORMATIONAL;
    3907           6 :       ike0->ispi = clib_host_to_net_u64 (sa->ispi);
    3908           6 :       ike0->rspi = clib_host_to_net_u64 (sa->rspi);
    3909           6 :       ike0->flags = 0;
    3910           6 :       ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id);
    3911           6 :       sa->last_init_msg_id += 1;
    3912           6 :       len = ikev2_generate_message (b0, sa, ike0, 0, 0, 0);
    3913           6 :       if (~0 == len)
    3914           0 :         return;
    3915             : 
    3916           6 :       if (ikev2_natt_active (sa))
    3917           1 :         len = ikev2_insert_non_esp_marker (ike0, len);
    3918             : 
    3919           6 :       if (sa->is_initiator)
    3920             :         {
    3921           5 :           src = &sa->iaddr;
    3922           5 :           dst = &sa->raddr;
    3923             :         }
    3924             :       else
    3925             :         {
    3926           1 :           dst = &sa->iaddr;
    3927           1 :           src = &sa->raddr;
    3928             :         }
    3929             : 
    3930           6 :       ikev2_send_ike (vm, src, dst, bi0, len,
    3931           6 :                       ikev2_get_port (sa), sa->dst_port, 0);
    3932             :     }
    3933             : 
    3934           0 : delete_sa:
    3935             :   /* delete local SA */
    3936          12 :   vec_foreach (c, sa->childs)
    3937           6 :     ikev2_delete_tunnel_interface (km->vnet_main, sa, c);
    3938             : 
    3939           6 :   u64 rspi = sa->rspi;
    3940           6 :   ikev2_sa_free_all_vec (sa);
    3941           6 :   uword *p = hash_get (tkm->sa_by_rspi, rspi);
    3942           6 :   if (p)
    3943             :     {
    3944           6 :       hash_unset (tkm->sa_by_rspi, rspi);
    3945           6 :       pool_put (tkm->sas, sa);
    3946             :     }
    3947             : }
    3948             : 
    3949             : static void
    3950          20 : ikev2_cleanup_profile_sessions (ikev2_main_t * km, ikev2_profile_t * p)
    3951             : {
    3952             :   ikev2_main_per_thread_data_t *tkm;
    3953             :   ikev2_sa_t *sa;
    3954          20 :   u32 pi = p - km->profiles;
    3955             :   u32 *sai;
    3956          20 :   u32 *del_sai = 0;
    3957             : 
    3958             :   /* *INDENT-OFF* */
    3959          20 :   pool_foreach (sa, km->sais)  {
    3960           0 :     if (pi == sa->profile_index)
    3961           0 :       vec_add1 (del_sai, sa - km->sais);
    3962             :   }
    3963             :   /* *INDENT-ON* */
    3964             : 
    3965          20 :   vec_foreach (sai, del_sai)
    3966             :   {
    3967           0 :     sa = pool_elt_at_index (km->sais, sai[0]);
    3968           0 :     ikev2_sa_free_all_vec (sa);
    3969           0 :     hash_unset (km->sa_by_ispi, sa->ispi);
    3970           0 :     pool_put (km->sais, sa);
    3971             :   }
    3972          20 :   vec_reset_length (del_sai);
    3973             : 
    3974          40 :   vec_foreach (tkm, km->per_thread_data)
    3975             :   {
    3976             :     /* *INDENT-OFF* */
    3977          20 :     pool_foreach (sa, tkm->sas)  {
    3978           0 :       if (sa->profile_index != ~0 && pi == sa->profile_index)
    3979           0 :         vec_add1 (del_sai, sa - tkm->sas);
    3980             :     }
    3981             :     /* *INDENT-ON* */
    3982             : 
    3983          20 :     vec_foreach (sai, del_sai)
    3984             :     {
    3985           0 :       sa = pool_elt_at_index (tkm->sas, sai[0]);
    3986           0 :       ikev2_initiate_delete_ike_sa_internal (km->vlib_main, tkm, sa, 1);
    3987             :     }
    3988             : 
    3989          20 :     vec_reset_length (del_sai);
    3990             :   }
    3991             : 
    3992          20 :   vec_free (del_sai);
    3993          20 : }
    3994             : 
    3995             : static void
    3996          20 : ikev2_profile_responder_free (ikev2_responder_t *r)
    3997             : {
    3998          20 :   vec_free (r->hostname);
    3999          20 : }
    4000             : 
    4001             : static void
    4002          20 : ikev2_profile_free (ikev2_profile_t * p)
    4003             : {
    4004          20 :   vec_free (p->name);
    4005             : 
    4006          20 :   vec_free (p->auth.data);
    4007          20 :   if (p->auth.key)
    4008           1 :     EVP_PKEY_free (p->auth.key);
    4009             : 
    4010          20 :   ikev2_profile_responder_free (&p->responder);
    4011             : 
    4012          20 :   vec_free (p->loc_id.data);
    4013          20 :   vec_free (p->rem_id.data);
    4014          20 : }
    4015             : 
    4016             : static void
    4017          22 : ikev2_bind (vlib_main_t *vm, ikev2_main_t *km)
    4018             : {
    4019          22 :   if (0 == km->bind_refcount)
    4020             :     {
    4021          21 :       udp_register_dst_port (vm, IKEV2_PORT, ikev2_node_ip4.index, 1);
    4022          21 :       udp_register_dst_port (vm, IKEV2_PORT, ikev2_node_ip6.index, 0);
    4023          21 :       udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip4.index, 1);
    4024          21 :       udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip6.index, 0);
    4025             : 
    4026          21 :       vlib_punt_register (km->punt_hdl,
    4027             :                           ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0],
    4028             :                           "ikev2-ip4-natt");
    4029             :     }
    4030             : 
    4031          22 :   km->bind_refcount++;
    4032          22 : }
    4033             : 
    4034             : static void
    4035          20 : ikev2_unbind (vlib_main_t *vm, ikev2_main_t *km)
    4036             : {
    4037          20 :   km->bind_refcount--;
    4038          20 :   if (0 == km->bind_refcount)
    4039             :     {
    4040          19 :       vlib_punt_unregister (km->punt_hdl,
    4041             :                             ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0],
    4042             :                             "ikev2-ip4-natt");
    4043             : 
    4044          19 :       udp_unregister_dst_port (vm, IKEV2_PORT_NATT, 0);
    4045          19 :       udp_unregister_dst_port (vm, IKEV2_PORT_NATT, 1);
    4046          19 :       udp_unregister_dst_port (vm, IKEV2_PORT, 0);
    4047          19 :       udp_unregister_dst_port (vm, IKEV2_PORT, 1);
    4048             :     }
    4049          20 : }
    4050             : 
    4051             : static void ikev2_lazy_init (ikev2_main_t *km);
    4052             : 
    4053             : clib_error_t *
    4054          42 : ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add)
    4055             : {
    4056          42 :   ikev2_main_t *km = &ikev2_main;
    4057             :   ikev2_profile_t *p;
    4058             : 
    4059          42 :   ikev2_lazy_init (km);
    4060             : 
    4061          42 :   if (is_add)
    4062             :     {
    4063          22 :       if (ikev2_profile_index_by_name (name))
    4064           0 :         return clib_error_return (0, "policy %v already exists", name);
    4065             : 
    4066          22 :       pool_get (km->profiles, p);
    4067          22 :       clib_memset (p, 0, sizeof (*p));
    4068          22 :       p->name = vec_dup (name);
    4069          22 :       p->ipsec_over_udp_port = IPSEC_UDP_PORT_NONE;
    4070          22 :       p->responder.sw_if_index = ~0;
    4071          22 :       p->tun_itf = ~0;
    4072          22 :       uword index = p - km->profiles;
    4073          22 :       mhash_set_mem (&km->profile_index_by_name, name, &index, 0);
    4074             : 
    4075          22 :       ikev2_bind (vm, km);
    4076             :     }
    4077             :   else
    4078             :     {
    4079          20 :       p = ikev2_profile_index_by_name (name);
    4080          20 :       if (!p)
    4081           0 :         return clib_error_return (0, "policy %v does not exists", name);
    4082             : 
    4083          20 :       ikev2_unbind (vm, km);
    4084             : 
    4085          20 :       ikev2_unregister_udp_port (p);
    4086          20 :       ikev2_cleanup_profile_sessions (km, p);
    4087             : 
    4088          20 :       ikev2_profile_free (p);
    4089          20 :       pool_put (km->profiles, p);
    4090          20 :       mhash_unset (&km->profile_index_by_name, name, 0);
    4091             :     }
    4092          42 :   return 0;
    4093             : }
    4094             : 
    4095             : clib_error_t *
    4096          22 : ikev2_set_profile_auth (vlib_main_t * vm, u8 * name, u8 auth_method,
    4097             :                         u8 * auth_data, u8 data_hex_format)
    4098             : {
    4099             :   ikev2_profile_t *p;
    4100             :   clib_error_t *r;
    4101             : 
    4102          22 :   p = ikev2_profile_index_by_name (name);
    4103             : 
    4104          22 :   if (!p)
    4105             :     {
    4106           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4107           0 :       return r;
    4108             :     }
    4109             : 
    4110          22 :   if (p->auth.key)
    4111           0 :     EVP_PKEY_free (p->auth.key);
    4112          22 :   vec_free (p->auth.data);
    4113             : 
    4114          22 :   p->auth.method = auth_method;
    4115          22 :   p->auth.data = vec_dup (auth_data);
    4116          22 :   p->auth.hex = data_hex_format;
    4117             : 
    4118          22 :   if (auth_method == IKEV2_AUTH_METHOD_RSA_SIG)
    4119             :     {
    4120           1 :       vec_add1 (p->auth.data, 0);
    4121           1 :       p->auth.key = ikev2_load_cert_file (p->auth.data);
    4122           1 :       if (p->auth.key == NULL)
    4123           0 :         return clib_error_return (0, "load cert '%s' failed", p->auth.data);
    4124             :     }
    4125             : 
    4126          22 :   return 0;
    4127             : }
    4128             : 
    4129             : static int
    4130          43 : ikev2_is_id_supported (u8 id_type)
    4131             : {
    4132          42 :   return (id_type == IKEV2_ID_TYPE_ID_IPV4_ADDR ||
    4133          41 :           id_type == IKEV2_ID_TYPE_ID_IPV6_ADDR ||
    4134          85 :           id_type == IKEV2_ID_TYPE_ID_RFC822_ADDR ||
    4135             :           id_type == IKEV2_ID_TYPE_ID_FQDN);
    4136             : }
    4137             : 
    4138             : clib_error_t *
    4139          43 : ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data,
    4140             :                       int is_local)
    4141             : {
    4142             :   ikev2_profile_t *p;
    4143             :   clib_error_t *r;
    4144             : 
    4145          43 :   if (!ikev2_is_id_supported (id_type))
    4146             :     {
    4147           0 :       r = clib_error_return (0, "unsupported identity type %U",
    4148             :                              format_ikev2_id_type, id_type);
    4149           0 :       return r;
    4150             :     }
    4151             : 
    4152          43 :   p = ikev2_profile_index_by_name (name);
    4153             : 
    4154          43 :   if (!p)
    4155             :     {
    4156           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4157           0 :       return r;
    4158             :     }
    4159             : 
    4160          43 :   if (is_local)
    4161             :     {
    4162          22 :       vec_free (p->loc_id.data);
    4163          22 :       p->loc_id.type = id_type;
    4164          22 :       p->loc_id.data = vec_dup (data);
    4165             :     }
    4166             :   else
    4167             :     {
    4168          21 :       vec_free (p->rem_id.data);
    4169          21 :       p->rem_id.type = id_type;
    4170          21 :       p->rem_id.data = vec_dup (data);
    4171             :     }
    4172             : 
    4173          43 :   return 0;
    4174             : }
    4175             : 
    4176             : static void
    4177          44 : ikev2_set_ts_type (ikev2_ts_t *ts, const ip_address_t *addr)
    4178             : {
    4179          44 :   if (ip_addr_version (addr) == AF_IP4)
    4180          40 :     ts->ts_type = TS_IPV4_ADDR_RANGE;
    4181             :   else
    4182           4 :     ts->ts_type = TS_IPV6_ADDR_RANGE;
    4183          44 : }
    4184             : 
    4185             : static void
    4186          44 : ikev2_set_ts_addrs (ikev2_ts_t *ts, const ip_address_t *start,
    4187             :                     const ip_address_t *end)
    4188             : {
    4189          44 :   ip_address_copy (&ts->start_addr, start);
    4190          44 :   ip_address_copy (&ts->end_addr, end);
    4191          44 : }
    4192             : 
    4193             : clib_error_t *
    4194          44 : ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id,
    4195             :                       u16 start_port, u16 end_port, ip_address_t start_addr,
    4196             :                       ip_address_t end_addr, int is_local)
    4197             : {
    4198             :   ikev2_profile_t *p;
    4199             :   clib_error_t *r;
    4200             : 
    4201          44 :   p = ikev2_profile_index_by_name (name);
    4202             : 
    4203          44 :   if (!p)
    4204             :     {
    4205           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4206           0 :       return r;
    4207             :     }
    4208             : 
    4209          44 :   if (ip_addr_version (&start_addr) != ip_addr_version (&end_addr))
    4210           0 :     return clib_error_return (0, "IP address version mismatch!");
    4211             : 
    4212          44 :   if (is_local)
    4213             :     {
    4214          22 :       ikev2_set_ts_addrs (&p->loc_ts, &start_addr, &end_addr);
    4215          22 :       p->loc_ts.start_port = start_port;
    4216          22 :       p->loc_ts.end_port = end_port;
    4217          22 :       p->loc_ts.protocol_id = protocol_id;
    4218          22 :       ikev2_set_ts_type (&p->loc_ts, &start_addr);
    4219             :     }
    4220             :   else
    4221             :     {
    4222          22 :       ikev2_set_ts_addrs (&p->rem_ts, &start_addr, &end_addr);
    4223          22 :       p->rem_ts.start_port = start_port;
    4224          22 :       p->rem_ts.end_port = end_port;
    4225          22 :       p->rem_ts.protocol_id = protocol_id;
    4226          22 :       ikev2_set_ts_type (&p->rem_ts, &start_addr);
    4227             :     }
    4228             : 
    4229          44 :   return 0;
    4230             : }
    4231             : 
    4232             : clib_error_t *
    4233           4 : ikev2_set_profile_responder_hostname (vlib_main_t *vm, u8 *name, u8 *hostname,
    4234             :                                       u32 sw_if_index)
    4235             : {
    4236             :   ikev2_profile_t *p;
    4237             :   clib_error_t *r;
    4238             : 
    4239           4 :   p = ikev2_profile_index_by_name (name);
    4240             : 
    4241           4 :   if (!p)
    4242             :     {
    4243           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4244           0 :       return r;
    4245             :     }
    4246             : 
    4247           4 :   p->responder.is_resolved = 0;
    4248           4 :   p->responder.sw_if_index = sw_if_index;
    4249           4 :   p->responder.hostname = vec_dup (hostname);
    4250             : 
    4251           4 :   return 0;
    4252             : }
    4253             : 
    4254             : clib_error_t *
    4255           4 : ikev2_set_profile_responder (vlib_main_t * vm, u8 * name,
    4256             :                              u32 sw_if_index, ip_address_t addr)
    4257             : {
    4258             :   ikev2_profile_t *p;
    4259             :   clib_error_t *r;
    4260             : 
    4261           4 :   p = ikev2_profile_index_by_name (name);
    4262             : 
    4263           4 :   if (!p)
    4264             :     {
    4265           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4266           0 :       return r;
    4267             :     }
    4268             : 
    4269           4 :   p->responder.is_resolved = 1;
    4270           4 :   p->responder.sw_if_index = sw_if_index;
    4271           4 :   ip_address_copy (&p->responder.addr, &addr);
    4272             : 
    4273           4 :   return 0;
    4274             : }
    4275             : 
    4276             : clib_error_t *
    4277           8 : ikev2_set_profile_ike_transforms (vlib_main_t * vm, u8 * name,
    4278             :                                   ikev2_transform_encr_type_t crypto_alg,
    4279             :                                   ikev2_transform_integ_type_t integ_alg,
    4280             :                                   ikev2_transform_dh_type_t dh_type,
    4281             :                                   u32 crypto_key_size)
    4282             : {
    4283             :   ikev2_profile_t *p;
    4284             : 
    4285           8 :   p = ikev2_profile_index_by_name (name);
    4286           8 :   if (!p)
    4287           0 :     return clib_error_return (0, "unknown profile %v", name);
    4288             : 
    4289           8 :   if ((IKEV2_TRANSFORM_INTEG_TYPE_NONE != integ_alg) +
    4290           8 :         (IKEV2_TRANSFORM_ENCR_TYPE_AES_GCM_16 == crypto_alg) !=
    4291             :       1)
    4292           0 :     return clib_error_return (0, "invalid cipher + integrity algorithm");
    4293             : 
    4294           8 :   p->ike_ts.crypto_alg = crypto_alg;
    4295           8 :   p->ike_ts.integ_alg = integ_alg;
    4296           8 :   p->ike_ts.dh_type = dh_type;
    4297           8 :   p->ike_ts.crypto_key_size = crypto_key_size;
    4298           8 :   return 0;
    4299             : }
    4300             : 
    4301             : clib_error_t *
    4302           8 : ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name,
    4303             :                                   ikev2_transform_encr_type_t crypto_alg,
    4304             :                                   ikev2_transform_integ_type_t integ_alg,
    4305             :                                   u32 crypto_key_size)
    4306             : {
    4307             :   ikev2_profile_t *p;
    4308             :   clib_error_t *r;
    4309             : 
    4310           8 :   p = ikev2_profile_index_by_name (name);
    4311             : 
    4312           8 :   if (!p)
    4313             :     {
    4314           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4315           0 :       return r;
    4316             :     }
    4317             : 
    4318           8 :   p->esp_ts.crypto_alg = crypto_alg;
    4319           8 :   p->esp_ts.integ_alg = integ_alg;
    4320           8 :   p->esp_ts.crypto_key_size = crypto_key_size;
    4321           8 :   return 0;
    4322             : }
    4323             : 
    4324             : clib_error_t *
    4325           1 : ikev2_set_profile_tunnel_interface (vlib_main_t * vm,
    4326             :                                     u8 * name, u32 sw_if_index)
    4327             : {
    4328             :   ikev2_profile_t *p;
    4329             :   clib_error_t *r;
    4330             : 
    4331           1 :   p = ikev2_profile_index_by_name (name);
    4332             : 
    4333           1 :   if (!p)
    4334             :     {
    4335           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4336           0 :       return r;
    4337             :     }
    4338             : 
    4339           1 :   p->tun_itf = sw_if_index;
    4340             : 
    4341           1 :   return 0;
    4342             : }
    4343             : 
    4344             : vnet_api_error_t
    4345           2 : ikev2_set_profile_ipsec_udp_port (vlib_main_t * vm, u8 * name, u16 port,
    4346             :                                   u8 is_set)
    4347             : {
    4348           2 :   ikev2_profile_t *p = ikev2_profile_index_by_name (name);
    4349           2 :   vnet_api_error_t rv = 0;
    4350             : 
    4351           2 :   if (!p)
    4352           0 :     return VNET_API_ERROR_INVALID_VALUE;
    4353             : 
    4354           2 :   if (is_set)
    4355             :     {
    4356           2 :       if (p->ipsec_over_udp_port != IPSEC_UDP_PORT_NONE)
    4357           0 :         return VNET_API_ERROR_VALUE_EXIST;
    4358             : 
    4359           2 :       rv = ikev2_register_udp_port (p, port);
    4360             :     }
    4361             :   else
    4362             :     {
    4363           0 :       if (p->ipsec_over_udp_port == IPSEC_UDP_PORT_NONE)
    4364           0 :         return VNET_API_ERROR_INVALID_VALUE;
    4365             : 
    4366           0 :       ikev2_unregister_udp_port (p);
    4367             :     }
    4368           2 :   return rv;
    4369             : }
    4370             : 
    4371             : clib_error_t *
    4372           2 : ikev2_set_profile_udp_encap (vlib_main_t * vm, u8 * name)
    4373             : {
    4374           2 :   ikev2_profile_t *p = ikev2_profile_index_by_name (name);
    4375             :   clib_error_t *r;
    4376             : 
    4377           2 :   if (!p)
    4378             :     {
    4379           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4380           0 :       return r;
    4381             :     }
    4382             : 
    4383           2 :   p->udp_encap = 1;
    4384           2 :   return 0;
    4385             : }
    4386             : 
    4387             : clib_error_t *
    4388           1 : ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
    4389             :                                u64 lifetime, u32 jitter, u32 handover,
    4390             :                                u64 maxdata)
    4391             : {
    4392             :   ikev2_profile_t *p;
    4393             :   clib_error_t *r;
    4394             : 
    4395           1 :   p = ikev2_profile_index_by_name (name);
    4396             : 
    4397           1 :   if (!p)
    4398             :     {
    4399           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4400           0 :       return r;
    4401             :     }
    4402             : 
    4403           1 :   p->lifetime = lifetime;
    4404           1 :   p->lifetime_jitter = jitter;
    4405           1 :   p->handover = handover;
    4406           1 :   p->lifetime_maxdata = maxdata;
    4407           1 :   return 0;
    4408             : }
    4409             : 
    4410             : static int
    4411           6 : ikev2_get_if_address (u32 sw_if_index, ip_address_family_t af,
    4412             :                       ip_address_t * out_addr)
    4413             : {
    4414             :   ip4_address_t *if_ip4;
    4415             :   ip6_address_t *if_ip6;
    4416             : 
    4417           6 :   if (af == AF_IP4)
    4418             :     {
    4419           6 :       if_ip4 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
    4420           6 :       if (if_ip4)
    4421             :         {
    4422           6 :           ip_address_set (out_addr, if_ip4, AF_IP4);
    4423           6 :           return 1;
    4424             :         }
    4425             :     }
    4426             :   else
    4427             :     {
    4428           0 :       if_ip6 = ip6_interface_first_address (&ip6_main, sw_if_index);
    4429           0 :       if (if_ip6)
    4430             :         {
    4431           0 :           ip_address_set (out_addr, if_ip6, AF_IP6);
    4432           0 :           return 1;
    4433             :         }
    4434             :     }
    4435           0 :   return 0;
    4436             : }
    4437             : 
    4438             : static clib_error_t *
    4439           4 : ikev2_resolve_responder_hostname (vlib_main_t *vm, ikev2_responder_t *r)
    4440             : {
    4441           4 :   ikev2_main_t *km = &ikev2_main;
    4442           4 :   dns_cache_entry_t *ep = 0;
    4443           4 :   dns_pending_request_t _t0, *t0 = &_t0;
    4444           4 :   dns_resolve_name_t _rn, *rn = &_rn;
    4445             :   u8 *name;
    4446             :   int rv;
    4447             : 
    4448           4 :   if (!km->dns_resolve_name_ptr)
    4449           0 :     return clib_error_return (0, "cannot load symbols from dns plugin");
    4450             : 
    4451           4 :   t0->request_type = DNS_API_PENDING_NAME_TO_IP;
    4452             :   /* VPP main curse: IKEv2 uses only non-NULL terminated vectors internally
    4453             :    * whereas DNS resolver expects a NULL-terminated C-string */
    4454           4 :   name = vec_dup (r->hostname);
    4455           4 :   vec_terminate_c_string (name);
    4456           4 :   rv = ((__typeof__ (dns_resolve_name) *) km->dns_resolve_name_ptr) (name, &ep,
    4457             :                                                                      t0, rn);
    4458           4 :   vec_free (name);
    4459           4 :   if (rv < 0)
    4460           0 :     return clib_error_return (0, "dns lookup failure");
    4461             : 
    4462           4 :   if (ep == 0)
    4463           0 :     return 0;
    4464             : 
    4465           4 :   ip_address_copy (&r->addr, &rn->address);
    4466           4 :   r->is_resolved = 1;
    4467           4 :   return 0;
    4468             : }
    4469             : 
    4470             : clib_error_t *
    4471           6 : ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
    4472             : {
    4473             :   ikev2_profile_t *p;
    4474             :   clib_error_t *r;
    4475           6 :   ikev2_main_t *km = &ikev2_main;
    4476             :   vlib_buffer_t *b0;
    4477             :   ike_header_t *ike0;
    4478           6 :   u32 bi0 = 0;
    4479           6 :   int len = sizeof (ike_header_t), valid_ip = 0;
    4480           6 :   ip_address_t src_if_ip = ip_address_initializer;
    4481             : 
    4482           6 :   p = ikev2_profile_index_by_name (name);
    4483             : 
    4484           6 :   if (!p)
    4485             :     {
    4486           0 :       r = clib_error_return (0, "unknown profile %v", name);
    4487           0 :       return r;
    4488             :     }
    4489             : 
    4490          12 :   if (p->responder.sw_if_index == ~0 ||
    4491           6 :       (ip_address_is_zero (&p->responder.addr) &&
    4492           4 :        vec_len (p->responder.hostname) == 0))
    4493             :     {
    4494           0 :       r = clib_error_return (0, "responder not set for profile %v", name);
    4495           0 :       return r;
    4496             :     }
    4497             : 
    4498           6 :   if (!p->responder.is_resolved)
    4499             :     {
    4500             :       /* try to resolve using dns plugin
    4501             :        * success does not mean we have resolved the name */
    4502           4 :       r = ikev2_resolve_responder_hostname (vm, &p->responder);
    4503           4 :       if (r)
    4504           0 :         return r;
    4505             :     }
    4506             : 
    4507          12 :   if (p->responder.is_resolved &&
    4508           6 :       ikev2_get_if_address (p->responder.sw_if_index,
    4509           6 :                             ip_addr_version (&p->responder.addr), &src_if_ip))
    4510             :     {
    4511           6 :       valid_ip = 1;
    4512             :     }
    4513             : 
    4514             :   /* Prepare the SA and the IKE payload */
    4515             :   ikev2_sa_t sa;
    4516           6 :   clib_memset (&sa, 0, sizeof (ikev2_sa_t));
    4517           6 :   ikev2_payload_chain_t *chain = 0;
    4518           6 :   ikev2_payload_new_chain (chain);
    4519             : 
    4520             :   /* Build the IKE proposal payload */
    4521           6 :   ikev2_sa_proposal_t *proposals = 0;
    4522           6 :   ikev2_set_initiator_proposals (vm, &sa, &p->ike_ts, &proposals, 1);
    4523           6 :   proposals[0].proposal_num = 1;
    4524           6 :   proposals[0].protocol_id = IKEV2_PROTOCOL_IKE;
    4525             : 
    4526             :   /* Add and then cleanup proposal data */
    4527           6 :   ikev2_payload_add_sa (chain, proposals);
    4528           6 :   ikev2_sa_free_proposal_vector (&proposals);
    4529             : 
    4530           6 :   sa.is_initiator = 1;
    4531           6 :   sa.profile_index = p - km->profiles;
    4532           6 :   sa.state = IKEV2_STATE_SA_INIT;
    4533           6 :   sa.tun_itf = p->tun_itf;
    4534           6 :   sa.udp_encap = p->udp_encap;
    4535           6 :   if (p->natt_disabled)
    4536           0 :     sa.natt_state = IKEV2_NATT_DISABLED;
    4537           6 :   sa.ipsec_over_udp_port = p->ipsec_over_udp_port;
    4538           6 :   sa.is_tun_itf_set = 1;
    4539           6 :   sa.initial_contact = 1;
    4540           6 :   sa.dst_port = IKEV2_PORT;
    4541             : 
    4542           6 :   ikev2_generate_sa_error_t rc = ikev2_generate_sa_init_data (&sa);
    4543           6 :   if (rc != IKEV2_GENERATE_SA_INIT_OK)
    4544             :     {
    4545           0 :       ikev2_sa_free_all_vec (&sa);
    4546           0 :       ikev2_payload_destroy_chain (chain);
    4547           0 :       return clib_error_return (0, "%U", format_ikev2_gen_sa_error, rc);
    4548             :     }
    4549             : 
    4550           6 :   ikev2_payload_add_ke (chain, sa.dh_group, sa.i_dh_data);
    4551           6 :   ikev2_payload_add_nonce (chain, sa.i_nonce);
    4552             : 
    4553             :   /* Build the child SA proposal */
    4554           6 :   vec_resize (sa.childs, 1);
    4555           6 :   ikev2_set_initiator_proposals (vm, &sa, &p->esp_ts,
    4556           6 :                                  &sa.childs[0].i_proposals, 0);
    4557           6 :   sa.childs[0].i_proposals[0].proposal_num = 1;
    4558           6 :   sa.childs[0].i_proposals[0].protocol_id = IKEV2_PROTOCOL_ESP;
    4559           6 :   RAND_bytes ((u8 *) & sa.childs[0].i_proposals[0].spi,
    4560             :               sizeof (sa.childs[0].i_proposals[0].spi));
    4561             : 
    4562             :   /* Add NAT detection notification messages (mandatory) */
    4563           6 :   u8 *nat_detection_sha1 = ikev2_compute_nat_sha1 (
    4564             :     clib_host_to_net_u64 (sa.ispi), clib_host_to_net_u64 (sa.rspi), &src_if_ip,
    4565           6 :     clib_host_to_net_u16 (IKEV2_PORT));
    4566             : 
    4567           6 :   ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
    4568             :                             nat_detection_sha1);
    4569           6 :   vec_free (nat_detection_sha1);
    4570           6 :   nat_detection_sha1 =
    4571           6 :     ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa.ispi),
    4572             :                             clib_host_to_net_u64 (sa.rspi),
    4573             :                             &p->responder.addr,
    4574           6 :                             clib_host_to_net_u16 (sa.dst_port));
    4575           6 :   ikev2_payload_add_notify (chain,
    4576             :                             IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
    4577             :                             nat_detection_sha1);
    4578           6 :   vec_free (nat_detection_sha1);
    4579             : 
    4580           6 :   u8 *sig_hash_algo = vec_new (u8, 8);
    4581           6 :   u64 tmpsig = clib_host_to_net_u64 (0x0001000200030004);
    4582           6 :   clib_memcpy_fast (sig_hash_algo, &tmpsig, sizeof (tmpsig));
    4583           6 :   ikev2_payload_add_notify (chain,
    4584             :                             IKEV2_NOTIFY_MSG_SIGNATURE_HASH_ALGORITHMS,
    4585             :                             sig_hash_algo);
    4586           6 :   vec_free (sig_hash_algo);
    4587             : 
    4588           6 :   bi0 = ikev2_get_new_ike_header_buff (vm, &b0);
    4589           6 :   if (!bi0)
    4590             :     {
    4591           0 :       ikev2_sa_free_all_vec (&sa);
    4592           0 :       ikev2_payload_destroy_chain (chain);
    4593           0 :       char *errmsg = "buffer alloc failure";
    4594           0 :       ikev2_log_error (errmsg);
    4595           0 :       return clib_error_return (0, errmsg);
    4596             :     }
    4597           6 :   ike0 = vlib_buffer_get_current (b0);
    4598             : 
    4599             :   /* Buffer update and boilerplate */
    4600           6 :   len += vec_len (chain->data);
    4601           6 :   ike0->nextpayload = chain->first_payload_type;
    4602           6 :   ike0->length = clib_host_to_net_u32 (len);
    4603           6 :   clib_memcpy_fast (ike0->payload, chain->data, vec_len (chain->data));
    4604           6 :   ikev2_payload_destroy_chain (chain);
    4605             : 
    4606           6 :   ike0->version = IKE_VERSION_2;
    4607           6 :   ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
    4608           6 :   ike0->exchange = IKEV2_EXCHANGE_SA_INIT;
    4609           6 :   ike0->ispi = clib_host_to_net_u64 (sa.ispi);
    4610           6 :   ike0->rspi = 0;
    4611           6 :   ike0->msgid = 0;
    4612           6 :   sa.last_init_msg_id += 1;
    4613             : 
    4614             :   /* store whole IKE payload - needed for PSK auth */
    4615           6 :   vec_reset_length (sa.last_sa_init_req_packet_data);
    4616           6 :   vec_add (sa.last_sa_init_req_packet_data, ike0, len);
    4617             : 
    4618             :   /* add data to the SA then add it to the pool */
    4619           6 :   ip_address_copy (&sa.iaddr, &src_if_ip);
    4620           6 :   ip_address_copy (&sa.raddr, &p->responder.addr);
    4621           6 :   sa.i_id.type = p->loc_id.type;
    4622           6 :   sa.i_id.data = vec_dup (p->loc_id.data);
    4623           6 :   sa.r_id.type = p->rem_id.type;
    4624           6 :   sa.r_id.data = vec_dup (p->rem_id.data);
    4625           6 :   sa.i_auth.method = p->auth.method;
    4626           6 :   sa.i_auth.hex = p->auth.hex;
    4627           6 :   sa.i_auth.data = vec_dup (p->auth.data);
    4628           6 :   sa.sw_if_index = p->responder.sw_if_index;
    4629           6 :   vec_add (sa.childs[0].tsi, &p->loc_ts, 1);
    4630           6 :   vec_add (sa.childs[0].tsr, &p->rem_ts, 1);
    4631             : 
    4632           6 :   ikev2_initial_contact_cleanup (0, &sa);
    4633             : 
    4634             :   /* add SA to the pool */
    4635           6 :   ikev2_sa_t *sa0 = 0;
    4636           6 :   pool_get (km->sais, sa0);
    4637           6 :   clib_memcpy_fast (sa0, &sa, sizeof (*sa0));
    4638           6 :   hash_set (km->sa_by_ispi, sa0->ispi, sa0 - km->sais);
    4639             : 
    4640           6 :   if (valid_ip)
    4641             :     {
    4642           6 :       ikev2_send_ike (vm, &src_if_ip, &p->responder.addr, bi0, len, IKEV2_PORT,
    4643           6 :                       sa.dst_port, sa.sw_if_index);
    4644             : 
    4645           6 :       ikev2_elog_exchange
    4646             :         ("ispi %lx rspi %lx IKEV2_EXCHANGE_SA_INIT sent to ",
    4647             :          clib_host_to_net_u64 (sa0->ispi), 0,
    4648             :          ip_addr_v4 (&p->responder.addr).as_u32,
    4649             :          ip_addr_version (&p->responder.addr) == AF_IP4);
    4650             :     }
    4651             : 
    4652           6 :   return 0;
    4653             : }
    4654             : 
    4655             : static void
    4656           0 : ikev2_delete_child_sa_internal (vlib_main_t * vm, ikev2_sa_t * sa,
    4657             :                                 ikev2_child_sa_t * csa)
    4658             : {
    4659             :   /* Create the Initiator notification for child SA removal */
    4660           0 :   ikev2_main_t *km = &ikev2_main;
    4661             :   ike_header_t *ike0;
    4662           0 :   u32 bi0 = 0;
    4663             :   vlib_buffer_t *b0;
    4664             :   int len;
    4665             : 
    4666           0 :   bi0 = ikev2_get_new_ike_header_buff (vm, &b0);
    4667           0 :   if (!bi0)
    4668             :     {
    4669           0 :       ikev2_log_error ("buffer alloc failure");
    4670           0 :       return;
    4671             :     }
    4672             : 
    4673           0 :   ike0 = vlib_buffer_get_current (b0);
    4674           0 :   ike0->exchange = IKEV2_EXCHANGE_INFORMATIONAL;
    4675           0 :   ike0->ispi = clib_host_to_net_u64 (sa->ispi);
    4676           0 :   ike0->rspi = clib_host_to_net_u64 (sa->rspi);
    4677           0 :   ike0->flags = 0;
    4678           0 :   vec_resize (sa->del, 1);
    4679           0 :   sa->del->protocol_id = IKEV2_PROTOCOL_ESP;
    4680           0 :   sa->del->spi = csa->i_proposals->spi;
    4681           0 :   ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id);
    4682           0 :   sa->last_init_msg_id += 1;
    4683           0 :   len = ikev2_generate_message (b0, sa, ike0, 0, 0, 0);
    4684           0 :   if (~0 == len)
    4685           0 :     return;
    4686             : 
    4687           0 :   if (ikev2_natt_active (sa))
    4688           0 :     len = ikev2_insert_non_esp_marker (ike0, len);
    4689           0 :   ikev2_send_ike (vm, &sa->iaddr, &sa->raddr, bi0, len,
    4690           0 :                   ikev2_get_port (sa), sa->dst_port, sa->sw_if_index);
    4691             : 
    4692             :   /* delete local child SA */
    4693           0 :   ikev2_delete_tunnel_interface (km->vnet_main, sa, csa);
    4694           0 :   ikev2_sa_del_child_sa (sa, csa);
    4695             : }
    4696             : 
    4697             : clib_error_t *
    4698           0 : ikev2_initiate_delete_child_sa (vlib_main_t * vm, u32 ispi)
    4699             : {
    4700             :   clib_error_t *r;
    4701           0 :   ikev2_main_t *km = &ikev2_main;
    4702             :   ikev2_main_per_thread_data_t *tkm;
    4703           0 :   ikev2_sa_t *fsa = 0;
    4704           0 :   ikev2_child_sa_t *fchild = 0;
    4705             : 
    4706             :   /* Search for the child SA */
    4707           0 :   vec_foreach (tkm, km->per_thread_data)
    4708             :   {
    4709             :     ikev2_sa_t *sa;
    4710           0 :     if (fchild)
    4711           0 :       break;
    4712             :     /* *INDENT-OFF* */
    4713           0 :     pool_foreach (sa, tkm->sas)  {
    4714           0 :       fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
    4715           0 :       if (fchild)
    4716             :         {
    4717           0 :           fsa = sa;
    4718           0 :           break;
    4719             :         }
    4720             :     }
    4721             :     /* *INDENT-ON* */
    4722             :   }
    4723             : 
    4724           0 :   if (!fchild || !fsa)
    4725             :     {
    4726           0 :       r = clib_error_return (0, "Child SA not found");
    4727           0 :       return r;
    4728             :     }
    4729             :   else
    4730             :     {
    4731           0 :       ikev2_delete_child_sa_internal (vm, fsa, fchild);
    4732             :     }
    4733             : 
    4734           0 :   return 0;
    4735             : }
    4736             : 
    4737             : clib_error_t *
    4738           6 : ikev2_initiate_delete_ike_sa (vlib_main_t * vm, u64 ispi)
    4739             : {
    4740             :   clib_error_t *r;
    4741           6 :   ikev2_main_t *km = &ikev2_main;
    4742             :   ikev2_main_per_thread_data_t *tkm;
    4743           6 :   ikev2_sa_t *fsa = 0;
    4744           6 :   ikev2_main_per_thread_data_t *ftkm = 0;
    4745             : 
    4746             :   /* Search for the IKE SA */
    4747          12 :   vec_foreach (tkm, km->per_thread_data)
    4748             :   {
    4749             :     ikev2_sa_t *sa;
    4750           6 :     if (fsa)
    4751           0 :       break;
    4752             :     /* *INDENT-OFF* */
    4753           6 :     pool_foreach (sa, tkm->sas)  {
    4754           6 :       if (sa->ispi == ispi)
    4755             :         {
    4756           6 :           fsa = sa;
    4757           6 :           ftkm = tkm;
    4758           6 :           break;
    4759             :         }
    4760             :     }
    4761             :     /* *INDENT-ON* */
    4762             :   }
    4763             : 
    4764           6 :   if (!fsa)
    4765             :     {
    4766           0 :       r = clib_error_return (0, "IKE SA not found");
    4767           0 :       return r;
    4768             :     }
    4769             : 
    4770           6 :   ikev2_initiate_delete_ike_sa_internal (vm, ftkm, fsa, 1);
    4771           6 :   return 0;
    4772             : }
    4773             : 
    4774             : static void
    4775           3 : ikev2_rekey_child_sa_internal (vlib_main_t * vm, ikev2_sa_t * sa,
    4776             :                                ikev2_child_sa_t * csa)
    4777             : {
    4778             :   /* Create the Initiator request for create child SA */
    4779             :   ike_header_t *ike0;
    4780             :   vlib_buffer_t *b0;
    4781           3 :   u32 bi0 = 0;
    4782             :   int len;
    4783             : 
    4784           3 :   bi0 = ikev2_get_new_ike_header_buff (vm, &b0);
    4785           3 :   if (!bi0)
    4786             :     {
    4787           0 :       ikev2_log_error ("buffer alloc failure");
    4788           0 :       return;
    4789             :     }
    4790             : 
    4791           3 :   ike0 = vlib_buffer_get_current (b0);
    4792           3 :   ike0->version = IKE_VERSION_2;
    4793           3 :   ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
    4794           3 :   ike0->exchange = IKEV2_EXCHANGE_CREATE_CHILD_SA;
    4795           3 :   ike0->ispi = clib_host_to_net_u64 (sa->ispi);
    4796           3 :   ike0->rspi = clib_host_to_net_u64 (sa->rspi);
    4797           3 :   ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id);
    4798           3 :   sa->last_init_msg_id += 1;
    4799             : 
    4800             :   ikev2_rekey_t *rekey;
    4801           3 :   vec_reset_length (sa->rekey);
    4802           3 :   vec_add2 (sa->rekey, rekey, 1);
    4803           3 :   rekey->kex = 0;
    4804           3 :   ikev2_sa_proposal_t *proposals = vec_dup (csa->i_proposals);
    4805             : 
    4806             :   /*need new ispi */
    4807           3 :   RAND_bytes ((u8 *) & proposals[0].spi, sizeof (proposals[0].spi));
    4808           3 :   rekey->spi = proposals[0].spi;
    4809           3 :   rekey->ispi = csa->i_proposals->spi;
    4810           3 :   len = ikev2_generate_message (b0, sa, ike0, proposals, 0, 0);
    4811           3 :   if (~0 == len)
    4812           0 :     return;
    4813             : 
    4814           3 :   if (ikev2_natt_active (sa))
    4815           0 :     len = ikev2_insert_non_esp_marker (ike0, len);
    4816           3 :   ikev2_send_ike (vm, &sa->iaddr, &sa->raddr, bi0, len,
    4817           3 :                   ikev2_get_port (sa), ikev2_get_port (sa), sa->sw_if_index);
    4818           3 :   vec_free (proposals);
    4819             : }
    4820             : 
    4821             : clib_error_t *
    4822           3 : ikev2_initiate_rekey_child_sa (vlib_main_t * vm, u32 ispi)
    4823             : {
    4824             :   clib_error_t *r;
    4825           3 :   ikev2_main_t *km = &ikev2_main;
    4826             :   ikev2_main_per_thread_data_t *tkm;
    4827           3 :   ikev2_sa_t *fsa = 0;
    4828           3 :   ikev2_child_sa_t *fchild = 0;
    4829             : 
    4830             :   /* Search for the child SA */
    4831           6 :   vec_foreach (tkm, km->per_thread_data)
    4832             :   {
    4833             :     ikev2_sa_t *sa;
    4834           3 :     if (fchild)
    4835           0 :       break;
    4836             :     /* *INDENT-OFF* */
    4837           3 :     pool_foreach (sa, tkm->sas)  {
    4838           3 :       fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
    4839           3 :       if (fchild)
    4840             :         {
    4841           3 :           fsa = sa;
    4842           3 :           break;
    4843             :         }
    4844             :     }
    4845             :     /* *INDENT-ON* */
    4846             :   }
    4847             : 
    4848           3 :   if (!fchild || !fsa)
    4849             :     {
    4850           0 :       r = clib_error_return (0, "Child SA not found");
    4851           0 :       return r;
    4852             :     }
    4853             :   else
    4854             :     {
    4855           3 :       ikev2_rekey_child_sa_internal (vm, fsa, fchild);
    4856             :     }
    4857             : 
    4858           3 :   return 0;
    4859             : }
    4860             : 
    4861             : static int
    4862           0 : ikev2_sa_sw_if_match (ikev2_sa_t * sa, u32 sw_if_index)
    4863             : {
    4864           0 :   return (sa->sw_if_index == sw_if_index) && sa->is_initiator;
    4865             : }
    4866             : 
    4867             : static void
    4868           0 : ikev2_sa_del (ikev2_profile_t * p, u32 sw_if_index)
    4869             : {
    4870           0 :   u64 *ispi, *ispi_vec = 0;
    4871           0 :   ikev2_sa_t *sa, **sap, **sa_vec = 0;
    4872           0 :   ikev2_main_t *km = &ikev2_main;
    4873             :   ikev2_main_per_thread_data_t *tkm;
    4874           0 :   p->responder.sw_if_index = ~0;
    4875             : 
    4876           0 :   vec_foreach (tkm, km->per_thread_data)
    4877             :   {
    4878             :     /* *INDENT-OFF* */
    4879           0 :     pool_foreach (sa, tkm->sas)  {
    4880           0 :       if (ikev2_sa_sw_if_match (sa, sw_if_index))
    4881           0 :         vec_add1 (sa_vec, sa);
    4882             :     }
    4883             :     /* *INDENT-ON* */
    4884             : 
    4885           0 :     vec_foreach (sap, sa_vec)
    4886             :     {
    4887           0 :       ikev2_initiate_delete_ike_sa_internal (km->vlib_main, tkm, *sap, 0);
    4888             :     }
    4889           0 :     vec_reset_length (sa_vec);
    4890             :   }
    4891           0 :   vec_free (sa_vec);
    4892             : 
    4893             :   /* *INDENT-OFF* */
    4894           0 :   pool_foreach (sa, km->sais)  {
    4895           0 :     if (ikev2_sa_sw_if_match (sa, sw_if_index))
    4896           0 :       vec_add1 (ispi_vec, sa->ispi);
    4897             :   }
    4898             :   /* *INDENT-ON* */
    4899             : 
    4900           0 :   vec_foreach (ispi, ispi_vec)
    4901             :   {
    4902           0 :     ikev2_del_sa_init_from_main (ispi);
    4903             :   }
    4904             : 
    4905           0 :   vec_free (ispi_vec);
    4906           0 : }
    4907             : 
    4908             : static clib_error_t *
    4909       11597 : ikev2_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
    4910             : {
    4911       11597 :   ikev2_main_t *km = &ikev2_main;
    4912             :   ikev2_profile_t *p;
    4913             : 
    4914       11597 :   if (is_add)
    4915        7418 :     return 0;
    4916             : 
    4917             :   /* *INDENT-OFF* */
    4918        4198 :   pool_foreach (p, km->profiles)  {
    4919          19 :     if (p->responder.sw_if_index == sw_if_index)
    4920           0 :       ikev2_sa_del (p, sw_if_index);
    4921             :   }
    4922             :   /* *INDENT-ON* */
    4923             : 
    4924        4179 :   return 0;
    4925             : }
    4926             : 
    4927        1683 : VNET_SW_INTERFACE_ADD_DEL_FUNCTION (ikev2_sw_interface_add_del);
    4928             : 
    4929             : clib_error_t *
    4930         559 : ikev2_init (vlib_main_t * vm)
    4931             : {
    4932         559 :   ikev2_main_t *km = &ikev2_main;
    4933             : 
    4934         559 :   clib_memset (km, 0, sizeof (ikev2_main_t));
    4935             : 
    4936         559 :   km->log_level = IKEV2_LOG_ERROR;
    4937         559 :   km->log_class = vlib_log_register_class ("ikev2", 0);
    4938             : 
    4939         559 :   km->vnet_main = vnet_get_main ();
    4940         559 :   km->vlib_main = vm;
    4941             : 
    4942         559 :   km->liveness_period = IKEV2_LIVENESS_PERIOD_CHECK;
    4943         559 :   km->liveness_max_retries = IKEV2_LIVENESS_RETRIES;
    4944             : 
    4945         559 :   return 0;
    4946             : }
    4947             : 
    4948             : /* *INDENT-OFF* */
    4949        1119 : VLIB_INIT_FUNCTION (ikev2_init) = {
    4950             :   .runs_after = VLIB_INITS ("ipsec_init", "ipsec_punt_init"),
    4951             : };
    4952             : /* *INDENT-ON* */
    4953             : 
    4954             : static u8
    4955          16 : ikev2_mngr_process_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * csa,
    4956             :                              u8 del_old_ids)
    4957             : {
    4958          16 :   ikev2_main_t *km = &ikev2_main;
    4959          16 :   ikev2_profile_t *p = 0;
    4960          16 :   vlib_main_t *vm = km->vlib_main;
    4961          16 :   f64 now = vlib_time_now (vm);
    4962          16 :   u8 res = 0;
    4963             : 
    4964          16 :   if (sa->profile_index != ~0)
    4965          16 :     p = pool_elt_at_index (km->profiles, sa->profile_index);
    4966             : 
    4967          16 :   if (sa->is_initiator && p && csa->time_to_expiration
    4968           0 :       && now > csa->time_to_expiration)
    4969             :     {
    4970           0 :       if (!csa->is_expired || csa->rekey_retries > 0)
    4971             :         {
    4972           0 :           ikev2_rekey_child_sa_internal (vm, sa, csa);
    4973           0 :           csa->time_to_expiration = now + p->handover;
    4974           0 :           csa->is_expired = 1;
    4975           0 :           if (csa->rekey_retries == 0)
    4976             :             {
    4977           0 :               csa->rekey_retries = 5;
    4978             :             }
    4979           0 :           else if (csa->rekey_retries > 0)
    4980             :             {
    4981           0 :               csa->rekey_retries--;
    4982           0 :               ikev2_log_debug ("Rekeying Child SA 0x%x, retries left %d",
    4983             :                                csa->i_proposals->spi, csa->rekey_retries);
    4984           0 :               if (csa->rekey_retries == 0)
    4985             :                 {
    4986           0 :                   csa->rekey_retries = -1;
    4987             :                 }
    4988             :             }
    4989           0 :           res |= 1;
    4990             :         }
    4991             :       else
    4992             :         {
    4993           0 :           csa->time_to_expiration = 0;
    4994           0 :           ikev2_delete_child_sa_internal (vm, sa, csa);
    4995           0 :           res |= 1;
    4996           0 :           return res;
    4997             :         }
    4998             :     }
    4999             : 
    5000          16 :   if (del_old_ids)
    5001             :     {
    5002           2 :       ipip_tunnel_t *ipip = NULL;
    5003           2 :       u32 sw_if_index = sa->is_tun_itf_set ? sa->tun_itf : ~0;
    5004           2 :       if (~0 == sw_if_index)
    5005             :         {
    5006             :           ip46_address_t local_ip;
    5007             :           ip46_address_t remote_ip;
    5008           2 :           if (sa->is_initiator)
    5009             :             {
    5010           0 :               local_ip = to_ip46 (ip_addr_version (&sa->iaddr),
    5011             :                                   ip_addr_bytes (&sa->iaddr));
    5012           0 :               remote_ip = to_ip46 (ip_addr_version (&sa->raddr),
    5013             :                                    ip_addr_bytes (&sa->raddr));
    5014             :             }
    5015             :           else
    5016             :             {
    5017           2 :               local_ip = to_ip46 (ip_addr_version (&sa->raddr),
    5018             :                                   ip_addr_bytes (&sa->raddr));
    5019           2 :               remote_ip = to_ip46 (ip_addr_version (&sa->iaddr),
    5020             :                                    ip_addr_bytes (&sa->iaddr));
    5021             :             }
    5022             : 
    5023             :        /* *INDENT-OFF* */
    5024           2 :        ipip_tunnel_key_t key = {
    5025             :          .src = local_ip,
    5026             :          .dst = remote_ip,
    5027             :          .transport = IPIP_TRANSPORT_IP4,
    5028             :          .fib_index = 0,
    5029             :        };
    5030             :        /* *INDENT-ON* */
    5031             : 
    5032           2 :           ipip = ipip_tunnel_db_find (&key);
    5033             : 
    5034           2 :           if (ipip)
    5035           2 :             sw_if_index = ipip->sw_if_index;
    5036             :           else
    5037           0 :             return res;
    5038             :         }
    5039             : 
    5040           2 :       u32 *sas_in = NULL;
    5041           2 :       vec_add1 (sas_in, csa->remote_sa_id);
    5042           2 :       vlib_worker_thread_barrier_sync (vm);
    5043           2 :       int rv = ipsec_tun_protect_update (sw_if_index, NULL,
    5044             :                                          csa->local_sa_id, sas_in);
    5045           2 :       if (rv)
    5046           0 :         vec_free (sas_in);
    5047           2 :       ipsec_sa_unlock_id (ikev2_flip_alternate_sa_bit (csa->remote_sa_id));
    5048           2 :       vlib_worker_thread_barrier_release (vm);
    5049             :     }
    5050             : 
    5051          16 :   return res;
    5052             : }
    5053             : 
    5054             : int
    5055          20 : ikev2_set_log_level (ikev2_log_level_t log_level)
    5056             : {
    5057          20 :   ikev2_main_t *km = &ikev2_main;
    5058             : 
    5059          20 :   if (log_level >= IKEV2_LOG_MAX)
    5060             :     {
    5061           0 :       ikev2_log_error ("unknown logging level %d", log_level);
    5062           0 :       return -1;
    5063             :     }
    5064             : 
    5065          20 :   km->log_level = log_level;
    5066          20 :   return 0;
    5067             : }
    5068             : 
    5069             : clib_error_t *
    5070           2 : ikev2_set_liveness_params (u32 period, u32 max_retries)
    5071             : {
    5072           2 :   ikev2_main_t *km = &ikev2_main;
    5073             : 
    5074           2 :   if (period == 0 || max_retries == 0)
    5075           0 :     return clib_error_return (0, "invalid args");
    5076             : 
    5077           2 :   km->liveness_period = period;
    5078           2 :   km->liveness_max_retries = max_retries;
    5079           2 :   return 0;
    5080             : }
    5081             : 
    5082             : clib_error_t *
    5083           1 : ikev2_profile_natt_disable (u8 * name)
    5084             : {
    5085           1 :   ikev2_profile_t *p = ikev2_profile_index_by_name (name);
    5086           1 :   if (!p)
    5087           0 :     return clib_error_return (0, "unknown profile %v", name);
    5088             : 
    5089           1 :   p->natt_disabled = 1;
    5090           1 :   return 0;
    5091             : }
    5092             : 
    5093             : static void
    5094          39 : ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa)
    5095             : {
    5096          39 :   ikev2_main_t *km = &ikev2_main;
    5097          39 :   vlib_main_t *vm = km->vlib_main;
    5098             :   ikev2_main_per_thread_data_t *tkm;
    5099          39 :   ikev2_sa_t *fsa = 0;
    5100          39 :   ikev2_profile_t *p = 0;
    5101          39 :   ikev2_child_sa_t *fchild = 0;
    5102          39 :   f64 now = vlib_time_now (vm);
    5103             :   vlib_counter_t counts;
    5104             : 
    5105             :   /* Search for the SA and child SA */
    5106          78 :   vec_foreach (tkm, km->per_thread_data)
    5107             :   {
    5108             :     ikev2_sa_t *sa;
    5109          39 :     if (fchild)
    5110           0 :       break;
    5111             :     /* *INDENT-OFF* */
    5112          62 :     pool_foreach (sa, tkm->sas)  {
    5113          39 :       fchild = ikev2_sa_get_child(sa, ipsec_sa->spi, IKEV2_PROTOCOL_ESP, 1);
    5114          39 :       if (fchild)
    5115             :         {
    5116          16 :           fsa = sa;
    5117          16 :           break;
    5118             :         }
    5119             :     }
    5120             :     /* *INDENT-ON* */
    5121             :   }
    5122          39 :   vlib_get_combined_counter (&ipsec_sa_counters,
    5123             :                              ipsec_sa->stat_index, &counts);
    5124             : 
    5125          39 :   if (fsa && fsa->profile_index != ~0 && fsa->is_initiator)
    5126           2 :     p = pool_elt_at_index (km->profiles, fsa->profile_index);
    5127             : 
    5128          39 :   if (fchild && p && p->lifetime_maxdata)
    5129             :     {
    5130           0 :       if (!fchild->is_expired && counts.bytes > p->lifetime_maxdata)
    5131             :         {
    5132           0 :           fchild->time_to_expiration = now;
    5133             :         }
    5134             :     }
    5135          39 : }
    5136             : 
    5137             : static void
    5138           0 : ikev2_process_pending_sa_init_one (vlib_main_t *vm, ikev2_main_t *km,
    5139             :                                    ikev2_sa_t *sa)
    5140             : {
    5141             :   ikev2_profile_t *p;
    5142             :   u32 bi0;
    5143             :   u8 *nat_sha, *np;
    5144           0 :   p = pool_elt_at_index (km->profiles, sa->profile_index);
    5145             : 
    5146           0 :   if (!p->responder.is_resolved)
    5147             :     {
    5148           0 :       clib_error_t *r = ikev2_resolve_responder_hostname (vm, &p->responder);
    5149           0 :       if (r)
    5150             :         {
    5151           0 :           clib_error_free (r);
    5152           0 :           return;
    5153             :         }
    5154             : 
    5155           0 :       if (!p->responder.is_resolved)
    5156           0 :         return;
    5157             : 
    5158           0 :       ip_address_copy (&sa->raddr, &p->responder.addr);
    5159             : 
    5160             :       /* update nat detection destination hash */
    5161           0 :       np = ikev2_find_ike_notify_payload (
    5162           0 :         (ike_header_t *) sa->last_sa_init_req_packet_data,
    5163             :         IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP);
    5164           0 :       if (np)
    5165             :         {
    5166           0 :           nat_sha = ikev2_compute_nat_sha1 (
    5167             :             clib_host_to_net_u64 (sa->ispi), clib_host_to_net_u64 (sa->rspi),
    5168           0 :             &sa->raddr, clib_host_to_net_u16 (sa->dst_port));
    5169           0 :           clib_memcpy_fast (np, nat_sha, vec_len (nat_sha));
    5170           0 :           vec_free (nat_sha);
    5171             :         }
    5172             :     }
    5173             : 
    5174           0 :   if (ip_address_is_zero (&sa->iaddr))
    5175             :     {
    5176           0 :       if (!ikev2_get_if_address (p->responder.sw_if_index,
    5177           0 :                                  ip_addr_version (&p->responder.addr),
    5178             :                                  &sa->iaddr))
    5179           0 :         return;
    5180             : 
    5181             :       /* update NAT detection payload */
    5182             :       np =
    5183           0 :         ikev2_find_ike_notify_payload
    5184           0 :         ((ike_header_t *) sa->last_sa_init_req_packet_data,
    5185             :          IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP);
    5186           0 :       if (np)
    5187             :         {
    5188           0 :           nat_sha =
    5189           0 :             ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa->ispi),
    5190             :                                     clib_host_to_net_u64 (sa->rspi),
    5191             :                                     &sa->iaddr,
    5192           0 :                                     clib_host_to_net_u16 (IKEV2_PORT));
    5193           0 :           clib_memcpy_fast (np, nat_sha, vec_len (nat_sha));
    5194           0 :           vec_free (nat_sha);
    5195             :         }
    5196             :     }
    5197             : 
    5198           0 :   if (vlib_buffer_alloc (km->vlib_main, &bi0, 1) != 1)
    5199           0 :     return;
    5200             : 
    5201           0 :   vlib_buffer_t *b = vlib_get_buffer (km->vlib_main, bi0);
    5202           0 :   clib_memcpy_fast (vlib_buffer_get_current (b),
    5203           0 :                     sa->last_sa_init_req_packet_data,
    5204           0 :                     vec_len (sa->last_sa_init_req_packet_data));
    5205             : 
    5206           0 :   ikev2_send_ike (km->vlib_main, &sa->iaddr, &sa->raddr, bi0,
    5207           0 :                   vec_len (sa->last_sa_init_req_packet_data),
    5208           0 :                   ikev2_get_port (sa), IKEV2_PORT, sa->sw_if_index);
    5209             : }
    5210             : 
    5211             : static void
    5212          42 : ikev2_process_pending_sa_init (vlib_main_t *vm, ikev2_main_t *km)
    5213             : {
    5214             :   u32 sai;
    5215             :   u64 ispi;
    5216             :   ikev2_sa_t *sa;
    5217             : 
    5218             :   /* *INDENT-OFF* */
    5219        2730 :   hash_foreach (ispi, sai, km->sa_by_ispi,
    5220             :   ({
    5221             :     sa = pool_elt_at_index (km->sais, sai);
    5222             :     if (sa->init_response_received)
    5223             :       continue;
    5224             : 
    5225             :     ikev2_process_pending_sa_init_one (vm, km, sa);
    5226             :   }));
    5227             :   /* *INDENT-ON* */
    5228          42 : }
    5229             : 
    5230             : static void
    5231           2 : ikev2_send_informational_request (ikev2_sa_t * sa)
    5232             : {
    5233           2 :   ikev2_main_t *km = &ikev2_main;
    5234             :   ip_address_t *src, *dst;
    5235             :   ike_header_t *ike0;
    5236             :   vlib_buffer_t *b0;
    5237           2 :   u32 bi0 = 0;
    5238             :   u16 dp;
    5239             :   int len;
    5240             : 
    5241           2 :   bi0 = ikev2_get_new_ike_header_buff (km->vlib_main, &b0);
    5242           2 :   if (!bi0)
    5243             :     {
    5244           0 :       ikev2_log_error ("buffer alloc failure");
    5245           0 :       return;
    5246             :     }
    5247             : 
    5248           2 :   ike0 = vlib_buffer_get_current (b0);
    5249           2 :   ike0->exchange = IKEV2_EXCHANGE_INFORMATIONAL;
    5250           2 :   ike0->ispi = clib_host_to_net_u64 (sa->ispi);
    5251           2 :   ike0->rspi = clib_host_to_net_u64 (sa->rspi);
    5252           2 :   ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id);
    5253           2 :   ike0->flags = 0;
    5254           2 :   sa->last_init_msg_id += 1;
    5255           2 :   len = ikev2_generate_message (b0, sa, ike0, 0, 0, 0);
    5256           2 :   if (~0 == len)
    5257           0 :     return;
    5258             : 
    5259           2 :   if (ikev2_natt_active (sa))
    5260           0 :     len = ikev2_insert_non_esp_marker (ike0, len);
    5261             : 
    5262           2 :   if (sa->is_initiator)
    5263             :     {
    5264           0 :       src = &sa->iaddr;
    5265           0 :       dst = &sa->raddr;
    5266             :     }
    5267             :   else
    5268             :     {
    5269           2 :       dst = &sa->iaddr;
    5270           2 :       src = &sa->raddr;
    5271             :     }
    5272             : 
    5273           2 :   dp = sa->dst_port ? sa->dst_port : ikev2_get_port (sa);
    5274           2 :   ikev2_send_ike (km->vlib_main, src, dst, bi0, len, ikev2_get_port (sa), dp,
    5275             :                   sa->sw_if_index);
    5276             : }
    5277             : 
    5278             : void
    5279          18 : ikev2_disable_dpd (void)
    5280             : {
    5281          18 :   ikev2_main_t *km = &ikev2_main;
    5282          18 :   km->dpd_disabled = 1;
    5283          18 : }
    5284             : 
    5285             : static int
    5286           5 : ikev2_mngr_process_responder_sas (ikev2_sa_t *sa)
    5287             : {
    5288           5 :   ikev2_main_t *km = &ikev2_main;
    5289           5 :   vlib_main_t *vm = km->vlib_main;
    5290             : 
    5291           5 :   if (!sa->keys_generated)
    5292           0 :     return 0;
    5293             : 
    5294           5 :   if (sa->liveness_retries >= km->liveness_max_retries)
    5295           1 :     return 1;
    5296             : 
    5297           4 :   f64 now = vlib_time_now (vm);
    5298             : 
    5299           4 :   if (sa->liveness_period_check < now)
    5300             :     {
    5301           2 :       sa->liveness_retries++;
    5302           2 :       sa->liveness_period_check = now + km->liveness_period;
    5303           2 :       ikev2_send_informational_request (sa);
    5304             :     }
    5305           4 :   return 0;
    5306             : }
    5307             : 
    5308             : static uword
    5309         559 : ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
    5310             :                        vlib_frame_t * f)
    5311             : {
    5312         559 :   ikev2_main_t *km = &ikev2_main;
    5313             :   ikev2_profile_t *p;
    5314             :   ikev2_child_sa_t *c;
    5315             :   u32 *sai;
    5316             : 
    5317             :   /* lazy init will wake it up */
    5318         559 :   vlib_process_wait_for_event (vm);
    5319             : 
    5320             :   while (1)
    5321          42 :     {
    5322          63 :       vlib_process_wait_for_event_or_clock (vm, 2);
    5323          42 :       vlib_process_get_events (vm, NULL);
    5324             : 
    5325             :       /* process ike child sas */
    5326             :       ikev2_main_per_thread_data_t *tkm;
    5327          84 :       vec_foreach (tkm, km->per_thread_data)
    5328             :       {
    5329             :         ikev2_sa_t *sa;
    5330          42 :         u32 *to_be_deleted = 0;
    5331             : 
    5332             :         /* *INDENT-OFF* */
    5333          58 :         pool_foreach (sa, tkm->sas)  {
    5334             :           ikev2_child_sa_t *c;
    5335          16 :           u8 del_old_ids = 0;
    5336             : 
    5337          16 :           if (sa->state != IKEV2_STATE_AUTHENTICATED)
    5338           0 :             continue;
    5339             : 
    5340          16 :           if (sa->old_remote_id_present && 0 > sa->old_id_expiration)
    5341             :             {
    5342           2 :               sa->old_remote_id_present = 0;
    5343           2 :               del_old_ids = 1;
    5344             :             }
    5345             :           else
    5346          14 :             sa->old_id_expiration -= 1;
    5347             : 
    5348          32 :           vec_foreach (c, sa->childs)
    5349          16 :             ikev2_mngr_process_child_sa(sa, c, del_old_ids);
    5350             : 
    5351          16 :           if (!km->dpd_disabled && ikev2_mngr_process_responder_sas (sa))
    5352           1 :             vec_add1 (to_be_deleted, sa - tkm->sas);
    5353             :         }
    5354             :         /* *INDENT-ON* */
    5355             : 
    5356          43 :         vec_foreach (sai, to_be_deleted)
    5357             :         {
    5358           1 :           sa = pool_elt_at_index (tkm->sas, sai[0]);
    5359           1 :           const u32 profile_index = sa->profile_index;
    5360           1 :           const int reinitiate = (sa->is_initiator && profile_index != ~0);
    5361           2 :           vec_foreach (c, sa->childs)
    5362             :           {
    5363           1 :             ikev2_delete_tunnel_interface (km->vnet_main, sa, c);
    5364           1 :             ikev2_sa_del_child_sa (sa, c);
    5365             :           }
    5366           1 :           ikev2_sa_free_all_vec (sa);
    5367           1 :           hash_unset (tkm->sa_by_rspi, sa->rspi);
    5368           1 :           pool_put (tkm->sas, sa);
    5369             : 
    5370           1 :           if (reinitiate)
    5371             :             {
    5372           0 :               p = pool_elt_at_index (km->profiles, profile_index);
    5373           0 :               if (p)
    5374             :                 {
    5375           0 :                   clib_error_t *e = ikev2_initiate_sa_init (vm, p->name);
    5376           0 :                   if (e)
    5377             :                     {
    5378           0 :                       ikev2_log_error ("%U", format_clib_error, e);
    5379           0 :                       clib_error_free (e);
    5380             :                     }
    5381             :                 }
    5382             :             }
    5383             :         }
    5384          42 :         vec_free (to_be_deleted);
    5385             :       }
    5386             : 
    5387             :       /* process ipsec sas */
    5388             :       ipsec_sa_t *sa;
    5389             :       /* *INDENT-OFF* */
    5390          81 :       pool_foreach (sa, ipsec_sa_pool)
    5391             :         {
    5392          39 :           ikev2_mngr_process_ipsec_sa (sa);
    5393             :         }
    5394             :       /* *INDENT-ON* */
    5395             : 
    5396          42 :       ikev2_process_pending_sa_init (vm, km);
    5397             :     }
    5398             :   return 0;
    5399             : }
    5400             : 
    5401             : /* *INDENT-OFF* */
    5402      122120 : VLIB_REGISTER_NODE (ikev2_mngr_process_node, static) = {
    5403             :     .function = ikev2_mngr_process_fn,
    5404             :     .type = VLIB_NODE_TYPE_PROCESS,
    5405             :     .name =
    5406             :     "ikev2-manager-process",
    5407             : };
    5408             : 
    5409             : static void
    5410          42 : ikev2_lazy_init (ikev2_main_t *km)
    5411             : {
    5412          42 :   vlib_thread_main_t *tm = vlib_get_thread_main ();
    5413             :   int thread_id;
    5414             : 
    5415          42 :   if (km->lazy_init_done)
    5416          21 :     return;
    5417             : 
    5418          21 :   ikev2_crypto_init (km);
    5419             : 
    5420          21 :   mhash_init_vec_string (&km->profile_index_by_name, sizeof (uword));
    5421             : 
    5422          21 :   vec_validate_aligned (km->per_thread_data, tm->n_vlib_mains - 1,
    5423             :                         CLIB_CACHE_LINE_BYTES);
    5424          42 :   for (thread_id = 0; thread_id < tm->n_vlib_mains; thread_id++)
    5425             :     {
    5426          21 :       ikev2_main_per_thread_data_t *ptd =
    5427          21 :         vec_elt_at_index (km->per_thread_data, thread_id);
    5428             : 
    5429          21 :       ptd->sa_by_rspi = hash_create (0, sizeof (uword));
    5430             : 
    5431             : #if OPENSSL_VERSION_NUMBER >= 0x10100000L
    5432          21 :       ptd->evp_ctx = EVP_CIPHER_CTX_new ();
    5433          21 :       ptd->hmac_ctx = HMAC_CTX_new ();
    5434             : #else
    5435             :       EVP_CIPHER_CTX_init (&ptd->_evp_ctx);
    5436             :       ptd->evp_ctx = &ptd->_evp_ctx;
    5437             :       HMAC_CTX_init (&(ptd->_hmac_ctx));
    5438             :       ptd->hmac_ctx = &ptd->_hmac_ctx;
    5439             : #endif
    5440             :     }
    5441             : 
    5442          21 :   km->sa_by_ispi = hash_create (0, sizeof (uword));
    5443          21 :   km->sw_if_indices = hash_create (0, 0);
    5444             : 
    5445          21 :   km->punt_hdl = vlib_punt_client_register ("ikev2");
    5446             : 
    5447          21 :   km->dns_resolve_name_ptr =
    5448          21 :     vlib_get_plugin_symbol ("dns_plugin.so", "dns_resolve_name");
    5449          21 :   if (!km->dns_resolve_name_ptr)
    5450           0 :     ikev2_log_error ("cannot load symbols from dns plugin");
    5451             : 
    5452             :   /* wake up ikev2 process */
    5453          21 :   vlib_process_signal_event (vlib_get_first_main (),
    5454          21 :                              ikev2_mngr_process_node.index, 0, 0);
    5455             : 
    5456          21 :   km->lazy_init_done = 1;
    5457             : }
    5458             : 
    5459             : VLIB_PLUGIN_REGISTER () = {
    5460             :     .version = VPP_BUILD_VER,
    5461             :     .description = "Internet Key Exchange (IKEv2) Protocol",
    5462             : };
    5463             : /* *INDENT-ON* */
    5464             : 
    5465             : /*
    5466             :  * fd.io coding-style-patch-verification: ON
    5467             :  *
    5468             :  * Local Variables:
    5469             :  * eval: (c-set-style "gnu")
    5470             :  * End:
    5471             :  */

Generated by: LCOV version 1.14