/*
 * Copyright (c) 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 Local TCP/IP stack punt infrastructure.
 *
 * Provides a set of VPP nodes together with the relevant APIs and CLI
 * commands in order to adjust and dispatch packets from the VPP data plane
 * to the local TCP/IP stack
 */

#include <vnet/ip/ip.h>
#include <vlib/vlib.h>
#include <vnet/udp/udp.h>
#include <vnet/tcp/tcp.h>
#include <vnet/ip/punt.h>
#include <vlib/unix/unix.h>

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <stdlib.h>

punt_main_t punt_main;

char *
vnet_punt_get_server_pathname (void)
{
  punt_main_t *pm = &punt_main;
  return pm->sun_path;
}

static void
punt_client_l4_db_add (ip_address_family_t af, u16 port, u32 index)
{
  punt_main_t *pm = &punt_main;

  pm->db.clients_by_l4_port = hash_set (pm->db.clients_by_l4_port,
					punt_client_l4_mk_key (af, port),
					index);
}

static u32
punt_client_l4_db_remove (ip_address_family_t af, u16 port)
{
  punt_main_t *pm = &punt_main;
  u32 key, index = ~0;
  uword *p;

  key = punt_client_l4_mk_key (af, port);
  p = hash_get (pm->db.clients_by_l4_port, key);

  if (p)
    index = p[0];

  hash_unset (pm->db.clients_by_l4_port, key);

  return (index);
}

static void
punt_client_ip_proto_db_add (ip_address_family_t af,
			     ip_protocol_t proto, u32 index)
{
  punt_main_t *pm = &punt_main;

  pm->db.clients_by_ip_proto = hash_set (pm->db.clients_by_ip_proto,
					 punt_client_ip_proto_mk_key (af,
								      proto),
					 index);
}

static u32
punt_client_ip_proto_db_remove (ip_address_family_t af, ip_protocol_t proto)
{
  punt_main_t *pm = &punt_main;
  u32 key, index = ~0;
  uword *p;

  key = punt_client_ip_proto_mk_key (af, proto);
  p = hash_get (pm->db.clients_by_ip_proto, key);

  if (p)
    index = p[0];

  hash_unset (pm->db.clients_by_ip_proto, key);

  return (index);
}

static void
punt_client_exception_db_add (vlib_punt_reason_t reason, u32 pci)
{
  punt_main_t *pm = &punt_main;

  vec_validate_init_empty (pm->db.clients_by_exception, reason, ~0);

  pm->db.clients_by_exception[reason] = pci;
}

static u32
punt_client_exception_db_remove (vlib_punt_reason_t reason)
{
  punt_main_t *pm = &punt_main;
  u32 pci = ~0;

  if (punt_client_exception_get (reason))
    {
      pci = pm->db.clients_by_exception[reason];
      pm->db.clients_by_exception[reason] = ~0;
    }

  return pci;
}

static clib_error_t *
punt_socket_read_ready (clib_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  punt_main_t *pm = &punt_main;

  /** Schedule the rx node */
  vlib_node_set_interrupt_pending (vm, punt_socket_rx_node.index);
  vec_add1 (pm->ready_fds, uf->file_descriptor);

  return 0;
}

static clib_error_t *
punt_socket_register_l4 (vlib_main_t * vm,
			 ip_address_family_t af,
			 u8 protocol, u16 port, char *client_pathname)
{
  punt_main_t *pm = &punt_main;
  punt_client_t *c;

  /* For now we only support UDP punt */
  if (protocol != IP_PROTOCOL_UDP)
    return clib_error_return (0,
			      "only UDP protocol (%d) is supported, got %d",
			      IP_PROTOCOL_UDP, protocol);

  if (port == (u16) ~ 0)
    return clib_error_return (0, "UDP port number required");

  c = punt_client_l4_get (af, port);

  if (NULL == c)
    {
      pool_get_zero (pm->punt_client_pool, c);
      punt_client_l4_db_add (af, port, c - pm->punt_client_pool);
    }

  snprintf (c->caddr.sun_path, sizeof (c->caddr.sun_path), "%s",
	    client_pathname);
  c->caddr.sun_family = AF_UNIX;
  c->reg.type = PUNT_TYPE_L4;
  c->reg.punt.l4.port = port;
  c->reg.punt.l4.protocol = protocol;
  c->reg.punt.l4.af = af;

  u32 node_index = (af == AF_IP4 ?
		    udp4_punt_socket_node.index :
		    udp6_punt_socket_node.index);

  udp_register_dst_port (vm, port, node_index, af == AF_IP4);

  return (NULL);
}

static clib_error_t *
punt_socket_register_ip_proto (vlib_main_t * vm,
			       ip_address_family_t af,
			       ip_protocol_t proto, char *client_pathname)
{
  punt_main_t *pm = &punt_main;
  punt_client_t *c;

  c = punt_client_ip_proto_get (af, proto);

  if (NULL == c)
    {
      pool_get_zero (pm->punt_client_pool, c);
      punt_client_ip_proto_db_add (af, proto, c - pm->punt_client_pool);
    }

  snprintf (c->caddr.sun_path, sizeof (c->caddr.sun_path), "%s",
	    client_pathname);
  c->caddr.sun_family = AF_UNIX;
  c->reg.type = PUNT_TYPE_IP_PROTO;
  c->reg.punt.ip_proto.protocol = proto;
  c->reg.punt.ip_proto.af = af;

  if (af == AF_IP4)
    ip4_register_protocol (proto, ip4_proto_punt_socket_node.index);
  else
    ip6_register_protocol (proto, ip6_proto_punt_socket_node.index);

  return (NULL);
}

static clib_error_t *
punt_socket_register_exception (vlib_main_t * vm,
				vlib_punt_reason_t reason,
				char *client_pathname)
{
  punt_main_t *pm = &punt_main;
  punt_client_t *pc;

  pc = punt_client_exception_get (reason);

  if (NULL == pc)
    {
      pool_get_zero (pm->punt_client_pool, pc);
      punt_client_exception_db_add (reason, pc - pm->punt_client_pool);
    }

  snprintf (pc->caddr.sun_path, sizeof (pc->caddr.sun_path), "%s",
	    client_pathname);
  pc->caddr.sun_family = AF_UNIX;
  pc->reg.type = PUNT_TYPE_EXCEPTION;
  pc->reg.punt.exception.reason = reason;

  vlib_punt_register (pm->hdl,
		      pc->reg.punt.exception.reason, "exception-punt-socket");

  return (NULL);
}

static clib_error_t *
punt_socket_unregister_l4 (ip_address_family_t af,
			   ip_protocol_t protocol, u16 port)
{
  u32 pci;

  udp_unregister_dst_port (vlib_get_main (), port, af == AF_IP4);

  pci = punt_client_l4_db_remove (af, port);

  if (~0 != pci)
    pool_put_index (punt_main.punt_client_pool, pci);

  return (NULL);
}

static clib_error_t *
punt_socket_unregister_ip_proto (ip_address_family_t af, ip_protocol_t proto)
{
  u32 pci;

  if (af == AF_IP4)
    ip4_unregister_protocol (proto);
  else
    ip6_unregister_protocol (proto);

  pci = punt_client_ip_proto_db_remove (af, proto);

  if (~0 != pci)
    pool_put_index (punt_main.punt_client_pool, pci);

  return (NULL);
}

static clib_error_t *
punt_socket_unregister_exception (vlib_punt_reason_t reason)
{
  u32 pci;

  pci = punt_client_exception_db_remove (reason);

  if (~0 != pci)
    pool_put_index (punt_main.punt_client_pool, pci);

  return (NULL);
}

clib_error_t *
vnet_punt_socket_add (vlib_main_t * vm, u32 header_version,
		      const punt_reg_t * pr, char *client_pathname)
{
  punt_main_t *pm = &punt_main;

  if (!pm->is_configured)
    return clib_error_return (0, "socket is not configured");

  if (header_version != PUNT_PACKETDESC_VERSION)
    return clib_error_return (0, "Invalid packet descriptor version");

  if (strncmp (client_pathname, vnet_punt_get_server_pathname (),
	       UNIX_PATH_MAX) == 0)
    return clib_error_return (0,
			      "Punt socket: Invalid client path: %s",
			      client_pathname);

  /* Register client */
  switch (pr->type)
    {
    case PUNT_TYPE_L4:
      return (punt_socket_register_l4 (vm,
				       pr->punt.l4.af,
				       pr->punt.l4.protocol,
				       pr->punt.l4.port, client_pathname));
    case PUNT_TYPE_IP_PROTO:
      return (punt_socket_register_ip_proto (vm,
					     pr->punt.ip_proto.af,
					     pr->punt.ip_proto.protocol,
					     client_pathname));
    case PUNT_TYPE_EXCEPTION:
      return (punt_socket_register_exception (vm,
					      pr->punt.exception.reason,
					      client_pathname));
    }

  return 0;
}

clib_error_t *
vnet_punt_socket_del (vlib_main_t * vm, const punt_reg_t * pr)
{
  punt_main_t *pm = &punt_main;

  if (!pm->is_configured)
    return clib_error_return (0, "socket is not configured");

  switch (pr->type)
    {
    case PUNT_TYPE_L4:
      return (punt_socket_unregister_l4 (pr->punt.l4.af,
					 pr->punt.l4.protocol,
					 pr->punt.l4.port));
    case PUNT_TYPE_IP_PROTO:
      return (punt_socket_unregister_ip_proto (pr->punt.ip_proto.af,
					       pr->punt.ip_proto.protocol));
    case PUNT_TYPE_EXCEPTION:
      return (punt_socket_unregister_exception (pr->punt.exception.reason));
    }

  return 0;
}

/**
 * @brief Request IP L4 traffic punt to the local TCP/IP stack.
 *
 * @em Note
 * - UDP is the only protocol supported in the current implementation
 *
 * @param vm       vlib_main_t corresponding to the current thread
 * @param af       IP address family.
 * @param protocol 8-bits L4 protocol value
 *                 UDP is 17
 *                 TCP is 1
 * @param port     16-bits L4 (TCP/IP) port number when applicable (UDP only)
 *
 * @returns 0 on success, non-zero value otherwise
 */
static clib_error_t *
punt_l4_add_del (vlib_main_t * vm,
		 ip_address_family_t af,
		 ip_protocol_t protocol, u16 port, bool is_add)
{
  int is_ip4 = af == AF_IP4;

  /* For now we only support TCP and UDP punt */
  if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
    return clib_error_return (0,
			      "only UDP (%d) and TCP (%d) protocols are supported, got %d",
			      IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);

  if (port == (u16) ~ 0)
    {
      if (protocol == IP_PROTOCOL_UDP)
	udp_punt_unknown (vm, is_ip4, is_add);
      else if (protocol == IP_PROTOCOL_TCP)
	tcp_punt_unknown (vm, is_ip4, is_add);

      return 0;
    }

  else if (is_add)
    {
      const vlib_node_registration_t *punt_node =
	is_ip4 ? &udp4_punt_node : &udp6_punt_node;

      if (protocol == IP_PROTOCOL_TCP)
	return clib_error_return (0, "punt TCP ports is not supported yet");

      udp_register_dst_port (vm, port, punt_node->index, is_ip4);

      return 0;
    }
  else
    {
      if (protocol == IP_PROTOCOL_TCP)
	return clib_error_return (0, "punt TCP ports is not supported yet");

      udp_unregister_dst_port (vm, port, is_ip4);

      return 0;
    }
}

/**
 * @brief Request exception traffic punt.
 *
 * @param reason   Punting reason
 *
 * @returns 0 on success, non-zero value otherwise
 */
static clib_error_t *
punt_exception_add_del (vlib_punt_reason_t reason, bool is_add)
{
  punt_main_t *pm = &punt_main;
  int rv = 0;
  vnet_punt_reason_flag_t flag = vlib_punt_reason_get_flags (reason);
  const char *node_name =
    vnet_punt_reason_flag_is_IP6_PACKET (flag) ? "ip6-punt" : "ip4-punt";
  if (is_add)
    rv = vlib_punt_register (pm->hdl, reason, node_name);
  else
    rv = vlib_punt_unregister (pm->hdl, reason, node_name);
  if (!rv)
    return 0;
  else
    return clib_error_return (0, is_add ? "Existing punting registration..." :
					  "Punting registration not found...");
}

clib_error_t *
vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add)
{
  switch (pr->type)
    {
    case PUNT_TYPE_L4:
      return (punt_l4_add_del (vm, pr->punt.l4.af, pr->punt.l4.protocol,
			       pr->punt.l4.port, is_add));
    case PUNT_TYPE_EXCEPTION:
      return punt_exception_add_del (pr->punt.exception.reason, is_add);
    case PUNT_TYPE_IP_PROTO:
      break;
    }

  return (clib_error_return (0, "Unsupported punt type: %d", pr->type));
}

static clib_error_t *
punt_cli (vlib_main_t * vm,
	  unformat_input_t * input__, vlib_cli_command_t * cmd)
{
  unformat_input_t line_input, *input = &line_input;
  clib_error_t *error = NULL;
  bool is_add = true;
  /* *INDENT-OFF* */
  punt_reg_t pr = {
    .punt = {
      .l4 = {
        .af = AF_IP4,
        .port = ~0,
        .protocol = IP_PROTOCOL_UDP,
      },
    },
    .type = PUNT_TYPE_L4,
  };
  u32 port;
  /* *INDENT-ON* */

  if (!unformat_user (input__, unformat_line_input, input))
    return 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "del"))
	is_add = false;
      else if (unformat (input, "reason %U", unformat_punt_reason,
			 &pr.punt.exception.reason))
	pr.type = PUNT_TYPE_EXCEPTION;
      else if (unformat (input, "ipv4"))
	pr.punt.l4.af = AF_IP4;
      else if (unformat (input, "ipv6"))
	pr.punt.l4.af = AF_IP6;
      else if (unformat (input, "ip6"))
	pr.punt.l4.af = AF_IP6;
      else if (unformat (input, "%d", &port))
	pr.punt.l4.port = port;
      else if (unformat (input, "all"))
	pr.punt.l4.port = ~0;
      else if (unformat (input, "udp"))
	pr.punt.l4.protocol = IP_PROTOCOL_UDP;
      else if (unformat (input, "tcp"))
	pr.punt.l4.protocol = IP_PROTOCOL_TCP;
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  /* punt both IPv6 and IPv4 when used in CLI */
  error = vnet_punt_add_del (vm, &pr, is_add);
  if (error)
    {
      clib_error_report (error);
    }

done:
  unformat_free (input);
  return error;
}

/*?
 * The set of '<em>set punt</em>' commands allows specific IP traffic to
 * be punted to the host TCP/IP stack
 *
 * @em Note
 * - UDP is the only protocol supported in the current implementation
 * - All TCP traffic is currently punted to the host by default
 *
 * @cliexpar
 * @parblock
 * Example of how to request NTP traffic to be punted
 * @cliexcmd{set punt udp 125}
 *
 * Example of how to request all 'unknown' UDP traffic to be punted
 * @cliexcmd{set punt udp all}
 *
 * Example of how to stop all 'unknown' UDP traffic to be punted
 * @cliexcmd{set punt udp del all}
 * @endparblock
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_command, static) = {
  .path = "set punt",
  .short_help = "set punt [IPV4|ip6|ipv6] [UDP|tcp] [del] [ALL|<port-num>]",
  .function = punt_cli,
};
/* *INDENT-ON* */

static clib_error_t *
punt_socket_register_cmd (vlib_main_t * vm,
			  unformat_input_t * input__,
			  vlib_cli_command_t * cmd)
{
  unformat_input_t line_input, *input = &line_input;
  u8 *socket_name = 0;
  clib_error_t *error = NULL;
  /* *INDENT-OFF* */
  punt_reg_t pr = {
    .punt = {
      .l4 = {
        .af = AF_IP4,
        .port = ~0,
        .protocol = IP_PROTOCOL_UDP,
      },
    },
    .type = PUNT_TYPE_L4,
  };
  /* *INDENT-ON* */

  if (!unformat_user (input__, unformat_line_input, input))
    return 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "ipv4"))
	pr.punt.l4.af = AF_IP4;
      else if (unformat (input, "ipv6"))
	pr.punt.l4.af = AF_IP6;
      else if (unformat (input, "udp"))
	pr.punt.l4.protocol = IP_PROTOCOL_UDP;
      else if (unformat (input, "tcp"))
	pr.punt.l4.protocol = IP_PROTOCOL_TCP;
      else if (unformat (input, "%d", &pr.punt.l4.port))
	;
      else if (unformat (input, "all"))
	pr.punt.l4.port = ~0;
      else if (unformat (input, "socket %s", &socket_name))
	;
      else if (unformat (input, "reason %U", unformat_punt_reason,
			 &pr.punt.exception.reason))
	pr.type = PUNT_TYPE_EXCEPTION;
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  if (!socket_name)
    error = clib_error_return (0, "socket name not specified");
  else
    error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name);

done:
  unformat_free (input);
  return error;
}

/*?
 *
 * @cliexpar
 * @cliexcmd{punt socket register socket punt_l4_foo.sock}

 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_socket_register_command, static) =
{
  .path = "punt socket register",
  .function = punt_socket_register_cmd,
  .short_help = "punt socket register [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>] socket <socket>",
  .is_mp_safe = 1,
};
/* *INDENT-ON* */

static clib_error_t *
punt_socket_deregister_cmd (vlib_main_t * vm,
			    unformat_input_t * input__,
			    vlib_cli_command_t * cmd)
{
  unformat_input_t line_input, *input = &line_input;
  clib_error_t *error = NULL;
  /* *INDENT-OFF* */
  punt_reg_t pr = {
    .punt = {
      .l4 = {
        .af = AF_IP4,
        .port = ~0,
        .protocol = IP_PROTOCOL_UDP,
      },
    },
    .type = PUNT_TYPE_L4,
  };
  /* *INDENT-ON* */

  if (!unformat_user (input__, unformat_line_input, input))
    return 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "ipv4"))
	pr.punt.l4.af = AF_IP4;
      else if (unformat (input, "ipv6"))
	pr.punt.l4.af = AF_IP6;
      else if (unformat (input, "udp"))
	pr.punt.l4.protocol = IP_PROTOCOL_UDP;
      else if (unformat (input, "tcp"))
	pr.punt.l4.protocol = IP_PROTOCOL_TCP;
      else if (unformat (input, "%d", &pr.punt.l4.port))
	;
      else if (unformat (input, "all"))
	pr.punt.l4.port = ~0;
      else if (unformat (input, "reason %U", unformat_punt_reason,
			 &pr.punt.exception.reason))
	pr.type = PUNT_TYPE_EXCEPTION;
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  error = vnet_punt_socket_del (vm, &pr);
done:
  unformat_free (input);
  return error;
}

/*?
 *
 * @cliexpar
 * @cliexcmd{punt socket register}
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_socket_deregister_command, static) =
{
  .path = "punt socket deregister",
  .function = punt_socket_deregister_cmd,
  .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>]",
  .is_mp_safe = 1,
};
/* *INDENT-ON* */

void
punt_client_walk (punt_type_t pt, punt_client_walk_cb_t cb, void *ctx)
{
  punt_main_t *pm = &punt_main;

  switch (pt)
    {
    case PUNT_TYPE_L4:
      {
	u32 pci, key;

        /* *INDENT-OFF* */
        hash_foreach(key, pci, pm->db.clients_by_l4_port,
        ({
          cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
        }));
        /* *INDENT-ON* */
	break;
      }
    case PUNT_TYPE_IP_PROTO:
      {
	u32 pci, key;

        /* *INDENT-OFF* */
        hash_foreach(key, pci, pm->db.clients_by_ip_proto,
        ({
          cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
        }));
        /* *INDENT-ON* */
	break;
      }
    case PUNT_TYPE_EXCEPTION:
      {
	u32 *pci;

	vec_foreach (pci, pm->db.clients_by_exception)
	{
	  if (~0 != *pci)
	    cb (pool_elt_at_index (pm->punt_client_pool, *pci), ctx);
	}

	break;
      }
    }
}

static u8 *
format_punt_client (u8 * s, va_list * args)
{
  punt_client_t *pc = va_arg (*args, punt_client_t *);

  s = format (s, " punt ");

  switch (pc->reg.type)
    {
    case PUNT_TYPE_L4:
      s = format (s, "%U %U port %d",
		  format_ip_address_family, pc->reg.punt.l4.af,
		  format_ip_protocol, pc->reg.punt.l4.protocol,
		  pc->reg.punt.l4.port);
      break;
    case PUNT_TYPE_IP_PROTO:
      s = format (s, "%U %U",
		  format_ip_address_family, pc->reg.punt.ip_proto.af,
		  format_ip_protocol, pc->reg.punt.ip_proto.protocol);
      break;
    case PUNT_TYPE_EXCEPTION:
      s = format (s, " %U", format_vlib_punt_reason,
		  pc->reg.punt.exception.reason);
      break;
    }

  s = format (s, " to socket %s \n", pc->caddr.sun_path);

  return (s);
}

static walk_rc_t
punt_client_show_one (const punt_client_t * pc, void *ctx)
{
  vlib_cli_output (ctx, "%U", format_punt_client, pc);

  return (WALK_CONTINUE);
}

static clib_error_t *
punt_socket_show_cmd (vlib_main_t * vm,
		      unformat_input_t * input__, vlib_cli_command_t * cmd)
{
  unformat_input_t line_input, *input = &line_input;
  clib_error_t *error = NULL;
  punt_type_t pt;

  pt = PUNT_TYPE_L4;

  if (!unformat_user (input__, unformat_line_input, input))
    return 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "exception"))
	pt = PUNT_TYPE_EXCEPTION;
      else if (unformat (input, "l4"))
	pt = PUNT_TYPE_L4;
      else if (unformat (input, "ip"))
	pt = PUNT_TYPE_IP_PROTO;
      else
	{
	  error = clib_error_return (0, "parse error: '%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }

  punt_client_walk (pt, punt_client_show_one, vm);

done:
  unformat_free (input);
  return (error);
}

/*?
 *
 * @cliexpar
 * @cliexcmd{show punt socket ipv4}
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) =
{
  .path = "show punt socket registrations",
  .function = punt_socket_show_cmd,
  .short_help = "show punt socket registrations [l4|exception]",
  .is_mp_safe = 1,
};
/* *INDENT-ON* */

clib_error_t *
ip_punt_init (vlib_main_t * vm)
{
  clib_error_t *error = NULL;
  punt_main_t *pm = &punt_main;
  vlib_thread_main_t *tm = vlib_get_thread_main ();

  pm->is_configured = false;
  pm->interface_output_node =
    vlib_get_node_by_name (vm, (u8 *) "interface-output");

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

  pm->hdl = vlib_punt_client_register ("ip-punt");

  vec_validate_aligned (pm->thread_data, tm->n_vlib_mains,
			CLIB_CACHE_LINE_BYTES);

  return (error);
}

u8 *
format_vnet_punt_reason_flags (u8 *s, va_list *args)
{
  vnet_punt_reason_flag_t flag = va_arg (*args, int);
#define _(pos, len, value, name, str)                                         \
  if (vnet_punt_reason_flag_is_##name (flag))                                 \
    s = format (s, "%s ", str);

  foreach_vnet_punt_reason_flag
#undef _
    return (s);
}

VLIB_INIT_FUNCTION (ip_punt_init);

static clib_error_t *
punt_config (vlib_main_t * vm, unformat_input_t * input)
{
  punt_main_t *pm = &punt_main;
  char *socket_path = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "socket %s", &socket_path))
	strncpy (pm->sun_path, socket_path, UNIX_PATH_MAX - 1);
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (socket_path == 0)
    return 0;

  /* UNIX domain socket */
  struct sockaddr_un addr;
  if ((pm->socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
    {
      return clib_error_return (0, "socket error");
    }

  clib_memset (&addr, 0, sizeof (addr));
  addr.sun_family = AF_UNIX;
  if (*socket_path == '\0')
    {
      *addr.sun_path = '\0';
      strncpy (addr.sun_path + 1, socket_path + 1,
	       sizeof (addr.sun_path) - 2);
    }
  else
    {
      strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
      unlink (socket_path);
    }

  if (bind (pm->socket_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
    {
      return clib_error_return (0, "bind error");
    }

  int n_bytes = 0x10000;

  if (setsockopt
      (pm->socket_fd, SOL_SOCKET, SO_SNDBUF, &n_bytes,
       sizeof (n_bytes)) == -1)
    {
      return clib_error_return (0, "setsockopt error");
    }

  /* Register socket */
  clib_file_main_t *fm = &file_main;
  clib_file_t template = { 0 };
  template.read_function = punt_socket_read_ready;
  template.file_descriptor = pm->socket_fd;
  template.description = format (0, "punt socket %s", socket_path);
  pm->clib_file_index = clib_file_add (fm, &template);

  pm->is_configured = true;

  return 0;
}

VLIB_CONFIG_FUNCTION (punt_config, "punt");

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