/*
 * sr.c: ipv6 segment routing
 *
 * Copyright (c) 2013 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.
 */

/**
 * @file
 * @brief Segment Routing main functions
 *
 */
#include <vnet/vnet.h>
#include <vnet/sr/sr.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/dpo/dpo.h>

#include <openssl/hmac.h>

ip6_sr_main_t sr_main;
static vlib_node_registration_t sr_local_node;

/**
 * @brief Dynamically added SR DPO type
 */
static dpo_type_t sr_dpo_type;

/**
 * @brief Use passed HMAC key in ip6_sr_header_t in OpenSSL HMAC routines
 *
 * @param sm ip6_sr_main_t *
 * @param ip ip6_header_t *
 * @param sr ip6_sr_header_t *
 */
void
sr_fix_hmac (ip6_sr_main_t * sm, ip6_header_t * ip, ip6_sr_header_t * sr)
{
  u32 key_index;
  static u8 *keybuf;
  u8 *copy_target;
  int first_segment;
  ip6_address_t *addrp;
  int i;
  ip6_sr_hmac_key_t *hmac_key;
  u32 sig_len;

  key_index = sr->hmac_key;

  /* No signature? Pass... */
  if (key_index == 0)
    return;

  /* We don't know about this key? Fail... */
  if (key_index >= vec_len (sm->hmac_keys))
    return;

  hmac_key = sm->hmac_keys + key_index;

  vec_reset_length (keybuf);

  /* pkt ip6 src address */
  vec_add2 (keybuf, copy_target, sizeof (ip6_address_t));
  clib_memcpy (copy_target, ip->src_address.as_u8, sizeof (ip6_address_t));

  /* first segment */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0] = sr->first_segment;

  /* octet w/ bit 0 = "clean" flag */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0]
    = (sr->flags & clib_host_to_net_u16 (IP6_SR_HEADER_FLAG_CLEANUP))
    ? 0x80 : 0;

  /* hmac key id */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0] = sr->hmac_key;

  first_segment = sr->first_segment;

  addrp = sr->segments;

  /* segments */
  for (i = 0; i <= first_segment; i++)
    {
      vec_add2 (keybuf, copy_target, sizeof (ip6_address_t));
      clib_memcpy (copy_target, addrp->as_u8, sizeof (ip6_address_t));
      addrp++;
    }

  addrp++;

  HMAC_CTX_init (sm->hmac_ctx);
  if (!HMAC_Init (sm->hmac_ctx, hmac_key->shared_secret,
		  vec_len (hmac_key->shared_secret), sm->md))
    clib_warning ("barf1");
  if (!HMAC_Update (sm->hmac_ctx, keybuf, vec_len (keybuf)))
    clib_warning ("barf2");
  if (!HMAC_Final (sm->hmac_ctx, (unsigned char *) addrp, &sig_len))
    clib_warning ("barf3");
  HMAC_CTX_cleanup (sm->hmac_ctx);
}

/**
 * @brief Format function for decoding various SR flags
 *
 * @param s u8 * - formatted string
 * @param args va_list * - u16 flags
 *
 * @return formatted output string u8 *
 */
u8 *
format_ip6_sr_header_flags (u8 * s, va_list * args)
{
  u16 flags = (u16) va_arg (*args, int);
  u8 pl_flag;
  int bswap_needed = va_arg (*args, int);
  int i;

  if (bswap_needed)
    flags = clib_host_to_net_u16 (flags);

  if (flags & IP6_SR_HEADER_FLAG_CLEANUP)
    s = format (s, "cleanup ");

  if (flags & IP6_SR_HEADER_FLAG_PROTECTED)
    s = format (s, "reroute ");

  s = format (s, "pl: ");
  for (i = 1; i <= 4; i++)
    {
      pl_flag = ip6_sr_policy_list_flags (flags, i);
      s = format (s, "[%d] ", i);

      switch (pl_flag)
	{
	case IP6_SR_HEADER_FLAG_PL_ELT_NOT_PRESENT:
	  s = format (s, "NotPr ");
	  break;
	case IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE:
	  s = format (s, "InPE ");
	  break;
	case IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE:
	  s = format (s, "EgPE ");
	  break;

	case IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR:
	  s = format (s, "OrgSrc ");
	  break;
	}
    }
  return s;
}

/**
 * @brief Format function for decoding ip6_sr_header_t
 *
 * @param s u8 * - formatted string
 * @param args va_list * - ip6_sr_header_t
 *
 * @return formatted output string u8 *
 */
u8 *
format_ip6_sr_header (u8 * s, va_list * args)
{
  ip6_sr_header_t *h = va_arg (*args, ip6_sr_header_t *);
  ip6_address_t placeholder_addr =
    { {254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
       254, 254}
  };
  int print_hmac = va_arg (*args, int);
  int i, pl_index, max_segs;
  int flags_host_byte_order = clib_net_to_host_u16 (h->flags);

  s = format (s, "next proto %d, len %d, type %d",
	      h->protocol, (h->length << 3) + 8, h->type);
  s = format (s, "\n      segs left %d, first_segment %d, hmac key %d",
	      h->segments_left, h->first_segment, h->hmac_key);
  s = format (s, "\n      flags %U", format_ip6_sr_header_flags,
	      flags_host_byte_order, 0 /* bswap needed */ );

  /*
   * Header length is in 8-byte units (minus one), so
   * divide by 2 to ascertain the number of ip6 addresses in the
   * segment list
   */
  max_segs = (h->length >> 1);

  if (!print_hmac && h->hmac_key)
    max_segs -= 2;

  s = format (s, "\n  Segments (in processing order):");

  for (i = h->first_segment; i >= 1; i--)
    s = format (s, "\n  %U", format_ip6_address, h->segments + i);
  if (ip6_address_is_equal (&placeholder_addr, h->segments))
    s = format (s, "\n  (empty placeholder)");
  else
    s = format (s, "\n  %U", format_ip6_address, h->segments);

  s = format (s, "\n  Policy List:");

  pl_index = 1;			/* to match the RFC text */
  for (i = (h->first_segment + 1); i < max_segs; i++, pl_index++)
    {
      char *tag;
      char *tags[] = { " ", "InPE: ", "EgPE: ", "OrgSrc: " };

      tag = tags[0];
      if (pl_index >= 1 && pl_index <= 4)
	{
	  int this_pl_flag = ip6_sr_policy_list_flags
	    (flags_host_byte_order, pl_index);
	  tag = tags[this_pl_flag];
	}

      s = format (s, "\n  %s%U", tag, format_ip6_address, h->segments + i);
    }

  return s;
}

/**
 * @brief Format function for decoding ip6_sr_header_t with length
 *
 * @param s u8 * - formatted string
 * @param args va_list * - ip6_header_t + ip6_sr_header_t
 *
 * @return formatted output string u8 *
 */
u8 *
format_ip6_sr_header_with_length (u8 * s, va_list * args)
{
  ip6_header_t *h = va_arg (*args, ip6_header_t *);
  u32 max_header_bytes = va_arg (*args, u32);
  uword header_bytes;

  header_bytes = sizeof (h[0]) + sizeof (ip6_sr_header_t);
  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
    return format (s, "ip6_sr header truncated");

  s = format (s, "IP6: %U\n", format_ip6_header, h, max_header_bytes);
  s =
    format (s, "SR: %U\n", format_ip6_sr_header, (ip6_sr_header_t *) (h + 1),
	    0 /* print_hmac */ , max_header_bytes);
  return s;
}

/**
 * @brief Defined valid next nodes
 * @note Cannot call replicate yet without DPDK
*/
#if DPDK > 0
#define foreach_sr_rewrite_next                 \
_(ERROR, "error-drop")                          \
_(IP6_LOOKUP, "ip6-lookup")                     \
_(SR_LOCAL, "sr-local")                         \
_(SR_REPLICATE,"sr-replicate")
#else
#define foreach_sr_rewrite_next                 \
_(ERROR, "error-drop")                          \
_(IP6_LOOKUP, "ip6-lookup")                     \
_(SR_LOCAL, "sr-local")
#endif /* DPDK */

/**
 * @brief Struct for defined valid next nodes
*/
typedef enum
{
#define _(s,n) SR_REWRITE_NEXT_##s,
  foreach_sr_rewrite_next
#undef _
    SR_REWRITE_N_NEXT,
} sr_rewrite_next_t;

/**
 * @brief Struct for data for SR rewrite packet trace
 */
typedef struct
{
  ip6_address_t src, dst;
  u16 length;
  u32 next_index;
  u32 tunnel_index;
  u8 sr[256];
} sr_rewrite_trace_t;

/**
 * @brief Error strings for SR rewrite
 */
static char *sr_rewrite_error_strings[] = {
#define sr_error(n,s) s,
#include "sr_error.def"
#undef sr_error
};

/**
 * @brief Struct for SR rewrite error strings
 */
typedef enum
{
#define sr_error(n,s) SR_REWRITE_ERROR_##n,
#include "sr_error.def"
#undef sr_error
  SR_REWRITE_N_ERROR,
} sr_rewrite_error_t;


/**
 * @brief Format function for SR rewrite trace.
 */
u8 *
format_sr_rewrite_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 *);
  sr_rewrite_trace_t *t = va_arg (*args, sr_rewrite_trace_t *);
  ip6_sr_main_t *sm = &sr_main;
  ip6_sr_tunnel_t *tun = pool_elt_at_index (sm->tunnels, t->tunnel_index);
  ip6_fib_t *rx_fib, *tx_fib;

  rx_fib = ip6_fib_get (tun->rx_fib_index);
  tx_fib = ip6_fib_get (tun->tx_fib_index);

  s = format
    (s, "SR-REWRITE: next %s ip6 src %U dst %U len %u\n"
     "           rx-fib-id %d tx-fib-id %d\n%U",
     (t->next_index == SR_REWRITE_NEXT_SR_LOCAL)
     ? "sr-local" : "ip6-lookup",
     format_ip6_address, &t->src,
     format_ip6_address, &t->dst, t->length,
     rx_fib->table_id, tx_fib->table_id,
     format_ip6_sr_header, t->sr, 0 /* print_hmac */ );
  return s;
}

/**
 * @brief Main processing dual-loop for Segment Routing Rewrite
 * @node sr-rewrite
 *
 * @param vm vlib_main_t *
 * @param node vlib_node_runtime_t *
 * @param from_frame vlib_frame_t *
 *
 * @return from_frame->n_vectors uword
 */
static uword
sr_rewrite (vlib_main_t * vm,
	    vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  ip6_sr_main_t *sm = &sr_main;
  u32 (*sr_local_cb) (vlib_main_t *, vlib_node_runtime_t *,
		      vlib_buffer_t *, ip6_header_t *, ip6_sr_header_t *);
  sr_local_cb = sm->sr_local_cb;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = 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);

      /* Note 2x loop disabled */
      while (0 && n_left_from >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  vlib_buffer_t *b0, *b1;
	  ip6_header_t *ip0, *ip1;
	  ip6_sr_header_t *sr0, *sr1;
	  ip6_sr_tunnel_t *t0, *t1;
	  u32 next0 = SR_REWRITE_NEXT_IP6_LOOKUP;
	  u32 next1 = SR_REWRITE_NEXT_IP6_LOOKUP;
	  u16 new_l0 = 0;
	  u16 new_l1 = 0;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *p2, *p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);
	  }

	  bi0 = from[0];
	  bi1 = from[1];
	  to_next[0] = bi0;
	  to_next[1] = bi1;
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);

	  /*
	   * $$$ parse through header(s) to pick the point
	   * where we punch in the SR extention header
	   */
	  t0 =
	    pool_elt_at_index (sm->tunnels,
			       vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
	  t1 =
	    pool_elt_at_index (sm->tunnels,
			       vnet_buffer (b1)->ip.adj_index[VLIB_TX]);

	  ASSERT (VLIB_BUFFER_PRE_DATA_SIZE
		  >= ((word) vec_len (t0->rewrite)) + b0->current_data);
	  ASSERT (VLIB_BUFFER_PRE_DATA_SIZE
		  >= ((word) vec_len (t1->rewrite)) + b1->current_data);

	  vnet_buffer (b0)->sw_if_index[VLIB_TX] = t0->tx_fib_index;
	  vnet_buffer (b1)->sw_if_index[VLIB_TX] = t1->tx_fib_index;

	  ip0 = vlib_buffer_get_current (b0);
	  ip1 = vlib_buffer_get_current (b1);
#if DPDK > 0			/* Cannot call replication node yet without DPDK */
	  /* add a replication node */
	  if (PREDICT_FALSE (t0->policy_index != ~0))
	    {
	      vnet_buffer (b0)->ip.save_protocol = t0->policy_index;
	      next0 = SR_REWRITE_NEXT_SR_REPLICATE;
	      sr0 = (ip6_sr_header_t *) (t0->rewrite);
	      goto processnext;
	    }
#endif /* DPDK */

	  /*
	   * SR-unaware service chaining case: pkt coming back from
	   * service has the original dst address, and will already
	   * have an SR header. If so, send it to sr-local
	   */
	  if (PREDICT_FALSE (ip0->protocol == IPPROTO_IPV6_ROUTE))
	    {
	      vlib_buffer_advance (b0, sizeof (ip0));
	      sr0 = (ip6_sr_header_t *) (ip0 + 1);
	      new_l0 = clib_net_to_host_u16 (ip0->payload_length);
	      next0 = SR_REWRITE_NEXT_SR_LOCAL;
	    }
	  else
	    {
	      u32 len_bytes = sizeof (ip6_header_t);
	      u8 next_hdr = ip0->protocol;

	      /* HBH must immediately follow ipv6 header */
	      if (PREDICT_FALSE
		  (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
		  len_bytes +=
		    ip6_ext_header_len ((ip6_ext_header_t *) ext_hdr);
		  /* Ignoring the sr_local for now, if RH follows HBH here */
		  next_hdr = ext_hdr->next_hdr;
		  ext_hdr->next_hdr = IPPROTO_IPV6_ROUTE;
		}
	      else
		{
		  ip0->protocol = IPPROTO_IPV6_ROUTE;	/* routing extension header */
		}
	      /*
	       * Copy data before the punch-in point left by the
	       * required amount. Assume (for the moment) that only
	       * the main packet header needs to be copied.
	       */
	      clib_memcpy (((u8 *) ip0) - vec_len (t0->rewrite),
			   ip0, len_bytes);
	      vlib_buffer_advance (b0, -(word) vec_len (t0->rewrite));
	      ip0 = vlib_buffer_get_current (b0);
	      sr0 = (ip6_sr_header_t *) ((u8 *) ip0 + len_bytes);
	      /* $$$ tune */
	      clib_memcpy (sr0, t0->rewrite, vec_len (t0->rewrite));

	      /* Fix the next header chain */
	      sr0->protocol = next_hdr;

	      new_l0 = clib_net_to_host_u16 (ip0->payload_length) +
		vec_len (t0->rewrite);
	      ip0->payload_length = clib_host_to_net_u16 (new_l0);

	      /* Copy dst address into the DA slot in the segment list */
	      clib_memcpy (sr0->segments, ip0->dst_address.as_u64,
			   sizeof (ip6_address_t));
	      /* Rewrite the ip6 dst address with the first hop */
	      clib_memcpy (ip0->dst_address.as_u64, t0->first_hop.as_u64,
			   sizeof (ip6_address_t));

	      sr_fix_hmac (sm, ip0, sr0);

	      next0 = sr_local_cb ? sr_local_cb (vm, node, b0, ip0, sr0) :
		next0;

	      /*
	       * Ignore "do not rewrite" shtik in this path
	       */
	      if (PREDICT_FALSE (next0 & 0x80000000))
		{
		  next0 ^= 0xFFFFFFFF;
		  if (PREDICT_FALSE (next0 == SR_REWRITE_NEXT_ERROR))
		    b0->error = node->errors[SR_REWRITE_ERROR_APP_CALLBACK];
		}
	    }
#if DPDK > 0			/* Cannot call replication node yet without DPDK */
	processnext:
	  /* add a replication node */
	  if (PREDICT_FALSE (t1->policy_index != ~0))
	    {
	      vnet_buffer (b1)->ip.save_protocol = t1->policy_index;
	      next1 = SR_REWRITE_NEXT_SR_REPLICATE;
	      sr1 = (ip6_sr_header_t *) (t1->rewrite);
	      goto trace00;
	    }
#endif /* DPDK */
	  if (PREDICT_FALSE (ip1->protocol == IPPROTO_IPV6_ROUTE))
	    {
	      vlib_buffer_advance (b1, sizeof (ip1));
	      sr1 = (ip6_sr_header_t *) (ip1 + 1);
	      new_l1 = clib_net_to_host_u16 (ip1->payload_length);
	      next1 = SR_REWRITE_NEXT_SR_LOCAL;
	    }
	  else
	    {
	      u32 len_bytes = sizeof (ip6_header_t);
	      u8 next_hdr = ip1->protocol;

	      /* HBH must immediately follow ipv6 header */
	      if (PREDICT_FALSE
		  (ip1->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip1);
		  len_bytes +=
		    ip6_ext_header_len ((ip6_ext_header_t *) ext_hdr);
		  /* Ignoring the sr_local for now, if RH follows HBH here */
		  next_hdr = ext_hdr->next_hdr;
		  ext_hdr->next_hdr = IPPROTO_IPV6_ROUTE;
		}
	      else
		{
		  ip1->protocol = IPPROTO_IPV6_ROUTE;
		}
	      /*
	       * Copy data before the punch-in point left by the
	       * required amount. Assume (for the moment) that only
	       * the main packet header needs to be copied.
	       */
	      clib_memcpy (((u8 *) ip1) - vec_len (t1->rewrite),
			   ip1, len_bytes);
	      vlib_buffer_advance (b1, -(word) vec_len (t1->rewrite));
	      ip1 = vlib_buffer_get_current (b1);
	      sr1 = (ip6_sr_header_t *) ((u8 *) ip1 + len_bytes);
	      clib_memcpy (sr1, t1->rewrite, vec_len (t1->rewrite));

	      sr1->protocol = next_hdr;
	      new_l1 = clib_net_to_host_u16 (ip1->payload_length) +
		vec_len (t1->rewrite);
	      ip1->payload_length = clib_host_to_net_u16 (new_l1);

	      /* Copy dst address into the DA slot in the segment list */
	      clib_memcpy (sr1->segments, ip1->dst_address.as_u64,
			   sizeof (ip6_address_t));
	      /* Rewrite the ip6 dst address with the first hop */
	      clib_memcpy (ip1->dst_address.as_u64, t1->first_hop.as_u64,
			   sizeof (ip6_address_t));

	      sr_fix_hmac (sm, ip1, sr1);

	      next1 = sr_local_cb ? sr_local_cb (vm, node, b1, ip1, sr1) :
		next1;

	      /*
	       * Ignore "do not rewrite" shtik in this path
	       */
	      if (PREDICT_FALSE (next1 & 0x80000000))
		{
		  next1 ^= 0xFFFFFFFF;
		  if (PREDICT_FALSE (next1 == SR_REWRITE_NEXT_ERROR))
		    b1->error = node->errors[SR_REWRITE_ERROR_APP_CALLBACK];
		}
	    }
#if DPDK > 0			/* Cannot run replicate without DPDK and only replicate uses this label */
	trace00:
#endif /* DPDK */

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_rewrite_trace_t *tr = vlib_add_trace (vm, node,
						       b0, sizeof (*tr));
	      tr->tunnel_index = t0 - sm->tunnels;
	      clib_memcpy (tr->src.as_u8, ip0->src_address.as_u8,
			   sizeof (tr->src.as_u8));
	      clib_memcpy (tr->dst.as_u8, ip0->dst_address.as_u8,
			   sizeof (tr->dst.as_u8));
	      tr->length = new_l0;
	      tr->next_index = next0;
	      if (sr0)
		clib_memcpy (tr->sr, sr0, sizeof (tr->sr));
	    }
	  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_rewrite_trace_t *tr = vlib_add_trace (vm, node,
						       b1, sizeof (*tr));
	      tr->tunnel_index = t1 - sm->tunnels;
	      clib_memcpy (tr->src.as_u8, ip1->src_address.as_u8,
			   sizeof (tr->src.as_u8));
	      clib_memcpy (tr->dst.as_u8, ip1->dst_address.as_u8,
			   sizeof (tr->dst.as_u8));
	      tr->length = new_l1;
	      tr->next_index = next1;
	      if (sr1)
		clib_memcpy (tr->sr, sr1, sizeof (tr->sr));
	    }
	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  ip6_header_t *ip0 = 0;
	  ip6_sr_header_t *sr0 = 0;
	  ip6_sr_tunnel_t *t0;
	  u32 next0 = SR_REWRITE_NEXT_IP6_LOOKUP;
	  u16 new_l0 = 0;

	  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);


	  /*
	   * $$$ parse through header(s) to pick the point
	   * where we punch in the SR extention header
	   */
	  t0 =
	    pool_elt_at_index (sm->tunnels,
			       vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
#if DPDK > 0			/* Cannot call replication node yet without DPDK */
	  /* add a replication node */
	  if (PREDICT_FALSE (t0->policy_index != ~0))
	    {
	      vnet_buffer (b0)->ip.save_protocol = t0->policy_index;
	      next0 = SR_REWRITE_NEXT_SR_REPLICATE;
	      sr0 = (ip6_sr_header_t *) (t0->rewrite);
	      goto trace0;
	    }
#endif /* DPDK */

	  ASSERT (VLIB_BUFFER_PRE_DATA_SIZE
		  >= ((word) vec_len (t0->rewrite)) + b0->current_data);

	  vnet_buffer (b0)->sw_if_index[VLIB_TX] = t0->tx_fib_index;

	  ip0 = vlib_buffer_get_current (b0);

	  /*
	   * SR-unaware service chaining case: pkt coming back from
	   * service has the original dst address, and will already
	   * have an SR header. If so, send it to sr-local
	   */
	  if (PREDICT_FALSE (ip0->protocol == IPPROTO_IPV6_ROUTE))
	    {
	      vlib_buffer_advance (b0, sizeof (ip0));
	      sr0 = (ip6_sr_header_t *) (ip0 + 1);
	      new_l0 = clib_net_to_host_u16 (ip0->payload_length);
	      next0 = SR_REWRITE_NEXT_SR_LOCAL;
	    }
	  else
	    {
	      u32 len_bytes = sizeof (ip6_header_t);
	      u8 next_hdr = ip0->protocol;

	      /* HBH must immediately follow ipv6 header */
	      if (PREDICT_FALSE
		  (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
		  len_bytes +=
		    ip6_ext_header_len ((ip6_ext_header_t *) ext_hdr);
		  next_hdr = ext_hdr->next_hdr;
		  ext_hdr->next_hdr = IPPROTO_IPV6_ROUTE;
		  /* Ignoring the sr_local for now, if RH follows HBH here */
		}
	      else
		{
		  ip0->protocol = IPPROTO_IPV6_ROUTE;	/* routing extension header */
		}
	      /*
	       * Copy data before the punch-in point left by the
	       * required amount. Assume (for the moment) that only
	       * the main packet header needs to be copied.
	       */
	      clib_memcpy (((u8 *) ip0) - vec_len (t0->rewrite),
			   ip0, len_bytes);
	      vlib_buffer_advance (b0, -(word) vec_len (t0->rewrite));
	      ip0 = vlib_buffer_get_current (b0);
	      sr0 = (ip6_sr_header_t *) ((u8 *) ip0 + len_bytes);
	      /* $$$ tune */
	      clib_memcpy (sr0, t0->rewrite, vec_len (t0->rewrite));

	      /* Fix the next header chain */
	      sr0->protocol = next_hdr;
	      new_l0 = clib_net_to_host_u16 (ip0->payload_length) +
		vec_len (t0->rewrite);
	      ip0->payload_length = clib_host_to_net_u16 (new_l0);

	      /* Copy dst address into the DA slot in the segment list */
	      clib_memcpy (sr0->segments, ip0->dst_address.as_u64,
			   sizeof (ip6_address_t));
	      /* Rewrite the ip6 dst address with the first hop */
	      clib_memcpy (ip0->dst_address.as_u64, t0->first_hop.as_u64,
			   sizeof (ip6_address_t));

	      sr_fix_hmac (sm, ip0, sr0);

	      next0 = sr_local_cb ? sr_local_cb (vm, node, b0, ip0, sr0) :
		next0;

	      /*
	       * Ignore "do not rewrite" shtik in this path
	       */
	      if (PREDICT_FALSE (next0 & 0x80000000))
		{
		  next0 ^= 0xFFFFFFFF;
		  if (PREDICT_FALSE (next0 == SR_REWRITE_NEXT_ERROR))
		    b0->error = node->errors[SR_REWRITE_ERROR_APP_CALLBACK];
		}
	    }
#if DPDK > 0			/* Cannot run replicate without DPDK and only replicate uses this label */
	trace0:
#endif /* DPDK */

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_rewrite_trace_t *tr = vlib_add_trace (vm, node,
						       b0, sizeof (*tr));
	      tr->tunnel_index = t0 - sm->tunnels;
	      if (ip0)
		{
		  memcpy (tr->src.as_u8, ip0->src_address.as_u8,
			  sizeof (tr->src.as_u8));
		  memcpy (tr->dst.as_u8, ip0->dst_address.as_u8,
			  sizeof (tr->dst.as_u8));
		}
	      tr->length = new_l0;
	      tr->next_index = next0;
	      if (sr0)
		clib_memcpy (tr->sr, sr0, sizeof (tr->sr));
	    }
	  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);
    }
  return from_frame->n_vectors;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (sr_rewrite_node) = {
  .function = sr_rewrite,
  .name = "sr-rewrite",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .format_trace = format_sr_rewrite_trace,
  .format_buffer = format_ip6_sr_header_with_length,

  .n_errors = SR_REWRITE_N_ERROR,
  .error_strings = sr_rewrite_error_strings,

  .runtime_data_bytes = 0,

  .n_next_nodes = SR_REWRITE_N_NEXT,
  .next_nodes = {
#define _(s,n) [SR_REWRITE_NEXT_##s] = n,
    foreach_sr_rewrite_next
#undef _
  },
};

VLIB_NODE_FUNCTION_MULTIARCH (sr_rewrite_node, sr_rewrite)
/* *INDENT-ON* */

static int
ip6_delete_route_no_next_hop (ip6_address_t * dst_address_arg,
			      u32 dst_address_length, u32 rx_table_id)
{
  fib_prefix_t pfx = {
    .fp_len = dst_address_length,
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_addr = {
		.ip6 = *dst_address_arg,
		}
  };

  fib_table_entry_delete (fib_table_id_find_fib_index (FIB_PROTOCOL_IP6,
						       rx_table_id),
			  &pfx, FIB_SOURCE_SR);

  return 0;
}

/**
 * @brief Find or add if not found - HMAC shared secret
 *
 * @param sm ip6_sr_main_t *
 * @param secret u8 *
 * @param indexp u32 *
 *
 * @return ip6_sr_hmac_key_t *
 */
static ip6_sr_hmac_key_t *
find_or_add_shared_secret (ip6_sr_main_t * sm, u8 * secret, u32 * indexp)
{
  uword *p;
  ip6_sr_hmac_key_t *key = 0;
  int i;

  p = hash_get_mem (sm->hmac_key_by_shared_secret, secret);

  if (p)
    {
      key = vec_elt_at_index (sm->hmac_keys, p[0]);
      if (indexp)
	*indexp = p[0];
      return (key);
    }

  /* Specific key ID? */
  if (indexp && *indexp)
    {
      vec_validate (sm->hmac_keys, *indexp);
      key = sm->hmac_keys + *indexp;
    }
  else
    {
      for (i = 0; i < vec_len (sm->hmac_keys); i++)
	{
	  if (sm->hmac_keys[i].shared_secret == 0)
	    {
	      key = sm->hmac_keys + i;
	      goto found;
	    }
	}
      vec_validate (sm->hmac_keys, i);
      key = sm->hmac_keys + i;
    found:
      ;
    }

  key->shared_secret = vec_dup (secret);

  hash_set_mem (sm->hmac_key_by_shared_secret, key->shared_secret,
		key - sm->hmac_keys);

  if (indexp)
    *indexp = key - sm->hmac_keys;
  return (key);
}

/**
 * @brief Add or Delete a Segment Routing tunnel.
 *
 * @param a ip6_sr_add_del_tunnel_args_t *
 *
 * @return retval int
 */
int
ip6_sr_add_del_tunnel (ip6_sr_add_del_tunnel_args_t * a)
{
  ip6_main_t *im = &ip6_main;
  ip6_sr_tunnel_key_t key;
  ip6_sr_tunnel_t *t;
  uword *p, *n;
  ip6_sr_header_t *h = 0;
  u32 header_length;
  ip6_address_t *addrp, *this_address;
  ip6_sr_main_t *sm = &sr_main;
  u8 *key_copy;
  u32 rx_fib_index, tx_fib_index;
  u32 hmac_key_index_u32;
  u8 hmac_key_index = 0;
  ip6_sr_policy_t *pt;
  int i;
  dpo_id_t dpo = DPO_INVALID;

  /* Make sure that the rx FIB exists */
  p = hash_get (im->fib_index_by_table_id, a->rx_table_id);

  if (p == 0)
    return -3;

  /* remember the FIB index */
  rx_fib_index = p[0];

  /* Make sure that the supplied FIB exists */
  p = hash_get (im->fib_index_by_table_id, a->tx_table_id);

  if (p == 0)
    return -4;

  /* remember the FIB index */
  tx_fib_index = p[0];

  clib_memcpy (key.src.as_u8, a->src_address->as_u8, sizeof (key.src));
  clib_memcpy (key.dst.as_u8, a->dst_address->as_u8, sizeof (key.dst));

  /* When adding a tunnel:
   * - If a "name" is given, it must not exist.
   * - The "key" is always checked, and must not exist.
   * When deleting a tunnel:
   * - If the "name" is given, and it exists, then use it.
   * - If the "name" is not given, use the "key".
   * - If the "name" and the "key" are given, then both must point to the same
   *   thing.
   */

  /* Lookup the key */
  p = hash_get_mem (sm->tunnel_index_by_key, &key);

  /* If the name is given, look it up */
  if (a->name)
    n = hash_get_mem (sm->tunnel_index_by_name, a->name);
  else
    n = 0;

  /* validate key/name parameters */
  if (!a->is_del)		/* adding a tunnel */
    {
      if (a->name && n)		/* name given & exists already */
	return -1;
      if (p)			/* key exists already */
	return -1;
    }
  else				/* deleting a tunnel */
    {
      if (!p)			/* key doesn't exist */
	return -2;
      if (a->name && !n)	/* name given & it doesn't exist */
	return -2;

      if (n)			/* name given & found */
	{
	  if (n[0] != p[0])	/* name and key do not point to the same thing */
	    return -2;
	}
    }


  if (a->is_del)		/* delete the tunnel */
    {
      hash_pair_t *hp;

      /* Delete existing tunnel */
      t = pool_elt_at_index (sm->tunnels, p[0]);

      ip6_delete_route_no_next_hop (&t->key.dst, t->dst_mask_width,
				    a->rx_table_id);
      vec_free (t->rewrite);
      /* Remove tunnel from any policy if associated */
      if (t->policy_index != ~0)
	{
	  pt = pool_elt_at_index (sm->policies, t->policy_index);
	  for (i = 0; i < vec_len (pt->tunnel_indices); i++)
	    {
	      if (pt->tunnel_indices[i] == t - sm->tunnels)
		{
		  vec_delete (pt->tunnel_indices, 1, i);
		  goto found;
		}
	    }
	  clib_warning ("Tunnel index %d not found in policy_index %d",
			t - sm->tunnels, pt - sm->policies);
	found:
	  /* If this is last tunnel in the  policy, clean up the policy too */
	  if (vec_len (pt->tunnel_indices) == 0)
	    {
	      hash_unset_mem (sm->policy_index_by_policy_name, pt->name);
	      vec_free (pt->name);
	      pool_put (sm->policies, pt);
	    }
	}

      /* Clean up the tunnel by name */
      if (t->name)
	{
	  hash_unset_mem (sm->tunnel_index_by_name, t->name);
	  vec_free (t->name);
	}
      pool_put (sm->tunnels, t);
      hp = hash_get_pair (sm->tunnel_index_by_key, &key);
      key_copy = (void *) (hp->key);
      hash_unset_mem (sm->tunnel_index_by_key, &key);
      vec_free (key_copy);
      return 0;
    }

  /* create a new tunnel */
  pool_get (sm->tunnels, t);
  memset (t, 0, sizeof (*t));
  t->policy_index = ~0;

  clib_memcpy (&t->key, &key, sizeof (t->key));
  t->dst_mask_width = a->dst_mask_width;
  t->rx_fib_index = rx_fib_index;
  t->tx_fib_index = tx_fib_index;

  if (!vec_len (a->segments))
    /* there must be at least one segment... */
    return -4;

  /* The first specified hop goes right into the dst address */
  clib_memcpy (&t->first_hop, &a->segments[0], sizeof (ip6_address_t));

  /*
   * Create the sr header rewrite string
   * The list of segments needs an extra slot for the ultimate destination
   * which is taken from the packet we add the SRH to.
   */
  header_length = sizeof (*h) +
    sizeof (ip6_address_t) * (vec_len (a->segments) + 1 + vec_len (a->tags));

  if (a->shared_secret)
    {
      /* Allocate a new key slot if we don't find the secret key */
      hmac_key_index_u32 = 0;
      (void) find_or_add_shared_secret (sm, a->shared_secret,
					&hmac_key_index_u32);

      /* Hey Vinz Clortho: Gozzer is pissed.. you're out of keys! */
      if (hmac_key_index_u32 >= 256)
	return -5;
      hmac_key_index = hmac_key_index_u32;
      header_length += SHA256_DIGEST_LENGTH;
    }

  vec_validate (t->rewrite, header_length - 1);

  h = (ip6_sr_header_t *) t->rewrite;

  h->protocol = 0xFF;		/* we don't know yet */

  h->length = (header_length / 8) - 1;
  h->type = ROUTING_HEADER_TYPE_SR;

  /* first_segment and segments_left need to have the index of the last
   * element in the list; a->segments has one element less than ends up
   * in the header (it does not have the DA in it), so vec_len(a->segments)
   * is the value we want.
   */
  h->first_segment = h->segments_left = vec_len (a->segments);

  if (a->shared_secret)
    h->hmac_key = hmac_key_index & 0xFF;

  h->flags = a->flags_net_byte_order;

  /* Paint on the segment list, in reverse.
   * This is offset by one to leave room at the start for the ultimate
   * destination.
   */
  addrp = h->segments + vec_len (a->segments);

  vec_foreach (this_address, a->segments)
  {
    clib_memcpy (addrp->as_u8, this_address->as_u8, sizeof (ip6_address_t));
    addrp--;
  }

  /*
   * Since the ultimate destination address is not yet known, set that slot
   * to a value we will instantly recognize as bogus.
   */
  memset (h->segments, 0xfe, sizeof (ip6_address_t));

  /* Paint on the tag list, not reversed */
  addrp = h->segments + vec_len (a->segments);

  vec_foreach (this_address, a->tags)
  {
    clib_memcpy (addrp->as_u8, this_address->as_u8, sizeof (ip6_address_t));
    addrp++;
  }

  key_copy = vec_new (ip6_sr_tunnel_key_t, 1);
  clib_memcpy (key_copy, &key, sizeof (ip6_sr_tunnel_key_t));
  hash_set_mem (sm->tunnel_index_by_key, key_copy, t - sm->tunnels);

  /*
   * Stick the tunnel index into the rewrite header.
   *
   * Unfortunately, inserting an SR header according to the various
   * RFC's requires parsing through the ip6 header, perhaps consing a
   * buffer onto the head of the vlib_buffer_t, etc. We don't use the
   * normal reverse bcopy rewrite code.
   *
   * We don't handle ugly RFC-related cases yet, but I'm sure PL will complain
   * at some point...
   */
  dpo_set (&dpo, sr_dpo_type, DPO_PROTO_IP6, t - sm->tunnels);

  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = a->dst_mask_width,
    .fp_addr = {
		.ip6 = *a->dst_address,
		}
  };
  fib_table_entry_special_dpo_add (rx_fib_index,
				   &pfx,
				   FIB_SOURCE_SR,
				   FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
  dpo_reset (&dpo);

  if (a->policy_name)
    {
      p = hash_get_mem (sm->policy_index_by_policy_name, a->policy_name);
      if (p)
	{
	  pt = pool_elt_at_index (sm->policies, p[0]);
	}
      else			/* no policy, lets create one */
	{
	  pool_get (sm->policies, pt);
	  memset (pt, 0, sizeof (*pt));
	  pt->name = format (0, "%s%c", a->policy_name, 0);
	  hash_set_mem (sm->policy_index_by_policy_name, pt->name,
			pt - sm->policies);
	  p = hash_get_mem (sm->policy_index_by_policy_name, a->policy_name);
	}
      vec_add1 (pt->tunnel_indices, t - sm->tunnels);
      if (p == 0)
	clib_warning ("p is NULL!");
      t->policy_index = p ? p[0] : ~0;	/* equiv. to (pt - sm->policies) */
    }

  if (a->name)
    {
      t->name = format (0, "%s%c", a->name, 0);
      hash_set_mem (sm->tunnel_index_by_name, t->name, t - sm->tunnels);
    }

  return 0;
}

/**
 * @brief no-op lock function.
 * The lifetime of the SR entry is managed by the control plane
 */
static void
sr_dpo_lock (dpo_id_t * dpo)
{
}

/**
 * @brief no-op unlock function.
 * The lifetime of the SR entry is managed by the control plane
 */
static void
sr_dpo_unlock (dpo_id_t * dpo)
{
}

u8 *
format_sr_dpo (u8 * s, va_list * args)
{
  index_t index = va_arg (*args, index_t);
  CLIB_UNUSED (u32 indent) = va_arg (*args, u32);

  return (format (s, "SR: tunnel:[%d]", index));
}

const static dpo_vft_t sr_vft = {
  .dv_lock = sr_dpo_lock,
  .dv_unlock = sr_dpo_unlock,
  .dv_format = format_sr_dpo,
};

const static char *const sr_ip6_nodes[] = {
  "sr-rewrite",
  NULL,
};

const static char *const *const sr_nodes[DPO_PROTO_NUM] = {
  [DPO_PROTO_IP6] = sr_ip6_nodes,
};

/**
 * @brief CLI parser for Add or Delete a Segment Routing tunnel.
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
sr_add_del_tunnel_command_fn (vlib_main_t * vm,
			      unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  int is_del = 0;
  ip6_address_t src_address;
  int src_address_set = 0;
  ip6_address_t dst_address;
  u32 dst_mask_width;
  int dst_address_set = 0;
  u16 flags = 0;
  u8 *shared_secret = 0;
  u8 *name = 0;
  u8 *policy_name = 0;
  u32 rx_table_id = 0;
  u32 tx_table_id = 0;
  ip6_address_t *segments = 0;
  ip6_address_t *this_seg;
  ip6_address_t *tags = 0;
  ip6_address_t *this_tag;
  ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
  ip6_address_t next_address, tag;
  int pl_index;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_del = 1;
      else if (unformat (input, "rx-fib-id %d", &rx_table_id))
	;
      else if (unformat (input, "tx-fib-id %d", &tx_table_id))
	;
      else if (unformat (input, "src %U", unformat_ip6_address, &src_address))
	src_address_set = 1;
      else if (unformat (input, "name %s", &name))
	;
      else if (unformat (input, "policy %s", &policy_name))
	;
      else if (unformat (input, "dst %U/%d",
			 unformat_ip6_address, &dst_address, &dst_mask_width))
	dst_address_set = 1;
      else if (unformat (input, "next %U", unformat_ip6_address,
			 &next_address))
	{
	  vec_add2 (segments, this_seg, 1);
	  clib_memcpy (this_seg->as_u8, next_address.as_u8,
		       sizeof (*this_seg));
	}
      else if (unformat (input, "tag %U", unformat_ip6_address, &tag))
	{
	  vec_add2 (tags, this_tag, 1);
	  clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
	}
      else if (unformat (input, "clean"))
	flags |= IP6_SR_HEADER_FLAG_CLEANUP;
      else if (unformat (input, "protected"))
	flags |= IP6_SR_HEADER_FLAG_PROTECTED;
      else if (unformat (input, "key %s", &shared_secret))
	/* Do not include the trailing NULL byte. Guaranteed interop issue */
	_vec_len (shared_secret) -= 1;
      else if (unformat (input, "InPE %d", &pl_index))
	{
	  if (pl_index <= 0 || pl_index > 4)
	    {
	    pl_index_range_error:
	      return clib_error_return
		(0, "Policy List Element Index %d out of range (1-4)",
		 pl_index);

	    }
	  flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE
	    << ip6_sr_policy_list_shift_from_index (pl_index);
	}
      else if (unformat (input, "EgPE %d", &pl_index))
	{
	  if (pl_index <= 0 || pl_index > 4)
	    goto pl_index_range_error;
	  flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE
	    << ip6_sr_policy_list_shift_from_index (pl_index);
	}
      else if (unformat (input, "OrgSrc %d", &pl_index))
	{
	  if (pl_index <= 0 || pl_index > 4)
	    goto pl_index_range_error;
	  flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR
	    << ip6_sr_policy_list_shift_from_index (pl_index);
	}
      else
	break;
    }

  if (!src_address_set)
    return clib_error_return (0, "src address required");

  if (!dst_address_set)
    return clib_error_return (0, "dst address required");

  if (!segments)
    return clib_error_return (0, "at least one sr segment required");

  memset (a, 0, sizeof (*a));
  a->src_address = &src_address;
  a->dst_address = &dst_address;
  a->dst_mask_width = dst_mask_width;
  a->segments = segments;
  a->tags = tags;
  a->flags_net_byte_order = clib_host_to_net_u16 (flags);
  a->is_del = is_del;
  a->rx_table_id = rx_table_id;
  a->tx_table_id = tx_table_id;
  a->shared_secret = shared_secret;

  if (vec_len (name))
    a->name = name;
  else
    a->name = 0;

  if (vec_len (policy_name))
    a->policy_name = policy_name;
  else
    a->policy_name = 0;

  rv = ip6_sr_add_del_tunnel (a);

  vec_free (segments);
  vec_free (tags);
  vec_free (shared_secret);

  switch (rv)
    {
    case 0:
      break;

    case -1:
      return clib_error_return (0, "SR tunnel src %U dst %U already exists",
				format_ip6_address, &src_address,
				format_ip6_address, &dst_address);

    case -2:
      return clib_error_return (0, "SR tunnel src %U dst %U does not exist",
				format_ip6_address, &src_address,
				format_ip6_address, &dst_address);

    case -3:
      return clib_error_return (0, "FIB table %d does not exist",
				rx_table_id);

    case -4:
      return clib_error_return (0, "At least one segment is required");

    default:
      return clib_error_return (0, "BUG: ip6_sr_add_del_tunnel returns %d",
				rv);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (sr_tunnel_command, static) = {
    .path = "sr tunnel",
    .short_help =
      "sr tunnel [del] [name <name>] src <addr> dst <addr> [next <addr>] "
      "[clean] [reroute] [key <secret>] [policy <policy_name>]"
      "[rx-fib-id <fib_id>] [tx-fib-id <fib_id>]",
    .function = sr_add_del_tunnel_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief Display Segment Routing tunnel
 *
 * @param vm vlib_main_t *
 * @param t ip6_sr_tunnel_t *
 *
 */
void
ip6_sr_tunnel_display (vlib_main_t * vm, ip6_sr_tunnel_t * t)
{
  ip6_sr_main_t *sm = &sr_main;
  ip6_fib_t *rx_fib, *tx_fib;
  ip6_sr_policy_t *pt;

  rx_fib = ip6_fib_get (t->rx_fib_index);
  tx_fib = ip6_fib_get (t->tx_fib_index);

  if (t->name)
    vlib_cli_output (vm, "sr tunnel name: %s", (char *) t->name);

  vlib_cli_output (vm, "src %U dst %U first hop %U",
		   format_ip6_address, &t->key.src,
		   format_ip6_address, &t->key.dst,
		   format_ip6_address, &t->first_hop);
  vlib_cli_output (vm, "    rx-fib-id %d tx-fib-id %d",
		   rx_fib->table_id, tx_fib->table_id);
  vlib_cli_output (vm, "  sr: %U", format_ip6_sr_header, t->rewrite,
		   0 /* print_hmac */ );

  if (t->policy_index != ~0)
    {
      pt = pool_elt_at_index (sm->policies, t->policy_index);
      vlib_cli_output (vm, "sr policy: %s", (char *) pt->name);
    }
  vlib_cli_output (vm, "-------");

  return;
}

/**
 * @brief CLI Parser for Display Segment Routing tunnel
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
show_sr_tunnel_fn (vlib_main_t * vm,
		   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  static ip6_sr_tunnel_t **tunnels;
  ip6_sr_tunnel_t *t;
  ip6_sr_main_t *sm = &sr_main;
  int i;
  uword *p = 0;
  u8 *name = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "name %s", &name))
	{
	  p = hash_get_mem (sm->tunnel_index_by_name, name);
	  if (!p)
	    vlib_cli_output (vm, "No SR tunnel with name: %s. Showing all.",
			     name);
	}
      else
	break;
    }

  vec_reset_length (tunnels);

  if (!p)			/* Either name parm not passed or no tunnel with that name found, show all */
    {
      /* *INDENT-OFF* */
  pool_foreach (t, sm->tunnels,
  ({
    vec_add1 (tunnels, t);
  }));
  /* *INDENT-ON* */
    }
  else				/* Just show the one tunnel by name */
    vec_add1 (tunnels, &sm->tunnels[p[0]]);

  if (vec_len (tunnels) == 0)
    vlib_cli_output (vm, "No SR tunnels configured");

  for (i = 0; i < vec_len (tunnels); i++)
    {
      t = tunnels[i];
      ip6_sr_tunnel_display (vm, t);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_sr_tunnel_command, static) = {
    .path = "show sr tunnel",
    .short_help = "show sr tunnel [name <sr-tunnel-name>]",
    .function = show_sr_tunnel_fn,
};
/* *INDENT-ON* */

/**
 * @brief Add or Delete a Segment Routing policy
 *
 * @param a ip6_sr_add_del_policy_args_t *
 *
 * @return retval int
 */
int
ip6_sr_add_del_policy (ip6_sr_add_del_policy_args_t * a)
{
  ip6_sr_main_t *sm = &sr_main;
  uword *p;
  ip6_sr_tunnel_t *t = 0;
  ip6_sr_policy_t *policy;
  u32 *tunnel_indices = 0;
  int i;



  if (a->is_del)
    {
      p = hash_get_mem (sm->policy_index_by_policy_name, a->name);
      if (!p)
	return -6;		/* policy name not found */

      policy = pool_elt_at_index (sm->policies, p[0]);

      vec_foreach_index (i, policy->tunnel_indices)
      {
	t = pool_elt_at_index (sm->tunnels, policy->tunnel_indices[i]);
	t->policy_index = ~0;
      }
      hash_unset_mem (sm->policy_index_by_policy_name, a->name);
      pool_put (sm->policies, policy);
      return 0;
    }


  if (!vec_len (a->tunnel_names))
    return -3;			/*tunnel name is required case */

  vec_reset_length (tunnel_indices);
  /* Check tunnel names, add tunnel_index to policy */
  for (i = 0; i < vec_len (a->tunnel_names); i++)
    {
      p = hash_get_mem (sm->tunnel_index_by_name, a->tunnel_names[i]);
      if (!p)
	return -4;		/* tunnel name not found case */

      t = pool_elt_at_index (sm->tunnels, p[0]);
      /*
         No need to check t==0. -3 condition above ensures name
       */
      if (t->policy_index != ~0)
	return -5;		/* tunnel name already associated with a policy */

      /* Add to tunnel indicies */
      vec_add1 (tunnel_indices, p[0]);
    }

  /* Add policy to ip6_sr_main_t */
  pool_get (sm->policies, policy);
  policy->name = a->name;
  policy->tunnel_indices = tunnel_indices;
  hash_set_mem (sm->policy_index_by_policy_name, policy->name,
		policy - sm->policies);

  /* Yes, this could be construed as overkill but the last thing you should do is set
     the policy_index on the tunnel after everything is set in ip6_sr_main_t.
     If this is deemed overly cautious, could set this in the vec_len(tunnel_names) loop.
   */
  for (i = 0; i < vec_len (policy->tunnel_indices); i++)
    {
      t = pool_elt_at_index (sm->tunnels, policy->tunnel_indices[i]);
      t->policy_index = policy - sm->policies;
    }

  return 0;
}

/**
 * @brief CLI Parser for Add or Delete a Segment Routing policy
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
sr_add_del_policy_command_fn (vlib_main_t * vm,
			      unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  int is_del = 0;
  u8 **tunnel_names = 0;
  u8 *tunnel_name = 0;
  u8 *name = 0;
  ip6_sr_add_del_policy_args_t _a, *a = &_a;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_del = 1;
      else if (unformat (input, "name %s", &name))
	;
      else if (unformat (input, "tunnel %s", &tunnel_name))
	{
	  if (tunnel_name)
	    {
	      vec_add1 (tunnel_names, tunnel_name);
	      tunnel_name = 0;
	    }
	}
      else
	break;
    }

  if (!name)
    return clib_error_return (0, "name of SR policy required");


  memset (a, 0, sizeof (*a));

  a->is_del = is_del;
  a->name = name;
  a->tunnel_names = tunnel_names;

  rv = ip6_sr_add_del_policy (a);

  vec_free (tunnel_names);

  switch (rv)
    {
    case 0:
      break;

    case -3:
      return clib_error_return (0,
				"tunnel name to associate to SR policy is required");

    case -4:
      return clib_error_return (0, "tunnel name not found");

    case -5:
      return clib_error_return (0, "tunnel already associated with policy");

    case -6:
      return clib_error_return (0, "policy name %s not found", name);

    case -7:
      return clib_error_return (0, "TODO: deleting policy name %s", name);

    default:
      return clib_error_return (0, "BUG: ip6_sr_add_del_policy returns %d",
				rv);

    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (sr_policy_command, static) = {
    .path = "sr policy",
    .short_help =
    "sr policy [del] name <policy-name> tunnel <sr-tunnel-name> [tunnel <sr-tunnel-name>]*",
    .function = sr_add_del_policy_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief CLI Parser for Displaying Segment Routing policy
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
show_sr_policy_fn (vlib_main_t * vm,
		   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  static ip6_sr_policy_t **policies;
  ip6_sr_policy_t *policy;
  ip6_sr_tunnel_t *t;
  ip6_sr_main_t *sm = &sr_main;
  int i, j;
  uword *p = 0;
  u8 *name = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "name %s", &name))
	{
	  p = hash_get_mem (sm->policy_index_by_policy_name, name);
	  if (!p)
	    vlib_cli_output (vm,
			     "policy with name %s not found. Showing all.",
			     name);
	}
      else
	break;
    }

  vec_reset_length (policies);

  if (!p)			/* Either name parm not passed or no policy with that name found, show all */
    {
      /* *INDENT-OFF* */
  pool_foreach (policy, sm->policies,
  ({
    vec_add1 (policies, policy);
  }));
  /* *INDENT-ON* */
    }
  else				/* Just show the one policy by name and a summary of tunnel names */
    {
      policy = pool_elt_at_index (sm->policies, p[0]);
      vec_add1 (policies, policy);
    }

  if (vec_len (policies) == 0)
    vlib_cli_output (vm, "No SR policies configured");

  for (i = 0; i < vec_len (policies); i++)
    {
      policy = policies[i];

      if (policy->name)
	vlib_cli_output (vm, "SR policy name: %s", (char *) policy->name);
      for (j = 0; j < vec_len (policy->tunnel_indices); j++)
	{
	  t = pool_elt_at_index (sm->tunnels, policy->tunnel_indices[j]);
	  ip6_sr_tunnel_display (vm, t);
	}
    }

  return 0;

}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_sr_policy_command, static) = {
    .path = "show sr policy",
    .short_help = "show sr policy [name <sr-policy-name>]",
    .function = show_sr_policy_fn,
};
/* *INDENT-ON* */

/**
 * @brief Add or Delete a mapping of IP6 multicast address
 * to Segment Routing policy.
 *
 * @param a ip6_sr_add_del_multicastmap_args_t *
 *
 * @return retval int
 */
int
ip6_sr_add_del_multicastmap (ip6_sr_add_del_multicastmap_args_t * a)
{
  uword *p;
  ip6_sr_tunnel_t *t;
  ip6_sr_main_t *sm = &sr_main;
  ip6_sr_policy_t *pt;

  if (a->is_del)
    {
      /* clean up the adjacency */
      p =
	hash_get_mem (sm->policy_index_by_multicast_address,
		      a->multicast_address);
    }
  else
    {
      /* Get our policy by policy_name */
      p = hash_get_mem (sm->policy_index_by_policy_name, a->policy_name);

    }
  if (!p)
    return -1;

  pt = pool_elt_at_index (sm->policies, p[0]);

  /*
     Get the first tunnel associated with policy populate the fib adjacency.
     From there, since this tunnel will have it's policy_index != ~0 it will
     be the trigger in the dual_loop to pull up the policy and make a copy-rewrite
     for each tunnel in the policy
   */

  t = pool_elt_at_index (sm->tunnels, pt->tunnel_indices[0]);

  /*
   * Stick the tunnel index into the rewrite header.
   *
   * Unfortunately, inserting an SR header according to the various
   * RFC's requires parsing through the ip6 header, perhaps consing a
   * buffer onto the head of the vlib_buffer_t, etc. We don't use the
   * normal reverse bcopy rewrite code.
   *
   * We don't handle ugly RFC-related cases yet, but I'm sure PL will complain
   * at some point...
   */
  dpo_id_t dpo = DPO_INVALID;

  dpo_set (&dpo, sr_dpo_type, DPO_PROTO_IP6, t - sm->tunnels);

  /* Construct a FIB entry for multicast using the rx/tx fib from the first tunnel */
  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = 128,
    .fp_addr = {
		.ip6 = *a->multicast_address,
		}
  };
  fib_table_entry_special_dpo_add (t->rx_fib_index,
				   &pfx,
				   FIB_SOURCE_SR,
				   FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
  dpo_reset (&dpo);

  u8 *mcast_copy = 0;
  mcast_copy = vec_new (ip6_address_t, 1);
  memcpy (mcast_copy, a->multicast_address, sizeof (ip6_address_t));

  if (a->is_del)
    {
      hash_unset_mem (sm->policy_index_by_multicast_address, mcast_copy);
      vec_free (mcast_copy);
      return 0;
    }
  /* else */

  hash_set_mem (sm->policy_index_by_multicast_address, mcast_copy,
		pt - sm->policies);


  return 0;
}

/**
 * @brief CLI Parser for Adding or Delete a mapping of IP6 multicast address
 * to Segment Routing policy.
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
sr_add_del_multicast_map_command_fn (vlib_main_t * vm,
				     unformat_input_t * input,
				     vlib_cli_command_t * cmd)
{
  int is_del = 0;
  ip6_address_t multicast_address;
  u8 *policy_name = 0;
  int multicast_address_set = 0;
  ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_del = 1;
      else
	if (unformat
	    (input, "address %U", unformat_ip6_address, &multicast_address))
	multicast_address_set = 1;
      else if (unformat (input, "sr-policy %s", &policy_name))
	;
      else
	break;
    }

  if (!is_del && !policy_name)
    return clib_error_return (0, "name of sr policy required");

  if (!multicast_address_set)
    return clib_error_return (0, "multicast address required");

  memset (a, 0, sizeof (*a));

  a->is_del = is_del;
  a->multicast_address = &multicast_address;
  a->policy_name = policy_name;

#if DPDK > 0			/*Cannot call replicate or configure multicast map yet without DPDK */
  rv = ip6_sr_add_del_multicastmap (a);
#else
  return clib_error_return (0,
			    "cannot use multicast replicate spray case without DPDK installed");
#endif /* DPDK */

  switch (rv)
    {
    case 0:
      break;
    case -1:
      return clib_error_return (0, "no policy with name: %s", policy_name);

    case -2:
      return clib_error_return (0, "multicast map someting ");

    case -3:
      return clib_error_return (0,
				"tunnel name to associate to SR policy is required");

    case -7:
      return clib_error_return (0, "TODO: deleting policy name %s",
				policy_name);

    default:
      return clib_error_return (0, "BUG: ip6_sr_add_del_policy returns %d",
				rv);

    }
  return 0;

}


/* *INDENT-OFF* */
VLIB_CLI_COMMAND (sr_multicast_map_command, static) = {
    .path = "sr multicast-map",
    .short_help =
    "sr multicast-map address <multicast-ip6-address> sr-policy <sr-policy-name> [del]",
    .function = sr_add_del_multicast_map_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief CLI Parser for Displaying a mapping of IP6 multicast address
 * to Segment Routing policy.
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
show_sr_multicast_map_fn (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ip6_sr_main_t *sm = &sr_main;
  u8 *key = 0;
  u32 value;
  ip6_address_t multicast_address;
  ip6_sr_policy_t *pt;

  /* pull all entries from the hash table into vector for display */

  /* *INDENT-OFF* */
  hash_foreach_mem (key, value, sm->policy_index_by_multicast_address,
  ({
    if (!key)
	vlib_cli_output (vm, "no multicast maps configured");
    else
      {
	multicast_address = *((ip6_address_t *)key);
	pt = pool_elt_at_index (sm->policies, value);
	if (pt)
	  {
	    vlib_cli_output (vm, "address: %U policy: %s",
			     format_ip6_address, &multicast_address,
			     pt->name);
	  }
	else
	  vlib_cli_output (vm, "BUG: policy not found for address: %U with policy index %d",
			     format_ip6_address, &multicast_address,
			     value);

      }

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

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_sr_multicast_map_command, static) = {
    .path = "show sr multicast-map",
    .short_help = "show sr multicast-map",
    .function = show_sr_multicast_map_fn,
};
/* *INDENT-ON* */


#define foreach_sr_fix_dst_addr_next            \
_(DROP, "error-drop")

/**
 * @brief Struct for valid next-nodes for SR fix destination address node
 */
typedef enum
{
#define _(s,n) SR_FIX_DST_ADDR_NEXT_##s,
  foreach_sr_fix_dst_addr_next
#undef _
    SR_FIX_DST_ADDR_N_NEXT,
} sr_fix_dst_addr_next_t;

/**
 * @brief Error strings for SR Fix Destination rewrite
 */
static char *sr_fix_dst_error_strings[] = {
#define sr_fix_dst_error(n,s) s,
#include "sr_fix_dst_error.def"
#undef sr_fix_dst_error
};

/**
 * @brief Struct for errors for SR Fix Destination rewrite
 */
typedef enum
{
#define sr_fix_dst_error(n,s) SR_FIX_DST_ERROR_##n,
#include "sr_fix_dst_error.def"
#undef sr_fix_dst_error
  SR_FIX_DST_N_ERROR,
} sr_fix_dst_error_t;

/**
 * @brief Information for fix address trace
 */
typedef struct
{
  ip6_address_t src, dst;
  u32 next_index;
  u32 adj_index;
  u8 sr[256];
} sr_fix_addr_trace_t;

/**
 * @brief Formatter for fix address trace
 */
u8 *
format_sr_fix_addr_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 *);
  sr_fix_addr_trace_t *t = va_arg (*args, sr_fix_addr_trace_t *);
  vnet_hw_interface_t *hi = 0;
  ip_adjacency_t *adj;
  ip6_main_t *im = &ip6_main;
  ip_lookup_main_t *lm = &im->lookup_main;
  vnet_main_t *vnm = vnet_get_main ();

  if (t->adj_index != ~0)
    {
      adj = ip_get_adjacency (lm, t->adj_index);
      hi = vnet_get_sup_hw_interface (vnm, adj->rewrite_header.sw_if_index);
    }

  s = format (s, "SR-FIX_ADDR: next %s ip6 src %U dst %U\n",
	      (t->next_index == SR_FIX_DST_ADDR_NEXT_DROP)
	      ? "drop" : "output",
	      format_ip6_address, &t->src, format_ip6_address, &t->dst);
  if (t->next_index != SR_FIX_DST_ADDR_NEXT_DROP)
    {
      s =
	format (s, "%U\n", format_ip6_sr_header, t->sr, 1 /* print_hmac */ );
      s =
	format (s, "   output via %s",
		hi ? (char *) (hi->name) : "Invalid adj");
    }
  return s;
}

/**
 * @brief Fix SR destination address - dual-loop
 *
 * @node sr-fix-dst-addr
 * @param vm vlib_main_t *
 * @param node vlib_node_runtime_t *
 * @param from_frame vlib_frame_t *
 *
 * @return from_frame->n_vectors uword
 */
static uword
sr_fix_dst_addr (vlib_main_t * vm,
		 vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  ip6_main_t *im = &ip6_main;
  ip_lookup_main_t *lm = &im->lookup_main;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = 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);

#if 0
      while (0 && n_left_from >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  __attribute__ ((unused)) vlib_buffer_t *b0, *b1;
	  u32 next0 = SR_FIX_DST_ADDR_NEXT_DROP;
	  u32 next1 = SR_FIX_DST_ADDR_NEXT_DROP;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *p2, *p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);
	  }

	  bi0 = from[0];
	  bi1 = from[1];
	  to_next[0] = bi0;
	  to_next[1] = bi1;
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);


	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}
#endif

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  ip6_header_t *ip0;
	  ip_adjacency_t *adj0;
	  ip6_sr_header_t *sr0;
	  u32 next0 = SR_FIX_DST_ADDR_NEXT_DROP;
	  ip6_address_t *new_dst0;
	  ethernet_header_t *eh0;

	  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);

	  adj0 =
	    ip_get_adjacency (lm, vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
	  next0 = adj0->mcast_group_index;

	  /* We should be pointing at an Ethernet header... */
	  eh0 = vlib_buffer_get_current (b0);
	  ip0 = (ip6_header_t *) (eh0 + 1);
	  sr0 = (ip6_sr_header_t *) (ip0 + 1);

	  /* We'd better find an SR header... */
	  if (PREDICT_FALSE (ip0->protocol != IPPROTO_IPV6_ROUTE))
	    {
	      b0->error = node->errors[SR_FIX_DST_ERROR_NO_SR_HEADER];
	      goto do_trace0;
	    }
	  else
	    {
	      /*
	       * We get here from sr_rewrite or sr_local, with
	       * sr->segments_left pointing at the (copy of the original) dst
	       * address. Use it, then increment sr0->segments_left.
	       */

	      /* Out of segments? Turf the packet */
	      if (PREDICT_FALSE (sr0->segments_left == 0))
		{
		  b0->error = node->errors[SR_FIX_DST_ERROR_NO_MORE_SEGMENTS];
		  goto do_trace0;
		}

	      /*
	       * Rewrite the packet with the original dst address
	       * We assume that the last segment (in processing order) contains
	       * the original dst address. The list is reversed, so sr0->segments
	       * contains the original dst address.
	       */
	      new_dst0 = sr0->segments;
	      ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
	      ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];
	    }

	do_trace0:

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_fix_addr_trace_t *t = vlib_add_trace (vm, node,
						       b0, sizeof (*t));
	      t->next_index = next0;
	      t->adj_index = ~0;

	      if (next0 != SR_FIX_DST_ADDR_NEXT_DROP)
		{
		  t->adj_index = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
		  clib_memcpy (t->src.as_u8, ip0->src_address.as_u8,
			       sizeof (t->src.as_u8));
		  clib_memcpy (t->dst.as_u8, ip0->dst_address.as_u8,
			       sizeof (t->dst.as_u8));
		  clib_memcpy (t->sr, sr0, sizeof (t->sr));
		}
	    }

	  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);
    }
  return from_frame->n_vectors;
}


/* *INDENT-OFF* */
VLIB_REGISTER_NODE (sr_fix_dst_addr_node) = {
  .function = sr_fix_dst_addr,
  .name = "sr-fix-dst-addr",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .format_trace = format_sr_fix_addr_trace,
  .format_buffer = format_ip6_sr_header_with_length,

  .runtime_data_bytes = 0,

  .n_errors = SR_FIX_DST_N_ERROR,
  .error_strings = sr_fix_dst_error_strings,

  .n_next_nodes = SR_FIX_DST_ADDR_N_NEXT,
  .next_nodes = {
#define _(s,n) [SR_FIX_DST_ADDR_NEXT_##s] = n,
    foreach_sr_fix_dst_addr_next
#undef _
  },
};

VLIB_NODE_FUNCTION_MULTIARCH (sr_fix_dst_addr_node, sr_fix_dst_addr)
/* *INDENT-ON* */

static clib_error_t *
sr_init (vlib_main_t * vm)
{
  ip6_sr_main_t *sm = &sr_main;
  clib_error_t *error = 0;
  vlib_node_t *ip6_lookup_node, *ip6_rewrite_node;

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

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

  sm->vlib_main = vm;
  sm->vnet_main = vnet_get_main ();

  vec_validate (sm->hmac_keys, 0);
  sm->hmac_keys[0].shared_secret = (u8 *) 0xdeadbeef;

  sm->tunnel_index_by_key =
    hash_create_mem (0, sizeof (ip6_sr_tunnel_key_t), sizeof (uword));

  sm->tunnel_index_by_name = hash_create_string (0, sizeof (uword));

  sm->policy_index_by_policy_name = hash_create_string (0, sizeof (uword));

  sm->policy_index_by_multicast_address =
    hash_create_mem (0, sizeof (ip6_address_t), sizeof (uword));

  sm->hmac_key_by_shared_secret = hash_create_string (0, sizeof (uword));

  ip6_register_protocol (IPPROTO_IPV6_ROUTE, sr_local_node.index);

  ip6_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ip6-lookup");
  ASSERT (ip6_lookup_node);

  ip6_rewrite_node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite");
  ASSERT (ip6_rewrite_node);

#if DPDK > 0			/* Cannot run replicate without DPDK */
  /* Add a disposition to sr_replicate for the sr multicast replicate node */
  sm->ip6_lookup_sr_replicate_index =
    vlib_node_add_next (vm, ip6_lookup_node->index, sr_replicate_node.index);
#endif /* DPDK */

  /* Add a disposition to ip6_rewrite for the sr dst address hack node */
  sm->ip6_rewrite_sr_next_index =
    vlib_node_add_next (vm, ip6_rewrite_node->index,
			sr_fix_dst_addr_node.index);

  OpenSSL_add_all_digests ();

  sm->md = (void *) EVP_get_digestbyname ("sha1");
  sm->hmac_ctx = clib_mem_alloc (sizeof (HMAC_CTX));

  sr_dpo_type = dpo_register_new_type (&sr_vft, sr_nodes);

  return error;
}

VLIB_INIT_FUNCTION (sr_init);

/**
 * @brief Definition of next-nodes for SR local
 */
#define foreach_sr_local_next                   \
  _ (ERROR, "error-drop")                       \
  _ (IP6_LOOKUP, "ip6-lookup")

/**
 * @brief Struct for definition of next-nodes for SR local
 */
typedef enum
{
#define _(s,n) SR_LOCAL_NEXT_##s,
  foreach_sr_local_next
#undef _
    SR_LOCAL_N_NEXT,
} sr_local_next_t;

/**
 * @brief Struct for packet trace of SR local
 */
typedef struct
{
  u8 next_index;
  u8 sr_valid;
  ip6_address_t src, dst;
  u16 length;
  u8 sr[256];
} sr_local_trace_t;

/**
 * @brief Definition of SR local error-strings
 */
static char *sr_local_error_strings[] = {
#define sr_error(n,s) s,
#include "sr_error.def"
#undef sr_error
};

/**
 * @brief Struct for definition of SR local error-strings
 */
typedef enum
{
#define sr_error(n,s) SR_LOCAL_ERROR_##n,
#include "sr_error.def"
#undef sr_error
  SR_LOCAL_N_ERROR,
} sr_local_error_t;

/**
 * @brief Format SR local trace
 *
 * @param s u8 *
 * @param args va_list *
 *
 * @return s u8 *
 */
u8 *
format_sr_local_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 *);
  sr_local_trace_t *t = va_arg (*args, sr_local_trace_t *);

  s = format (s, "SR-LOCAL: src %U dst %U len %u next_index %d",
	      format_ip6_address, &t->src,
	      format_ip6_address, &t->dst, t->length, t->next_index);
  if (t->sr_valid)
    s =
      format (s, "\n  %U", format_ip6_sr_header, t->sr, 1 /* print_hmac */ );
  else
    s = format (s, "\n  popped SR header");

  return s;
}


/* $$$$ fixme: smp, don't copy data, cache input, output (maybe) */
/**
 * @brief Validate the SR HMAC
 *
 * @param sm ip6_sr_main_t *
 * @param ip ip6_header_t *
 * @param sr ip6_sr_header_t *
 *
 * @return retval int
 */
static int
sr_validate_hmac (ip6_sr_main_t * sm, ip6_header_t * ip, ip6_sr_header_t * sr)
{
  u32 key_index;
  static u8 *keybuf;
  u8 *copy_target;
  int first_segment;
  ip6_address_t *addrp;
  int i;
  ip6_sr_hmac_key_t *hmac_key;
  static u8 *signature;
  u32 sig_len;

  key_index = sr->hmac_key;

  /* No signature? Pass... */
  if (key_index == 0)
    return 0;

  /* We don't know about this key? Fail... */
  if (key_index >= vec_len (sm->hmac_keys))
    return 1;

  vec_validate (signature, SHA256_DIGEST_LENGTH - 1);

  hmac_key = sm->hmac_keys + key_index;

  vec_reset_length (keybuf);

  /* pkt ip6 src address */
  vec_add2 (keybuf, copy_target, sizeof (ip6_address_t));
  clib_memcpy (copy_target, ip->src_address.as_u8, sizeof (ip6_address_t));

  /* last segment */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0] = sr->first_segment;

  /* octet w/ bit 0 = "clean" flag */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0]
    = (sr->flags & clib_host_to_net_u16 (IP6_SR_HEADER_FLAG_CLEANUP))
    ? 0x80 : 0;

  /* hmac key id */
  vec_add2 (keybuf, copy_target, 1);
  copy_target[0] = sr->hmac_key;

  first_segment = sr->first_segment;

  addrp = sr->segments;

  /* segments */
  for (i = 0; i <= first_segment; i++)
    {
      vec_add2 (keybuf, copy_target, sizeof (ip6_address_t));
      clib_memcpy (copy_target, addrp->as_u8, sizeof (ip6_address_t));
      addrp++;
    }

  if (sm->is_debug)
    clib_warning ("verify key index %d keybuf: %U", key_index,
		  format_hex_bytes, keybuf, vec_len (keybuf));

  /* shared secret */

  /* SHA1 is shorter than SHA-256 */
  memset (signature, 0, vec_len (signature));

  HMAC_CTX_init (sm->hmac_ctx);
  if (!HMAC_Init (sm->hmac_ctx, hmac_key->shared_secret,
		  vec_len (hmac_key->shared_secret), sm->md))
    clib_warning ("barf1");
  if (!HMAC_Update (sm->hmac_ctx, keybuf, vec_len (keybuf)))
    clib_warning ("barf2");
  if (!HMAC_Final (sm->hmac_ctx, signature, &sig_len))
    clib_warning ("barf3");
  HMAC_CTX_cleanup (sm->hmac_ctx);

  if (sm->is_debug)
    clib_warning ("computed signature len %d, value %U", sig_len,
		  format_hex_bytes, signature, vec_len (signature));

  /* Point at the SHA signature in the packet */
  addrp++;
  if (sm->is_debug)
    clib_warning ("read signature %U", format_hex_bytes, addrp,
		  SHA256_DIGEST_LENGTH);

  return memcmp (signature, addrp, SHA256_DIGEST_LENGTH);
}

/**
 * @brief SR local node
 * @node sr-local
 *
 * @param vm vlib_main_t *
 * @param node vlib_node_runtime_t *
 * @param from_frame vlib_frame_t *
 *
 * @return from_frame->n_vectors uword
 */
static uword
sr_local (vlib_main_t * vm,
	  vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  ip6_sr_main_t *sm = &sr_main;
  u32 (*sr_local_cb) (vlib_main_t *, vlib_node_runtime_t *,
		      vlib_buffer_t *, ip6_header_t *, ip6_sr_header_t *);
  sr_local_cb = sm->sr_local_cb;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = 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 >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  vlib_buffer_t *b0, *b1;
	  ip6_header_t *ip0, *ip1;
	  ip6_sr_header_t *sr0, *sr1;
	  ip6_address_t *new_dst0, *new_dst1;
	  u32 next0 = SR_LOCAL_NEXT_IP6_LOOKUP;
	  u32 next1 = SR_LOCAL_NEXT_IP6_LOOKUP;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t *p2, *p3;

	    p2 = vlib_get_buffer (vm, from[2]);
	    p3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (p2, LOAD);
	    vlib_prefetch_buffer_header (p3, LOAD);

	    CLIB_PREFETCH (p2->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	    CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
	  }

	  bi0 = from[0];
	  bi1 = from[1];
	  to_next[0] = bi0;
	  to_next[1] = bi1;
	  from += 2;
	  to_next += 2;
	  n_left_to_next -= 2;
	  n_left_from -= 2;


	  b0 = vlib_get_buffer (vm, bi0);
	  ip0 = vlib_buffer_get_current (b0);
	  sr0 = (ip6_sr_header_t *) (ip0 + 1);
	  if (PREDICT_FALSE
	      (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
	    {
	      ip6_hop_by_hop_ext_t *ext_hdr =
		(ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
	      sr0 =
		(ip6_sr_header_t *) ip6_ext_next_header ((ip6_ext_header_t *)
							 ext_hdr);
	    }

	  if (PREDICT_FALSE (sr0->type != ROUTING_HEADER_TYPE_SR))
	    {
	      next0 = SR_LOCAL_NEXT_ERROR;
	      b0->error =
		node->errors[SR_LOCAL_ERROR_BAD_ROUTING_HEADER_TYPE];
	      goto do_trace0;
	    }

	  /* Out of segments? Turf the packet */
	  if (PREDICT_FALSE (sr0->segments_left == 0))
	    {
	      next0 = SR_LOCAL_NEXT_ERROR;
	      b0->error = node->errors[SR_LOCAL_ERROR_NO_MORE_SEGMENTS];
	      goto do_trace0;
	    }

	  if (PREDICT_FALSE (sm->validate_hmac))
	    {
	      if (sr_validate_hmac (sm, ip0, sr0))
		{
		  next0 = SR_LOCAL_NEXT_ERROR;
		  b0->error = node->errors[SR_LOCAL_ERROR_HMAC_INVALID];
		  goto do_trace0;
		}
	    }

	  next0 = sr_local_cb ? sr_local_cb (vm, node, b0, ip0, sr0) : next0;

	  /*
	   * To suppress rewrite, return ~SR_LOCAL_NEXT_xxx
	   */
	  if (PREDICT_FALSE (next0 & 0x80000000))
	    {
	      next0 ^= 0xFFFFFFFF;
	      if (PREDICT_FALSE (next0 == SR_LOCAL_NEXT_ERROR))
		b0->error = node->errors[SR_LOCAL_ERROR_APP_CALLBACK];
	    }
	  else
	    {
	      u32 segment_index0;

	      segment_index0 = sr0->segments_left - 1;

	      /* Rewrite the packet */
	      new_dst0 = (ip6_address_t *) (sr0->segments + segment_index0);
	      ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
	      ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];

	      if (PREDICT_TRUE (sr0->segments_left > 0))
		sr0->segments_left -= 1;
	    }

	  /* End of the path. Clean up the SR header, or not */
	  if (PREDICT_FALSE
	      (sr0->segments_left == 0 &&
	       (sr0->flags &
		clib_host_to_net_u16 (IP6_SR_HEADER_FLAG_CLEANUP))))
	    {
	      u64 *copy_dst0, *copy_src0;
	      u16 new_l0;
	      u32 copy_len_u64s0 = 0;
	      int i;

	      /*
	       * Copy the ip6 header right by the (real) length of the
	       * sr header.
	       */
	      if (PREDICT_FALSE
		  (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
		  copy_len_u64s0 =
		    (((ip6_ext_header_t *) ext_hdr)->n_data_u64s) + 1;
		  ext_hdr->next_hdr = sr0->protocol;
		}
	      else
		{
		  ip0->protocol = sr0->protocol;
		}
	      vlib_buffer_advance (b0, (sr0->length + 1) * 8);

	      new_l0 = clib_net_to_host_u16 (ip0->payload_length) -
		(sr0->length + 1) * 8;
	      ip0->payload_length = clib_host_to_net_u16 (new_l0);

	      copy_src0 = (u64 *) ip0;
	      copy_dst0 = copy_src0 + (sr0->length + 1);

	      copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0];
	      copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0];
	      copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0];
	      copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0];
	      copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0];

	      for (i = copy_len_u64s0 - 1; i >= 0; i--)
		{
		  copy_dst0[i] = copy_src0[i];
		}

	      sr0 = 0;
	    }

	do_trace0:
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_local_trace_t *tr = vlib_add_trace (vm, node,
						     b0, sizeof (*tr));
	      clib_memcpy (tr->src.as_u8, ip0->src_address.as_u8,
			   sizeof (tr->src.as_u8));
	      clib_memcpy (tr->dst.as_u8, ip0->dst_address.as_u8,
			   sizeof (tr->dst.as_u8));
	      tr->length = vlib_buffer_length_in_chain (vm, b0);
	      tr->next_index = next0;
	      tr->sr_valid = sr0 != 0;
	      if (tr->sr_valid)
		clib_memcpy (tr->sr, sr0, sizeof (tr->sr));
	    }

	  b1 = vlib_get_buffer (vm, bi1);
	  ip1 = vlib_buffer_get_current (b1);
	  sr1 = (ip6_sr_header_t *) (ip1 + 1);
	  if (PREDICT_FALSE
	      (ip1->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
	    {

	      ip6_hop_by_hop_ext_t *ext_hdr =
		(ip6_hop_by_hop_ext_t *) ip6_next_header (ip1);
	      sr1 =
		(ip6_sr_header_t *) ip6_ext_next_header ((ip6_ext_header_t *)
							 ext_hdr);
	    }

	  if (PREDICT_FALSE (sr1->type != ROUTING_HEADER_TYPE_SR))
	    {
	      next1 = SR_LOCAL_NEXT_ERROR;
	      b1->error =
		node->errors[SR_LOCAL_ERROR_BAD_ROUTING_HEADER_TYPE];
	      goto do_trace1;
	    }

	  /* Out of segments? Turf the packet */
	  if (PREDICT_FALSE (sr1->segments_left == 0))
	    {
	      next1 = SR_LOCAL_NEXT_ERROR;
	      b1->error = node->errors[SR_LOCAL_ERROR_NO_MORE_SEGMENTS];
	      goto do_trace1;
	    }

	  if (PREDICT_FALSE (sm->validate_hmac))
	    {
	      if (sr_validate_hmac (sm, ip1, sr1))
		{
		  next1 = SR_LOCAL_NEXT_ERROR;
		  b1->error = node->errors[SR_LOCAL_ERROR_HMAC_INVALID];
		  goto do_trace1;
		}
	    }

	  next1 = sr_local_cb ? sr_local_cb (vm, node, b1, ip1, sr1) : next1;

	  /*
	   * To suppress rewrite, return ~SR_LOCAL_NEXT_xxx
	   */
	  if (PREDICT_FALSE (next1 & 0x80000000))
	    {
	      next1 ^= 0xFFFFFFFF;
	      if (PREDICT_FALSE (next1 == SR_LOCAL_NEXT_ERROR))
		b1->error = node->errors[SR_LOCAL_ERROR_APP_CALLBACK];
	    }
	  else
	    {
	      u32 segment_index1;

	      segment_index1 = sr1->segments_left - 1;

	      /* Rewrite the packet */
	      new_dst1 = (ip6_address_t *) (sr1->segments + segment_index1);
	      ip1->dst_address.as_u64[0] = new_dst1->as_u64[0];
	      ip1->dst_address.as_u64[1] = new_dst1->as_u64[1];

	      if (PREDICT_TRUE (sr1->segments_left > 0))
		sr1->segments_left -= 1;
	    }

	  /* End of the path. Clean up the SR header, or not */
	  if (PREDICT_FALSE
	      (sr1->segments_left == 0 &&
	       (sr1->flags &
		clib_host_to_net_u16 (IP6_SR_HEADER_FLAG_CLEANUP))))
	    {
	      u64 *copy_dst1, *copy_src1;
	      u16 new_l1;
	      u32 copy_len_u64s1 = 0;
	      int i;

	      /*
	       * Copy the ip6 header right by the (real) length of the
	       * sr header.
	       */
	      if (PREDICT_FALSE
		  (ip1->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip1);
		  copy_len_u64s1 =
		    (((ip6_ext_header_t *) ext_hdr)->n_data_u64s) + 1;
		  ext_hdr->next_hdr = sr1->protocol;
		}
	      else
		{
		  ip1->protocol = sr1->protocol;
		}
	      vlib_buffer_advance (b1, (sr1->length + 1) * 8);

	      new_l1 = clib_net_to_host_u16 (ip1->payload_length) -
		(sr1->length + 1) * 8;
	      ip1->payload_length = clib_host_to_net_u16 (new_l1);

	      copy_src1 = (u64 *) ip1;
	      copy_dst1 = copy_src1 + (sr1->length + 1);

	      copy_dst1[4 + copy_len_u64s1] = copy_src1[4 + copy_len_u64s1];
	      copy_dst1[3 + copy_len_u64s1] = copy_src1[3 + copy_len_u64s1];
	      copy_dst1[2 + copy_len_u64s1] = copy_src1[2 + copy_len_u64s1];
	      copy_dst1[1 + copy_len_u64s1] = copy_src1[1 + copy_len_u64s1];
	      copy_dst1[0 + copy_len_u64s1] = copy_src1[0 + copy_len_u64s1];

	      for (i = copy_len_u64s1 - 1; i >= 0; i--)
		{
		  copy_dst1[i] = copy_src1[i];
		}

	      sr1 = 0;
	    }

	do_trace1:
	  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_local_trace_t *tr = vlib_add_trace (vm, node,
						     b1, sizeof (*tr));
	      clib_memcpy (tr->src.as_u8, ip1->src_address.as_u8,
			   sizeof (tr->src.as_u8));
	      clib_memcpy (tr->dst.as_u8, ip1->dst_address.as_u8,
			   sizeof (tr->dst.as_u8));
	      tr->length = vlib_buffer_length_in_chain (vm, b1);
	      tr->next_index = next1;
	      tr->sr_valid = sr1 != 0;
	      if (tr->sr_valid)
		clib_memcpy (tr->sr, sr1, sizeof (tr->sr));
	    }

	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next1);
	}

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;
	  ip6_header_t *ip0 = 0;
	  ip6_sr_header_t *sr0;
	  ip6_address_t *new_dst0;
	  u32 next0 = SR_LOCAL_NEXT_IP6_LOOKUP;

	  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);
	  ip0 = vlib_buffer_get_current (b0);
	  sr0 = (ip6_sr_header_t *) (ip0 + 1);

	  if (PREDICT_FALSE
	      (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
	    {
	      ip6_hop_by_hop_ext_t *ext_hdr =
		(ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
	      sr0 =
		(ip6_sr_header_t *) ip6_ext_next_header ((ip6_ext_header_t *)
							 ext_hdr);
	    }
	  if (PREDICT_FALSE (sr0->type != ROUTING_HEADER_TYPE_SR))
	    {
	      next0 = SR_LOCAL_NEXT_ERROR;
	      b0->error =
		node->errors[SR_LOCAL_ERROR_BAD_ROUTING_HEADER_TYPE];
	      goto do_trace;
	    }

	  /* Out of segments? Turf the packet */
	  if (PREDICT_FALSE (sr0->segments_left == 0))
	    {
	      next0 = SR_LOCAL_NEXT_ERROR;
	      b0->error = node->errors[SR_LOCAL_ERROR_NO_MORE_SEGMENTS];
	      goto do_trace;
	    }

	  if (PREDICT_FALSE (sm->validate_hmac))
	    {
	      if (sr_validate_hmac (sm, ip0, sr0))
		{
		  next0 = SR_LOCAL_NEXT_ERROR;
		  b0->error = node->errors[SR_LOCAL_ERROR_HMAC_INVALID];
		  goto do_trace;
		}
	    }

	  next0 = sr_local_cb ? sr_local_cb (vm, node, b0, ip0, sr0) : next0;

	  /*
	   * To suppress rewrite, return ~SR_LOCAL_NEXT_xxx
	   */
	  if (PREDICT_FALSE (next0 & 0x80000000))
	    {
	      next0 ^= 0xFFFFFFFF;
	      if (PREDICT_FALSE (next0 == SR_LOCAL_NEXT_ERROR))
		b0->error = node->errors[SR_LOCAL_ERROR_APP_CALLBACK];
	    }
	  else
	    {
	      u32 segment_index0;

	      segment_index0 = sr0->segments_left - 1;

	      /* Rewrite the packet */
	      new_dst0 = (ip6_address_t *) (sr0->segments + segment_index0);
	      ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
	      ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];

	      if (PREDICT_TRUE (sr0->segments_left > 0))
		sr0->segments_left -= 1;
	    }

	  /* End of the path. Clean up the SR header, or not */
	  if (PREDICT_FALSE
	      (sr0->segments_left == 0 &&
	       (sr0->flags &
		clib_host_to_net_u16 (IP6_SR_HEADER_FLAG_CLEANUP))))
	    {
	      u64 *copy_dst0, *copy_src0;
	      u16 new_l0;
	      u32 copy_len_u64s0 = 0;
	      int i;

	      /*
	       * Copy the ip6 header right by the (real) length of the
	       * sr header.
	       */
	      if (PREDICT_FALSE
		  (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
		{
		  ip6_hop_by_hop_ext_t *ext_hdr =
		    (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
		  copy_len_u64s0 =
		    (((ip6_ext_header_t *) ext_hdr)->n_data_u64s) + 1;
		  ext_hdr->next_hdr = sr0->protocol;
		}
	      else
		{
		  ip0->protocol = sr0->protocol;
		}

	      vlib_buffer_advance (b0, (sr0->length + 1) * 8);

	      new_l0 = clib_net_to_host_u16 (ip0->payload_length) -
		(sr0->length + 1) * 8;
	      ip0->payload_length = clib_host_to_net_u16 (new_l0);

	      copy_src0 = (u64 *) ip0;
	      copy_dst0 = copy_src0 + (sr0->length + 1);
	      copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0];
	      copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0];
	      copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0];
	      copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0];
	      copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0];

	      for (i = copy_len_u64s0 - 1; i >= 0; i--)
		{
		  copy_dst0[i] = copy_src0[i];
		}

	      sr0 = 0;
	    }

	do_trace:
	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      sr_local_trace_t *tr = vlib_add_trace (vm, node,
						     b0, sizeof (*tr));
	      clib_memcpy (tr->src.as_u8, ip0->src_address.as_u8,
			   sizeof (tr->src.as_u8));
	      clib_memcpy (tr->dst.as_u8, ip0->dst_address.as_u8,
			   sizeof (tr->dst.as_u8));
	      tr->length = vlib_buffer_length_in_chain (vm, b0);
	      tr->next_index = next0;
	      tr->sr_valid = sr0 != 0;
	      if (tr->sr_valid)
		clib_memcpy (tr->sr, sr0, sizeof (tr->sr));
	    }

	  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, sr_local_node.index,
			       SR_LOCAL_ERROR_PKTS_PROCESSED,
			       from_frame->n_vectors);
  return from_frame->n_vectors;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (sr_local_node, static) = {
  .function = sr_local,
  .name = "sr-local",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .format_trace = format_sr_local_trace,

  .runtime_data_bytes = 0,

  .n_errors = SR_LOCAL_N_ERROR,
  .error_strings = sr_local_error_strings,

  .n_next_nodes = SR_LOCAL_N_NEXT,
  .next_nodes = {
#define _(s,n) [SR_LOCAL_NEXT_##s] = n,
    foreach_sr_local_next
#undef _
  },
};

VLIB_NODE_FUNCTION_MULTIARCH (sr_local_node, sr_local)
/* *INDENT-ON* */

ip6_sr_main_t *
sr_get_main (vlib_main_t * vm)
{
  vlib_call_init_function (vm, sr_init);
  ASSERT (sr_local_node.index);
  return &sr_main;
}

/**
 * @brief CLI parser for SR fix destination rewrite node
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
set_ip6_sr_rewrite_fn (vlib_main_t * vm,
		       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = 128,
  };
  u32 fib_index = 0;
  u32 fib_id = 0;
  u32 adj_index;
  ip_adjacency_t *adj;
  vnet_hw_interface_t *hi;
  u32 sw_if_index;
  ip6_sr_main_t *sm = &sr_main;
  vnet_main_t *vnm = vnet_get_main ();
  fib_node_index_t fei;

  if (!unformat (input, "%U", unformat_ip6_address, &pfx.fp_addr.ip6))
    return clib_error_return (0, "ip6 address missing in '%U'",
			      format_unformat_error, input);

  if (unformat (input, "rx-table-id %d", &fib_id))
    {
      fib_index = fib_table_id_find_fib_index (FIB_PROTOCOL_IP6, fib_id);
      if (fib_index == ~0)
	return clib_error_return (0, "fib-id %d not found", fib_id);
    }

  fei = fib_table_lookup_exact_match (fib_index, &pfx);

  if (FIB_NODE_INDEX_INVALID == fei)
    return clib_error_return (0, "no match for %U",
			      format_ip6_address, &pfx.fp_addr.ip6);

  adj_index = fib_entry_get_adj_for_source (fei, FIB_SOURCE_SR);

  if (ADJ_INDEX_INVALID == adj_index)
    return clib_error_return (0, "%U not SR sourced",
			      format_ip6_address, &pfx.fp_addr.ip6);

  adj = adj_get (adj_index);

  if (adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
    return clib_error_return (0, "%U unresolved (not a rewrite adj)",
			      format_ip6_address, &pfx.fp_addr.ip6);

  adj->rewrite_header.next_index = sm->ip6_rewrite_sr_next_index;

  sw_if_index = adj->rewrite_header.sw_if_index;
  hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
  adj->rewrite_header.node_index = sr_fix_dst_addr_node.index;

  /* $$$$$ hack... steal the mcast group index */
  adj->mcast_group_index =
    vlib_node_add_next (vm, sr_fix_dst_addr_node.index,
			hi->output_node_index);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_ip6_sr_rewrite, static) = {
    .path = "set ip6 sr rewrite",
    .short_help = "set ip6 sr rewrite <ip6-address> [fib-id <id>]",
    .function = set_ip6_sr_rewrite_fn,
};
/* *INDENT-ON* */

/**
 * @brief Register a callback routine to set next0 in sr_local
 *
 * @param cb void *
 */
void
vnet_register_sr_app_callback (void *cb)
{
  ip6_sr_main_t *sm = &sr_main;

  sm->sr_local_cb = cb;
}

/**
 * @brief Test routine for validation of HMAC
 */
static clib_error_t *
test_sr_hmac_validate_fn (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ip6_sr_main_t *sm = &sr_main;

  if (unformat (input, "validate on"))
    sm->validate_hmac = 1;
  else if (unformat (input, "chunk-offset off"))
    sm->validate_hmac = 0;
  else
    return clib_error_return (0, "expected validate on|off in '%U'",
			      format_unformat_error, input);

  vlib_cli_output (vm, "hmac signature validation %s",
		   sm->validate_hmac ? "on" : "off");
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_sr_hmac_validate, static) = {
    .path = "test sr hmac",
    .short_help = "test sr hmac validate [on|off]",
    .function = test_sr_hmac_validate_fn,
};
/* *INDENT-ON* */

/**
 * @brief Add or Delete HMAC key
 *
 * @param sm ip6_sr_main_t *
 * @param key_id u32
 * @param shared_secret u8 *
 * @param is_del u8
 *
 * @return retval i32
 */
// $$$ fixme shouldn't return i32
i32
sr_hmac_add_del_key (ip6_sr_main_t * sm, u32 key_id, u8 * shared_secret,
		     u8 is_del)
{
  u32 index;
  ip6_sr_hmac_key_t *key;

  if (is_del == 0)
    {
      /* Specific key in use? Fail. */
      if (key_id && vec_len (sm->hmac_keys) > key_id
	  && sm->hmac_keys[key_id].shared_secret)
	return -2;

      index = key_id;
      key = find_or_add_shared_secret (sm, shared_secret, &index);
      ASSERT (index == key_id);
      return 0;
    }

  /* delete */

  if (key_id)			/* delete by key ID */
    {
      if (vec_len (sm->hmac_keys) <= key_id)
	return -3;

      key = sm->hmac_keys + key_id;

      hash_unset_mem (sm->hmac_key_by_shared_secret, key->shared_secret);
      vec_free (key->shared_secret);
      return 0;
    }

  index = 0;
  key = find_or_add_shared_secret (sm, shared_secret, &index);
  hash_unset_mem (sm->hmac_key_by_shared_secret, key->shared_secret);
  vec_free (key->shared_secret);
  return 0;
}


static clib_error_t *
sr_hmac_add_del_key_fn (vlib_main_t * vm,
			unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ip6_sr_main_t *sm = &sr_main;
  u8 is_del = 0;
  u32 key_id = 0;
  u8 key_id_set = 0;
  u8 *shared_secret = 0;
  i32 rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_del = 1;
      else if (unformat (input, "id %d", &key_id))
	key_id_set = 1;
      else if (unformat (input, "key %s", &shared_secret))
	{
	  /* Do not include the trailing NULL byte. Guaranteed interop issue */
	  _vec_len (shared_secret) -= 1;
	}
      else
	break;
    }

  if (is_del == 0 && shared_secret == 0)
    return clib_error_return (0, "shared secret must be set to add a key");

  if (shared_secret == 0 && key_id_set == 0)
    return clib_error_return (0, "shared secret and key id both unset");

  rv = sr_hmac_add_del_key (sm, key_id, shared_secret, is_del);

  vec_free (shared_secret);

  switch (rv)
    {
    case 0:
      break;

    default:
      return clib_error_return (0, "sr_hmac_add_del_key returned %d", rv);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (sr_hmac, static) = {
    .path = "sr hmac",
    .short_help = "sr hmac [del] id <nn> key <str>",
    .function = sr_hmac_add_del_key_fn,
};
/* *INDENT-ON* */

/**
 * @brief CLI parser for show HMAC key shared secrets
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
show_sr_hmac_fn (vlib_main_t * vm,
		 unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ip6_sr_main_t *sm = &sr_main;
  int i;

  for (i = 1; i < vec_len (sm->hmac_keys); i++)
    {
      if (sm->hmac_keys[i].shared_secret)
	vlib_cli_output (vm, "[%d]: %v", i, sm->hmac_keys[i].shared_secret);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_sr_hmac, static) = {
    .path = "show sr hmac",
    .short_help = "show sr hmac",
    .function = show_sr_hmac_fn,
};
/* *INDENT-ON* */

/**
 * @brief Test for SR debug flag
 *
 * @param vm vlib_main_t *
 * @param input unformat_input_t *
 * @param cmd vlib_cli_command_t *
 *
 * @return error clib_error_t *
 */
static clib_error_t *
test_sr_debug_fn (vlib_main_t * vm,
		  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  ip6_sr_main_t *sm = &sr_main;

  if (unformat (input, "on"))
    sm->is_debug = 1;
  else if (unformat (input, "off"))
    sm->is_debug = 0;
  else
    return clib_error_return (0, "expected on|off in '%U'",
			      format_unformat_error, input);

  vlib_cli_output (vm, "debug trace now %s", sm->is_debug ? "on" : "off");

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_sr_debug, static) = {
    .path = "test sr debug",
    .short_help = "test sr debug on|off",
    .function = test_sr_debug_fn,
};
/* *INDENT-ON* */

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