/*
 * dhcp_proxy.h: DHCP v4 & v6 proxy common functions/types
 *
 * Copyright (c) 2013 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.
 */

#ifndef included_dhcp_proxy_h
#define included_dhcp_proxy_h

#include <vnet/vnet.h>
#include <vnet/dhcp/dhcp4_packet.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/ip4.h>
#include <vnet/ip/ip4_packet.h>
#include <vnet/pg/pg.h>
#include <vnet/ip/format.h>
#include <vnet/udp/udp.h>

typedef enum
{
#define dhcp_proxy_error(n,s) DHCP_PROXY_ERROR_##n,
#include <vnet/dhcp/dhcp4_proxy_error.def>
#undef dhcp_proxy_error
  DHCP_PROXY_N_ERROR,
} dhcp_proxy_error_t;

typedef enum
{
#define dhcpv6_proxy_error(n,s) DHCPV6_PROXY_ERROR_##n,
#include <vnet/dhcp/dhcp6_proxy_error.def>
#undef dhcpv6_proxy_error
  DHCPV6_PROXY_N_ERROR,
} dhcpv6_proxy_error_t;


/**
 * @brief The Virtual Sub-net Selection information for a given RX FIB
 */
typedef struct dhcp_vss_t_
{
    /**
     * @brief VSS type as defined in RFC 6607:
     *	 0 for NVT ASCII VPN Identifier
     *   1 for RFC 2685 VPN-ID of 7 octects - 3 bytes OUI & 4 bytes VPN index
     *   255 for global default VPN
     */
  u8 vss_type;
#define VSS_TYPE_ASCII 0
#define VSS_TYPE_VPN_ID 1
#define VSS_TYPE_INVALID 123
#define VSS_TYPE_DEFAULT 255
    /**
     * @brief Type 1 VPN-ID
     */
  u8 vpn_id[7];
    /**
     * @brief Type 0 ASCII VPN Identifier
     */
  u8 *vpn_ascii_id;
} dhcp_vss_t;

/**
 * @brief A representation of a single DHCP Server within a given VRF config
 */
typedef struct dhcp_server_t_
{
    /**
     * @brief The address of the DHCP server to which to relay the client's
     *        messages
     */
  ip46_address_t dhcp_server;

    /**
     * @brief The FIB index (not the external Table-ID) in which the server
     *        is reachable.
     */
  u32 server_fib_index;
} dhcp_server_t;

/**
 * @brief A DHCP proxy represenation fpr per-client VRF config
 */
typedef struct dhcp_proxy_t_
{
    /**
     * @brief The set of DHCP servers to which messages are relayed.
     *  If multiple servers are configured then discover/solict messages
     * are relayed to each. A cookie is maintained for the relay, and only
     * one message is replayed to the client, based on the presence of the
     * cookie.
     * The expectation is there are only 1 or 2 servers, hence no fancy DB.
     */
  dhcp_server_t *dhcp_servers;

    /**
     * @brief Hash table of pending requets key'd on the clients MAC address
     */
  uword *dhcp_pending;

    /**
     * @brief A lock for the pending request DB.
     */
  int lock;

    /**
     * @brief The source address to use in relayed messaes
     */
  ip46_address_t dhcp_src_address;

    /**
     * @brief The FIB index (not the external Table-ID) in which the client
     *        is resides.
     */
  u32 rx_fib_index;
} dhcp_proxy_t;

#define DHCP_N_PROTOS (FIB_PROTOCOL_IP6 + 1)

/**
 * @brief Collection of global DHCP proxy data
 */
typedef struct
{
  /* Pool of DHCP servers */
  dhcp_proxy_t *dhcp_servers[DHCP_N_PROTOS];

  /* Pool of selected DHCP server. Zero is the default server */
  u32 *dhcp_server_index_by_rx_fib_index[DHCP_N_PROTOS];

  /* to drop pkts in server-to-client direction */
  u32 error_drop_node_index;

  dhcp_vss_t *vss[DHCP_N_PROTOS];

  /* hash lookup specific vrf_id -> option 82 vss suboption  */
  u32 *vss_index_by_rx_fib_index[DHCP_N_PROTOS];
} dhcp_proxy_main_t;

extern dhcp_proxy_main_t dhcp_proxy_main;

/**
 * @brief Send the details of a proxy session to the API client during a dump
 */
void dhcp_send_details (fib_protocol_t proto,
			void *opaque, u32 context, dhcp_proxy_t * proxy);

/**
 * @brief Show (on CLI) a VSS config during a show walk
 */
int dhcp_vss_show_walk (dhcp_vss_t * vss, u32 rx_table_id, void *ctx);

/**
 * @brief Configure/set a new VSS info
 */
int dhcp_proxy_set_vss (fib_protocol_t proto,
			u32 tbl_id,
			u8 vss_type,
			u8 * vpn_ascii_id, u32 oui, u32 vpn_index, u8 is_del);

/**
 * @brief Dump the proxy configs to the API
 */
void dhcp_proxy_dump (fib_protocol_t proto, void *opaque, u32 context);

/**
 * @brief Add a new DHCP proxy server configuration.
 * @return 1 is the config is new,
 *         0 otherwise (implying a modify of an existing)
 */
int dhcp_proxy_server_add (fib_protocol_t proto,
			   ip46_address_t * addr,
			   ip46_address_t * src_address,
			   u32 rx_fib_iindex, u32 server_table_id);

/**
 * @brief Delete a DHCP proxy config
 * @return 1 if the proxy is deleted, 0 otherwise
 */
int dhcp_proxy_server_del (fib_protocol_t proto,
			   u32 rx_fib_index,
			   ip46_address_t * addr, u32 server_table_id);

u32 dhcp_proxy_rx_table_get_table_id (fib_protocol_t proto, u32 fib_index);

/**
 * @brief Callback function invoked for each DHCP proxy entry
 *  return 0 to break the walk, non-zero otherwise.
 */
typedef int (*dhcp_proxy_walk_fn_t) (dhcp_proxy_t * server, void *ctx);

/**
 * @brief Walk/Visit each DHCP proxy server
 */
void dhcp_proxy_walk (fib_protocol_t proto,
		      dhcp_proxy_walk_fn_t fn, void *ctx);

/**
 * @brief Callback function invoked for each DHCP VSS entry
 *  return 0 to break the walk, non-zero otherwise.
 */
typedef int (*dhcp_vss_walk_fn_t) (dhcp_vss_t * server,
				   u32 rx_table_id, void *ctx);

/**
 * @brief Walk/Visit each DHCP proxy VSS
 */
void dhcp_vss_walk (fib_protocol_t proto, dhcp_vss_walk_fn_t fn, void *ctx);

/**
 * @brief Lock a proxy object to prevent simultaneous access of its
 *  pending store
 */
void dhcp_proxy_lock (dhcp_proxy_t * server);

/**
 * @brief Lock a proxy object to prevent simultaneous access of its
 *  pending store
 */
void dhcp_proxy_unlock (dhcp_proxy_t * server);

/**
 * @brief Get the VSS data for the FIB index
 */
static inline dhcp_vss_t *
dhcp_get_vss_info (dhcp_proxy_main_t * dm,
		   u32 rx_fib_index, fib_protocol_t proto)
{
  dhcp_vss_t *v = NULL;

  if (vec_len (dm->vss_index_by_rx_fib_index[proto]) > rx_fib_index &&
      dm->vss_index_by_rx_fib_index[proto][rx_fib_index] != ~0)
    {
      v = pool_elt_at_index (dm->vss[proto],
			     dm->vss_index_by_rx_fib_index[proto]
			     [rx_fib_index]);
    }

  return (v);
}

/**
 * @brief Get the DHCP proxy server data for the FIB index
 */
static inline dhcp_proxy_t *
dhcp_get_proxy (dhcp_proxy_main_t * dm,
		u32 rx_fib_index, fib_protocol_t proto)
{
  dhcp_proxy_t *s = NULL;

  if (vec_len (dm->dhcp_server_index_by_rx_fib_index[proto]) > rx_fib_index &&
      dm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] != ~0)
    {
      s = pool_elt_at_index (dm->dhcp_servers[proto],
			     dm->dhcp_server_index_by_rx_fib_index[proto]
			     [rx_fib_index]);
    }

  return (s);
}

int dhcp6_proxy_set_server (ip46_address_t * addr,
			    ip46_address_t * src_addr,
			    u32 rx_table_id, u32 server_table_id, int is_del);
int dhcp4_proxy_set_server (ip46_address_t * addr,
			    ip46_address_t * src_addr,
			    u32 rx_table_id, u32 server_table_id, int is_del);

#endif /* included_dhcp_proxy_h */

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