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

#include <vnet/vnet.h>
#include <vnet/mpls/mpls.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/mpls_fib.h>

const static char* mpls_eos_bit_names[] = MPLS_EOS_BITS;

mpls_main_t mpls_main;

u8 * format_mpls_unicast_label (u8 * s, va_list * args)
{
  mpls_label_t label = va_arg (*args, mpls_label_t);

  switch (label) {
  case MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL:
      s = format (s, "%s", MPLS_IETF_IPV4_EXPLICIT_NULL_STRING);
      break;
  case MPLS_IETF_ROUTER_ALERT_LABEL:
      s = format (s, "%s", MPLS_IETF_ROUTER_ALERT_STRING);
      break;
  case MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL:
      s = format (s, "%s", MPLS_IETF_IPV6_EXPLICIT_NULL_STRING);
      break;
  case MPLS_IETF_IMPLICIT_NULL_LABEL:
      s = format (s, "%s", MPLS_IETF_IMPLICIT_NULL_STRING);
      break;
  case MPLS_IETF_ELI_LABEL:
      s = format (s, "%s", MPLS_IETF_ELI_STRING);
      break;
  case MPLS_IETF_GAL_LABEL:
      s = format (s, "%s", MPLS_IETF_GAL_STRING);
      break;
  default:
      s = format (s, "%d", label);
      break;
  }
  return s;
}

uword unformat_mpls_unicast_label (unformat_input_t * input, va_list * args)
{
  mpls_label_t *label = va_arg (*args, mpls_label_t*);
  
  if (unformat (input, MPLS_IETF_IPV4_EXPLICIT_NULL_STRING))
      *label = MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL;
  else if (unformat (input, MPLS_IETF_IPV6_EXPLICIT_NULL_STRING))
      *label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL;
  else if (unformat (input, MPLS_IETF_ROUTER_ALERT_STRING))
      *label = MPLS_IETF_ROUTER_ALERT_LABEL;
  else if (unformat (input, MPLS_IETF_IMPLICIT_NULL_STRING))
      *label = MPLS_IETF_IMPLICIT_NULL_LABEL;
  else if (unformat (input, "%d", label))
      ;

  return (1);
}

u8 * format_mpls_eos_bit (u8 * s, va_list * args)
{
  mpls_eos_bit_t eb = va_arg (*args, mpls_eos_bit_t);

  ASSERT(eb <= MPLS_EOS);

  s = format(s, "%s", mpls_eos_bit_names[eb]);

  return (s);
}

u8 * format_mpls_header (u8 * s, va_list * args)
{
  mpls_unicast_header_t hdr = va_arg (*args, mpls_unicast_header_t);

  return (format(s, "[%U:%d:%d:%U]",
		 format_mpls_unicast_label, 
		 vnet_mpls_uc_get_label(hdr.label_exp_s_ttl),
		 vnet_mpls_uc_get_ttl(hdr.label_exp_s_ttl),
		 vnet_mpls_uc_get_exp(hdr.label_exp_s_ttl),
		 format_mpls_eos_bit,
		 vnet_mpls_uc_get_s(hdr.label_exp_s_ttl)));
}

uword
unformat_mpls_header (unformat_input_t * input, va_list * args)
{
  u8 ** result = va_arg (*args, u8 **);
  mpls_unicast_header_t _h, * h = &_h;
  u32 label, label_exp_s_ttl;

  if (! unformat (input, "MPLS %d", &label))
    return 0;

  label_exp_s_ttl = (label<<12) | (1<<8) /* s-bit */ | 0xFF;
  h->label_exp_s_ttl = clib_host_to_net_u32 (label_exp_s_ttl);

  /* Add gre, mpls headers to result. */
  {
    void * p;
    u32 h_n_bytes = sizeof (h[0]);

    vec_add2 (*result, p, h_n_bytes);
    clib_memcpy (p, h, h_n_bytes);
  }

  return 1;
}

uword
unformat_mpls_label_net_byte_order (unformat_input_t * input,
                                        va_list * args)
{
  u32 * result = va_arg (*args, u32 *);
  u32 label;

  if (!unformat (input, "MPLS: label %d", &label))
    return 0;

  label = (label<<12) | (1<<8) /* s-bit set */ | 0xFF /* ttl */;

  *result = clib_host_to_net_u32 (label);
  return 1;
}

u8 * format_mpls_unicast_header_host_byte_order (u8 * s, va_list * args)
{
  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
  u32 label = h->label_exp_s_ttl;
  
  s = format (s, "label %d exp %d, s %d, ttl %d",
              vnet_mpls_uc_get_label (label),
              vnet_mpls_uc_get_exp (label),
              vnet_mpls_uc_get_s (label),
              vnet_mpls_uc_get_ttl (label));
  return s;
}

u8 * format_mpls_unicast_header_net_byte_order (u8 * s, va_list * args)
{
  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
  mpls_unicast_header_t h_host;

  h_host.label_exp_s_ttl = clib_net_to_host_u32 (h->label_exp_s_ttl);

  return format (s, "%U", format_mpls_unicast_header_host_byte_order,
                 &h_host);
}

int
mpls_dest_cmp(void * a1, void * a2)
{
  show_mpls_fib_t * r1 = a1;
  show_mpls_fib_t * r2 = a2;

  return clib_net_to_host_u32(r1->dest) - clib_net_to_host_u32(r2->dest);
}

int
mpls_fib_index_cmp(void * a1, void * a2)
{
  show_mpls_fib_t * r1 = a1;
  show_mpls_fib_t * r2 = a2;

  return r1->fib_index - r2->fib_index;
}

int
mpls_label_cmp(void * a1, void * a2)
{
  show_mpls_fib_t * r1 = a1;
  show_mpls_fib_t * r2 = a2;

  return r1->label - r2->label;
}

static clib_error_t *
vnet_mpls_local_label (vlib_main_t * vm,
                       unformat_input_t * input,
                       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, * line_input = &_line_input;
  fib_route_path_t *rpaths = NULL, rpath;
  u32 table_id, is_del, is_ip;
  mpls_label_t local_label;
  mpls_label_t out_label;
  clib_error_t * error;
  mpls_eos_bit_t eos;
  vnet_main_t * vnm;
  fib_prefix_t pfx;

  vnm = vnet_get_main();
  error = NULL;
  is_ip = 0;
  table_id = 0;
  eos = MPLS_EOS;
  is_del = 0;
  local_label = MPLS_LABEL_INVALID;
  memset(&pfx, 0, sizeof(pfx));

   /* Get a line of input. */
  if (! unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      memset(&rpath, 0, sizeof(rpath));

      if (unformat (line_input, "table %d", &table_id))
	;
      else if (unformat (line_input, "del"))
	is_del = 1;
      else if (unformat (line_input, "add"))
	is_del = 0;
      else if (unformat (line_input, "eos"))
	pfx.fp_eos = MPLS_EOS;
      else if (unformat (line_input, "non-eos"))
	pfx.fp_eos = MPLS_NON_EOS;
      else if (unformat (line_input, "%U/%d",
			 unformat_ip4_address,
			 &pfx.fp_addr.ip4,
			 &pfx.fp_len))
      {
	  pfx.fp_proto = FIB_PROTOCOL_IP4;
          is_ip = 1;
      }
      else if (unformat (line_input, "%U/%d",
			 unformat_ip6_address,
			 &pfx.fp_addr.ip6,
			 &pfx.fp_len))
      {
	  pfx.fp_proto = FIB_PROTOCOL_IP6;
          is_ip = 1;
      }
      else if (unformat (line_input, "via %U %U weight %u",
			 unformat_ip4_address,
			 &rpath.frp_addr.ip4,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index,
			 &rpath.frp_weight))
      {
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	  vec_add1(rpaths, rpath);
      }

      else if (unformat (line_input, "via %U %U weight %u",
			 unformat_ip6_address,
			 &rpath.frp_addr.ip6,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index,
			 &rpath.frp_weight))
      {
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	  vec_add1(rpaths, rpath);
      }

      else if (unformat (line_input, "via %U %U",
			 unformat_ip4_address,
 			 &rpath.frp_addr.ip4,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index))
      {
	  rpath.frp_weight = 1;
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	  vec_add1(rpaths, rpath);
      }
			 
      else if (unformat (line_input, "via %U %U",
			 unformat_ip6_address,
 			 &rpath.frp_addr.ip6,
			 unformat_vnet_sw_interface, vnm,
			 &rpath.frp_sw_if_index))
      {
	  rpath.frp_weight = 1;
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "via %U next-hop-table %d",
			 unformat_ip4_address,
  			 &rpath.frp_addr.ip4,
			 &rpath.frp_fib_index))
      {
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "via %U next-hop-table %d",
			 unformat_ip6_address,
  			 &rpath.frp_addr.ip6,
			 &rpath.frp_fib_index))
      {
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "via %U",
			 unformat_ip4_address,
  			 &rpath.frp_addr.ip4))
      {
	  /*
	   * the recursive next-hops are by default in the same table
	   * as the prefix
	   */
	  rpath.frp_fib_index = table_id;
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP4;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "via %U",
			 unformat_ip6_address,
  			 &rpath.frp_addr.ip6))
      {
	  rpath.frp_fib_index = table_id;
	  rpath.frp_weight = 1;
	  rpath.frp_sw_if_index = ~0;
	  rpath.frp_proto = FIB_PROTOCOL_IP6;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "%d", &local_label))
	;
      else if (unformat (line_input,
			 "ip4-lookup-in-table %d",
			 &rpath.frp_fib_index))
      {
          rpath.frp_proto = FIB_PROTOCOL_IP4;
          rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
	  pfx.fp_payload_proto = DPO_PROTO_IP4;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input,
			 "ip6-lookup-in-table %d",
			 &rpath.frp_fib_index))
      {
          rpath.frp_proto = FIB_PROTOCOL_IP6;
          rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
	  vec_add1(rpaths, rpath);
	  pfx.fp_payload_proto = DPO_PROTO_IP6;
      }
      else if (unformat (line_input,
			 "mpls-lookup-in-table %d",
			 &rpath.frp_fib_index))
      {
          rpath.frp_proto = FIB_PROTOCOL_MPLS;
          rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
	  pfx.fp_payload_proto = DPO_PROTO_MPLS;
	  vec_add1(rpaths, rpath);
      }
      else if (unformat (line_input, "out-label %U",
                         unformat_mpls_unicast_label,
			 &out_label))
      {
	  if (vec_len(rpaths) == 0)
	  {
	      error = clib_error_return(0 , "Paths then labels");
	      goto done;
	  }
	  vec_add1(rpaths[vec_len(rpaths)-1].frp_label_stack, out_label);
      }
      else
      {
          error = clib_error_return (0, "unkown input: %U",
                                     format_unformat_error, line_input);
          goto done;
      }

    }

  if (MPLS_LABEL_INVALID == local_label)
  {
      error = clib_error_return (0, "local-label required: %U",
				 format_unformat_error, input);
      goto done;
  }


  if (is_ip)
  {
      u32 fib_index = fib_table_find(pfx.fp_proto, table_id);

      if (FIB_NODE_INDEX_INVALID == fib_index)
      {
          error = clib_error_return (0, "%U table-id %d does not exist",
                                     format_fib_protocol, pfx.fp_proto, table_id);
          goto done;
      }

      if (is_del)
      {
          fib_table_entry_local_label_remove(fib_index, &pfx, local_label);
      }
      else
      {
          fib_table_entry_local_label_add(fib_index, &pfx, local_label);
      }
  }
  else
  {
      fib_node_index_t lfe, fib_index;
      u32 fi;

      if (NULL == rpaths)
      {
	  error = clib_error_return(0 , "no paths");
	  goto done;
      }

      pfx.fp_proto = FIB_PROTOCOL_MPLS;
      pfx.fp_len = 21;
      pfx.fp_label = local_label;
      pfx.fp_payload_proto = fib_proto_to_dpo(rpaths[0].frp_proto);

      /*
       * the CLI parsing stored table Ids, swap to FIB indicies
       */
      if (FIB_NODE_INDEX_INVALID == rpath.frp_sw_if_index)
      {
	  fi = fib_table_id_find_fib_index(dpo_proto_to_fib(pfx.fp_payload_proto),
					   rpaths[0].frp_fib_index);

	  if (~0 == fi)
	  {
	      error = clib_error_return(0 , "%U Via table %d does not exist",
					format_dpo_proto, pfx.fp_payload_proto,
					rpaths[0].frp_fib_index);
	      goto done;
	  }
	  rpaths[0].frp_fib_index = fi;
      }

      fib_index = mpls_fib_index_from_table_id(table_id);

      if (FIB_NODE_INDEX_INVALID == fib_index)
      {
          error = clib_error_return (0, "MPLS table-id %d does not exist",
                                     table_id);
          goto done;
      }

      lfe = fib_table_entry_path_add2(fib_index,
				      &pfx,
				      FIB_SOURCE_CLI,
				      FIB_ENTRY_FLAG_NONE,
				      rpaths);

      if (FIB_NODE_INDEX_INVALID == lfe)
      {
          error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d",
                                     format_mpls_unicast_label, local_label,
                                     format_mpls_eos_bit, eos,
                                     table_id);
          goto done;
      }
  }

done:
  unformat_free (line_input);

  return error;
}

VLIB_CLI_COMMAND (mpls_local_label_command, static) = {
  .path = "mpls local-label",
  .function = vnet_mpls_local_label,
  .short_help = "Create/Delete MPL local labels",
};

int
mpls_fib_reset_labels (u32 fib_id)
{
  // FIXME
  return 0;
}

static clib_error_t *
mpls_init (vlib_main_t * vm)
{
  mpls_main_t * mm = &mpls_main;
  clib_error_t * error;

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

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

  return vlib_call_init_function (vm, mpls_input_init);
}

VLIB_INIT_FUNCTION (mpls_init);

mpls_main_t * mpls_get_main (vlib_main_t * vm)
{
  vlib_call_init_function (vm, mpls_init);
  return &mpls_main;
}

