/*
 * 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 punt_thread_data_t_
{
  struct iovec *iovecs;
} punt_thread_data_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;
  punt_thread_data_t *thread_data;
  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:
 */
