/*
 * Copyright (c) 2016 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 __ADJ_INTERNAL_H__
#define __ADJ_INTERNAL_H__

#include <vnet/adj/adj.h>
#include <vnet/adj/adj_mcast.h>
#include <vnet/ip/ip.h>
#include <vnet/mpls/mpls.h>
#include <vnet/adj/adj_l2.h>
#include <vnet/adj/adj_nsh.h>

/**
 * big switch to turn on Adjacency debugging
 */
#undef ADJ_DEBUG

/*
 * Debug macro
 */
extern vlib_log_class_t adj_logger;
#define ADJ_DBG(_adj, _fmt, _args...)		        \
{                                                       \
    vlib_log_debug(adj_logger, "adj:[%d:%p]:" _fmt,     \
                   _adj - adj_pool, _adj,		\
                   ##_args);                            \
}

/*
 * Vlib nodes
 */
extern vlib_node_registration_t adj_nsh_midchain_node;
extern vlib_node_registration_t adj_nsh_rewrite_node;
extern vlib_node_registration_t adj_midchain_tx;

static inline u32
adj_get_rewrite_node (vnet_link_t linkt)
{
    switch (linkt) {
    case VNET_LINK_IP4:
	return (ip4_rewrite_node.index);
    case VNET_LINK_IP6:
	return (ip6_rewrite_node.index);
    case VNET_LINK_MPLS:
	return (mpls_output_node.index);
    case VNET_LINK_ETHERNET:
        return (adj_l2_rewrite_node.index);
    case VNET_LINK_NSH:
        return (adj_nsh_rewrite_node.index);
    case VNET_LINK_ARP:
	break;
    }
    ASSERT(0);
    return (0);
}

static inline vnet_link_t
adj_fib_proto_2_nd (fib_protocol_t fp)
{
    switch (fp)
    {
    case FIB_PROTOCOL_IP4:
	return (VNET_LINK_ARP);
    case FIB_PROTOCOL_IP6:
	return (VNET_LINK_IP6);
    case FIB_PROTOCOL_MPLS:
	return (VNET_LINK_MPLS);
    }
    return (0);
}

static inline ip46_type_t
adj_proto_to_46 (fib_protocol_t proto)
{
    switch (proto)
    {
    case FIB_PROTOCOL_IP4:
	return (IP46_TYPE_IP4);
    case FIB_PROTOCOL_IP6:
	return (IP46_TYPE_IP6);
    default:
	return (IP46_TYPE_IP4);
    }
    return (IP46_TYPE_IP4);
}

/**
 * @brief
 * Get a pointer to an adjacency object from its index
 */
static inline adj_index_t
adj_get_index (const ip_adjacency_t *adj)
{
    return (adj - adj_pool);
}

extern void adj_nbr_update_rewrite_internal(ip_adjacency_t *adj,
                                            ip_lookup_next_t adj_next_index,
                                            u32 complete_next_index,
                                            u32 next_index,
                                            u8 *rewrite);
extern void adj_midchain_setup(adj_index_t adj_index,
                               adj_midchain_fixup_t fixup,
                               const void *data,
                               adj_flags_t flags);

extern ip_adjacency_t * adj_alloc(fib_protocol_t proto);

extern void adj_nbr_remove(adj_index_t ai,
                           fib_protocol_t nh_proto,
			   vnet_link_t link_type,
			   const ip46_address_t *nh_addr,
			   u32 sw_if_index);
extern u32 adj_nbr_get_n_adjs(vnet_link_t link_type, u32 sw_if_index);
extern void adj_glean_remove(ip_adjacency_t *adj);
extern void adj_mcast_remove(fib_protocol_t proto,
			     u32 sw_if_index);
extern void adj_midchain_teardown(ip_adjacency_t *adj);

extern u32 adj_dpo_get_urpf(const dpo_id_t *dpo);
extern u16 adj_dpo_get_mtu(const dpo_id_t *dpo);

/*
 * Adj BFD
 */
extern int adj_bfd_is_up (adj_index_t ai);

/*
 * Adj delegates
 */ 
extern void adj_delegate_adj_deleted(ip_adjacency_t *adj);
extern void adj_delegate_adj_created(ip_adjacency_t *adj);
extern void adj_delegate_adj_modified(ip_adjacency_t *adj);
extern u8* adj_delegate_format(u8* s, ip_adjacency_t *adj);

#endif
