/*
 * 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/ip/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 ?? RFC doesn't say
     */
    u32 oui;
    /**
     * @brief VPN-ID
     */
    u32 fib_id;
} dhcp_vss_t;

/**
 * @brief A DHCP proxy server represenation
 */
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 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 server
     *        is reachable.
     */
    u32 server_fib_index;

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

#define DHCP_N_PROTOS (FIB_PROTOCOL_IP6 + 1)

/**
 * @brief Collection of global DHCP proxy data
 */
typedef struct {
  /* Pool of DHCP servers */
  dhcp_server_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,
                        const ip46_address_t *server,
                        const ip46_address_t *src,
                        u32 server_fib_id,
                        u32 rx_fib_id,
                        u32 vss_fib_id,
                        u32 vss_oui);

/**
 * @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 vrf_id,
                       u32 oui,
                       u32 fib_id,
                       int 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 0 is deleted, otherwise an error code
 */
int dhcp_proxy_server_del(fib_protocol_t proto,
                          u32 rx_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_server_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 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_server_t *
dhcp_get_server (dhcp_proxy_main_t *dm,
                 u32 rx_fib_index,
                 fib_protocol_t proto)
{
  dhcp_server_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 */
