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

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

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