/*
 * Copyright (c) 2020 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 <vppinfra/error.h>
#include <vppinfra/format.h>
#include <vppinfra/format_table.h>
#include <vnet/udp/udp.h>
#include <vnet/session/session_types.h>

u8 *
format_udp_connection_id (u8 * s, va_list * args)
{
  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
  if (!uc)
    return s;
  if (uc->c_is_ip4)
    s = format (s, "[%u:%u][%s] %U:%d->%U:%d", uc->c_thread_index,
		uc->c_s_index, "U", format_ip4_address, &uc->c_lcl_ip4,
		clib_net_to_host_u16 (uc->c_lcl_port), format_ip4_address,
		&uc->c_rmt_ip4, clib_net_to_host_u16 (uc->c_rmt_port));
  else
    s = format (s, "[%u:%u][%s] %U:%d->%U:%d", uc->c_thread_index,
		uc->c_s_index, "U", format_ip6_address, &uc->c_lcl_ip6,
		clib_net_to_host_u16 (uc->c_lcl_port), format_ip6_address,
		&uc->c_rmt_ip6, clib_net_to_host_u16 (uc->c_rmt_port));
  return s;
}

static const char *udp_cfg_flags_str[] = {
#define _(sym, str) str,
  foreach_udp_cfg_flag
#undef _
};

static u8 *
format_udp_cfg_flags (u8 *s, va_list *args)
{
  udp_connection_t *tc = va_arg (*args, udp_connection_t *);
  int i, last = -1;

  for (i = 0; i < UDP_CFG_N_FLAG_BITS; i++)
    if (tc->cfg_flags & (1 << i))
      last = i;
  if (last >= 0)
    s = format (s, " cfg: ");
  for (i = 0; i < last; i++)
    {
      if (tc->cfg_flags & (1 << i))
	s = format (s, "%s, ", udp_cfg_flags_str[i]);
    }
  if (last >= 0)
    s = format (s, "%s", udp_cfg_flags_str[last]);
  return s;
}

static const char *udp_connection_flags_str[] = {
#define _(sym, str) str,
  foreach_udp_connection_flag
#undef _
};

static u8 *
format_udp_connection_flags (u8 * s, va_list * args)
{
  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
  int i, last = -1;

  for (i = 0; i < UDP_CONN_N_FLAGS; i++)
    if (uc->flags & (1 << i))
      last = i;
  for (i = 0; i < last; i++)
    {
      if (uc->flags & (1 << i))
	s = format (s, "%s, ", udp_connection_flags_str[i]);
    }
  if (last >= 0)
    s = format (s, "%s", udp_connection_flags_str[last]);
  return s;
}

static u8 *
format_udp_vars (u8 * s, va_list * args)
{
  udp_connection_t *uc = va_arg (*args, udp_connection_t *);

  s = format (s, " index %u%U flags: %U\n", uc->c_c_index,
	      format_udp_cfg_flags, uc, format_udp_connection_flags, uc);
  s = format (s, " fib_index: %u next_node: %u opaque: %u ", uc->c_fib_index);
  if (!(uc->flags & UDP_CONN_F_LISTEN))
    s = format (s, " sw_if_index: %d mss: %u\n", uc->sw_if_index, uc->mss);
  else
    s = format (s, "\n");

  return s;
}

u8 *
format_udp_connection (u8 * s, va_list * args)
{
  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
  u32 verbose = va_arg (*args, u32);
  if (!uc)
    return s;
  s = format (s, "%-" SESSION_CLI_ID_LEN "U", format_udp_connection_id, uc);
  if (verbose)
    {
      s = format (s, "%-" SESSION_CLI_STATE_LEN "s",
		  (uc->flags & UDP_CONN_F_LISTEN) ? "LISTEN" : "OPENED", uc);
      if (verbose > 1)
	s = format (s, "\n%U", format_udp_vars, uc);
    }
  return s;
}

static clib_error_t *
udp_config_fn (vlib_main_t * vm, unformat_input_t * input)
{
  udp_main_t *um = &udp_main;
  u32 tmp;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "mtu %u", &tmp))
	um->default_mtu = tmp;
      else if (unformat (input, "icmp-unreachable-disabled"))
	um->icmp_send_unreachable_disabled = 1;
      else if (unformat (input, "no-csum-offload"))
	um->csum_offload = 0;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }
  return 0;
}

VLIB_CONFIG_FUNCTION (udp_config_fn, "udp");

static clib_error_t *
show_udp_punt_fn (vlib_main_t * vm, unformat_input_t * input,
		  vlib_cli_command_t * cmd_arg)
{
  udp_main_t *um = vnet_get_udp_main ();

  clib_error_t *error = NULL;

  if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    return clib_error_return (0, "unknown input `%U'", format_unformat_error,
			      input);

  udp_dst_port_info_t *port_info;
  if (um->punt_unknown4)
    {
      vlib_cli_output (vm, "IPv4 UDP punt: enabled");
    }
  else
    {
      u8 *s = NULL;
      vec_foreach (port_info, um->dst_port_infos[UDP_IP4])
      {
	if (udp_is_valid_dst_port (port_info->dst_port, 1))
	  {
	    s = format (s, (!s) ? "%d" : ", %d", port_info->dst_port);
	  }
      }
      s = format (s, "%c", 0);
      vlib_cli_output (vm, "IPV4 UDP ports punt : %s", s);
    }

  if (um->punt_unknown6)
    {
      vlib_cli_output (vm, "IPv6 UDP punt: enabled");
    }
  else
    {
      u8 *s = NULL;
      vec_foreach (port_info, um->dst_port_infos[UDP_IP6])
      {
	if (udp_is_valid_dst_port (port_info->dst_port, 01))
	  {
	    s = format (s, (!s) ? "%d" : ", %d", port_info->dst_port);
	  }
      }
      s = format (s, "%c", 0);
      vlib_cli_output (vm, "IPV6 UDP ports punt : %s", s);
    }

  return (error);
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_tcp_punt_command, static) =
{
  .path = "show udp punt",
  .short_help = "show udp punt [ipv4|ipv6]",
  .function = show_udp_punt_fn,
};
/* *INDENT-ON* */

static void
table_format_udp_port_ (vlib_main_t *vm, udp_main_t *um, table_t *t, int *c,
			int port, int bind, int is_ip4)
{
  const udp_dst_port_info_t *pi;

  if (bind && !udp_is_valid_dst_port (port, is_ip4))
    return;

  pi = udp_get_dst_port_info (um, port, is_ip4);
  if (!pi)
    return;

  table_format_cell (t, *c, 0, "%d", pi->dst_port);
  table_format_cell (t, *c, 1, is_ip4 ? "ip4" : "ip6");
  table_format_cell (t, *c, 2, ~0 == pi->node_index ? "none" : "%U",
		     format_vlib_node_name, vm, pi->node_index);
  table_format_cell (t, *c, 3, "%s", pi->name);

  (*c)++;
}

static void
table_format_udp_port (vlib_main_t *vm, udp_main_t *um, table_t *t, int *c,
		       int port, int bind, int ip4, int ip6)
{
  if (ip4)
    table_format_udp_port_ (vm, um, t, c, port, bind, 1 /* is_ip4 */);
  if (ip6)
    table_format_udp_port_ (vm, um, t, c, port, bind, 0 /* is_ip4 */);
}

static clib_error_t *
show_udp_ports (vlib_main_t *vm, unformat_input_t *input,
		vlib_cli_command_t *cmd)
{
  table_t table = {}, *t = &table;
  udp_main_t *um = &udp_main;
  clib_error_t *err = 0;
  int ip4 = 1, ip6 = 1;
  int port = -1;
  int bind = 1;
  int c = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "ip4"))
	ip6 = 0;
      else if (unformat (input, "ip6"))
	ip4 = 0;
      else if (unformat (input, "bind"))
	bind = 1;
      else if (unformat (input, "all"))
	bind = 0;
      else if (unformat (input, "%d", &port))
	;
      else
	{
	  err = clib_error_return (0, "unknown input `%U'",
				   format_unformat_error, input);
	  goto out;
	}
    }

  table_add_header_col (t, 4, "port", "proto", "node", "desc");

  if (port > 65535)
    {
      err = clib_error_return (0, "wrong port %d", port);
      goto out;
    }
  else if (port < 0)
    {
      for (port = 0; port < 65536; port++)
	table_format_udp_port (vm, um, t, &c, port, bind, ip4, ip6);
    }
  else
    {
      table_format_udp_port (vm, um, t, &c, port, bind, ip4, ip6);
    }

  vlib_cli_output (vm, "%U", format_table, t);

out:
  table_free (t);
  return err;
}

VLIB_CLI_COMMAND (show_udp_ports_cmd, static) = {
  .path = "show udp ports",
  .function = show_udp_ports,
  .short_help = "show udp ports [ip4|ip6] [bind|all|<port>]",
  .is_mp_safe = 1,
};

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