/*
 * 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/mfib/mfib_table.h>
#include <vnet/dpo/dpo.h>
#include <vnet/dpo/replicate_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 Dynamically added SR FIB Node type
 */
static fib_node_type_t sr_fib_node_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
*/
#define foreach_sr_rewrite_next                 \
_(ERROR, "error-drop")                          \
_(SR_LOCAL, "sr-local")

/**
 * @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;
	  u32 next1;
	  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);

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

	      vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
		t0->first_hop_dpo.dpoi_index;
	      next0 = t0->first_hop_dpo.dpoi_next_node;
	      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 (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);

	      vnet_buffer (b1)->ip.adj_index[VLIB_TX] =
		t1->first_hop_dpo.dpoi_index;
	      next1 = t1->first_hop_dpo.dpoi_next_node;
	      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 (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;
	  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]);

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

	      vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
		t0->first_hop_dpo.dpoi_index;
	      next0 = t0->first_hop_dpo.dpoi_next_node;
	      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 (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_routes_add_del (ip6_sr_tunnel_t * t, int is_del)
{
  ip6_sr_main_t *sm = &sr_main;

  /*
   * the prefix for the tunnel's destination
   */
  /* *INDENT-OFF* */
  fib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = t->dst_mask_width,
    .fp_addr = {
      .ip6 = t->key.dst,
    }
  };
  /* *INDENT-ON* */

  if (is_del)
    {
      fib_table_entry_delete (t->rx_fib_index, &pfx, FIB_SOURCE_SR);
    }
  else
    {
      dpo_id_t dpo = DPO_INVALID;

      dpo_set (&dpo, sr_dpo_type, DPO_PROTO_IP6, t - sm->tunnels);
      fib_table_entry_special_dpo_add (t->rx_fib_index,
				       &pfx,
				       FIB_SOURCE_SR,
				       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
      dpo_reset (&dpo);
    }

  /*
   * Track the first hop address so we don't need to perform an extra
   * lookup in the data-path
   */
  /* *INDENT-OFF* */
  const fib_prefix_t first_hop_pfx = {
    .fp_len = 128,
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_addr = {
      .ip6 = t->first_hop,
    }
  };
  /* *INDENT-ON* */

  if (is_del)
    {
      fib_entry_child_remove (t->fib_entry_index, t->sibling_index);
      fib_table_entry_delete_index (t->fib_entry_index, FIB_SOURCE_RR);
    }
  else
    {
      t->fib_entry_index =
	fib_table_entry_special_add (t->rx_fib_index,
				     &first_hop_pfx,
				     FIB_SOURCE_RR,
				     FIB_ENTRY_FLAG_NONE, ADJ_INDEX_INVALID);
      t->sibling_index =
	fib_entry_child_add (t->fib_entry_index,
			     sr_fib_node_type, t - sm->tunnels);
    }

  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 Stack a tunnel on the forwarding chain of the first-hop
 */
static void
sr_tunnel_stack (ip6_sr_tunnel_t * st)
{
  dpo_stack (sr_dpo_type,
	     DPO_PROTO_IP6,
	     &st->first_hop_dpo,
	     fib_entry_contribute_ip_forwarding (st->fib_entry_index));
}

/**
 * @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;

  /* 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_routes_add_del (t, 1);

      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);
	}
      dpo_reset (&t->first_hop_dpo);
      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;
  fib_node_init (&t->node, sr_fib_node_type);

  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...
   */

  /*
   * Add the routes for the tunnel destination and first-hop, then stack
   * the tunnel on the appropriate forwarding DPOs.
   */
  ip6_routes_add_del (t, 0);
  sr_tunnel_stack (t);

  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_dpo_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,
};

static ip6_sr_tunnel_t *
sr_tunnel_from_fib_node (fib_node_t * node)
{
#if (CLIB_DEBUG > 0)
  ASSERT (sr_fib_node_type == node->fn_type);
#endif
  return ((ip6_sr_tunnel_t *) (((char *) node) -
			       STRUCT_OFFSET_OF (ip6_sr_tunnel_t, node)));
}

/**
 * Function definition to backwalk a FIB node
 */
static fib_node_back_walk_rc_t
sr_tunnel_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
{
  sr_tunnel_stack (sr_tunnel_from_fib_node (node));

  return (FIB_NODE_BACK_WALK_CONTINUE);
}

/**
 * Function definition to get a FIB node from its index
 */
static fib_node_t *
sr_tunnel_fib_node_get (fib_node_index_t index)
{
  ip6_sr_tunnel_t *st;
  ip6_sr_main_t *sm;

  sm = &sr_main;
  st = pool_elt_at_index (sm->tunnels, index);

  return (&st->node);
}

/**
 * Function definition to inform the FIB node that its last lock has gone.
 */
static void
sr_tunnel_last_lock_gone (fib_node_t * node)
{
  /*
   * The SR tunnel is a root of the graph. As such
   * it never has children and thus is never locked.
   */
  ASSERT (0);
}

/*
 * Virtual function table registered by SR tunnels
 * for participation in the FIB object graph.
 */
const static fib_node_vft_t sr_fib_vft = {
  .fnv_get = sr_tunnel_fib_node_get,
  .fnv_last_lock = sr_tunnel_last_lock_gone,
  .fnv_back_walk = sr_tunnel_back_walk,
};

/**
 * @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;
  index_t rep;
  u32 ii;

  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...
   */

  /*
   * Construct an mFIB entry for the multicast address,
   * using the rx/tx fib from the first tunnel.
   * There is no RPF information for this address (I need to discuss this with
   * Pablo), so for now accept from anywhere...
   */
  /* *INDENT-OFF* */
  mfib_prefix_t pfx = {
    .fp_proto = FIB_PROTOCOL_IP6,
    .fp_len = 128,
    .fp_grp_addr = {
      .ip6 = *a->multicast_address,
    }
  };
  /* *INDENT-ON* */

  if (a->is_del)
    mfib_table_entry_delete (t->rx_fib_index, &pfx, MFIB_SOURCE_SRv6);
  else
    {
      /*
       * Construct a replicate DPO that will replicate received packets over
       * each tunnel in the policy
       */
      dpo_id_t dpo = DPO_INVALID;

      rep = replicate_create (vec_len (pt->tunnel_indices), DPO_PROTO_IP6);

      vec_foreach_index (ii, pt->tunnel_indices)
      {
	dpo_set (&dpo, sr_dpo_type, DPO_PROTO_IP6, pt->tunnel_indices[ii]);

	replicate_set_bucket (rep, ii, &dpo);
      }

      mfib_table_entry_special_add (t->rx_fib_index,
				    &pfx,
				    MFIB_SOURCE_SRv6,
				    MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF, rep);

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

  rv = ip6_sr_add_del_multicastmap (a);

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

  /* 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_dpo_vft, sr_nodes);
  sr_fib_node_type = fib_node_register_new_type (&sr_fib_vft);

  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 interface address index */
  adj->if_address_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:
 */
