/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vppinfra/error.h>
#include <vppinfra/random.h>
#include <vnet/udp/udp.h>
#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/ikev2.h>
#include <vnet/ipsec/ikev2_priv.h>
#include <openssl/sha.h>

ikev2_main_t ikev2_main;

static int ikev2_delete_tunnel_interface (vnet_main_t * vnm,
					  ikev2_sa_t * sa,
					  ikev2_child_sa_t * child);

#define ikev2_set_state(sa, v) do { \
    (sa)->state = v; \
    clib_warning("sa state changed to " #v); \
  } while(0);

typedef struct
{
  u32 next_index;
  u32 sw_if_index;
} ikev2_trace_t;

static u8 *
format_ikev2_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  ikev2_trace_t *t = va_arg (*args, ikev2_trace_t *);

  s = format (s, "ikev2: sw_if_index %d, next index %d",
	      t->sw_if_index, t->next_index);
  return s;
}

static vlib_node_registration_t ikev2_node;

#define foreach_ikev2_error \
_(PROCESSED, "IKEv2 packets processed") \
_(IKE_SA_INIT_RETRANSMIT, "IKE_SA_INIT retransmit ") \
_(IKE_SA_INIT_IGNORE, "IKE_SA_INIT ignore (IKE SA already auth)") \
_(IKE_REQ_RETRANSMIT, "IKE request retransmit") \
_(IKE_REQ_IGNORE, "IKE request ignore (old msgid)") \
_(NOT_IKEV2, "Non IKEv2 packets received")

typedef enum
{
#define _(sym,str) IKEV2_ERROR_##sym,
  foreach_ikev2_error
#undef _
    IKEV2_N_ERROR,
} ikev2_error_t;

static char *ikev2_error_strings[] = {
#define _(sym,string) string,
  foreach_ikev2_error
#undef _
};

typedef enum
{
  IKEV2_NEXT_IP4_LOOKUP,
  IKEV2_NEXT_ERROR_DROP,
  IKEV2_N_NEXT,
} ikev2_next_t;

static ikev2_sa_transform_t *
ikev2_find_transform_data (ikev2_sa_transform_t * t)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_sa_transform_t *td;

  vec_foreach (td, km->supported_transforms)
  {
    if (td->type != t->type)
      continue;

    if (td->transform_id != t->transform_id)
      continue;

    if (td->type == IKEV2_TRANSFORM_TYPE_ENCR)
      {
	if (vec_len (t->attrs) != 4 || t->attrs[0] != 0x80
	    || t->attrs[1] != 14)
	  continue;

	if (((t->attrs[2] << 8 | t->attrs[3]) / 8) != td->key_len)
	  continue;
      }
    return td;
  }
  return 0;
}

static ikev2_sa_proposal_t *
ikev2_select_proposal (ikev2_sa_proposal_t * proposals,
		       ikev2_protocol_id_t prot_id)
{
  ikev2_sa_proposal_t *rv = 0;
  ikev2_sa_proposal_t *proposal;
  ikev2_sa_transform_t *transform, *new_t;
  u8 mandatory_bitmap, optional_bitmap;

  if (prot_id == IKEV2_PROTOCOL_IKE)
    {
      mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) |
	(1 << IKEV2_TRANSFORM_TYPE_PRF) |
	(1 << IKEV2_TRANSFORM_TYPE_INTEG) | (1 << IKEV2_TRANSFORM_TYPE_DH);
      optional_bitmap = mandatory_bitmap;
    }
  else if (prot_id == IKEV2_PROTOCOL_ESP)
    {
      mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) |
	(1 << IKEV2_TRANSFORM_TYPE_ESN);
      optional_bitmap = mandatory_bitmap |
	(1 << IKEV2_TRANSFORM_TYPE_INTEG) | (1 << IKEV2_TRANSFORM_TYPE_DH);
    }
  else if (prot_id == IKEV2_PROTOCOL_AH)
    {
      mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_INTEG) |
	(1 << IKEV2_TRANSFORM_TYPE_ESN);
      optional_bitmap = mandatory_bitmap | (1 << IKEV2_TRANSFORM_TYPE_DH);
    }
  else
    return 0;

  vec_add2 (rv, proposal, 1);

  vec_foreach (proposal, proposals)
  {
    u8 bitmap = 0;
    if (proposal->protocol_id != prot_id)
      continue;

    vec_foreach (transform, proposal->transforms)
    {
      if ((1 << transform->type) & bitmap)
	continue;

      if (ikev2_find_transform_data (transform))
	{
	  bitmap |= 1 << transform->type;
	  vec_add2 (rv->transforms, new_t, 1);
	  clib_memcpy (new_t, transform, sizeof (*new_t));
	  new_t->attrs = vec_dup (transform->attrs);
	}
    }

    clib_warning ("bitmap is %x mandatory is %x optional is %x",
		  bitmap, mandatory_bitmap, optional_bitmap);

    if ((bitmap & mandatory_bitmap) == mandatory_bitmap &&
	(bitmap & ~optional_bitmap) == 0)
      {
	rv->proposal_num = proposal->proposal_num;
	rv->protocol_id = proposal->protocol_id;
	RAND_bytes ((u8 *) & rv->spi, sizeof (rv->spi));
	goto done;
      }
    else
      {
	vec_free (rv->transforms);
      }
  }

  vec_free (rv);
done:
  return rv;
}

ikev2_sa_transform_t *
ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p,
			  ikev2_transform_type_t type)
{
  ikev2_sa_transform_t *t;

  if (!p)
    return 0;

  vec_foreach (t, p->transforms)
  {
    if (t->type == type)
      return ikev2_find_transform_data (t);
  }
  return 0;
}

ikev2_child_sa_t *
ikev2_sa_get_child (ikev2_sa_t * sa, u32 spi, ikev2_protocol_id_t prot_id,
		    int by_initiator)
{
  ikev2_child_sa_t *c;
  vec_foreach (c, sa->childs)
  {
    ikev2_sa_proposal_t *proposal =
      by_initiator ? &c->i_proposals[0] : &c->r_proposals[0];
    if (proposal && proposal->spi == spi && proposal->protocol_id == prot_id)
      return c;
  }

  return 0;
}

void
ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v)
{
  ikev2_sa_proposal_t *p;
  ikev2_sa_transform_t *t;

  if (!*v)
    return;

  vec_foreach (p, *v)
  {
    vec_foreach (t, p->transforms)
    {
      vec_free (t->attrs);
    }
    vec_free (p->transforms);
  }
  vec_free (*v);
};

static void
ikev2_sa_free_all_child_sa (ikev2_child_sa_t ** childs)
{
  ikev2_child_sa_t *c;
  vec_foreach (c, *childs)
  {
    ikev2_sa_free_proposal_vector (&c->r_proposals);
    ikev2_sa_free_proposal_vector (&c->i_proposals);
    vec_free (c->sk_ai);
    vec_free (c->sk_ar);
    vec_free (c->sk_ei);
    vec_free (c->sk_er);
  }

  vec_free (*childs);
}

static void
ikev2_sa_del_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * child)
{
  ikev2_sa_free_proposal_vector (&child->r_proposals);
  ikev2_sa_free_proposal_vector (&child->i_proposals);
  vec_free (child->sk_ai);
  vec_free (child->sk_ar);
  vec_free (child->sk_ei);
  vec_free (child->sk_er);

  vec_del1 (sa->childs, child - sa->childs);
}

static void
ikev2_sa_free_all_vec (ikev2_sa_t * sa)
{
  vec_free (sa->i_nonce);
  vec_free (sa->i_dh_data);
  vec_free (sa->dh_shared_key);
  vec_free (sa->dh_private_key);

  ikev2_sa_free_proposal_vector (&sa->r_proposals);
  ikev2_sa_free_proposal_vector (&sa->i_proposals);

  vec_free (sa->sk_d);
  vec_free (sa->sk_ai);
  vec_free (sa->sk_ar);
  vec_free (sa->sk_ei);
  vec_free (sa->sk_er);
  vec_free (sa->sk_pi);
  vec_free (sa->sk_pr);

  vec_free (sa->i_id.data);
  vec_free (sa->i_auth.data);
  vec_free (sa->r_id.data);
  vec_free (sa->r_auth.data);
  if (sa->r_auth.key)
    EVP_PKEY_free (sa->r_auth.key);

  vec_free (sa->del);

  ikev2_sa_free_all_child_sa (&sa->childs);
}

static void
ikev2_delete_sa (ikev2_sa_t * sa)
{
  ikev2_main_t *km = &ikev2_main;
  u32 thread_index = vlib_get_thread_index ();
  uword *p;

  ikev2_sa_free_all_vec (sa);

  p = hash_get (km->per_thread_data[thread_index].sa_by_rspi, sa->rspi);
  if (p)
    {
      hash_unset (km->per_thread_data[thread_index].sa_by_rspi, sa->rspi);
      pool_put (km->per_thread_data[thread_index].sas, sa);
    }
}

static void
ikev2_generate_sa_init_data (ikev2_sa_t * sa)
{
  ikev2_sa_transform_t *t = 0, *t2;
  ikev2_main_t *km = &ikev2_main;

  if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
    {
      return;
    }

  /* check if received DH group is on our list of supported groups */
  vec_foreach (t2, km->supported_transforms)
  {
    if (t2->type == IKEV2_TRANSFORM_TYPE_DH && sa->dh_group == t2->dh_type)
      {
	t = t2;
	break;
      }
  }

  if (!t)
    {
      clib_warning ("unknown dh data group %u (data len %u)", sa->dh_group,
		    vec_len (sa->i_dh_data));
      sa->dh_group = IKEV2_TRANSFORM_DH_TYPE_NONE;
      return;
    }

  if (sa->is_initiator)
    {
      /* generate rspi */
      RAND_bytes ((u8 *) & sa->ispi, 8);

      /* generate nonce */
      sa->i_nonce = vec_new (u8, IKEV2_NONCE_SIZE);
      RAND_bytes ((u8 *) sa->i_nonce, IKEV2_NONCE_SIZE);
    }
  else
    {
      /* generate rspi */
      RAND_bytes ((u8 *) & sa->rspi, 8);

      /* generate nonce */
      sa->r_nonce = vec_new (u8, IKEV2_NONCE_SIZE);
      RAND_bytes ((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE);
    }

  /* generate dh keys */
  ikev2_generate_dh (sa, t);

}

static void
ikev2_complete_sa_data (ikev2_sa_t * sa, ikev2_sa_t * sai)
{
  ikev2_sa_transform_t *t = 0, *t2;
  ikev2_main_t *km = &ikev2_main;


  /*move some data to the new SA */
#define _(A) ({void* __tmp__ = (A); (A) = 0; __tmp__;})
  sa->i_nonce = _(sai->i_nonce);
  sa->i_dh_data = _(sai->i_dh_data);
  sa->dh_private_key = _(sai->dh_private_key);
  sa->iaddr.as_u32 = sai->iaddr.as_u32;
  sa->raddr.as_u32 = sai->raddr.as_u32;
  sa->is_initiator = sai->is_initiator;
  sa->profile = sai->profile;
  sa->i_id.type = sai->i_id.type;
  sa->i_id.data = _(sai->i_id.data);
  sa->i_auth.method = sai->i_auth.method;
  sa->i_auth.hex = sai->i_auth.hex;
  sa->i_auth.data = _(sai->i_auth.data);
  sa->i_auth.key = _(sai->i_auth.key);
  sa->last_sa_init_req_packet_data = _(sai->last_sa_init_req_packet_data);
  sa->childs = _(sai->childs);
#undef _


  if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
    {
      return;
    }

  /* check if received DH group is on our list of supported groups */
  vec_foreach (t2, km->supported_transforms)
  {
    if (t2->type == IKEV2_TRANSFORM_TYPE_DH && sa->dh_group == t2->dh_type)
      {
	t = t2;
	break;
      }
  }

  if (!t)
    {
      clib_warning ("unknown dh data group %u (data len %u)", sa->dh_group,
		    vec_len (sa->i_dh_data));
      sa->dh_group = IKEV2_TRANSFORM_DH_TYPE_NONE;
      return;
    }


  /* generate dh keys */
  ikev2_complete_dh (sa, t);

}

static void
ikev2_calc_keys (ikev2_sa_t * sa)
{
  u8 *tmp;
  /* calculate SKEYSEED = prf(Ni | Nr, g^ir) */
  u8 *skeyseed = 0;
  u8 *s = 0;
  ikev2_sa_transform_t *tr_encr, *tr_prf, *tr_integ;
  tr_encr =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
  tr_prf =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
  tr_integ =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);

  vec_append (s, sa->i_nonce);
  vec_append (s, sa->r_nonce);
  skeyseed = ikev2_calc_prf (tr_prf, s, sa->dh_shared_key);

  /* Calculate S = Ni | Nr | SPIi | SPIr */
  u64 *spi;
  vec_add2 (s, tmp, 2 * sizeof (*spi));
  spi = (u64 *) tmp;
  spi[0] = clib_host_to_net_u64 (sa->ispi);
  spi[1] = clib_host_to_net_u64 (sa->rspi);

  /* calculate PRFplus */
  u8 *keymat;
  int len = tr_prf->key_trunc +	/* SK_d */
    tr_integ->key_len * 2 +	/* SK_ai, SK_ar */
    tr_encr->key_len * 2 +	/* SK_ei, SK_er */
    tr_prf->key_len * 2;	/* SK_pi, SK_pr */

  keymat = ikev2_calc_prfplus (tr_prf, skeyseed, s, len);
  vec_free (skeyseed);
  vec_free (s);

  int pos = 0;

  /* SK_d */
  sa->sk_d = vec_new (u8, tr_prf->key_trunc);
  clib_memcpy (sa->sk_d, keymat + pos, tr_prf->key_trunc);
  pos += tr_prf->key_trunc;

  /* SK_ai */
  sa->sk_ai = vec_new (u8, tr_integ->key_len);
  clib_memcpy (sa->sk_ai, keymat + pos, tr_integ->key_len);
  pos += tr_integ->key_len;

  /* SK_ar */
  sa->sk_ar = vec_new (u8, tr_integ->key_len);
  clib_memcpy (sa->sk_ar, keymat + pos, tr_integ->key_len);
  pos += tr_integ->key_len;

  /* SK_ei */
  sa->sk_ei = vec_new (u8, tr_encr->key_len);
  clib_memcpy (sa->sk_ei, keymat + pos, tr_encr->key_len);
  pos += tr_encr->key_len;

  /* SK_er */
  sa->sk_er = vec_new (u8, tr_encr->key_len);
  clib_memcpy (sa->sk_er, keymat + pos, tr_encr->key_len);
  pos += tr_encr->key_len;

  /* SK_pi */
  sa->sk_pi = vec_new (u8, tr_prf->key_len);
  clib_memcpy (sa->sk_pi, keymat + pos, tr_prf->key_len);
  pos += tr_prf->key_len;

  /* SK_pr */
  sa->sk_pr = vec_new (u8, tr_prf->key_len);
  clib_memcpy (sa->sk_pr, keymat + pos, tr_prf->key_len);
  pos += tr_prf->key_len;

  vec_free (keymat);
}

static void
ikev2_calc_child_keys (ikev2_sa_t * sa, ikev2_child_sa_t * child)
{
  u8 *s = 0;
  ikev2_sa_transform_t *tr_prf, *ctr_encr, *ctr_integ;
  tr_prf =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
  ctr_encr =
    ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
  ctr_integ =
    ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);

  vec_append (s, sa->i_nonce);
  vec_append (s, sa->r_nonce);
  /* calculate PRFplus */
  u8 *keymat;
  int len = ctr_encr->key_len * 2 + ctr_integ->key_len * 2;

  keymat = ikev2_calc_prfplus (tr_prf, sa->sk_d, s, len);

  int pos = 0;

  /* SK_ei */
  child->sk_ei = vec_new (u8, ctr_encr->key_len);
  clib_memcpy (child->sk_ei, keymat + pos, ctr_encr->key_len);
  pos += ctr_encr->key_len;

  /* SK_ai */
  child->sk_ai = vec_new (u8, ctr_integ->key_len);
  clib_memcpy (child->sk_ai, keymat + pos, ctr_integ->key_len);
  pos += ctr_integ->key_len;

  /* SK_er */
  child->sk_er = vec_new (u8, ctr_encr->key_len);
  clib_memcpy (child->sk_er, keymat + pos, ctr_encr->key_len);
  pos += ctr_encr->key_len;

  /* SK_ar */
  child->sk_ar = vec_new (u8, ctr_integ->key_len);
  clib_memcpy (child->sk_ar, keymat + pos, ctr_integ->key_len);
  pos += ctr_integ->key_len;

  ASSERT (pos == len);

  vec_free (keymat);
}

static void
ikev2_process_sa_init_req (vlib_main_t * vm, ikev2_sa_t * sa,
			   ike_header_t * ike)
{
  int p = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  u8 payload = ike->nextpayload;

  clib_warning ("ispi %lx rspi %lx nextpayload %x version %x "
		"exchange %x flags %x msgid %x length %u",
		clib_net_to_host_u64 (ike->ispi),
		clib_net_to_host_u64 (ike->rspi),
		payload, ike->version,
		ike->exchange, ike->flags,
		clib_net_to_host_u32 (ike->msgid), len);

  sa->ispi = clib_net_to_host_u64 (ike->ispi);

  /* store whole IKE payload - needed for PSK auth */
  vec_free (sa->last_sa_init_req_packet_data);
  vec_add (sa->last_sa_init_req_packet_data, ike, len);

  while (p < len && payload != IKEV2_PAYLOAD_NONE)
    {
      ike_payload_header_t *ikep = (ike_payload_header_t *) & ike->payload[p];
      u32 plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (ike_payload_header_t))
	return;

      if (payload == IKEV2_PAYLOAD_SA)
	{
	  ikev2_sa_free_proposal_vector (&sa->i_proposals);
	  sa->i_proposals = ikev2_parse_sa_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_KE)
	{
	  ike_ke_payload_header_t *ke = (ike_ke_payload_header_t *) ikep;
	  sa->dh_group = clib_net_to_host_u16 (ke->dh_group);
	  vec_free (sa->i_dh_data);
	  vec_add (sa->i_dh_data, ke->payload, plen - sizeof (*ke));
	}
      else if (payload == IKEV2_PAYLOAD_NONCE)
	{
	  vec_free (sa->i_nonce);
	  vec_add (sa->i_nonce, ikep->payload, plen - sizeof (*ikep));
	}
      else if (payload == IKEV2_PAYLOAD_NOTIFY)
	{
	  ikev2_notify_t *n = ikev2_parse_notify_payload (ikep);
	  vec_free (n);
	}
      else if (payload == IKEV2_PAYLOAD_VENDOR)
	{
	  ikev2_parse_vendor_payload (ikep);
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u", payload,
			ikep->flags, plen);
	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	      sa->unsupported_cp = payload;
	      return;
	    }
	}

      payload = ikep->nextpayload;
      p += plen;
    }

  ikev2_set_state (sa, IKEV2_STATE_SA_INIT);
}

static void
ikev2_process_sa_init_resp (vlib_main_t * vm, ikev2_sa_t * sa,
			    ike_header_t * ike)
{
  int p = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  u8 payload = ike->nextpayload;

  clib_warning ("ispi %lx rspi %lx nextpayload %x version %x "
		"exchange %x flags %x msgid %x length %u",
		clib_net_to_host_u64 (ike->ispi),
		clib_net_to_host_u64 (ike->rspi),
		payload, ike->version,
		ike->exchange, ike->flags,
		clib_net_to_host_u32 (ike->msgid), len);

  sa->ispi = clib_net_to_host_u64 (ike->ispi);
  sa->rspi = clib_net_to_host_u64 (ike->rspi);

  /* store whole IKE payload - needed for PSK auth */
  vec_free (sa->last_sa_init_res_packet_data);
  vec_add (sa->last_sa_init_res_packet_data, ike, len);

  while (p < len && payload != IKEV2_PAYLOAD_NONE)
    {
      ike_payload_header_t *ikep = (ike_payload_header_t *) & ike->payload[p];
      u32 plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (ike_payload_header_t))
	return;

      if (payload == IKEV2_PAYLOAD_SA)
	{
	  ikev2_sa_free_proposal_vector (&sa->r_proposals);
	  sa->r_proposals = ikev2_parse_sa_payload (ikep);
	  if (sa->r_proposals)
	    {
	      ikev2_set_state (sa, IKEV2_STATE_SA_INIT);
	      ike->msgid =
		clib_host_to_net_u32 (clib_net_to_host_u32 (ike->msgid) + 1);
	    }
	}
      else if (payload == IKEV2_PAYLOAD_KE)
	{
	  ike_ke_payload_header_t *ke = (ike_ke_payload_header_t *) ikep;
	  sa->dh_group = clib_net_to_host_u16 (ke->dh_group);
	  vec_free (sa->r_dh_data);
	  vec_add (sa->r_dh_data, ke->payload, plen - sizeof (*ke));
	}
      else if (payload == IKEV2_PAYLOAD_NONCE)
	{
	  vec_free (sa->r_nonce);
	  vec_add (sa->r_nonce, ikep->payload, plen - sizeof (*ikep));
	}
      else if (payload == IKEV2_PAYLOAD_NOTIFY)
	{
	  ikev2_notify_t *n = ikev2_parse_notify_payload (ikep);
	  vec_free (n);
	}
      else if (payload == IKEV2_PAYLOAD_VENDOR)
	{
	  ikev2_parse_vendor_payload (ikep);
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u", payload,
			ikep->flags, plen);
	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	      sa->unsupported_cp = payload;
	      return;
	    }
	}

      payload = ikep->nextpayload;
      p += plen;
    }
}

static u8 *
ikev2_decrypt_sk_payload (ikev2_sa_t * sa, ike_header_t * ike, u8 * payload)
{
  int p = 0;
  u8 last_payload = 0;
  u8 *hmac = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  ike_payload_header_t *ikep = 0;
  u32 plen = 0;
  ikev2_sa_transform_t *tr_integ;
  tr_integ =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);

  while (p < len &&
	 *payload != IKEV2_PAYLOAD_NONE && last_payload != IKEV2_PAYLOAD_SK)
    {
      ikep = (ike_payload_header_t *) & ike->payload[p];
      plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (*ikep))
	return 0;

      if (*payload == IKEV2_PAYLOAD_SK)
	{
	  clib_warning ("received IKEv2 payload SK, len %u", plen - 4);
	  last_payload = *payload;
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u", payload,
			ikep->flags, plen);
	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      sa->unsupported_cp = *payload;
	      return 0;
	    }
	}

      *payload = ikep->nextpayload;
      p += plen;
    }

  if (last_payload != IKEV2_PAYLOAD_SK)
    {
      clib_warning ("Last payload must be SK");
      return 0;
    }

  hmac =
    ikev2_calc_integr (tr_integ, sa->is_initiator ? sa->sk_ar : sa->sk_ai,
		       (u8 *) ike, len - tr_integ->key_trunc);

  plen = plen - sizeof (*ikep) - tr_integ->key_trunc;

  if (memcmp (hmac, &ikep->payload[plen], tr_integ->key_trunc))
    {
      clib_warning ("message integrity check failed");
      vec_free (hmac);
      return 0;
    }
  vec_free (hmac);

  return ikev2_decrypt_data (sa, ikep->payload, plen);
}

static void
ikev2_initial_contact_cleanup (ikev2_sa_t * sa)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_sa_t *tmp;
  u32 i, *delete = 0;
  ikev2_child_sa_t *c;
  u32 thread_index = vlib_get_thread_index ();

  if (!sa->initial_contact)
    return;

  /* find old IKE SAs with the same authenticated identity */
  /* *INDENT-OFF* */
  pool_foreach (tmp, km->per_thread_data[thread_index].sas, ({
        if (tmp->i_id.type != sa->i_id.type ||
            vec_len(tmp->i_id.data) != vec_len(sa->i_id.data) ||
            memcmp(sa->i_id.data, tmp->i_id.data, vec_len(sa->i_id.data)))
          continue;

        if (sa->rspi != tmp->rspi)
          vec_add1(delete, tmp - km->per_thread_data[thread_index].sas);
  }));
  /* *INDENT-ON* */

  for (i = 0; i < vec_len (delete); i++)
    {
      tmp =
	pool_elt_at_index (km->per_thread_data[thread_index].sas, delete[i]);
      vec_foreach (c,
		   tmp->childs) ikev2_delete_tunnel_interface (km->vnet_main,
							       tmp, c);
      ikev2_delete_sa (tmp);
    }

  vec_free (delete);
  sa->initial_contact = 0;
}

static void
ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa, ike_header_t * ike)
{
  ikev2_child_sa_t *first_child_sa;
  int p = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  u8 payload = ike->nextpayload;
  u8 *plaintext = 0;

  ike_payload_header_t *ikep;
  u32 plen;

  clib_warning ("ispi %lx rspi %lx nextpayload %x version %x "
		"exchange %x flags %x msgid %x length %u",
		clib_net_to_host_u64 (ike->ispi),
		clib_net_to_host_u64 (ike->rspi),
		payload, ike->version,
		ike->exchange, ike->flags,
		clib_net_to_host_u32 (ike->msgid), len);

  ikev2_calc_keys (sa);

  plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload);

  if (!plaintext)
    {
      if (sa->unsupported_cp)
	ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
      goto cleanup_and_exit;
    }

  /* select or create 1st child SA */
  if (sa->is_initiator)
    {
      first_child_sa = &sa->childs[0];
    }
  else
    {
      ikev2_sa_free_all_child_sa (&sa->childs);
      vec_add2 (sa->childs, first_child_sa, 1);
    }


  /* process encrypted payload */
  p = 0;
  while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE)
    {
      ikep = (ike_payload_header_t *) & plaintext[p];
      plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (ike_payload_header_t))
	goto cleanup_and_exit;

      if (payload == IKEV2_PAYLOAD_SA)	/* 33 */
	{
	  clib_warning ("received payload SA, len %u", plen - sizeof (*ikep));
	  if (sa->is_initiator)
	    {
	      ikev2_sa_free_proposal_vector (&first_child_sa->r_proposals);
	      first_child_sa->r_proposals = ikev2_parse_sa_payload (ikep);
	    }
	  else
	    {
	      ikev2_sa_free_proposal_vector (&first_child_sa->i_proposals);
	      first_child_sa->i_proposals = ikev2_parse_sa_payload (ikep);
	    }
	}
      else if (payload == IKEV2_PAYLOAD_IDI)	/* 35 */
	{
	  ike_id_payload_header_t *id = (ike_id_payload_header_t *) ikep;

	  sa->i_id.type = id->id_type;
	  vec_free (sa->i_id.data);
	  vec_add (sa->i_id.data, id->payload, plen - sizeof (*id));

	  clib_warning ("received payload IDi, len %u id_type %u",
			plen - sizeof (*id), id->id_type);
	}
      else if (payload == IKEV2_PAYLOAD_IDR)	/* 36 */
	{
	  ike_id_payload_header_t *id = (ike_id_payload_header_t *) ikep;

	  sa->r_id.type = id->id_type;
	  vec_free (sa->r_id.data);
	  vec_add (sa->r_id.data, id->payload, plen - sizeof (*id));

	  clib_warning ("received payload IDr len %u id_type %u",
			plen - sizeof (*id), id->id_type);
	}
      else if (payload == IKEV2_PAYLOAD_AUTH)	/* 39 */
	{
	  ike_auth_payload_header_t *a = (ike_auth_payload_header_t *) ikep;

	  if (sa->is_initiator)
	    {
	      sa->r_auth.method = a->auth_method;
	      vec_free (sa->r_auth.data);
	      vec_add (sa->r_auth.data, a->payload, plen - sizeof (*a));
	    }
	  else
	    {
	      sa->i_auth.method = a->auth_method;
	      vec_free (sa->i_auth.data);
	      vec_add (sa->i_auth.data, a->payload, plen - sizeof (*a));
	    }

	  clib_warning ("received payload AUTH, len %u auth_type %u",
			plen - sizeof (*a), a->auth_method);
	}
      else if (payload == IKEV2_PAYLOAD_NOTIFY)	/* 41 */
	{
	  ikev2_notify_t *n = ikev2_parse_notify_payload (ikep);
	  if (n->msg_type == IKEV2_NOTIFY_MSG_INITIAL_CONTACT)
	    {
	      sa->initial_contact = 1;
	    }
	  vec_free (n);
	}
      else if (payload == IKEV2_PAYLOAD_VENDOR)	/* 43 */
	{
	  ikev2_parse_vendor_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_TSI)	/* 44 */
	{
	  clib_warning ("received payload TSi, len %u",
			plen - sizeof (*ikep));

	  vec_free (first_child_sa->tsi);
	  first_child_sa->tsi = ikev2_parse_ts_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_TSR)	/* 45 */
	{
	  clib_warning ("received payload TSr, len %u",
			plen - sizeof (*ikep));

	  vec_free (first_child_sa->tsr);
	  first_child_sa->tsr = ikev2_parse_ts_payload (ikep);
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u data %u",
			payload, ikep->flags, plen - 4,
			format_hex_bytes, ikep->payload, plen - 4);

	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	      sa->unsupported_cp = payload;
	      return;
	    }
	}

      payload = ikep->nextpayload;
      p += plen;
    }

cleanup_and_exit:
  vec_free (plaintext);
}

static void
ikev2_process_informational_req (vlib_main_t * vm, ikev2_sa_t * sa,
				 ike_header_t * ike)
{
  int p = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  u8 payload = ike->nextpayload;
  u8 *plaintext = 0;

  ike_payload_header_t *ikep;
  u32 plen;

  clib_warning ("ispi %lx rspi %lx nextpayload %x version %x "
		"exchange %x flags %x msgid %x length %u",
		clib_net_to_host_u64 (ike->ispi),
		clib_net_to_host_u64 (ike->rspi),
		payload, ike->version,
		ike->exchange, ike->flags,
		clib_net_to_host_u32 (ike->msgid), len);

  plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload);

  if (!plaintext)
    goto cleanup_and_exit;

  /* process encrypted payload */
  p = 0;
  while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE)
    {
      ikep = (ike_payload_header_t *) & plaintext[p];
      plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (ike_payload_header_t))
	goto cleanup_and_exit;

      if (payload == IKEV2_PAYLOAD_NOTIFY)	/* 41 */
	{
	  ikev2_notify_t *n = ikev2_parse_notify_payload (ikep);
	  if (n->msg_type == IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED)
	    ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
	  vec_free (n);
	}
      else if (payload == IKEV2_PAYLOAD_DELETE)	/* 42 */
	{
	  sa->del = ikev2_parse_delete_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_VENDOR)	/* 43 */
	{
	  ikev2_parse_vendor_payload (ikep);
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u data %u",
			payload, ikep->flags, plen - 4,
			format_hex_bytes, ikep->payload, plen - 4);

	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      sa->unsupported_cp = payload;
	      return;
	    }
	}

      payload = ikep->nextpayload;
      p += plen;
    }

cleanup_and_exit:
  vec_free (plaintext);
}

static void
ikev2_process_create_child_sa_req (vlib_main_t * vm, ikev2_sa_t * sa,
				   ike_header_t * ike)
{
  int p = 0;
  u32 len = clib_net_to_host_u32 (ike->length);
  u8 payload = ike->nextpayload;
  u8 *plaintext = 0;
  u8 rekeying = 0;
  u8 nonce[IKEV2_NONCE_SIZE];

  ike_payload_header_t *ikep;
  u32 plen;
  ikev2_notify_t *n = 0;
  ikev2_ts_t *tsi = 0;
  ikev2_ts_t *tsr = 0;
  ikev2_sa_proposal_t *proposal = 0;
  ikev2_child_sa_t *child_sa;

  clib_warning ("ispi %lx rspi %lx nextpayload %x version %x "
		"exchange %x flags %x msgid %x length %u",
		clib_net_to_host_u64 (ike->ispi),
		clib_net_to_host_u64 (ike->rspi),
		payload, ike->version,
		ike->exchange, ike->flags,
		clib_net_to_host_u32 (ike->msgid), len);

  plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload);

  if (!plaintext)
    goto cleanup_and_exit;

  /* process encrypted payload */
  p = 0;
  while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE)
    {
      ikep = (ike_payload_header_t *) & plaintext[p];
      plen = clib_net_to_host_u16 (ikep->length);

      if (plen < sizeof (ike_payload_header_t))
	goto cleanup_and_exit;

      else if (payload == IKEV2_PAYLOAD_SA)
	{
	  proposal = ikev2_parse_sa_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_NOTIFY)
	{
	  n = ikev2_parse_notify_payload (ikep);
	  if (n->msg_type == IKEV2_NOTIFY_MSG_REKEY_SA)
	    {
	      rekeying = 1;
	    }
	}
      else if (payload == IKEV2_PAYLOAD_DELETE)
	{
	  sa->del = ikev2_parse_delete_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_VENDOR)
	{
	  ikev2_parse_vendor_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_NONCE)
	{
	  clib_memcpy (nonce, ikep->payload, plen - sizeof (*ikep));
	}
      else if (payload == IKEV2_PAYLOAD_TSI)
	{
	  tsi = ikev2_parse_ts_payload (ikep);
	}
      else if (payload == IKEV2_PAYLOAD_TSR)
	{
	  tsr = ikev2_parse_ts_payload (ikep);
	}
      else
	{
	  clib_warning ("unknown payload %u flags %x length %u data %u",
			payload, ikep->flags, plen - 4,
			format_hex_bytes, ikep->payload, plen - 4);

	  if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL)
	    {
	      sa->unsupported_cp = payload;
	      return;
	    }
	}

      payload = ikep->nextpayload;
      p += plen;
    }

  if (sa->is_initiator && proposal->protocol_id == IKEV2_PROTOCOL_ESP)
    {
      ikev2_rekey_t *rekey = &sa->rekey[0];
      rekey->protocol_id = proposal->protocol_id;
      rekey->i_proposal =
	ikev2_select_proposal (proposal, IKEV2_PROTOCOL_ESP);
      rekey->i_proposal->spi = rekey->spi;
      rekey->r_proposal = proposal;
      rekey->tsi = tsi;
      rekey->tsr = tsr;
      /* update Nr */
      vec_free (sa->r_nonce);
      vec_add (sa->r_nonce, nonce, IKEV2_NONCE_SIZE);
      child_sa = ikev2_sa_get_child (sa, rekey->ispi, IKEV2_PROTOCOL_ESP, 1);
      if (child_sa)
	{
	  child_sa->rekey_retries = 0;
	}
    }
  else if (rekeying)
    {
      ikev2_rekey_t *rekey;
      child_sa = ikev2_sa_get_child (sa, n->spi, n->protocol_id, 1);
      if (!child_sa)
	{
	  clib_warning ("child SA spi %lx not found", n->spi);
	  goto cleanup_and_exit;
	}
      vec_add2 (sa->rekey, rekey, 1);
      rekey->protocol_id = n->protocol_id;
      rekey->spi = n->spi;
      rekey->i_proposal = proposal;
      rekey->r_proposal =
	ikev2_select_proposal (proposal, IKEV2_PROTOCOL_ESP);
      rekey->tsi = tsi;
      rekey->tsr = tsr;
      /* update Ni */
      vec_free (sa->i_nonce);
      vec_add (sa->i_nonce, nonce, IKEV2_NONCE_SIZE);
      /* generate new Nr */
      vec_free (sa->r_nonce);
      sa->r_nonce = vec_new (u8, IKEV2_NONCE_SIZE);
      RAND_bytes ((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE);
    }

cleanup_and_exit:
  vec_free (plaintext);
  vec_free (n);
}

static u8 *
ikev2_sa_generate_authmsg (ikev2_sa_t * sa, int is_responder)
{
  u8 *authmsg = 0;
  u8 *data;
  u8 *nonce;
  ikev2_id_t *id;
  u8 *key;
  u8 *packet_data;
  ikev2_sa_transform_t *tr_prf;

  tr_prf =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);

  if (is_responder)
    {
      id = &sa->r_id;
      key = sa->sk_pr;
      nonce = sa->i_nonce;
      packet_data = sa->last_sa_init_res_packet_data;
    }
  else
    {
      id = &sa->i_id;
      key = sa->sk_pi;
      nonce = sa->r_nonce;
      packet_data = sa->last_sa_init_req_packet_data;
    }

  data = vec_new (u8, 4);
  data[0] = id->type;
  vec_append (data, id->data);

  u8 *id_hash = ikev2_calc_prf (tr_prf, key, data);
  vec_append (authmsg, packet_data);
  vec_append (authmsg, nonce);
  vec_append (authmsg, id_hash);
  vec_free (id_hash);
  vec_free (data);

  return authmsg;
}

static int
ikev2_ts_cmp (ikev2_ts_t * ts1, ikev2_ts_t * ts2)
{
  if (ts1->ts_type == ts2->ts_type && ts1->protocol_id == ts2->protocol_id &&
      ts1->start_port == ts2->start_port && ts1->end_port == ts2->end_port &&
      ts1->start_addr.as_u32 == ts2->start_addr.as_u32 &&
      ts1->end_addr.as_u32 == ts2->end_addr.as_u32)
    return 1;

  return 0;
}

static void
ikev2_sa_match_ts (ikev2_sa_t * sa)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_profile_t *p;
  ikev2_ts_t *ts, *p_tsi, *p_tsr, *tsi = 0, *tsr = 0;
  ikev2_id_t *id;

  /* *INDENT-OFF* */
  pool_foreach (p, km->profiles, ({

    if (sa->is_initiator)
      {
        p_tsi = &p->loc_ts;
        p_tsr = &p->rem_ts;
        id = &sa->r_id;
      }
    else
      {
        p_tsi = &p->rem_ts;
        p_tsr = &p->loc_ts;
        id = &sa->i_id;
      }

    /* check id */
    if (p->rem_id.type != id->type ||
        vec_len(p->rem_id.data) != vec_len(id->data) ||
        memcmp(p->rem_id.data, id->data, vec_len(p->rem_id.data)))
      continue;

    vec_foreach(ts, sa->childs[0].tsi)
      {
        if (ikev2_ts_cmp(p_tsi, ts))
          {
            tsi = vec_dup(ts);
            break;
          }
      }

    vec_foreach(ts, sa->childs[0].tsr)
      {
        if (ikev2_ts_cmp(p_tsr, ts))
          {
            tsr = vec_dup(ts);
            break;
          }
      }

    break;
  }));
  /* *INDENT-ON* */

  if (tsi && tsr)
    {
      vec_free (sa->childs[0].tsi);
      vec_free (sa->childs[0].tsr);
      sa->childs[0].tsi = tsi;
      sa->childs[0].tsr = tsr;
    }
  else
    {
      vec_free (tsi);
      vec_free (tsr);
      ikev2_set_state (sa, IKEV2_STATE_TS_UNACCEPTABLE);
    }
}

static void
ikev2_sa_auth (ikev2_sa_t * sa)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_profile_t *p, *sel_p = 0;
  u8 *authmsg, *key_pad, *psk = 0, *auth = 0;
  ikev2_sa_transform_t *tr_prf;

  tr_prf =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);

  /* only shared key and rsa signature */
  if (!(sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC ||
	sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG))
    {
      clib_warning ("unsupported authentication method %u",
		    sa->i_auth.method);
      ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
      return;
    }

  key_pad = format (0, "%s", IKEV2_KEY_PAD);
  authmsg = ikev2_sa_generate_authmsg (sa, sa->is_initiator);

  ikev2_id_t *sa_id;
  ikev2_auth_t *sa_auth;

  if (sa->is_initiator)
    {
      sa_id = &sa->r_id;
      sa_auth = &sa->r_auth;
    }
  else
    {
      sa_id = &sa->i_id;
      sa_auth = &sa->i_auth;
    }

  /* *INDENT-OFF* */
  pool_foreach (p, km->profiles, ({

    /* check id */
    if (p->rem_id.type != sa_id->type ||
        vec_len(p->rem_id.data) != vec_len(sa_id->data) ||
        memcmp(p->rem_id.data, sa_id->data, vec_len(p->rem_id.data)))
      continue;

    if (sa_auth->method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
      {
        if (!p->auth.data ||
             p->auth.method != IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
          continue;

        psk = ikev2_calc_prf(tr_prf, p->auth.data, key_pad);
        auth = ikev2_calc_prf(tr_prf, psk, authmsg);

        if (!memcmp(auth, sa_auth->data, vec_len(sa_auth->data)))
          {
            ikev2_set_state(sa, IKEV2_STATE_AUTHENTICATED);
            vec_free(auth);
            sel_p = p;
            break;
          }

      }
    else if (sa_auth->method == IKEV2_AUTH_METHOD_RSA_SIG)
      {
        if (p->auth.method != IKEV2_AUTH_METHOD_RSA_SIG)
          continue;

        if (ikev2_verify_sign(p->auth.key, sa_auth->data, authmsg) == 1)
          {
            ikev2_set_state(sa, IKEV2_STATE_AUTHENTICATED);
            sel_p = p;
            break;
          }
      }

    vec_free(auth);
    vec_free(psk);
  }));
  /* *INDENT-ON* */

  vec_free (authmsg);

  if (sa->state == IKEV2_STATE_AUTHENTICATED)
    {
      if (!sa->is_initiator)
	{
	  vec_free (sa->r_id.data);
	  sa->r_id.data = vec_dup (sel_p->loc_id.data);
	  sa->r_id.type = sel_p->loc_id.type;

	  /* generate our auth data */
	  authmsg = ikev2_sa_generate_authmsg (sa, 1);
	  if (sel_p->auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
	    {
	      sa->r_auth.data = ikev2_calc_prf (tr_prf, psk, authmsg);
	      sa->r_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC;
	    }
	  else if (sel_p->auth.method == IKEV2_AUTH_METHOD_RSA_SIG)
	    {
	      sa->r_auth.data = ikev2_calc_sign (km->pkey, authmsg);
	      sa->r_auth.method = IKEV2_AUTH_METHOD_RSA_SIG;
	    }
	  vec_free (authmsg);

	  /* select transforms for 1st child sa */
	  ikev2_sa_free_proposal_vector (&sa->childs[0].r_proposals);
	  sa->childs[0].r_proposals =
	    ikev2_select_proposal (sa->childs[0].i_proposals,
				   IKEV2_PROTOCOL_ESP);
	}
    }
  else
    {
      ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
    }
  vec_free (psk);
  vec_free (key_pad);
}


static void
ikev2_sa_auth_init (ikev2_sa_t * sa)
{
  ikev2_main_t *km = &ikev2_main;
  u8 *authmsg, *key_pad, *psk = 0, *auth = 0;
  ikev2_sa_transform_t *tr_prf;

  tr_prf =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);

  /* only shared key and rsa signature */
  if (!(sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC ||
	sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG))
    {
      clib_warning ("unsupported authentication method %u",
		    sa->i_auth.method);
      ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED);
      return;
    }

  key_pad = format (0, "%s", IKEV2_KEY_PAD);
  authmsg = ikev2_sa_generate_authmsg (sa, 0);
  psk = ikev2_calc_prf (tr_prf, sa->i_auth.data, key_pad);
  auth = ikev2_calc_prf (tr_prf, psk, authmsg);


  if (sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC)
    {
      sa->i_auth.data = ikev2_calc_prf (tr_prf, psk, authmsg);
      sa->i_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC;
    }
  else if (sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG)
    {
      sa->i_auth.data = ikev2_calc_sign (km->pkey, authmsg);
      sa->i_auth.method = IKEV2_AUTH_METHOD_RSA_SIG;
    }

  vec_free (psk);
  vec_free (key_pad);
  vec_free (auth);
  vec_free (authmsg);
}


static int
ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa,
			       ikev2_child_sa_t * child)
{
  ipsec_add_del_tunnel_args_t a;
  ikev2_sa_transform_t *tr;
  ikev2_sa_proposal_t *proposals;
  u8 encr_type = 0;

  if (!child->r_proposals)
    {
      ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
      return 1;
    }

  memset (&a, 0, sizeof (a));
  a.is_add = 1;
  if (sa->is_initiator)
    {
      a.local_ip.as_u32 = sa->iaddr.as_u32;
      a.remote_ip.as_u32 = sa->raddr.as_u32;
      proposals = child->i_proposals;
      a.local_spi = child->r_proposals[0].spi;
      a.remote_spi = child->i_proposals[0].spi;
    }
  else
    {
      a.local_ip.as_u32 = sa->raddr.as_u32;
      a.remote_ip.as_u32 = sa->iaddr.as_u32;
      proposals = child->r_proposals;
      a.local_spi = child->i_proposals[0].spi;
      a.remote_spi = child->r_proposals[0].spi;
    }
  a.anti_replay = 1;

  tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_ESN);
  if (tr)
    a.esn = tr->esn_type;
  else
    a.esn = 0;

  tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_ENCR);
  if (tr)
    {
      if (tr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC && tr->key_len)
	{
	  switch (tr->key_len)
	    {
	    case 16:
	      encr_type = IPSEC_CRYPTO_ALG_AES_CBC_128;
	      break;
	    case 24:
	      encr_type = IPSEC_CRYPTO_ALG_AES_CBC_192;
	      break;
	    case 32:
	      encr_type = IPSEC_CRYPTO_ALG_AES_CBC_256;
	      break;
	    default:
	      ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
	      return 1;
	      break;
	    }
	}
      else
	{
	  ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
	  return 1;
	}
    }
  else
    {
      ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
      return 1;
    }

  tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_INTEG);
  if (tr)
    {
      if (tr->integ_type != IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96)
	{
	  ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
	  return 1;
	}
    }
  else
    {
      ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN);
      return 1;
    }

  ikev2_calc_child_keys (sa, child);

  u8 *loc_ckey, *rem_ckey, *loc_ikey, *rem_ikey;
  if (sa->is_initiator)
    {
      loc_ikey = child->sk_ai;
      rem_ikey = child->sk_ar;
      loc_ckey = child->sk_ei;
      rem_ckey = child->sk_er;
    }
  else
    {
      loc_ikey = child->sk_ar;
      rem_ikey = child->sk_ai;
      loc_ckey = child->sk_er;
      rem_ckey = child->sk_ei;
    }

  a.integ_alg = IPSEC_INTEG_ALG_SHA1_96;
  a.local_integ_key_len = vec_len (loc_ikey);
  clib_memcpy (a.local_integ_key, loc_ikey, a.local_integ_key_len);
  a.remote_integ_key_len = vec_len (rem_ikey);
  clib_memcpy (a.remote_integ_key, rem_ikey, a.remote_integ_key_len);

  a.crypto_alg = encr_type;
  a.local_crypto_key_len = vec_len (loc_ckey);
  clib_memcpy (a.local_crypto_key, loc_ckey, a.local_crypto_key_len);
  a.remote_crypto_key_len = vec_len (rem_ckey);
  clib_memcpy (a.remote_crypto_key, rem_ckey, a.remote_crypto_key_len);

  if (sa->profile && sa->profile->lifetime)
    {
      child->time_to_expiration = vlib_time_now (vnm->vlib_main)
	+ sa->profile->lifetime;
      if (sa->profile->lifetime_jitter)
	{
	  // This is not much better than rand(3), which Coverity warns
	  // is unsuitable for security applications; random_u32 is
	  // however fast. If this perturbance to the expiration time
	  // needs to use a better RNG then we may need to use something
	  // like /dev/urandom which has significant overhead.
	  u32 rnd = (u32) (vlib_time_now (vnm->vlib_main) * 1e6);
	  rnd = random_u32 (&rnd);

	  child->time_to_expiration +=
	    1 + (rnd % sa->profile->lifetime_jitter);
	}
    }

  ipsec_add_del_tunnel_if (&a);

  return 0;
}

static int
ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa,
			       ikev2_child_sa_t * child)
{
  ipsec_add_del_tunnel_args_t a;

  if (sa->is_initiator)
    {
      if (!vec_len (child->i_proposals))
	return 0;

      a.is_add = 0;
      a.local_ip.as_u32 = sa->iaddr.as_u32;
      a.remote_ip.as_u32 = sa->raddr.as_u32;
      a.local_spi = child->r_proposals[0].spi;
      a.remote_spi = child->i_proposals[0].spi;
    }
  else
    {
      if (!vec_len (child->r_proposals))
	return 0;

      a.is_add = 0;
      a.local_ip.as_u32 = sa->raddr.as_u32;
      a.remote_ip.as_u32 = sa->iaddr.as_u32;
      a.local_spi = child->i_proposals[0].spi;
      a.remote_spi = child->r_proposals[0].spi;
    }

  ipsec_add_del_tunnel_if (&a);
  return 0;
}

static u32
ikev2_generate_message (ikev2_sa_t * sa, ike_header_t * ike, void *user)
{
  v8 *integ = 0;
  ike_payload_header_t *ph;
  u16 plen;
  u32 tlen = 0;

  ikev2_sa_transform_t *tr_encr, *tr_integ;
  tr_encr =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
  tr_integ =
    ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);

  ikev2_payload_chain_t *chain = 0;
  ikev2_payload_new_chain (chain);

  if (ike->exchange == IKEV2_EXCHANGE_SA_INIT)
    {
      if (sa->r_proposals == 0)
	{
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0);
	  ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	}
      else if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE)
	{
	  u8 *data = vec_new (u8, 2);
	  ikev2_sa_transform_t *tr_dh;
	  tr_dh =
	    ikev2_sa_get_td_for_type (sa->r_proposals,
				      IKEV2_TRANSFORM_TYPE_DH);
	  ASSERT (tr_dh && tr_dh->dh_type);

	  data[0] = (tr_dh->dh_type >> 8) & 0xff;
	  data[1] = (tr_dh->dh_type) & 0xff;

	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD,
				    data);
	  vec_free (data);
	  ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	}
      else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE)
	{
	  u8 *data = vec_new (u8, 1);

	  data[0] = sa->unsupported_cp;
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
				    data);
	  vec_free (data);
	}
      else
	{
	  ike->rspi = clib_host_to_net_u64 (sa->rspi);
	  ikev2_payload_add_sa (chain, sa->r_proposals);
	  ikev2_payload_add_ke (chain, sa->dh_group, sa->r_dh_data);
	  ikev2_payload_add_nonce (chain, sa->r_nonce);
	}
    }
  else if (ike->exchange == IKEV2_EXCHANGE_IKE_AUTH)
    {
      if (sa->state == IKEV2_STATE_AUTHENTICATED)
	{
	  ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
	  ikev2_payload_add_auth (chain, &sa->r_auth);
	  ikev2_payload_add_sa (chain, sa->childs[0].r_proposals);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
	}
      else if (sa->state == IKEV2_STATE_AUTH_FAILED)
	{
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED,
				    0);
	  ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	}
      else if (sa->state == IKEV2_STATE_TS_UNACCEPTABLE)
	{
	  ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_TS_UNACCEPTABLE,
				    0);
	  ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
	  ikev2_payload_add_auth (chain, &sa->r_auth);
	}
      else if (sa->state == IKEV2_STATE_NO_PROPOSAL_CHOSEN)
	{
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0);
	  ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR);
	  ikev2_payload_add_auth (chain, &sa->r_auth);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
	}
      else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE)
	{
	  u8 *data = vec_new (u8, 1);

	  data[0] = sa->unsupported_cp;
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
				    data);
	  vec_free (data);
	}
      else if (sa->state == IKEV2_STATE_SA_INIT)
	{
	  ikev2_payload_add_id (chain, &sa->i_id, IKEV2_PAYLOAD_IDI);
	  ikev2_payload_add_auth (chain, &sa->i_auth);
	  ikev2_payload_add_sa (chain, sa->childs[0].i_proposals);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
	}
      else
	{
	  ikev2_set_state (sa, IKEV2_STATE_DELETED);
	  goto done;
	}
    }
  else if (ike->exchange == IKEV2_EXCHANGE_INFORMATIONAL)
    {
      /* if pending delete */
      if (sa->del)
	{
	  if (sa->del[0].protocol_id == IKEV2_PROTOCOL_IKE)
	    {
	      if (sa->is_initiator)
		ikev2_payload_add_delete (chain, sa->del);

	      /* The response to a request that deletes the IKE SA is an empty
	         INFORMATIONAL response. */
	      ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE);
	    }
	  /* The response to a request that deletes ESP or AH SAs will contain
	     delete payloads for the paired SAs going in the other direction. */
	  else
	    {
	      ikev2_payload_add_delete (chain, sa->del);
	    }
	  vec_free (sa->del);
	  sa->del = 0;
	}
      /* received N(AUTHENTICATION_FAILED) */
      else if (sa->state == IKEV2_STATE_AUTH_FAILED)
	{
	  ikev2_set_state (sa, IKEV2_STATE_DELETED);
	  goto done;
	}
      /* received unsupported critical payload */
      else if (sa->unsupported_cp)
	{
	  u8 *data = vec_new (u8, 1);

	  data[0] = sa->unsupported_cp;
	  ikev2_payload_add_notify (chain,
				    IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
				    data);
	  vec_free (data);
	  sa->unsupported_cp = 0;
	}
      /* else send empty response */
    }
  else if (ike->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA)
    {
      if (sa->is_initiator)
	{

	  ikev2_sa_proposal_t *proposals = (ikev2_sa_proposal_t *) user;
	  ikev2_notify_t notify;
	  u8 *data = vec_new (u8, 4);
	  memset (&notify, 0, sizeof (notify));
	  notify.protocol_id = IKEV2_PROTOCOL_ESP;
	  notify.spi = sa->childs[0].i_proposals->spi;
	  *(u32 *) data = clib_host_to_net_u32 (notify.spi);

	  ikev2_payload_add_sa (chain, proposals);
	  ikev2_payload_add_nonce (chain, sa->i_nonce);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI);
	  ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR);
	  ikev2_payload_add_notify_2 (chain, IKEV2_NOTIFY_MSG_REKEY_SA, data,
				      &notify);

	  vec_free (data);
	}
      else
	{
	  if (sa->rekey)
	    {
	      ikev2_payload_add_sa (chain, sa->rekey[0].r_proposal);
	      ikev2_payload_add_nonce (chain, sa->r_nonce);
	      ikev2_payload_add_ts (chain, sa->rekey[0].tsi,
				    IKEV2_PAYLOAD_TSI);
	      ikev2_payload_add_ts (chain, sa->rekey[0].tsr,
				    IKEV2_PAYLOAD_TSR);
	      vec_del1 (sa->rekey, 0);
	    }
	  else if (sa->unsupported_cp)
	    {
	      u8 *data = vec_new (u8, 1);

	      data[0] = sa->unsupported_cp;
	      ikev2_payload_add_notify (chain,
					IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD,
					data);
	      vec_free (data);
	      sa->unsupported_cp = 0;
	    }
	  else
	    {
	      ikev2_payload_add_notify (chain,
					IKEV2_NOTIFY_MSG_NO_ADDITIONAL_SAS,
					0);
	    }
	}
    }

  /* IKEv2 header */
  ike->version = IKE_VERSION_2;
  ike->nextpayload = IKEV2_PAYLOAD_SK;
  tlen = sizeof (*ike);
  if (sa->is_initiator)
    {
      ike->flags = IKEV2_HDR_FLAG_INITIATOR;
      sa->last_init_msg_id = clib_net_to_host_u32 (ike->msgid);
    }
  else
    {
      ike->flags = IKEV2_HDR_FLAG_RESPONSE;
    }


  if (ike->exchange == IKEV2_EXCHANGE_SA_INIT)
    {
      tlen += vec_len (chain->data);
      ike->nextpayload = chain->first_payload_type;
      ike->length = clib_host_to_net_u32 (tlen);
      clib_memcpy (ike->payload, chain->data, vec_len (chain->data));

      /* store whole IKE payload - needed for PSK auth */
      vec_free (sa->last_sa_init_res_packet_data);
      vec_add (sa->last_sa_init_res_packet_data, ike, tlen);
    }
  else
    {

      ikev2_payload_chain_add_padding (chain, tr_encr->block_size);

      /* SK payload */
      plen = sizeof (*ph);
      ph = (ike_payload_header_t *) & ike->payload[0];
      ph->nextpayload = chain->first_payload_type;
      ph->flags = 0;
      int enc_len = ikev2_encrypt_data (sa, chain->data, ph->payload);
      plen += enc_len;

      /* add space for hmac */
      plen += tr_integ->key_trunc;
      tlen += plen;

      /* payload and total length */
      ph->length = clib_host_to_net_u16 (plen);
      ike->length = clib_host_to_net_u32 (tlen);

      /* calc integrity data for whole packet except hash itself */
      integ =
	ikev2_calc_integr (tr_integ, sa->is_initiator ? sa->sk_ai : sa->sk_ar,
			   (u8 *) ike, tlen - tr_integ->key_trunc);

      clib_memcpy (ike->payload + tlen - tr_integ->key_trunc - sizeof (*ike),
		   integ, tr_integ->key_trunc);

      /* store whole IKE payload - needed for retransmit */
      vec_free (sa->last_res_packet_data);
      vec_add (sa->last_res_packet_data, ike, tlen);
    }

done:
  ikev2_payload_destroy_chain (chain);
  vec_free (integ);
  return tlen;
}

static int
ikev2_retransmit_sa_init (ike_header_t * ike,
			  ip4_address_t iaddr, ip4_address_t raddr)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_sa_t *sa;
  u32 thread_index = vlib_get_thread_index ();

  /* *INDENT-OFF* */
  pool_foreach (sa, km->per_thread_data[thread_index].sas, ({
    if (sa->ispi == clib_net_to_host_u64(ike->ispi) &&
        sa->iaddr.as_u32 == iaddr.as_u32 &&
        sa->raddr.as_u32 == raddr.as_u32)
      {
        int p = 0;
        u32 len = clib_net_to_host_u32(ike->length);
        u8 payload = ike->nextpayload;

        while (p < len && payload!= IKEV2_PAYLOAD_NONE) {
          ike_payload_header_t * ikep = (ike_payload_header_t *) &ike->payload[p];
          u32 plen = clib_net_to_host_u16(ikep->length);

          if (plen < sizeof(ike_payload_header_t))
            return -1;

          if (payload == IKEV2_PAYLOAD_NONCE)
            {
              if (!memcmp(sa->i_nonce, ikep->payload, plen - sizeof(*ikep)))
                {
                  /* req is retransmit */
                  if (sa->state == IKEV2_STATE_SA_INIT)
                    {
                      ike_header_t * tmp;
                      tmp = (ike_header_t*)sa->last_sa_init_res_packet_data;
                      ike->ispi = tmp->ispi;
                      ike->rspi = tmp->rspi;
                      ike->nextpayload = tmp->nextpayload;
                      ike->version = tmp->version;
                      ike->exchange = tmp->exchange;
                      ike->flags = tmp->flags;
                      ike->msgid = tmp->msgid;
                      ike->length = tmp->length;
                      clib_memcpy(ike->payload, tmp->payload,
                             clib_net_to_host_u32(tmp->length) - sizeof(*ike));
                      clib_warning("IKE_SA_INIT retransmit from %U to %U",
                                   format_ip4_address, &raddr,
                                   format_ip4_address, &iaddr);
                      return 1;
                    }
                  /* else ignore req */
                  else
                    {
                      clib_warning("IKE_SA_INIT ignore from %U to %U",
                                   format_ip4_address, &raddr,
                                   format_ip4_address, &iaddr);
                      return -1;
                    }
                }
            }
          payload = ikep->nextpayload;
          p+=plen;
        }
      }
  }));
  /* *INDENT-ON* */

  /* req is not retransmit */
  return 0;
}

static int
ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike)
{
  u32 msg_id = clib_net_to_host_u32 (ike->msgid);

  /* new req */
  if (msg_id > sa->last_msg_id)
    {
      sa->last_msg_id = msg_id;
      return 0;
    }
  /* retransmitted req */
  else if (msg_id == sa->last_msg_id)
    {
      ike_header_t *tmp;
      tmp = (ike_header_t *) sa->last_res_packet_data;
      ike->ispi = tmp->ispi;
      ike->rspi = tmp->rspi;
      ike->nextpayload = tmp->nextpayload;
      ike->version = tmp->version;
      ike->exchange = tmp->exchange;
      ike->flags = tmp->flags;
      ike->msgid = tmp->msgid;
      ike->length = tmp->length;
      clib_memcpy (ike->payload, tmp->payload,
		   clib_net_to_host_u32 (tmp->length) - sizeof (*ike));
      clib_warning ("IKE msgid %u retransmit from %U to %U",
		    msg_id,
		    format_ip4_address, &sa->raddr,
		    format_ip4_address, &sa->iaddr);
      return 1;
    }
  /* old req ignore */
  else
    {
      clib_warning ("IKE msgid %u req ignore from %U to %U",
		    msg_id,
		    format_ip4_address, &sa->raddr,
		    format_ip4_address, &sa->iaddr);
      return -1;
    }
}

static uword
ikev2_node_fn (vlib_main_t * vm,
	       vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left_from, *from, *to_next;
  ikev2_next_t next_index;
  ikev2_main_t *km = &ikev2_main;
  u32 thread_index = vlib_get_thread_index ();

  from = vlib_frame_vector_args (frame);
  n_left_from = frame->n_vectors;
  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  u32 next0 = IKEV2_NEXT_ERROR_DROP;
	  u32 sw_if_index0;
	  ip4_header_t *ip40;
	  udp_header_t *udp0;
	  ike_header_t *ike0;
	  ikev2_sa_t *sa0 = 0;
	  ikev2_sa_t sa;	/* temporary store for SA */
	  int len = 0;
	  int r;

	  /* speculatively enqueue b0 to the current next frame */
	  bi0 = from[0];
	  to_next[0] = bi0;
	  from += 1;
	  to_next += 1;
	  n_left_from -= 1;
	  n_left_to_next -= 1;

	  b0 = vlib_get_buffer (vm, bi0);
	  ike0 = vlib_buffer_get_current (b0);
	  vlib_buffer_advance (b0, -sizeof (*udp0));
	  udp0 = vlib_buffer_get_current (b0);
	  vlib_buffer_advance (b0, -sizeof (*ip40));
	  ip40 = vlib_buffer_get_current (b0);

	  if (ike0->version != IKE_VERSION_2)
	    {
	      vlib_node_increment_counter (vm, ikev2_node.index,
					   IKEV2_ERROR_NOT_IKEV2, 1);
	      goto dispatch0;
	    }

	  if (ike0->exchange == IKEV2_EXCHANGE_SA_INIT)
	    {
	      sa0 = &sa;
	      memset (sa0, 0, sizeof (*sa0));

	      if (ike0->flags & IKEV2_HDR_FLAG_INITIATOR)
		{
		  if (ike0->rspi == 0)
		    {
		      sa0->raddr.as_u32 = ip40->dst_address.as_u32;
		      sa0->iaddr.as_u32 = ip40->src_address.as_u32;

		      r = ikev2_retransmit_sa_init (ike0, sa0->iaddr,
						    sa0->raddr);
		      if (r == 1)
			{
			  vlib_node_increment_counter (vm, ikev2_node.index,
						       IKEV2_ERROR_IKE_SA_INIT_RETRANSMIT,
						       1);
			  len = clib_net_to_host_u32 (ike0->length);
			  goto dispatch0;
			}
		      else if (r == -1)
			{
			  vlib_node_increment_counter (vm, ikev2_node.index,
						       IKEV2_ERROR_IKE_SA_INIT_IGNORE,
						       1);
			  goto dispatch0;
			}

		      ikev2_process_sa_init_req (vm, sa0, ike0);

		      if (sa0->state == IKEV2_STATE_SA_INIT)
			{
			  ikev2_sa_free_proposal_vector (&sa0->r_proposals);
			  sa0->r_proposals =
			    ikev2_select_proposal (sa0->i_proposals,
						   IKEV2_PROTOCOL_IKE);
			  ikev2_generate_sa_init_data (sa0);
			}

		      if (sa0->state == IKEV2_STATE_SA_INIT
			  || sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE)
			{
			  len = ikev2_generate_message (sa0, ike0, 0);
			}

		      if (sa0->state == IKEV2_STATE_SA_INIT)
			{
			  /* add SA to the pool */
			  pool_get (km->per_thread_data[thread_index].sas,
				    sa0);
			  clib_memcpy (sa0, &sa, sizeof (*sa0));
			  hash_set (km->
				    per_thread_data[thread_index].sa_by_rspi,
				    sa0->rspi,
				    sa0 -
				    km->per_thread_data[thread_index].sas);
			}
		      else
			{
			  ikev2_sa_free_all_vec (sa0);
			}
		    }
		}
	      else
		{
		  ikev2_process_sa_init_resp (vm, sa0, ike0);

		  if (sa0->state == IKEV2_STATE_SA_INIT)
		    {
		      ike0->exchange = IKEV2_EXCHANGE_IKE_AUTH;
		      uword *p = hash_get (km->sa_by_ispi, ike0->ispi);
		      if (p)
			{
			  ikev2_sa_t *sai =
			    pool_elt_at_index (km->sais, p[0]);

			  ikev2_complete_sa_data (sa0, sai);
			  ikev2_calc_keys (sa0);
			  ikev2_sa_auth_init (sa0);
			  len = ikev2_generate_message (sa0, ike0, 0);
			}
		    }

		  if (sa0->state == IKEV2_STATE_SA_INIT)
		    {
		      /* add SA to the pool */
		      pool_get (km->per_thread_data[thread_index].sas, sa0);
		      clib_memcpy (sa0, &sa, sizeof (*sa0));
		      hash_set (km->per_thread_data[thread_index].sa_by_rspi,
				sa0->rspi,
				sa0 - km->per_thread_data[thread_index].sas);
		    }
		  else
		    {
		      ikev2_sa_free_all_vec (sa0);
		    }
		}
	    }
	  else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH)
	    {
	      uword *p;
	      p = hash_get (km->per_thread_data[thread_index].sa_by_rspi,
			    clib_net_to_host_u64 (ike0->rspi));
	      if (p)
		{
		  sa0 =
		    pool_elt_at_index (km->per_thread_data[thread_index].sas,
				       p[0]);

		  r = ikev2_retransmit_resp (sa0, ike0);
		  if (r == 1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_RETRANSMIT,
						   1);
		      len = clib_net_to_host_u32 (ike0->length);
		      goto dispatch0;
		    }
		  else if (r == -1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_IGNORE,
						   1);
		      goto dispatch0;
		    }

		  ikev2_process_auth_req (vm, sa0, ike0);
		  ikev2_sa_auth (sa0);
		  if (sa0->state == IKEV2_STATE_AUTHENTICATED)
		    {
		      ikev2_initial_contact_cleanup (sa0);
		      ikev2_sa_match_ts (sa0);
		      if (sa0->state != IKEV2_STATE_TS_UNACCEPTABLE)
			ikev2_create_tunnel_interface (km->vnet_main, sa0,
						       &sa0->childs[0]);
		    }

		  if (sa0->is_initiator)
		    {
		      uword *p = hash_get (km->sa_by_ispi, ike0->ispi);
		      if (p)
			{
			  ikev2_sa_t *sai =
			    pool_elt_at_index (km->sais, p[0]);
			  hash_unset (km->sa_by_ispi, sai->ispi);
			  ikev2_sa_free_all_vec (sai);
			  pool_put (km->sais, sai);
			}
		    }
		  else
		    {
		      len = ikev2_generate_message (sa0, ike0, 0);
		    }
		}
	    }
	  else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL)
	    {
	      uword *p;
	      p = hash_get (km->per_thread_data[thread_index].sa_by_rspi,
			    clib_net_to_host_u64 (ike0->rspi));
	      if (p)
		{
		  sa0 =
		    pool_elt_at_index (km->per_thread_data[thread_index].sas,
				       p[0]);

		  r = ikev2_retransmit_resp (sa0, ike0);
		  if (r == 1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_RETRANSMIT,
						   1);
		      len = clib_net_to_host_u32 (ike0->length);
		      goto dispatch0;
		    }
		  else if (r == -1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_IGNORE,
						   1);
		      goto dispatch0;
		    }

		  ikev2_process_informational_req (vm, sa0, ike0);
		  if (sa0->del)
		    {
		      if (sa0->del[0].protocol_id != IKEV2_PROTOCOL_IKE)
			{
			  ikev2_delete_t *d, *tmp, *resp = 0;
			  vec_foreach (d, sa0->del)
			  {
			    ikev2_child_sa_t *ch_sa;
			    ch_sa = ikev2_sa_get_child (sa0, d->spi,
							d->protocol_id,
							!sa0->is_initiator);
			    if (ch_sa)
			      {
				ikev2_delete_tunnel_interface (km->vnet_main,
							       sa0, ch_sa);
				if (!sa0->is_initiator)
				  {
				    vec_add2 (resp, tmp, 1);
				    tmp->protocol_id = d->protocol_id;
				    tmp->spi = ch_sa->r_proposals[0].spi;
				  }
				ikev2_sa_del_child_sa (sa0, ch_sa);
			      }
			  }
			  if (!sa0->is_initiator)
			    {
			      vec_free (sa0->del);
			      sa0->del = resp;
			    }
			}
		    }
		  if (!sa0->is_initiator)
		    {
		      len = ikev2_generate_message (sa0, ike0, 0);
		    }
		}
	    }
	  else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA)
	    {
	      uword *p;
	      p = hash_get (km->per_thread_data[thread_index].sa_by_rspi,
			    clib_net_to_host_u64 (ike0->rspi));
	      if (p)
		{
		  sa0 =
		    pool_elt_at_index (km->per_thread_data[thread_index].sas,
				       p[0]);

		  r = ikev2_retransmit_resp (sa0, ike0);
		  if (r == 1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_RETRANSMIT,
						   1);
		      len = clib_net_to_host_u32 (ike0->length);
		      goto dispatch0;
		    }
		  else if (r == -1)
		    {
		      vlib_node_increment_counter (vm, ikev2_node.index,
						   IKEV2_ERROR_IKE_REQ_IGNORE,
						   1);
		      goto dispatch0;
		    }

		  ikev2_process_create_child_sa_req (vm, sa0, ike0);
		  if (sa0->rekey)
		    {
		      if (sa0->rekey[0].protocol_id != IKEV2_PROTOCOL_IKE)
			{
			  ikev2_child_sa_t *child;
			  vec_add2 (sa0->childs, child, 1);
			  child->r_proposals = sa0->rekey[0].r_proposal;
			  child->i_proposals = sa0->rekey[0].i_proposal;
			  child->tsi = sa0->rekey[0].tsi;
			  child->tsr = sa0->rekey[0].tsr;
			  ikev2_create_tunnel_interface (km->vnet_main, sa0,
							 child);
			}
		      if (sa0->is_initiator)
			{
			  vec_del1 (sa0->rekey, 0);
			}
		      else
			{
			  len = ikev2_generate_message (sa0, ike0, 0);
			}
		    }
		}
	    }
	  else
	    {
	      clib_warning ("IKEv2 exchange %u packet received from %U to %U",
			    ike0->exchange,
			    format_ip4_address, ip40->src_address.as_u8,
			    format_ip4_address, ip40->dst_address.as_u8);
	    }

	dispatch0:
	  /* if we are sending packet back, rewrite headers */
	  if (len)
	    {
	      next0 = IKEV2_NEXT_IP4_LOOKUP;
	      if (sa0->is_initiator)
		{
		  ip40->dst_address.as_u32 = sa0->raddr.as_u32;
		  ip40->src_address.as_u32 = sa0->iaddr.as_u32;
		}
	      else
		{
		  ip40->dst_address.as_u32 = sa0->iaddr.as_u32;
		  ip40->src_address.as_u32 = sa0->raddr.as_u32;
		}
	      udp0->length =
		clib_host_to_net_u16 (len + sizeof (udp_header_t));
	      udp0->checksum = 0;
	      b0->current_length =
		len + sizeof (ip4_header_t) + sizeof (udp_header_t);
	      ip40->length = clib_host_to_net_u16 (b0->current_length);
	      ip40->checksum = ip4_header_checksum (ip40);
	    }
	  /* delete sa */
	  if (sa0 && (sa0->state == IKEV2_STATE_DELETED ||
		      sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE))
	    {
	      ikev2_child_sa_t *c;

	      vec_foreach (c, sa0->childs)
		ikev2_delete_tunnel_interface (km->vnet_main, sa0, c);

	      ikev2_delete_sa (sa0);
	    }
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];

	  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
			     && (b0->flags & VLIB_BUFFER_IS_TRACED)))
	    {
	      ikev2_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
	      t->sw_if_index = sw_if_index0;
	      t->next_index = next0;
	    }

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
					   n_left_to_next, bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  vlib_node_increment_counter (vm, ikev2_node.index,
			       IKEV2_ERROR_PROCESSED, frame->n_vectors);
  return frame->n_vectors;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ikev2_node,static) = {
  .function = ikev2_node_fn,
  .name = "ikev2",
  .vector_size = sizeof (u32),
  .format_trace = format_ikev2_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(ikev2_error_strings),
  .error_strings = ikev2_error_strings,

  .n_next_nodes = IKEV2_N_NEXT,

  .next_nodes = {
    [IKEV2_NEXT_IP4_LOOKUP] = "ip4-lookup",
        [IKEV2_NEXT_ERROR_DROP] = "error-drop",
  },
};
/* *INDENT-ON* */


static clib_error_t *
ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa,
			       ikev2_transforms_set * ts,
			       ikev2_sa_proposal_t ** proposals, int is_ike)
{
  clib_error_t *r;
  ikev2_main_t *km = &ikev2_main;
  ikev2_sa_proposal_t *proposal;
  vec_add2 (*proposals, proposal, 1);
  ikev2_sa_transform_t *td;
  int error;

  /* Encryption */
  error = 1;
  vec_foreach (td, km->supported_transforms)
  {
    if (td->type == IKEV2_TRANSFORM_TYPE_ENCR
	&& td->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC
	&& td->key_len == ts->crypto_key_size / 8)
      {
	u16 attr[2];
	attr[0] = clib_host_to_net_u16 (14 | (1 << 15));
	attr[1] = clib_host_to_net_u16 (td->key_len << 3);
	vec_add (td->attrs, (u8 *) attr, 4);
	vec_add1 (proposal->transforms, *td);
	td->attrs = 0;

	error = 0;
	break;
      }
  }
  if (error)
    {
      r = clib_error_return (0, "Unsupported algorithm");
      return r;
    }

  /* Integrity */
  error = 1;
  vec_foreach (td, km->supported_transforms)
  {
    if (td->type == IKEV2_TRANSFORM_TYPE_INTEG
	&& td->integ_type == IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96)
      {
	vec_add1 (proposal->transforms, *td);
	error = 0;
	break;
      }
  }
  if (error)
    {
      r = clib_error_return (0, "Unsupported algorithm");
      return r;
    }

  /* PRF */
  if (is_ike)
    {
      error = 1;
      vec_foreach (td, km->supported_transforms)
      {
	if (td->type == IKEV2_TRANSFORM_TYPE_PRF
	    && td->prf_type == IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1)
	  {
	    vec_add1 (proposal->transforms, *td);
	    error = 0;
	    break;
	  }
      }
      if (error)
	{
	  r = clib_error_return (0, "Unsupported algorithm");
	  return r;
	}
    }

  /* DH */
  error = 1;
  vec_foreach (td, km->supported_transforms)
  {
    if (td->type == IKEV2_TRANSFORM_TYPE_DH && td->dh_type == ts->dh_type)
      {
	vec_add1 (proposal->transforms, *td);
	if (is_ike)
	  {
	    sa->dh_group = td->dh_type;
	  }
	error = 0;
	break;
      }
  }
  if (error)
    {
      r = clib_error_return (0, "Unsupported algorithm");
      return r;
    }

  if (!is_ike)
    {
      error = 1;
      vec_foreach (td, km->supported_transforms)
      {
	if (td->type == IKEV2_TRANSFORM_TYPE_ESN)
	  {
	    vec_add1 (proposal->transforms, *td);
	    error = 0;
	    break;
	  }
      }
      if (error)
	{
	  r = clib_error_return (0, "Unsupported algorithm");
	  return r;
	}
    }


  return 0;
}

static ikev2_profile_t *
ikev2_profile_index_by_name (u8 * name)
{
  ikev2_main_t *km = &ikev2_main;
  uword *p;

  p = mhash_get (&km->profile_index_by_name, name);
  if (!p)
    return 0;

  return pool_elt_at_index (km->profiles, p[0]);
}


static void
ikev2_send_ike (vlib_main_t * vm, ip4_address_t * src, ip4_address_t * dst,
		u32 bi0, u32 len)
{
  ip4_header_t *ip40;
  udp_header_t *udp0;
  vlib_buffer_t *b0;
  vlib_frame_t *f;
  u32 *to_next;

  b0 = vlib_get_buffer (vm, bi0);
  vlib_buffer_advance (b0, -sizeof (udp_header_t));
  udp0 = vlib_buffer_get_current (b0);
  vlib_buffer_advance (b0, -sizeof (ip4_header_t));
  ip40 = vlib_buffer_get_current (b0);


  ip40->ip_version_and_header_length = 0x45;
  ip40->tos = 0;
  ip40->fragment_id = 0;
  ip40->flags_and_fragment_offset = 0;
  ip40->ttl = 0xff;
  ip40->protocol = IP_PROTOCOL_UDP;
  ip40->dst_address.as_u32 = dst->as_u32;
  ip40->src_address.as_u32 = src->as_u32;
  udp0->dst_port = clib_host_to_net_u16 (500);
  udp0->src_port = clib_host_to_net_u16 (500);
  udp0->length = clib_host_to_net_u16 (len + sizeof (udp_header_t));
  udp0->checksum = 0;
  b0->current_length = len + sizeof (ip4_header_t) + sizeof (udp_header_t);
  ip40->length = clib_host_to_net_u16 (b0->current_length);
  ip40->checksum = ip4_header_checksum (ip40);


  /* send the request */
  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
  to_next = vlib_frame_vector_args (f);
  to_next[0] = bi0;
  f->n_vectors = 1;
  vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);

}

static u32
ikev2_get_new_ike_header_buff (vlib_main_t * vm, ike_header_t ** ike)
{
  u32 bi0;
  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
    {
      *ike = 0;
      return 0;
    }
  vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
  *ike = vlib_buffer_get_current (b0);
  return bi0;
}

clib_error_t *
ikev2_set_local_key (vlib_main_t * vm, u8 * file)
{
  ikev2_main_t *km = &ikev2_main;

  km->pkey = ikev2_load_key_file (file);
  if (km->pkey == NULL)
    return clib_error_return (0, "load key '%s' failed", file);

  return 0;
}

clib_error_t *
ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add)
{
  ikev2_main_t *km = &ikev2_main;
  ikev2_profile_t *p;

  if (is_add)
    {
      if (ikev2_profile_index_by_name (name))
	return clib_error_return (0, "policy %v already exists", name);

      pool_get (km->profiles, p);
      memset (p, 0, sizeof (*p));
      p->name = vec_dup (name);
      p->responder.sw_if_index = ~0;
      uword index = p - km->profiles;
      mhash_set_mem (&km->profile_index_by_name, name, &index, 0);
    }
  else
    {
      p = ikev2_profile_index_by_name (name);
      if (!p)
	return clib_error_return (0, "policy %v does not exists", name);

      vec_free (p->name);
      pool_put (km->profiles, p);
      mhash_unset (&km->profile_index_by_name, name, 0);
    }
  return 0;
}

clib_error_t *
ikev2_set_profile_auth (vlib_main_t * vm, u8 * name, u8 auth_method,
			u8 * auth_data, u8 data_hex_format)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }
  vec_free (p->auth.data);
  p->auth.method = auth_method;
  p->auth.data = vec_dup (auth_data);
  p->auth.hex = data_hex_format;

  if (auth_method == IKEV2_AUTH_METHOD_RSA_SIG)
    {
      vec_add1 (p->auth.data, 0);
      if (p->auth.key)
	EVP_PKEY_free (p->auth.key);
      p->auth.key = ikev2_load_cert_file (auth_data);
      if (p->auth.key == NULL)
	return clib_error_return (0, "load cert '%s' failed", auth_data);
    }

  return 0;
}

clib_error_t *
ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data,
		      int is_local)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  if (id_type > IKEV2_ID_TYPE_ID_RFC822_ADDR
      && id_type < IKEV2_ID_TYPE_ID_KEY_ID)
    {
      r = clib_error_return (0, "unsupported identity type %U",
			     format_ikev2_id_type, id_type);
      return r;
    }

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  if (is_local)
    {
      vec_free (p->loc_id.data);
      p->loc_id.type = id_type;
      p->loc_id.data = vec_dup (data);
    }
  else
    {
      vec_free (p->rem_id.data);
      p->rem_id.type = id_type;
      p->rem_id.data = vec_dup (data);
    }

  return 0;
}

clib_error_t *
ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id,
		      u16 start_port, u16 end_port, ip4_address_t start_addr,
		      ip4_address_t end_addr, int is_local)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  if (is_local)
    {
      p->loc_ts.start_addr.as_u32 = start_addr.as_u32;
      p->loc_ts.end_addr.as_u32 = end_addr.as_u32;
      p->loc_ts.start_port = start_port;
      p->loc_ts.end_port = end_port;
      p->loc_ts.protocol_id = protocol_id;
      p->loc_ts.ts_type = 7;
    }
  else
    {
      p->rem_ts.start_addr.as_u32 = start_addr.as_u32;
      p->rem_ts.end_addr.as_u32 = end_addr.as_u32;
      p->rem_ts.start_port = start_port;
      p->rem_ts.end_port = end_port;
      p->rem_ts.protocol_id = protocol_id;
      p->rem_ts.ts_type = 7;
    }

  return 0;
}


clib_error_t *
ikev2_set_profile_responder (vlib_main_t * vm, u8 * name,
			     u32 sw_if_index, ip4_address_t ip4)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  p->responder.sw_if_index = sw_if_index;
  p->responder.ip4 = ip4;

  return 0;
}

clib_error_t *
ikev2_set_profile_ike_transforms (vlib_main_t * vm, u8 * name,
				  ikev2_transform_encr_type_t crypto_alg,
				  ikev2_transform_integ_type_t integ_alg,
				  ikev2_transform_dh_type_t dh_type,
				  u32 crypto_key_size)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  p->ike_ts.crypto_alg = crypto_alg;
  p->ike_ts.integ_alg = integ_alg;
  p->ike_ts.dh_type = dh_type;
  p->ike_ts.crypto_key_size = crypto_key_size;
  return 0;
}

clib_error_t *
ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name,
				  ikev2_transform_encr_type_t crypto_alg,
				  ikev2_transform_integ_type_t integ_alg,
				  ikev2_transform_dh_type_t dh_type,
				  u32 crypto_key_size)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  p->esp_ts.crypto_alg = crypto_alg;
  p->esp_ts.integ_alg = integ_alg;
  p->esp_ts.dh_type = dh_type;
  p->esp_ts.crypto_key_size = crypto_key_size;
  return 0;
}

clib_error_t *
ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
			       u64 lifetime, u32 jitter, u32 handover,
			       u64 maxdata)
{
  ikev2_profile_t *p;
  clib_error_t *r;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  p->lifetime = lifetime;
  p->lifetime_jitter = jitter;
  p->handover = handover;
  p->lifetime_maxdata = maxdata;
  return 0;
}

clib_error_t *
ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
{
  ikev2_profile_t *p;
  clib_error_t *r;
  ip4_main_t *im = &ip4_main;
  ikev2_main_t *km = &ikev2_main;

  p = ikev2_profile_index_by_name (name);

  if (!p)
    {
      r = clib_error_return (0, "unknown profile %v", name);
      return r;
    }

  if (p->responder.sw_if_index == ~0 || p->responder.ip4.data_u32 == 0)
    {
      r = clib_error_return (0, "responder not set for profile %v", name);
      return r;
    }


  /* Create the Initiator Request */
  {
    ike_header_t *ike0;
    u32 bi0 = 0;
    ip_lookup_main_t *lm = &im->lookup_main;
    u32 if_add_index0;
    int len = sizeof (ike_header_t);

    /* Get own iface IP */
    if_add_index0 =
      lm->if_address_pool_index_by_sw_if_index[p->responder.sw_if_index];
    ip_interface_address_t *if_add =
      pool_elt_at_index (lm->if_address_pool, if_add_index0);
    ip4_address_t *if_ip = ip_interface_address_get_address (lm, if_add);

    bi0 = ikev2_get_new_ike_header_buff (vm, &ike0);

    /* Prepare the SA and the IKE payload */
    ikev2_sa_t sa;
    memset (&sa, 0, sizeof (ikev2_sa_t));
    ikev2_payload_chain_t *chain = 0;
    ikev2_payload_new_chain (chain);

    /* Build the IKE proposal payload */
    ikev2_sa_proposal_t *proposals = 0;
    ikev2_set_initiator_proposals (vm, &sa, &p->ike_ts, &proposals, 1);
    proposals[0].proposal_num = 1;
    proposals[0].protocol_id = IKEV2_PROTOCOL_IKE;

    /* Add and then cleanup proposal data */
    ikev2_payload_add_sa (chain, proposals);
    ikev2_sa_free_proposal_vector (&proposals);

    sa.is_initiator = 1;
    sa.profile = p;
    sa.state = IKEV2_STATE_SA_INIT;
    ikev2_generate_sa_init_data (&sa);
    ikev2_payload_add_ke (chain, sa.dh_group, sa.i_dh_data);
    ikev2_payload_add_nonce (chain, sa.i_nonce);

    /* Build the child SA proposal */
    vec_resize (sa.childs, 1);
    ikev2_set_initiator_proposals (vm, &sa, &p->esp_ts,
				   &sa.childs[0].i_proposals, 0);
    sa.childs[0].i_proposals[0].proposal_num = 1;
    sa.childs[0].i_proposals[0].protocol_id = IKEV2_PROTOCOL_ESP;
    RAND_bytes ((u8 *) & sa.childs[0].i_proposals[0].spi,
		sizeof (sa.childs[0].i_proposals[0].spi));



    /* Add NAT detection notification messages (mandatory) */
    u8 nat_detection_source[8 + 8 + 4 + 2];
    u8 *nat_detection_sha1 = vec_new (u8, 20);

    u64 tmpspi = clib_host_to_net_u64 (sa.ispi);
    clib_memcpy (&nat_detection_source[0], &tmpspi, sizeof (tmpspi));
    tmpspi = clib_host_to_net_u64 (sa.rspi);
    clib_memcpy (&nat_detection_source[8], &tmpspi, sizeof (tmpspi));
    u16 tmpport = clib_host_to_net_u16 (500);
    clib_memcpy (&nat_detection_source[8 + 8 + 4], &tmpport,
		 sizeof (tmpport));
    u32 tmpip = clib_host_to_net_u32 (if_ip->as_u32);
    clib_memcpy (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip));
    SHA1 (nat_detection_source, sizeof (nat_detection_source),
	  nat_detection_sha1);
    ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
			      nat_detection_sha1);
    tmpip = clib_host_to_net_u32 (p->responder.ip4.as_u32);
    clib_memcpy (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip));
    SHA1 (nat_detection_source, sizeof (nat_detection_source),
	  nat_detection_sha1);
    ikev2_payload_add_notify (chain,
			      IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
			      nat_detection_sha1);
    vec_free (nat_detection_sha1);

    u8 *sig_hash_algo = vec_new (u8, 8);
    u64 tmpsig = clib_host_to_net_u64 (0x0001000200030004);
    clib_memcpy (sig_hash_algo, &tmpsig, sizeof (tmpsig));
    ikev2_payload_add_notify (chain,
			      IKEV2_NOTIFY_MSG_SIGNATURE_HASH_ALGORITHMS,
			      sig_hash_algo);
    vec_free (sig_hash_algo);


    /* Buffer update and bolierplate */
    len += vec_len (chain->data);
    ike0->nextpayload = chain->first_payload_type;
    ike0->length = clib_host_to_net_u32 (len);
    clib_memcpy (ike0->payload, chain->data, vec_len (chain->data));
    ikev2_payload_destroy_chain (chain);

    ike0->version = IKE_VERSION_2;
    ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
    ike0->exchange = IKEV2_EXCHANGE_SA_INIT;
    ike0->ispi = sa.ispi;

    /* store whole IKE payload - needed for PSK auth */
    vec_free (sa.last_sa_init_req_packet_data);
    vec_add (sa.last_sa_init_req_packet_data, ike0, len);

    /* add data to the SA then add it to the pool */
    sa.iaddr.as_u32 = if_ip->as_u32;
    sa.raddr.as_u32 = p->responder.ip4.as_u32;
    sa.i_id.type = p->loc_id.type;
    sa.i_id.data = vec_dup (p->loc_id.data);
    sa.i_auth.method = p->auth.method;
    sa.i_auth.hex = p->auth.hex;
    sa.i_auth.data = vec_dup (p->auth.data);
    sa.i_auth.key = vec_dup (p->auth.key);
    vec_add (sa.childs[0].tsi, &p->loc_ts, 1);
    vec_add (sa.childs[0].tsr, &p->rem_ts, 1);

    /* add SA to the pool */
    ikev2_sa_t *sa0 = 0;
    pool_get (km->sais, sa0);
    clib_memcpy (sa0, &sa, sizeof (*sa0));
    hash_set (km->sa_by_ispi, sa0->ispi, sa0 - km->sais);

    ikev2_send_ike (vm, if_ip, &p->responder.ip4, bi0, len);

  }

  return 0;
}

static void
ikev2_delete_child_sa_internal (vlib_main_t * vm, ikev2_sa_t * sa,
				ikev2_child_sa_t * csa)
{
  /* Create the Initiator notification for child SA removal */
  ikev2_main_t *km = &ikev2_main;
  ike_header_t *ike0;
  u32 bi0 = 0;
  int len;

  bi0 = ikev2_get_new_ike_header_buff (vm, &ike0);


  ike0->exchange = IKEV2_EXCHANGE_INFORMATIONAL;
  ike0->ispi = clib_host_to_net_u64 (sa->ispi);
  ike0->rspi = clib_host_to_net_u64 (sa->rspi);
  vec_resize (sa->del, 1);
  sa->del->protocol_id = IKEV2_PROTOCOL_ESP;
  sa->del->spi = csa->i_proposals->spi;
  ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id + 1);
  sa->last_init_msg_id = clib_net_to_host_u32 (ike0->msgid);
  len = ikev2_generate_message (sa, ike0, 0);

  ikev2_send_ike (vm, &sa->iaddr, &sa->raddr, bi0, len);

  /* delete local child SA */
  ikev2_delete_tunnel_interface (km->vnet_main, sa, csa);
  ikev2_sa_del_child_sa (sa, csa);
}

clib_error_t *
ikev2_initiate_delete_child_sa (vlib_main_t * vm, u32 ispi)
{
  clib_error_t *r;
  ikev2_main_t *km = &ikev2_main;
  ikev2_main_per_thread_data_t *tkm;
  ikev2_sa_t *fsa = 0;
  ikev2_child_sa_t *fchild = 0;

  /* Search for the child SA */
  vec_foreach (tkm, km->per_thread_data)
  {
    ikev2_sa_t *sa;
    if (fchild)
      break;
    /* *INDENT-OFF* */
    pool_foreach (sa, tkm->sas, ({
      fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
      if (fchild)
        {
          fsa = sa;
          break;
        }
    }));
    /* *INDENT-ON* */
  }

  if (!fchild || !fsa)
    {
      r = clib_error_return (0, "Child SA not found");
      return r;
    }
  else
    {
      ikev2_delete_child_sa_internal (vm, fsa, fchild);
    }

  return 0;
}

clib_error_t *
ikev2_initiate_delete_ike_sa (vlib_main_t * vm, u64 ispi)
{
  clib_error_t *r;
  ikev2_main_t *km = &ikev2_main;
  ikev2_main_per_thread_data_t *tkm;
  ikev2_sa_t *fsa = 0;
  ikev2_main_per_thread_data_t *ftkm = 0;

  /* Search for the IKE SA */
  vec_foreach (tkm, km->per_thread_data)
  {
    ikev2_sa_t *sa;
    if (fsa)
      break;
    /* *INDENT-OFF* */
    pool_foreach (sa, tkm->sas, ({
      if (sa->ispi == ispi)
        {
          fsa = sa;
          ftkm = tkm;
          break;
        }
    }));
    /* *INDENT-ON* */
  }

  if (!fsa)
    {
      r = clib_error_return (0, "IKE SA not found");
      return r;
    }


  /* Create the Initiator notification for IKE SA removal */
  {
    ike_header_t *ike0;
    u32 bi0 = 0;
    int len;

    bi0 = ikev2_get_new_ike_header_buff (vm, &ike0);


    ike0->exchange = IKEV2_EXCHANGE_INFORMATIONAL;
    ike0->ispi = clib_host_to_net_u64 (fsa->ispi);
    ike0->rspi = clib_host_to_net_u64 (fsa->rspi);
    vec_resize (fsa->del, 1);
    fsa->del->protocol_id = IKEV2_PROTOCOL_IKE;
    fsa->del->spi = ispi;
    ike0->msgid = clib_host_to_net_u32 (fsa->last_init_msg_id + 1);
    fsa->last_init_msg_id = clib_net_to_host_u32 (ike0->msgid);
    len = ikev2_generate_message (fsa, ike0, 0);

    ikev2_send_ike (vm, &fsa->iaddr, &fsa->raddr, bi0, len);
  }


  /* delete local SA */
  ikev2_child_sa_t *c;
  vec_foreach (c, fsa->childs)
  {
    ikev2_delete_tunnel_interface (km->vnet_main, fsa, c);
    ikev2_sa_del_child_sa (fsa, c);
  }
  ikev2_sa_free_all_vec (fsa);
  uword *p = hash_get (ftkm->sa_by_rspi, fsa->rspi);
  if (p)
    {
      hash_unset (ftkm->sa_by_rspi, fsa->rspi);
      pool_put (ftkm->sas, fsa);
    }


  return 0;
}

static void
ikev2_rekey_child_sa_internal (vlib_main_t * vm, ikev2_sa_t * sa,
			       ikev2_child_sa_t * csa)
{
  /* Create the Initiator request for create child SA */
  ike_header_t *ike0;
  u32 bi0 = 0;
  int len;


  bi0 = ikev2_get_new_ike_header_buff (vm, &ike0);


  ike0->version = IKE_VERSION_2;
  ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
  ike0->exchange = IKEV2_EXCHANGE_CREATE_CHILD_SA;
  ike0->ispi = clib_host_to_net_u64 (sa->ispi);
  ike0->rspi = clib_host_to_net_u64 (sa->rspi);
  ike0->msgid = clib_host_to_net_u32 (sa->last_init_msg_id + 1);
  sa->last_init_msg_id = clib_net_to_host_u32 (ike0->msgid);

  ikev2_rekey_t *rekey;
  vec_add2 (sa->rekey, rekey, 1);
  ikev2_sa_proposal_t *proposals = vec_dup (csa->i_proposals);

  /*need new ispi */
  RAND_bytes ((u8 *) & proposals[0].spi, sizeof (proposals[0].spi));
  rekey->spi = proposals[0].spi;
  rekey->ispi = csa->i_proposals->spi;
  len = ikev2_generate_message (sa, ike0, proposals);
  ikev2_send_ike (vm, &sa->iaddr, &sa->raddr, bi0, len);
  vec_free (proposals);
}

clib_error_t *
ikev2_initiate_rekey_child_sa (vlib_main_t * vm, u32 ispi)
{
  clib_error_t *r;
  ikev2_main_t *km = &ikev2_main;
  ikev2_main_per_thread_data_t *tkm;
  ikev2_sa_t *fsa = 0;
  ikev2_child_sa_t *fchild = 0;

  /* Search for the child SA */
  vec_foreach (tkm, km->per_thread_data)
  {
    ikev2_sa_t *sa;
    if (fchild)
      break;
    /* *INDENT-OFF* */
    pool_foreach (sa, tkm->sas, ({
      fchild = ikev2_sa_get_child(sa, ispi, IKEV2_PROTOCOL_ESP, 1);
      if (fchild)
        {
          fsa = sa;
          break;
        }
    }));
    /* *INDENT-ON* */
  }

  if (!fchild || !fsa)
    {
      r = clib_error_return (0, "Child SA not found");
      return r;
    }
  else
    {
      ikev2_rekey_child_sa_internal (vm, fsa, fchild);
    }

  return 0;
}

clib_error_t *
ikev2_init (vlib_main_t * vm)
{
  ikev2_main_t *km = &ikev2_main;
  clib_error_t *error;
  vlib_thread_main_t *tm = vlib_get_thread_main ();
  int thread_id;

  memset (km, 0, sizeof (ikev2_main_t));
  km->vnet_main = vnet_get_main ();
  km->vlib_main = vm;

  ikev2_crypto_init (km);

  mhash_init_vec_string (&km->profile_index_by_name, sizeof (uword));

  vec_validate (km->per_thread_data, tm->n_vlib_mains - 1);
  for (thread_id = 0; thread_id < tm->n_vlib_mains - 1; thread_id++)
    {
      km->per_thread_data[thread_id].sa_by_rspi =
	hash_create (0, sizeof (uword));
    }

  km->sa_by_ispi = hash_create (0, sizeof (uword));


  if ((error = vlib_call_init_function (vm, ikev2_cli_init)))
    return error;

  udp_register_dst_port (vm, 500, ikev2_node.index, 1);

  return 0;
}


static u8
ikev2_mngr_process_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * csa)
{
  ikev2_main_t *km = &ikev2_main;
  vlib_main_t *vm = km->vlib_main;
  f64 now = vlib_time_now (vm);
  u8 res = 0;

  if (sa->is_initiator && sa->profile && csa->time_to_expiration
      && now > csa->time_to_expiration)
    {
      if (!csa->is_expired || csa->rekey_retries > 0)
	{
	  ikev2_rekey_child_sa_internal (vm, sa, csa);
	  csa->time_to_expiration = now + sa->profile->handover;
	  csa->is_expired = 1;
	  if (csa->rekey_retries == 0)
	    {
	      csa->rekey_retries = 5;
	    }
	  else if (csa->rekey_retries > 0)
	    {
	      csa->rekey_retries--;
	      clib_warning ("Rekeing Child SA 0x%x, retries left %d",
			    csa->i_proposals->spi, csa->rekey_retries);
	      if (csa->rekey_retries == 0)
		{
		  csa->rekey_retries = -1;
		}
	    }
	  res |= 1;
	}
      else
	{
	  csa->time_to_expiration = 0;
	  ikev2_delete_child_sa_internal (vm, sa, csa);
	  res |= 1;
	}
    }

  return res;
}

static void
ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa)
{
  ikev2_main_t *km = &ikev2_main;
  vlib_main_t *vm = km->vlib_main;
  ikev2_main_per_thread_data_t *tkm;
  ikev2_sa_t *fsa = 0;
  ikev2_child_sa_t *fchild = 0;
  f64 now = vlib_time_now (vm);

  /* Search for the SA and child SA */
  vec_foreach (tkm, km->per_thread_data)
  {
    ikev2_sa_t *sa;
    if (fchild)
      break;
    /* *INDENT-OFF* */
    pool_foreach (sa, tkm->sas, ({
      fchild = ikev2_sa_get_child(sa, ipsec_sa->spi, IKEV2_PROTOCOL_ESP, 1);
      if (fchild)
        {
          fsa = sa;
          break;
        }
    }));
    /* *INDENT-ON* */
  }

  if (fchild && fsa && fsa->profile && fsa->profile->lifetime_maxdata)
    {
      if (!fchild->is_expired
	  && ipsec_sa->total_data_size > fsa->profile->lifetime_maxdata)
	{
	  fchild->time_to_expiration = now;
	}
    }
}

static vlib_node_registration_t ikev2_mngr_process_node;

static uword
ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
		       vlib_frame_t * f)
{
  ikev2_main_t *km = &ikev2_main;
  ipsec_main_t *im = &ipsec_main;

  while (1)
    {
      u8 req_sent = 0;
      vlib_process_wait_for_event_or_clock (vm, 1);
      vlib_process_get_events (vm, NULL);

      /* process ike child sas */
      ikev2_main_per_thread_data_t *tkm;
      vec_foreach (tkm, km->per_thread_data)
      {
	ikev2_sa_t *sa;
        /* *INDENT-OFF* */
        pool_foreach (sa, tkm->sas, ({
          ikev2_child_sa_t *c;
          vec_foreach (c, sa->childs)
            {
            req_sent |= ikev2_mngr_process_child_sa(sa, c);
            }
        }));
        /* *INDENT-ON* */
      }

      /* process ipsec sas */
      ipsec_sa_t *sa;
      /* *INDENT-OFF* */
      pool_foreach (sa, im->sad, ({
        ikev2_mngr_process_ipsec_sa(sa);
      }));
      /* *INDENT-ON* */

      if (req_sent)
	{
	  vlib_process_wait_for_event_or_clock (vm, 5);
	  vlib_process_get_events (vm, NULL);
	  req_sent = 0;
	}

    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ikev2_mngr_process_node, static) = {
    .function = ikev2_mngr_process_fn,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name =
    "ikev2-manager-process",
};

/* *INDENT-ON* */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
