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

  /* 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 server ports, if not already done
 */
void dhcp_maybe_register_udp_ports (void);

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