/*
 * 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;

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

  u32 node_index;
  switch (protocol)
    {
    case IP_PROTOCOL_UDP:
      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);
      break;
    case IP_PROTOCOL_ICMP6:
      if (af != AF_IP6)
	return clib_error_return (
	  0, "only UDP or ICMP6 protocol (%d, %d) is supported, got %d",
	  IP_PROTOCOL_UDP, IP_PROTOCOL_ICMP6, protocol);

      node_index = icmp6_punt_socket_node.index;
      icmp6_register_type (vm, port, node_index);
      break;
    default:
      return clib_error_return (
	0, "only UDP or ICMP6 protocol (%d) is supported, got %d",
	IP_PROTOCOL_UDP, protocol);
    }

  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;

  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:
 */
