/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * node.c: srp packet processing
 *
 * Copyright (c) 2011 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <vlib/vlib.h>
#include <vnet/ip/ip_packet.h>	/* for ip_csum_fold */
#include <vnet/srp/srp.h>

typedef struct {
  u8 packet_data[32];
} srp_input_trace_t;

static u8 * format_srp_input_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
  srp_input_trace_t * t = va_arg (*va, srp_input_trace_t *);

  s = format (s, "%U", format_srp_header, t->packet_data);

  return s;
}

typedef enum {
  SRP_INPUT_NEXT_ERROR,
  SRP_INPUT_NEXT_ETHERNET_INPUT,
  SRP_INPUT_NEXT_CONTROL,
  SRP_INPUT_N_NEXT,
} srp_input_next_t;

typedef struct {
  u8 next_index;
  u8 buffer_advance;
  u16 error;
} srp_input_disposition_t;

static srp_input_disposition_t srp_input_disposition_by_mode[8] = {
  [SRP_MODE_reserved0] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved1] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved2] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved3] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_keep_alive] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_KEEP_ALIVE_DROPPED,
  },
  [SRP_MODE_data] = {
    .next_index = SRP_INPUT_NEXT_ETHERNET_INPUT,
    .buffer_advance = sizeof (srp_header_t),
  },
  [SRP_MODE_control_pass_to_host] = {
    .next_index = SRP_INPUT_NEXT_CONTROL,
  },
  [SRP_MODE_control_locally_buffered_for_host] = {
    .next_index = SRP_INPUT_NEXT_CONTROL,
  },
};

static uword
srp_input (vlib_main_t * vm,
	   vlib_node_runtime_t * node,
	   vlib_frame_t * from_frame)
{
  vnet_main_t * vnm = vnet_get_main();
  srp_main_t * sm = &srp_main;
  u32 n_left_from, next_index, * from, * to_next;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vlib_trace_frame_buffers_only (vm, node,
				   from,
				   n_left_from,
				   sizeof (from[0]),
				   sizeof (srp_input_trace_t));

  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, sw_if_index0, sw_if_index1;
	  vlib_buffer_t * b0, * b1;
	  u8 next0, next1, error0, error1;
	  srp_header_t * s0, * s1;
	  srp_input_disposition_t * d0, * d1;
	  vnet_hw_interface_t * hi0, * hi1;
	  srp_interface_t * si0, * si1;

	  /* Prefetch next iteration. */
	  {
	    vlib_buffer_t * b2, * b3;

	    b2 = vlib_get_buffer (vm, from[2]);
	    b3 = vlib_get_buffer (vm, from[3]);

	    vlib_prefetch_buffer_header (b2, LOAD);
	    vlib_prefetch_buffer_header (b3, LOAD);

	    CLIB_PREFETCH (b2->data, sizeof (srp_header_t), LOAD);
	    CLIB_PREFETCH (b3->data, sizeof (srp_header_t), 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);

	  s0 = (void *) (b0->data + b0->current_data);
	  s1 = (void *) (b1->data + b1->current_data);

	  /* Data packets are always assigned to side A (outer ring) interface. */
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];

	  hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
	  hi1 = vnet_get_sup_hw_interface (vnm, sw_if_index1);

	  si0 = pool_elt_at_index (sm->interface_pool, hi0->hw_instance);
	  si1 = pool_elt_at_index (sm->interface_pool, hi1->hw_instance);

	  sw_if_index0 = (s0->mode == SRP_MODE_data
			  ? si0->rings[SRP_RING_OUTER].sw_if_index
			  : sw_if_index0);
	  sw_if_index1 = (s1->mode == SRP_MODE_data
			  ? si1->rings[SRP_RING_OUTER].sw_if_index
			  : sw_if_index1);
	    
	  vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index0;
	  vnet_buffer (b1)->sw_if_index[VLIB_RX] = sw_if_index1;

	  d0 = srp_input_disposition_by_mode + s0->mode;
	  d1 = srp_input_disposition_by_mode + s1->mode;

	  next0 = d0->next_index;
	  next1 = d1->next_index;

	  error0 = d0->error;
	  error1 = d1->error;

	  vlib_buffer_advance (b0, d0->buffer_advance);
	  vlib_buffer_advance (b1, d1->buffer_advance);

	  b0->error = node->errors[error0];
	  b1->error = node->errors[error1];

	  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, sw_if_index0;
	  vlib_buffer_t * b0;
	  u8 next0, error0;
	  srp_header_t * s0;
	  srp_input_disposition_t * d0;
	  srp_interface_t * si0;
	  vnet_hw_interface_t * hi0;

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

	  b0 = vlib_get_buffer (vm, bi0);

	  s0 = (void *) (b0->data + b0->current_data);

	  /* Data packets are always assigned to side A (outer ring) interface. */
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];

	  hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);

	  si0 = pool_elt_at_index (sm->interface_pool, hi0->hw_instance);

	  sw_if_index0 = (s0->mode == SRP_MODE_data
			  ? si0->rings[SRP_RING_OUTER].sw_if_index
			  : sw_if_index0);
	    
	  vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index0;

	  d0 = srp_input_disposition_by_mode + s0->mode;

	  next0 = d0->next_index;

	  error0 = d0->error;

	  vlib_buffer_advance (b0, d0->buffer_advance);

	  b0->error = node->errors[error0];

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

static char * srp_error_strings[] = {
#define _(f,s) s,
  foreach_srp_error
#undef _
};

static vlib_node_registration_t srp_input_node = {
  .function = srp_input,
  .name = "srp-input",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .n_errors = SRP_N_ERROR,
  .error_strings = srp_error_strings,

  .n_next_nodes = SRP_INPUT_N_NEXT,
  .next_nodes = {
    [SRP_INPUT_NEXT_ERROR] = "error-drop",
    [SRP_INPUT_NEXT_ETHERNET_INPUT] = "ethernet-input",
    [SRP_INPUT_NEXT_CONTROL] = "srp-control",
  },

  .format_buffer = format_srp_header_with_length,
  .format_trace = format_srp_input_trace,
  .unformat_buffer = unformat_srp_header,
};

static uword
srp_topology_packet (vlib_main_t * vm, u32 sw_if_index, u8 ** contents)
{
  vnet_main_t * vnm = vnet_get_main();
  vnet_hw_interface_t * hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
  srp_topology_header_t * t;
  srp_topology_mac_binding_t * mb;
  u32 nb, nmb;

  t = (void *) *contents;

  nb = clib_net_to_host_u16 (t->n_bytes_of_data_that_follows);
  nmb = (nb - sizeof (t->originator_address)) / sizeof (mb[0]);
  if (vec_len (*contents) < sizeof (t[0]) + nmb * sizeof (mb[0]))
    return SRP_ERROR_TOPOLOGY_BAD_LENGTH;

  /* Fill in our source MAC address. */
  clib_memcpy (t->ethernet.src_address, hi->hw_address, vec_len (hi->hw_address));

  /* Make space for our MAC binding. */
  vec_resize (*contents, sizeof (srp_topology_mac_binding_t));
  t = (void *) *contents;
  t->n_bytes_of_data_that_follows = clib_host_to_net_u16 (nb + sizeof (mb[0]));

  mb = t->bindings + nmb;

  mb->flags =
    ((t->srp.is_inner_ring ? SRP_TOPOLOGY_MAC_BINDING_FLAG_IS_INNER_RING : 0)
     | (/* is wrapped FIXME */ 0));
  clib_memcpy (mb->address, hi->hw_address, vec_len (hi->hw_address));

  t->control.checksum
    = ~ip_csum_fold (ip_incremental_checksum (0, &t->control,
					      vec_len (*contents) - STRUCT_OFFSET_OF (srp_generic_control_header_t, control)));

  {
    vlib_frame_t * f = vlib_get_frame_to_node (vm, hi->output_node_index);
    vlib_buffer_t * b;
    u32 * to_next = vlib_frame_vector_args (f);
    u32 bi;

    bi = vlib_buffer_add_data (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX,
			       /* buffer to append to */ 0,
			       *contents, vec_len (*contents));
    b = vlib_get_buffer (vm, bi);
    vnet_buffer (b)->sw_if_index[VLIB_RX] = vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
    to_next[0] = bi;
    f->n_vectors = 1;
    vlib_put_frame_to_node (vm, hi->output_node_index, f);
  }

  return SRP_ERROR_CONTROL_PACKETS_PROCESSED;
}

typedef uword (srp_control_handler_function_t) (vlib_main_t * vm,
						u32 sw_if_index,
						u8 ** contents);

static uword
srp_control_input (vlib_main_t * vm,
		   vlib_node_runtime_t * node,
		   vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, * from, * to_next;
  vlib_node_runtime_t * error_node;
  static u8 * contents;

  error_node = vlib_node_get_runtime (vm, srp_input_node.index);

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vlib_trace_frame_buffers_only (vm, node,
				   from,
				   n_left_from,
				   sizeof (from[0]),
				   sizeof (srp_input_trace_t));

  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

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

      while (n_left_from > 0 && n_left_to_next > 0)
	{
	  u32 bi0, l2_len0, l3_len0;
	  vlib_buffer_t * b0;
	  u8 next0, error0;
	  srp_generic_control_header_t * s0;

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

	  b0 = vlib_get_buffer (vm, bi0);

	  s0 = (void *) (b0->data + b0->current_data);
	  l2_len0 = vlib_buffer_length_in_chain (vm, b0);
	  l3_len0 = l2_len0 - STRUCT_OFFSET_OF (srp_generic_control_header_t, control);

	  error0 = SRP_ERROR_CONTROL_PACKETS_PROCESSED;

	  error0 = s0->control.version != 0 ? SRP_ERROR_CONTROL_VERSION_NON_ZERO : error0;

	  {
	    u16 save0 = s0->control.checksum;
	    u16 computed0;
	    s0->control.checksum = 0;
	    computed0 = ~ip_csum_fold (ip_incremental_checksum (0, &s0->control, l3_len0));
	    error0 = save0 != computed0 ? SRP_ERROR_CONTROL_BAD_CHECKSUM : error0;
	  }

	  if (error0 == SRP_ERROR_CONTROL_PACKETS_PROCESSED)
	    {
	      static srp_control_handler_function_t * t[SRP_N_CONTROL_PACKET_TYPE] = {
		[SRP_CONTROL_PACKET_TYPE_topology] = srp_topology_packet,
	      };
	      srp_control_handler_function_t * f;

	      f = 0;
	      if (s0->control.type < ARRAY_LEN (t))
		f = t[s0->control.type];

	      if (f)
		{
		  vec_validate (contents, l2_len0 - 1);
		  vlib_buffer_contents (vm, bi0, contents);
		  error0 = f (vm, vnet_buffer (b0)->sw_if_index[VLIB_RX], &contents);
		}
	      else
		error0 = SRP_ERROR_UNKNOWN_CONTROL;
	    }

	  b0->error = error_node->errors[error0];
	  next0 = 0;

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

static vlib_node_registration_t srp_control_input_node = {
  .function = srp_control_input,
  .name = "srp-control",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .n_next_nodes = 1,
  .next_nodes = {
    [0] = "error-drop",
  },

  .format_buffer = format_srp_header_with_length,
  .format_trace = format_srp_input_trace,
  .unformat_buffer = unformat_srp_header,
};

static u8 * format_srp_ips_request_type (u8 * s, va_list * args)
{
  u32 x = va_arg (*args, u32);
  char * t = 0;
  switch (x)
    {
#define _(f,n) case SRP_IPS_REQUEST_##f: t = #f; break;
      foreach_srp_ips_request_type
#undef _
    default:
      return format (s, "unknown 0x%x", x);
    }
  return format (s, "%U", format_c_identifier, t);
}

static u8 * format_srp_ips_status (u8 * s, va_list * args)
{
  u32 x = va_arg (*args, u32);
  char * t = 0;
  switch (x)
    {
#define _(f,n) case SRP_IPS_STATUS_##f: t = #f; break;
      foreach_srp_ips_status
#undef _
    default:
      return format (s, "unknown 0x%x", x);
    }
  return format (s, "%U", format_c_identifier, t);
}

static u8 * format_srp_ips_state (u8 * s, va_list * args)
{
  u32 x = va_arg (*args, u32);
  char * t = 0;
  switch (x)
    {
#define _(f) case SRP_IPS_STATE_##f: t = #f; break;
      foreach_srp_ips_state
#undef _
    default:
      return format (s, "unknown 0x%x", x);
    }
  return format (s, "%U", format_c_identifier, t);
}

static u8 * format_srp_ring (u8 * s, va_list * args)
{
  u32 ring = va_arg (*args, u32);
  return format (s, "%s", ring == SRP_RING_INNER ? "inner" : "outer");
}

static u8 * format_srp_ips_header (u8 * s, va_list * args)
{
  srp_ips_header_t * h = va_arg (*args, srp_ips_header_t *);

  s = format (s, "%U, %U, %U, %s-path",
	      format_srp_ips_request_type, h->request_type,
	      format_ethernet_address, h->originator_address,
	      format_srp_ips_status, h->status,
	      h->is_long_path ? "long" : "short");

  return s;
}

static u8 * format_srp_interface (u8 * s, va_list * args)
{
  srp_interface_t * si = va_arg (*args, srp_interface_t *);
  srp_interface_ring_t * ir;

  s = format (s, "address %U, IPS state %U",
	      format_ethernet_address, si->my_address,
	      format_srp_ips_state, si->current_ips_state);
  for (ir = si->rings; ir < si->rings + SRP_N_RING; ir++)
    if (ir->rx_neighbor_address_valid)
      s = format (s, ", %U neighbor %U",
		  format_srp_ring, ir->ring,
		  format_ethernet_address, ir->rx_neighbor_address);

  return s;
}

u8 * format_srp_device (u8 * s, va_list * args)
{
  u32 hw_if_index = va_arg (*args, u32);
  CLIB_UNUSED (int verbose) = va_arg (*args, int);
  vnet_main_t * vnm = vnet_get_main();
  srp_main_t * sm = &srp_main;
  vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, hw_if_index);
  srp_interface_t * si = pool_elt_at_index (sm->interface_pool, hi->hw_instance);
  return format (s, "%U", format_srp_interface, si);
}

always_inline srp_interface_t *
srp_get_interface (u32 sw_if_index, srp_ring_type_t * ring)
{
  vnet_main_t * vnm = vnet_get_main();
  srp_main_t * sm = &srp_main;
  vnet_hw_interface_t * hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
  srp_interface_t * si;

  ASSERT (hi->hw_class_index == srp_hw_interface_class.index);
  si = pool_elt_at_index (sm->interface_pool, hi->hw_instance);

  ASSERT (si->rings[SRP_RING_INNER].hw_if_index == hi->hw_if_index
	  || si->rings[SRP_RING_OUTER].hw_if_index == hi->hw_if_index);
  if (ring)
    *ring =
      (hi->hw_if_index == si->rings[SRP_RING_INNER].hw_if_index
       ? SRP_RING_INNER
       : SRP_RING_OUTER);

  return si;
}

static void init_ips_packet (srp_interface_t * si,
			     srp_ring_type_t tx_ring,
			     srp_ips_header_t * i)
{
  memset (i, 0, sizeof (i[0]));

  i->srp.ttl = 1;
  i->srp.is_inner_ring = tx_ring;
  i->srp.priority = 7;
  i->srp.mode = SRP_MODE_control_locally_buffered_for_host;
  srp_header_compute_parity (&i->srp);

  clib_memcpy (&i->ethernet.src_address, &si->my_address, sizeof (si->my_address));
  i->ethernet.type = clib_host_to_net_u16 (ETHERNET_TYPE_SRP_CONTROL);

  /* Checksum will be filled in later. */
  i->control.version = 0;
  i->control.type = SRP_CONTROL_PACKET_TYPE_ips;
  i->control.ttl = 255;

  clib_memcpy (&i->originator_address, &si->my_address, sizeof (si->my_address));
}

static void tx_ips_packet (srp_interface_t * si,
			   srp_ring_type_t tx_ring,
			   srp_ips_header_t * i)
{
  srp_main_t * sm = &srp_main;
  vnet_main_t * vnm = vnet_get_main();
  vlib_main_t * vm = sm->vlib_main;
  vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, si->rings[tx_ring].hw_if_index);
  vlib_frame_t * f;
  vlib_buffer_t * b;
  u32 * to_next, bi;

  if (! vnet_sw_interface_is_admin_up (vnm, hi->sw_if_index))
    return;
  if (hi->hw_class_index != srp_hw_interface_class.index)
    return;

  i->control.checksum
    = ~ip_csum_fold (ip_incremental_checksum (0, &i->control,
					      sizeof (i[0]) - STRUCT_OFFSET_OF (srp_ips_header_t, control)));

  bi = vlib_buffer_add_data (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX,
			     /* buffer to append to */ 0,
			     i, sizeof (i[0]));

  /* FIXME trace. */
  if (0)
    clib_warning ("%U %U",
		  format_vnet_sw_if_index_name, vnm, hi->sw_if_index,
		  format_srp_ips_header, i);

  b = vlib_get_buffer (vm, bi);
  vnet_buffer (b)->sw_if_index[VLIB_RX] = vnet_buffer (b)->sw_if_index[VLIB_TX] = hi->sw_if_index;

  f = vlib_get_frame_to_node (vm, hi->output_node_index);
  to_next = vlib_frame_vector_args (f);
  to_next[0] = bi;
  f->n_vectors = 1;
  vlib_put_frame_to_node (vm, hi->output_node_index, f);
}

static void serialize_srp_interface_state_msg (serialize_main_t * m, va_list * va)
{
  srp_interface_t * si = va_arg (*va, srp_interface_t *);
  srp_main_t * sm = &srp_main;
  int r;

  ASSERT (! pool_is_free (sm->interface_pool, si));
  serialize_integer (m, si - sm->interface_pool, sizeof (u32));
  serialize_likely_small_unsigned_integer (m, si->current_ips_state);
  for (r = 0; r < SRP_N_RING; r++)
    {
      srp_interface_ring_t * ir = &si->rings[r];
      void * p;
      serialize_likely_small_unsigned_integer (m, ir->rx_neighbor_address_valid);
      if (ir->rx_neighbor_address_valid)
	{
	  p = serialize_get (m, sizeof (ir->rx_neighbor_address));
	  clib_memcpy (p, ir->rx_neighbor_address, sizeof (ir->rx_neighbor_address));
	}
      serialize_likely_small_unsigned_integer (m, ir->waiting_to_restore);
      if (ir->waiting_to_restore)
	serialize (m, serialize_f64, ir->wait_to_restore_start_time);
    }
}

static void unserialize_srp_interface_state_msg (serialize_main_t * m, va_list * va)
{
  CLIB_UNUSED (mc_main_t * mcm) = va_arg (*va, mc_main_t *);
  srp_main_t * sm = &srp_main;
  srp_interface_t * si;
  u32 si_index, r;

  unserialize_integer (m, &si_index, sizeof (u32));
  si = pool_elt_at_index (sm->interface_pool, si_index);
  si->current_ips_state = unserialize_likely_small_unsigned_integer (m);
  for (r = 0; r < SRP_N_RING; r++)
    {
      srp_interface_ring_t * ir = &si->rings[r];
      void * p;
      ir->rx_neighbor_address_valid = unserialize_likely_small_unsigned_integer (m);
      if (ir->rx_neighbor_address_valid)
	{
	  p = unserialize_get (m, sizeof (ir->rx_neighbor_address));
	  clib_memcpy (ir->rx_neighbor_address, p, sizeof (ir->rx_neighbor_address));
	}
      ir->waiting_to_restore = unserialize_likely_small_unsigned_integer (m);
      if (ir->waiting_to_restore)
	unserialize (m, unserialize_f64, &ir->wait_to_restore_start_time);
    }
}

MC_SERIALIZE_MSG (srp_interface_state_msg, static) = {
  .name = "vnet_srp_interface_state",
  .serialize = serialize_srp_interface_state_msg,
  .unserialize = unserialize_srp_interface_state_msg,
};

static int requests_switch (srp_ips_request_type_t r)
{
  static u8 t[16] = {
    [SRP_IPS_REQUEST_forced_switch] = 1,
    [SRP_IPS_REQUEST_manual_switch] = 1,
    [SRP_IPS_REQUEST_signal_fail] = 1,
    [SRP_IPS_REQUEST_signal_degrade] = 1,
  };
  return (int) r < ARRAY_LEN (t) ? t[r] : 0;
}

/* Called when an IPS control packet is received on given interface. */
void srp_ips_rx_packet (u32 sw_if_index, srp_ips_header_t * h)
{
  vnet_main_t * vnm = vnet_get_main();
  vlib_main_t * vm = srp_main.vlib_main;
  srp_ring_type_t rx_ring;
  srp_interface_t * si = srp_get_interface (sw_if_index, &rx_ring);
  srp_interface_ring_t * ir = &si->rings[rx_ring];
  int si_needs_broadcast = 0;

  /* FIXME trace. */
  if (0)
    clib_warning ("%U %U %U",
		  format_time_interval, "h:m:s:u", vlib_time_now (vm),
		  format_vnet_sw_if_index_name, vnm, sw_if_index,
		  format_srp_ips_header, h);

  /* Ignore self-generated IPS packets. */
  if (! memcmp (h->originator_address, si->my_address, sizeof (h->originator_address)))
    goto done;

  /* Learn neighbor address from short path messages. */
  if (! h->is_long_path)
    {
      if (ir->rx_neighbor_address_valid
	  && memcmp (ir->rx_neighbor_address, h->originator_address, sizeof (ir->rx_neighbor_address)))
	{
	  ASSERT (0);
	}
      ir->rx_neighbor_address_valid = 1;
      clib_memcpy (ir->rx_neighbor_address, h->originator_address, sizeof (ir->rx_neighbor_address));
    }

  switch (si->current_ips_state)
    {
    case SRP_IPS_STATE_idle:
      /* Received {REQ,NEIGHBOR,W,S} in idle state: wrap. */
      if (requests_switch (h->request_type)
	  && ! h->is_long_path
	  && h->status == SRP_IPS_STATUS_wrapped)
	{
	  srp_ips_header_t to_tx[2];

	  si_needs_broadcast = 1;
	  si->current_ips_state = SRP_IPS_STATE_wrapped;
	  si->hw_wrap_function (si->rings[SRP_SIDE_A].hw_if_index, /* enable_wrap */ 1);
	  si->hw_wrap_function (si->rings[SRP_SIDE_B].hw_if_index, /* enable_wrap */ 1);

	  init_ips_packet (si, rx_ring ^ 0, &to_tx[0]);
	  to_tx[0].request_type = SRP_IPS_REQUEST_idle;
	  to_tx[0].status = SRP_IPS_STATUS_wrapped;
	  to_tx[0].is_long_path = 0;
	  tx_ips_packet (si, rx_ring ^ 0, &to_tx[0]);

	  init_ips_packet (si, rx_ring ^ 1, &to_tx[1]);
	  to_tx[1].request_type = h->request_type;
	  to_tx[1].status = SRP_IPS_STATUS_wrapped;
	  to_tx[1].is_long_path = 1;
	  tx_ips_packet (si, rx_ring ^ 1, &to_tx[1]);
	}
      break;

    case SRP_IPS_STATE_wrapped:
      if (! h->is_long_path
	  && h->request_type == SRP_IPS_REQUEST_idle
	  && h->status == SRP_IPS_STATUS_idle)
	{
	  si_needs_broadcast = 1;
	  si->current_ips_state = SRP_IPS_STATE_idle;
	  si->hw_wrap_function (si->rings[SRP_SIDE_A].hw_if_index, /* enable_wrap */ 0);
	  si->hw_wrap_function (si->rings[SRP_SIDE_B].hw_if_index, /* enable_wrap */ 0);
	}
      break;

    case SRP_IPS_STATE_pass_thru:
      /* FIXME */
      break;

    default:
      abort ();
      break;
    }

 done:
  if (vm->mc_main && si_needs_broadcast)
    mc_serialize (vm->mc_main, &srp_interface_state_msg, si);
}

/* Preform local IPS request on given interface. */
void srp_ips_local_request (u32 sw_if_index, srp_ips_request_type_t request)
{
  vnet_main_t * vnm = vnet_get_main();
  srp_main_t * sm = &srp_main;
  vlib_main_t * vm = sm->vlib_main;
  srp_ring_type_t rx_ring;
  srp_interface_t * si = srp_get_interface (sw_if_index, &rx_ring);
  srp_interface_ring_t * ir = &si->rings[rx_ring];
  int si_needs_broadcast = 0;

  if (request == SRP_IPS_REQUEST_wait_to_restore)
    {
      if (si->current_ips_state != SRP_IPS_STATE_wrapped)
	return;
      if (! ir->waiting_to_restore)
	{
	  ir->wait_to_restore_start_time = vlib_time_now (sm->vlib_main);
	  ir->waiting_to_restore = 1;
	  si_needs_broadcast = 1;
	}
    }
  else
    {
      /* FIXME handle local signal fail. */
      si_needs_broadcast = ir->waiting_to_restore;
      ir->wait_to_restore_start_time = 0;
      ir->waiting_to_restore = 0;
    }

  /* FIXME trace. */
  if (0)
    clib_warning ("%U %U",
		  format_vnet_sw_if_index_name, vnm, sw_if_index,
		  format_srp_ips_request_type, request);

  if (vm->mc_main && si_needs_broadcast)
    mc_serialize (vm->mc_main, &srp_interface_state_msg, si);
}

static void maybe_send_ips_message (srp_interface_t * si)
{
  srp_main_t * sm = &srp_main;
  srp_ips_header_t to_tx[2];
  srp_ring_type_t rx_ring = SRP_RING_OUTER;
  srp_interface_ring_t * r0 = &si->rings[rx_ring ^ 0];
  srp_interface_ring_t * r1 = &si->rings[rx_ring ^ 1];
  f64 now = vlib_time_now (sm->vlib_main);

  if (! si->ips_process_enable)
    return;

  if (si->current_ips_state == SRP_IPS_STATE_wrapped
      && r0->waiting_to_restore
      && r1->waiting_to_restore
      && now >= r0->wait_to_restore_start_time + si->config.wait_to_restore_idle_delay
      && now >= r1->wait_to_restore_start_time + si->config.wait_to_restore_idle_delay)
    {
      si->current_ips_state = SRP_IPS_STATE_idle;
      r0->waiting_to_restore = r1->waiting_to_restore = 0;
      r0->wait_to_restore_start_time = r1->wait_to_restore_start_time = 0;
    }

  if (si->current_ips_state != SRP_IPS_STATE_idle)
    return;

  init_ips_packet (si, rx_ring ^ 0, &to_tx[0]);
  init_ips_packet (si, rx_ring ^ 1, &to_tx[1]);

  if (si->current_ips_state == SRP_IPS_STATE_idle)
    {
      to_tx[0].request_type = to_tx[1].request_type = SRP_IPS_REQUEST_idle;
      to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_idle;
      to_tx[0].is_long_path = to_tx[1].is_long_path = 0;
    }

  else if (si->current_ips_state == SRP_IPS_STATE_wrapped)
    {
      to_tx[0].request_type =
	(si->rings[rx_ring ^ 0].waiting_to_restore
	 ? SRP_IPS_REQUEST_wait_to_restore
	 : SRP_IPS_REQUEST_signal_fail);
      to_tx[1].request_type =
	(si->rings[rx_ring ^ 1].waiting_to_restore
	 ? SRP_IPS_REQUEST_wait_to_restore
	 : SRP_IPS_REQUEST_signal_fail);
      to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_wrapped;
      to_tx[0].is_long_path = 0;
      to_tx[1].is_long_path = 1;
    }

  tx_ips_packet (si, rx_ring ^ 0, &to_tx[0]);
  tx_ips_packet (si, rx_ring ^ 1, &to_tx[1]);
}

static uword
srp_ips_process (vlib_main_t * vm,
		 vlib_node_runtime_t * rt,
		 vlib_frame_t * f)
{
  srp_main_t * sm = &srp_main;
  srp_interface_t * si;

  while (1)
    {
      pool_foreach (si, sm->interface_pool, ({
	maybe_send_ips_message (si);
      }));
      vlib_process_suspend (vm, 1.0);
    }

  return 0;
}

vlib_node_registration_t srp_ips_process_node = {
    .function = srp_ips_process,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "srp-ips-process",
    .state = VLIB_NODE_STATE_DISABLED,
};

static clib_error_t * srp_init (vlib_main_t * vm)
{
  srp_main_t * sm = &srp_main;

  sm->default_data_ttl = 255;
  sm->vlib_main = vm;
  vlib_register_node (vm, &srp_ips_process_node);
  vlib_register_node (vm, &srp_input_node);
  vlib_register_node (vm, &srp_control_input_node);
  srp_setup_node (vm, srp_input_node.index);

  return 0;
}

VLIB_INIT_FUNCTION (srp_init);
