/*
 * Copyright (c) 2011-2016 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 LLDP CLI handling
 *
 */
#include <vnet/lisp-cp/lisp_types.h>
#include <vnet/lldp/lldp.h>
#include <vnet/lldp/lldp_node.h>

#ifndef ETHER_ADDR_LEN
#include <net/ethernet.h>
#endif

static clib_error_t *
lldp_cfg_err_to_clib_err (lldp_cfg_err_t e)
{

  switch (e)
    {
    case lldp_ok:
      return 0;
    case lldp_not_supported:
      return clib_error_return (0, "not supported");
    case lldp_invalid_arg:
      return clib_error_return (0, "invalid argument");
    }
  return 0;
}

lldp_cfg_err_t
lldp_cfg_intf_set (u32 hw_if_index, u8 ** port_desc, int enable)
{
  lldp_main_t *lm = &lldp_main;
  vnet_main_t *vnm = lm->vnet_main;
  ethernet_main_t *em = &ethernet_main;
  const vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  const ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index);

  if (!eif)
    {
      return lldp_not_supported;
    }

  if (enable)
    {
      lldp_intf_t *n = lldp_get_intf (lm, hw_if_index);
      if (n)
	{
	  /* already enabled */
	  return lldp_ok;
	}
      n = lldp_create_intf (lm, hw_if_index);

      if (port_desc && *port_desc)
	{
	  n->port_desc = *port_desc;
	  *port_desc = NULL;
	}

      const vnet_sw_interface_t *sw =
	vnet_get_sw_interface (lm->vnet_main, hi->sw_if_index);
      if (sw->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP |
		       VNET_SW_INTERFACE_FLAG_BOND_SLAVE))
	{
	  lldp_schedule_intf (lm, n);
	}
    }
  else
    {
      lldp_intf_t *n = lldp_get_intf (lm, hi->sw_if_index);
      lldp_delete_intf (lm, n);
    }

  return lldp_ok;
}

static clib_error_t *
lldp_intf_cmd (vlib_main_t * vm, unformat_input_t * input,
	       vlib_cli_command_t * cmd)
{
  lldp_main_t *lm = &lldp_main;
  vnet_main_t *vnm = lm->vnet_main;
  u32 sw_if_index = (u32) ~ 0;
  int enable = 1;
  u8 *port_desc = NULL;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "sw_if_index %d", &sw_if_index))
	;
      if (unformat
	  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
	;
      else if (unformat (input, "disable"))
	enable = 0;
      else if (unformat (input, "port-desc %s", &port_desc))
	;
      else
	break;
    }

  if (sw_if_index == (u32) ~ 0)
    return clib_error_return (0, "Interface name is invalid!");

  return lldp_cfg_err_to_clib_err (lldp_cfg_intf_set (sw_if_index,
						      &port_desc, enable));
}

lldp_cfg_err_t
lldp_cfg_set (u8 ** host, int hold_time, int tx_interval)
{
  lldp_main_t *lm = &lldp_main;
  int reschedule = 0;
  if (host && *host)
    {
      vec_free (lm->sys_name);
      lm->sys_name = *host;
      *host = NULL;
    }
  if (hold_time)
    {
      if (hold_time < LLDP_MIN_TX_HOLD || hold_time > LLDP_MAX_TX_HOLD)
	{
	  return lldp_invalid_arg;
	}
      if (lm->msg_tx_hold != hold_time)
	{
	  lm->msg_tx_hold = hold_time;
	  reschedule = 1;
	}
    }
  if (tx_interval)
    {
      if (tx_interval < LLDP_MIN_TX_INTERVAL ||
	  tx_interval > LLDP_MAX_TX_INTERVAL)
	{
	  return lldp_invalid_arg;
	}
      if (lm->msg_tx_interval != tx_interval)
	{
	  reschedule = 1;
	  lm->msg_tx_interval = tx_interval;
	}
    }
  if (reschedule)
    {
      vlib_process_signal_event (lm->vlib_main, lm->lldp_process_node_index,
				 LLDP_EVENT_RESCHEDULE, 0);
    }
  return lldp_ok;
}

static clib_error_t *
lldp_cfg_cmd (vlib_main_t * vm, unformat_input_t * input,
	      vlib_cli_command_t * cmd)
{
  int hold_time = 0;
  int tx_interval = 0;
  u8 *host = NULL;
  clib_error_t *ret = NULL;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "system-name %s", &host))
	{
	}
      else if (unformat (input, "tx-hold %d", &hold_time))
	{
	  if (hold_time < LLDP_MIN_TX_HOLD || hold_time > LLDP_MAX_TX_HOLD)
	    {
	      ret =
		clib_error_return (0,
				   "invalid tx-hold `%d' (out of range <%d,%d>)",
				   hold_time, LLDP_MIN_TX_HOLD,
				   LLDP_MAX_TX_HOLD);
	      goto out;
	    }
	}
      else if (unformat (input, "tx-interval %d", &tx_interval))
	{
	  if (tx_interval < LLDP_MIN_TX_INTERVAL ||
	      tx_interval > LLDP_MAX_TX_INTERVAL)
	    {
	      ret =
		clib_error_return (0,
				   "invalid tx-interval `%d' (out of range <%d,%d>)",
				   tx_interval, LLDP_MIN_TX_INTERVAL,
				   LLDP_MAX_TX_INTERVAL);
	      goto out;
	    }
	}
      else
	{
	  break;
	}
    }
  ret =
    lldp_cfg_err_to_clib_err (lldp_cfg_set (&host, hold_time, tx_interval));
out:
  vec_free (host);
  return ret;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND(set_interface_lldp_cmd, static) = {
  .path = "set interface lldp",
  .short_help = "set interface lldp <interface> | sw_if_index <idx>"
                " [port-desc <string>] [disable]",
  .function = lldp_intf_cmd,
};

VLIB_CLI_COMMAND(set_lldp_cmd, static) = {
  .path = "set lldp",
  .short_help = "set lldp [system-name <string>] [tx-hold <value>] "
                "[tx-interval <value>]",
  .function = lldp_cfg_cmd,
};
/* *INDENT-ON* */

static const char *
lldp_chassis_id_subtype_str (lldp_chassis_id_subtype_t t)
{
  switch (t)
    {
#define F(num, val, str) \
  case num:              \
    return str;
      foreach_chassis_id_subtype (F)
#undef F
    }
  return "unknown chassis subtype";
}

static const char *
lldp_port_id_subtype_str (lldp_port_id_subtype_t t)
{
  switch (t)
    {
#define F(num, val, str) \
  case num:              \
    return str;
      foreach_port_id_subtype (F)
#undef F
    }
  return "unknown port subtype";
}

/*
 * format port id subtype&value
 *
 * @param va - 1st argument - unsigned - port id subtype
 * @param va - 2nd argument - u8* - port id
 * @param va - 3rd argument - unsigned - port id length
 * @param va - 4th argument - int - 1 for detailed output, 0 for simple
 */
u8 *
format_lldp_port_id (u8 * s, va_list * va)
{
  const lldp_port_id_subtype_t subtype = va_arg (*va, unsigned);
  const u8 *id = va_arg (*va, u8 *);
  const unsigned len = va_arg (*va, unsigned);
  const int detail = va_arg (*va, int);
  if (!id)
    {
      return s;
    }
  switch (subtype)
    {
    case LLDP_PORT_ID_SUBTYPE_NAME (intf_alias):
      /* fallthrough */
    case LLDP_PORT_ID_SUBTYPE_NAME (port_comp):
      /* fallthrough */
    case LLDP_PORT_ID_SUBTYPE_NAME (local):
      /* fallthrough */
    case LLDP_PORT_ID_SUBTYPE_NAME (intf_name):
      if (detail)
	{
	  s = format (s, "%U(%s)", format_ascii_bytes, id, len,
		      lldp_port_id_subtype_str (subtype));
	}
      else
	{
	  s = format (s, "%U", format_ascii_bytes, id, len);
	}
      break;
    case LLDP_PORT_ID_SUBTYPE_NAME (mac_addr):
      if (ETHER_ADDR_LEN == len)
	{
	  if (detail)
	    {
	      s = format (s, "%U(%s)", format_mac_address, id,
			  lldp_port_id_subtype_str (subtype));
	    }
	  else
	    {
	      s = format (s, "%U", format_mac_address, id);
	    }
	  break;
	}
      /* fallthrough */
    case LLDP_PORT_ID_SUBTYPE_NAME (net_addr):
      /* TODO */
      /* fallthrough */
    default:
      if (detail)
	{
	  s = format (s, "%U(%s)", format_hex_bytes, id, len,
		      lldp_port_id_subtype_str (subtype));
	}
      else
	{
	  s = format (s, "%U", format_hex_bytes, id, len);
	}
      break;
    }
  return s;
}

/*
 * format chassis id subtype&value
 *
 * @param s format string
 * @param va - 1st argument - unsigned - chassis id subtype
 * @param va - 2nd argument - u8* - chassis id
 * @param va - 3rd argument - unsigned - chassis id length
 * @param va - 4th argument - int - 1 for detailed output, 0 for simple
 */
u8 *
format_lldp_chassis_id (u8 * s, va_list * va)
{
  const lldp_chassis_id_subtype_t subtype =
    va_arg (*va, lldp_chassis_id_subtype_t);
  const u8 *id = va_arg (*va, u8 *);
  const unsigned len = va_arg (*va, unsigned);
  const int detail = va_arg (*va, int);
  if (!id)
    {
      return s;
    }
  switch (subtype)
    {
    case LLDP_CHASS_ID_SUBTYPE_NAME (chassis_comp):
      /* fallthrough */
    case LLDP_CHASS_ID_SUBTYPE_NAME (intf_alias):
      /* fallthrough */
    case LLDP_CHASS_ID_SUBTYPE_NAME (port_comp):
      /* fallthrough */
    case LLDP_PORT_ID_SUBTYPE_NAME (local):
      /* fallthrough */
    case LLDP_CHASS_ID_SUBTYPE_NAME (intf_name):
      if (detail)
	{
	  s = format (s, "%U(%s)", format_ascii_bytes, id, len,
		      lldp_chassis_id_subtype_str (subtype));
	}
      else
	{
	  s = format (s, "%U", format_ascii_bytes, id, len);
	}
      break;
    case LLDP_CHASS_ID_SUBTYPE_NAME (mac_addr):
      if (ETHER_ADDR_LEN == len)
	{
	  if (detail)
	    {
	      s = format (s, "%U(%s)", format_mac_address, id,
			  lldp_chassis_id_subtype_str (subtype));
	    }
	  else
	    {
	      s = format (s, "%U", format_mac_address, id);
	    }
	  break;
	}
      /* fallthrough */
    case LLDP_CHASS_ID_SUBTYPE_NAME (net_addr):
      /* TODO */
    default:
      if (detail)
	{
	  s = format (s, "%U(%s)", format_hex_bytes, id, len,
		      lldp_chassis_id_subtype_str (subtype));
	}
      else
	{
	  s = format (s, "%U", format_hex_bytes, id, len);
	}
      break;
    }
  return s;
}

/*
 * convert a tlv code to human-readable string
 */
static const char *
lldp_tlv_code_str (lldp_tlv_code_t t)
{
  switch (t)
    {
#define F(n, t, s) \
  case n:          \
    return s;
      foreach_lldp_tlv_type (F)
#undef F
    }
  return "unknown lldp tlv";
}

/*
 * format a single LLDP TLV
 *
 * @param s format string
 * @param va variable list - pointer to lldp_tlv_t is expected
 */
u8 *
format_lldp_tlv (u8 * s, va_list * va)
{
  const lldp_tlv_t *tlv = va_arg (*va, lldp_tlv_t *);
  if (!tlv)
    {
      return s;
    }
  u16 l = lldp_tlv_get_length (tlv);
  switch (lldp_tlv_get_code (tlv))
    {
    case LLDP_TLV_NAME (chassis_id):
      s = format (s, "%U", format_lldp_chassis_id,
		  ((lldp_chassis_id_tlv_t *) tlv)->subtype,
		  ((lldp_chassis_id_tlv_t *) tlv)->id,
		  l - STRUCT_SIZE_OF (lldp_chassis_id_tlv_t, subtype), 1);
      break;
    case LLDP_TLV_NAME (port_id):
      s = format (s, "%U", format_lldp_port_id,
		  ((lldp_port_id_tlv_t *) tlv)->subtype,
		  ((lldp_port_id_tlv_t *) tlv)->id,
		  l - STRUCT_SIZE_OF (lldp_port_id_tlv_t, subtype), 1);
      break;
    case LLDP_TLV_NAME (ttl):
      s = format (s, "%d", ntohs (((lldp_ttl_tlv_t *) tlv)->ttl));
      break;
    case LLDP_TLV_NAME (sys_name):
      /* fallthrough */
    case LLDP_TLV_NAME (sys_desc):
      s = format (s, "%U", format_ascii_bytes, tlv->v, l);
      break;
    default:
      s = format (s, "%U", format_hex_bytes, tlv->v, l);
    }

  return s;
}

static u8 *
format_time_ago (u8 * s, va_list * va)
{
  f64 ago = va_arg (*va, double);
  f64 now = va_arg (*va, double);
  if (ago < 0.01)
    {
      return format (s, "never");
    }
  return format (s, "%.1fs ago", now - ago);
}

static u8 *
format_lldp_intfs_detail (u8 * s, vlib_main_t * vm, const lldp_main_t * lm)
{
  vnet_main_t *vnm = &vnet_main;
  const lldp_intf_t *n;
  const vnet_hw_interface_t *hw;
  const vnet_sw_interface_t *sw;
  s = format (s, "LLDP configuration:\n");
  if (lm->sys_name)
    {
      s = format (s, "Configured system name: %U\n", format_ascii_bytes,
		  lm->sys_name, vec_len (lm->sys_name));
    }
  s = format (s, "Configured tx-hold: %d\n", (int) lm->msg_tx_hold);
  s = format (s, "Configured tx-interval: %d\n", (int) lm->msg_tx_interval);
  s = format (s, "\nLLDP-enabled interface table:\n");
  f64 now = vlib_time_now (vm);

  /* *INDENT-OFF* */
  pool_foreach(
      n, lm->intfs, ({
        hw = vnet_get_hw_interface(vnm, n->hw_if_index);
        sw = vnet_get_sw_interface(lm->vnet_main, hw->sw_if_index);
        /* Interface shutdown */
        if (!(sw->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP |
                           VNET_SW_INTERFACE_FLAG_BOND_SLAVE)))
          {
            s = format(s, "\nInterface name: %s\nInterface/peer state: "
                          "interface down\nLast packet sent: %U\n",
                       hw->name, format_time_ago, n->last_sent, now);
          }
        else if (now < n->last_heard + n->ttl)
          {
            s = format(s,
                       "\nInterface name: %s\nPort Desc: %s\nInterface/peer "
                       "state: active\nPeer chassis ID: %U\nRemote port ID:"
                       " %U\nLast packet sent: %U\nLast packet received: %U\n",
                       hw->name, n->port_desc, format_lldp_chassis_id,
                       n->chassis_id_subtype, n->chassis_id,
                       vec_len(n->chassis_id), 1,
                       format_lldp_port_id, n->port_id_subtype, n->port_id,
                       vec_len(n->port_id), 1, format_time_ago, n->last_sent,
                       now, format_time_ago, n->last_heard, now);
          }
        else
          {
            s = format(s,
                       "\nInterface name: %s\nPort Desc: %s\nInterface/peer "
                       "state: inactive(timeout)\nLast known peer chassis ID:"
                       "%U\nLast known peer port ID: %U\nLast packet sent: "
                       "%U\nLast packet received: %U\n",
                       hw->name, n->port_desc, format_lldp_chassis_id,
                       n->chassis_id_subtype, n->chassis_id,
                       vec_len(n->chassis_id), 1,
                       format_lldp_port_id, n->port_id_subtype, n->port_id,
                       vec_len(n->port_id), 1, format_time_ago, n->last_sent,
                       now, format_time_ago, n->last_heard, now);
          }
      }));
  /* *INDENT-ON* */
  return s;
}

static u8 *
format_lldp_intfs (u8 * s, va_list * va)
{
  vlib_main_t *vm = va_arg (*va, vlib_main_t *);
  const lldp_main_t *lm = va_arg (*va, lldp_main_t *);
  const int detail = va_arg (*va, int);
  vnet_main_t *vnm = &vnet_main;
  const lldp_intf_t *n;

  if (detail)
    {
      return format_lldp_intfs_detail (s, vm, lm);
    }

  f64 now = vlib_time_now (vm);
  s = format (s, "%-25s %-25s %-25s %=15s %=15s %=10s\n", "Local interface",
	      "Peer chassis ID", "Remote port ID", "Last heard", "Last sent",
	      "Status");

  /* *INDENT-OFF* */
  pool_foreach(
      n, lm->intfs, ({
        const vnet_hw_interface_t *hw =
            vnet_get_hw_interface(vnm, n->hw_if_index);
        const vnet_sw_interface_t *sw =
            vnet_get_sw_interface(lm->vnet_main, hw->sw_if_index);
        /* Interface shutdown */
        if (!(sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
          continue;
        if (now < n->last_heard + n->ttl)
          {
            s = format(s, "%-25s %-25U %-25U %=15U %=15U %=10s\n", hw->name,
                       format_lldp_chassis_id, n->chassis_id_subtype,
                       n->chassis_id, vec_len(n->chassis_id), 0,
                       format_lldp_port_id, n->port_id_subtype, n->port_id,
                       vec_len(n->port_id), 0, format_time_ago, n->last_heard,
                       now, format_time_ago, n->last_sent, now, "active");
          }
        else
          {
            s = format(s, "%-25s %-25s %-25s %=15U %=15U %=10s\n", hw->name,
                       "", "", format_time_ago, n->last_heard, now,
                       format_time_ago, n->last_sent, now, "inactive");
          }
      }));
  /* *INDENT-ON* */
  return s;
}

static clib_error_t *
show_lldp (vlib_main_t * vm, unformat_input_t * input,
	   CLIB_UNUSED (vlib_cli_command_t * lmd))
{
  lldp_main_t *lm = &lldp_main;

  if (unformat (input, "detail"))
    {
      vlib_cli_output (vm, "%U\n", format_lldp_intfs, vm, lm, 1);
    }
  else
    {
      vlib_cli_output (vm, "%U\n", format_lldp_intfs, vm, lm, 0);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND(show_lldp_command, static) = {
  .path = "show lldp",
  .short_help = "show lldp [detail]",
  .function = show_lldp,
};
/* *INDENT-ON* */

/*
 * packet trace format function, very similar to
 * lldp_packet_scan except that we call the per TLV format
 * functions instead of the per TLV processing functions
 */
u8 *
lldp_input_format_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 *);
  const lldp_input_trace_t *t = va_arg (*args, lldp_input_trace_t *);
  const u8 *cur;
  const lldp_tlv_t *tlv;
  cur = t->data;
  while (((cur + lldp_tlv_get_length ((lldp_tlv_t *) cur)) <
	  t->data + t->len))
    {
      tlv = (lldp_tlv_t *) cur;
      if (cur == t->data)
	{
	  s = format (s, "TLV #%d(%s): %U\n", lldp_tlv_get_code (tlv),
		      lldp_tlv_code_str (lldp_tlv_get_code (tlv)),
		      format_lldp_tlv, tlv);
	}
      else
	{
	  s = format (s, "  TLV #%d(%s): %U\n", lldp_tlv_get_code (tlv),
		      lldp_tlv_code_str (lldp_tlv_get_code (tlv)),
		      format_lldp_tlv, tlv);
	}
      cur += STRUCT_SIZE_OF (lldp_tlv_t, head) + lldp_tlv_get_length (tlv);
    }

  return s;
}

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