/*
 * 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 Definitions for punt infrastructure.
 */
#ifndef included_punt_h
#define included_punt_h

#include <linux/un.h>
#include <stdbool.h>
#include <vnet/ip/ip.h>

#define foreach_punt_type                       \
  _(L4, "l4")                                   \
  _(EXCEPTION, "exception")                     \
  _(IP_PROTO, "ip-proto")

typedef enum punt_type_t_
{
#define _(v, s) PUNT_TYPE_##v,
  foreach_punt_type
#undef _
} punt_type_t;

typedef struct punt_l4_t_
{
  ip_address_family_t af;
  ip_protocol_t protocol;
  u16 port;
} punt_l4_t;

typedef struct punt_ip_proto_t_
{
  ip_address_family_t af;
  ip_protocol_t protocol;
} punt_ip_proto_t;

typedef struct punt_exception_t_
{
  vlib_punt_reason_t reason;
} punt_exception_t;

typedef struct punt_union_t_
{
  punt_exception_t exception;
  punt_l4_t l4;
  punt_ip_proto_t ip_proto;
} punt_union_t;

typedef struct punt_reg_t_
{
  punt_type_t type;
  punt_union_t punt;
} punt_reg_t;


clib_error_t *vnet_punt_add_del (vlib_main_t * vm,
				 const punt_reg_t * pr, bool is_add);
clib_error_t *vnet_punt_socket_add (vlib_main_t * vm,
				    u32 header_version,
				    const punt_reg_t * pr,
				    char *client_pathname);
clib_error_t *vnet_punt_socket_del (vlib_main_t * vm, const punt_reg_t * pr);
char *vnet_punt_get_server_pathname (void);

enum punt_action_e
{
  PUNT_L2 = 0,
  PUNT_IP4_ROUTED,
  PUNT_IP6_ROUTED,
};

/*
 * Packet descriptor header. Version 1
 * If this header changes, the version must also change to notify clients.
 */
#define PUNT_PACKETDESC_VERSION 1
typedef struct __attribute__ ((packed))
{
  u32 sw_if_index;		/* RX or TX interface */
  enum punt_action_e action;
} punt_packetdesc_t;

/*
 * Client registration
 */
typedef struct
{
  punt_reg_t reg;
  struct sockaddr_un caddr;
} punt_client_t;

typedef struct punt_client_db_t_
{
  void *clients_by_l4_port;
  u32 *clients_by_exception;
  void *clients_by_ip_proto;
} punt_client_db_t;

typedef struct
{
  int socket_fd;
  char sun_path[sizeof (struct sockaddr_un)];
  punt_client_db_t db;
  punt_client_t *punt_client_pool;
  u32 clib_file_index;
  bool is_configured;
  vlib_node_t *interface_output_node;
  u32 *ready_fds;
  u32 *rx_buffers;
  vlib_punt_hdl_t hdl;
} punt_main_t;

extern punt_main_t punt_main;

typedef walk_rc_t (*punt_client_walk_cb_t) (const punt_client_t * pc,
					    void *ctx);
extern void punt_client_walk (punt_type_t pt,
			      punt_client_walk_cb_t cb, void *ctx);

/*
 * inlines for the data-plane
 */
static_always_inline u32
punt_client_l4_mk_key (ip_address_family_t af, u16 port)
{
  return (af << BITS (port) | port);
}

static_always_inline punt_client_t *
punt_client_l4_get (ip_address_family_t af, u16 port)
{
  punt_main_t *pm = &punt_main;
  uword *p;

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

  if (p)
    return (pool_elt_at_index (pm->punt_client_pool, p[0]));

  return (NULL);
}

static_always_inline u32
punt_client_ip_proto_mk_key (ip_address_family_t af, ip_protocol_t proto)
{
  return (af << 16 | proto);
}

static_always_inline punt_client_t *
punt_client_ip_proto_get (ip_address_family_t af, ip_protocol_t proto)
{
  punt_main_t *pm = &punt_main;
  uword *p;

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

  if (p)
    return (pool_elt_at_index (pm->punt_client_pool, p[0]));

  return (NULL);
}

static_always_inline punt_client_t *
punt_client_exception_get (vlib_punt_reason_t reason)
{
  punt_main_t *pm = &punt_main;
  u32 pci;

  if (reason >= vec_len (pm->db.clients_by_exception))
    return (NULL);

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

  if (~0 != pci)
    return (pool_elt_at_index (pm->punt_client_pool, pci));

  return (NULL);
}

extern vlib_node_registration_t udp4_punt_node;
extern vlib_node_registration_t udp6_punt_node;
extern vlib_node_registration_t udp4_punt_socket_node;
extern vlib_node_registration_t udp6_punt_socket_node;
extern vlib_node_registration_t ip4_proto_punt_socket_node;
extern vlib_node_registration_t ip6_proto_punt_socket_node;
extern vlib_node_registration_t punt_socket_rx_node;

#endif

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