/*
 * 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 <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/ip/format.h>
#include <vnet/udp/udp_local.h>

typedef enum
{
#define dhcp_proxy_error(n,s) DHCP_PROXY_ERROR_##n,
#include <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 <dhcp/dhcp6_proxy_error.def>
#undef dhcpv6_proxy_error
  DHCPV6_PROXY_N_ERROR,
} dhcpv6_proxy_error_t;

/* flags to indicate which DHCP ports should be or have been registered */
typedef enum
{
  DHCP_PORT_REG_CLIENT = 0x1,
  DHCP_PORT_REG_SERVER = 0x2,
} dhcp_port_reg_flags_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 representation 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];

  /* flags to indicate which udp ports have been registered */
  int udp_ports_registered;

  /* convenience */
  vlib_main_t *vlib_main;

} dhcp_proxy_main_t;

extern dhcp_proxy_main_t dhcp_proxy_main;

/**
 * @brief Register the dhcp client and/or server ports, if not already done
 */
void dhcp_maybe_register_udp_ports (dhcp_port_reg_flags_t ports);

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