/*
 * 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.
 */
/**
 * @brief
 * Neighbour Adjacency sub-type. These adjs represent an L3 peer on a
 * connected link. 
 */

#ifndef __ADJ_NBR_H__
#define __ADJ_NBR_H__

#include <vnet/vnet.h>
#include <vnet/adj/adj_types.h>
#include <vnet/fib/fib_node.h>
#include <vnet/dpo/dpo.h>

/**
 * @brief
 *  Add (and lock) a new or lock an existing neighbour adjacency
 *
 * @param nh_proto
 *  The protocol for the next-hop address (v4 or v6)
 *
 * @param link_type
 *  A description of the protocol of the packets that will forward
 *  through this adj. On an ethernet interface this is the MAC header's
 *  ether-type
 *
 * @param nh_addr
 *  The address of the next-hop/peer to send the packet to
 *
 * @param sw_if_index
 *  The interface on which the peer resides
 */
extern adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto,
				       vnet_link_t link_type,
				       const ip46_address_t *nh_addr,
				       u32 sw_if_index);

/**
 * @brief
 *  Add (and lock) a new or lock an existing neighbour adjacency
 *
 * @param nh_proto
 *  The protocol for the next-hop address (v4 or v6)
 *
 * @param link_type
 *  A description of the protocol of the packets that will forward
 *  through this adj. On an ethernet interface this is the MAC header's
 *  ether-type
 *
 * @param nh_addr
 *  The address of the next-hop/peer to send the packet to
 *
 * @param sw_if_index
 *  The interface on which the peer resides
 *
 * @param rewrite
 *  The rewrite to prepend to packets
 */
extern adj_index_t adj_nbr_add_or_lock_w_rewrite(fib_protocol_t nh_proto,
						 vnet_link_t link_type,
						 const ip46_address_t *nh_addr,
						 u32 sw_if_index,
						 u8 *rewrite);
/**
 * @brief When adding a rewrite to an adjacency these are flags that
 * apply to that rewrite
 */
typedef enum adj_nbr_rewrite_flag_t_
{
    ADJ_NBR_REWRITE_FLAG_NONE,

    /**
     * An indication that the rewrite is incomplete, i.e. that it describes the
     * ARP/ND rewrite when probing.
     */
    ADJ_NBR_REWRITE_FLAG_INCOMPLETE = ADJ_NBR_REWRITE_FLAG_NONE,

    /**
     * An indication that the rewrite is complete, i.e. that it fully describes
     * the link-layer addressing for the desintation.
     * The opposite of this is an incomplete rewrite that describes the ARP/ND
     * rewrite when probing.
     */
    ADJ_NBR_REWRITE_FLAG_COMPLETE = (1 << 0),
} adj_nbr_rewrite_flag_t;

/**
 * @brief
 *  Update the rewrite string for an existing adjacecny.
 *
 * @param
 *  The index of the adj to update
 *
 * @param
 *  The new rewrite
 */
extern void adj_nbr_update_rewrite(adj_index_t adj_index,
				   adj_nbr_rewrite_flag_t flags,
				   u8 *rewrite);

/**
 * @brief
 * Format aa incomplete neigbour (ARP) adjacency
 */
extern u8* format_adj_nbr_incomplete(u8* s, va_list *ap);

/**
 * @brief
 * Format a neigbour (REWRITE) adjacency
 */
extern u8* format_adj_nbr(u8* s, va_list *ap);

/**
 * @brief Walk the neighbour Adjacencies on a given interface
 */
extern void adj_nbr_walk (u32 sw_if_index,
			  fib_protocol_t adj_nh_proto,
			  adj_walk_cb_t cb,
			  void *ctx);
/**
 * @brief Walk the neighbour Adjacencies on a given interface with a given next-hop
 */
void
adj_nbr_walk_nh (u32 sw_if_index,
		 fib_protocol_t adj_nh_proto,
		 const ip46_address_t *nh,
		 adj_walk_cb_t cb,
		 void *ctx);

/**
 * @brief Walk adjacencies on a link with a given v4 next-hop.
 * that is visit the adjacencies with different link types.
 */
void
adj_nbr_walk_nh4 (u32 sw_if_index,
		  const ip4_address_t *addr,
		  adj_walk_cb_t cb,
		  void *ctx);

/**
 * @brief Walk adjacencies on a link with a given v6 next-hop.
 * that is visit the adjacencies with different link types.
 */
void
adj_nbr_walk_nh6 (u32 sw_if_index,
		  const ip6_address_t *addr,
		  adj_walk_cb_t cb,
		  void *ctx);

/**
 * @brief
 *  Module initialisation
 */
extern void adj_nbr_module_init(void);

/**
 * @brief
 *  Return the size of the adjacency database. for testing purposes
 */
extern u32 adj_nbr_db_size(void);

#endif
