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

#include <vlib/vlib.h>
#include <vnet/ip/format.h>
#include <vnet/ip/lookup.h>
#include <vnet/adj/adj.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/dpo/drop_dpo.h>

#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_walk.h>
#include <vnet/fib/fib_entry_src.h>
#include <vnet/fib/fib_entry_cover.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_internal.h>
#include <vnet/fib/fib_attached_export.h>
#include <vnet/fib/fib_path_ext.h>
#include <vnet/fib/fib_entry_delegate.h>
#include <vnet/fib/fib_entry_track.h>

/*
 * Array of strings/names for the FIB sources
 */
static const char *fib_attribute_names[] = FIB_ENTRY_ATTRIBUTES;
static const char *fib_src_attribute_names[] = FIB_ENTRY_SRC_ATTRIBUTES;

/*
 * Pool for all fib_entries
 */
static fib_entry_t *fib_entry_pool;

/**
 * the logger
 */
vlib_log_class_t fib_entry_logger;

fib_entry_t *
fib_entry_get (fib_node_index_t index)
{
    return (pool_elt_at_index(fib_entry_pool, index));
}

static fib_node_t *
fib_entry_get_node (fib_node_index_t index)
{
    return ((fib_node_t*)fib_entry_get(index));
}

fib_node_index_t
fib_entry_get_index (const fib_entry_t * fib_entry)
{
    return (fib_entry - fib_entry_pool);
}

fib_protocol_t
fib_entry_get_proto (const fib_entry_t * fib_entry)
{
    return (fib_entry->fe_prefix.fp_proto);
}

dpo_proto_t
fib_entry_get_dpo_proto (const fib_entry_t * fib_entry)
{
    return (fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto));
}

fib_forward_chain_type_t
fib_entry_get_default_chain_type (const fib_entry_t *fib_entry)
{
    switch (fib_entry->fe_prefix.fp_proto)
    {
    case FIB_PROTOCOL_IP4:
	return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
    case FIB_PROTOCOL_IP6:
	return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
    case FIB_PROTOCOL_MPLS:
	if (MPLS_EOS == fib_entry->fe_prefix.fp_eos)
	    return (FIB_FORW_CHAIN_TYPE_MPLS_EOS);
	else
	    return (FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS);
    }

    return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
}

u8 *
format_fib_entry_flags (u8 *s, va_list *args)
{
    fib_entry_attribute_t attr;
    fib_entry_flag_t flag = va_arg(*args, int);

    FOR_EACH_FIB_ATTRIBUTE(attr) {
        if ((1<<attr) & flag) {
            s = format (s, "%s,", fib_attribute_names[attr]);
        }
    }

    return (s);
}

u8 *
format_fib_entry_src_flags (u8 *s, va_list *args)
{
    fib_entry_src_attribute_t sattr;
    fib_entry_src_flag_t flag = va_arg(*args, int);

    FOR_EACH_FIB_SRC_ATTRIBUTE(sattr) {
        if ((1<<sattr) & flag) {
            s = format (s, "%s,", fib_src_attribute_names[sattr]);
        }
    }

    return (s);
}

u8 *
format_fib_entry (u8 * s, va_list * args)
{
    fib_forward_chain_type_t fct;
    fib_entry_t *fib_entry;
    fib_entry_src_t *src;
    fib_node_index_t fei;
    fib_source_t source;
    int level;

    fei = va_arg (*args, fib_node_index_t);
    level = va_arg (*args, int);
    fib_entry = fib_entry_get(fei);

    s = format (s, "%U", format_fib_prefix, &fib_entry->fe_prefix);

    if (level >= FIB_ENTRY_FORMAT_DETAIL)
    {
	s = format (s, " fib:%d", fib_entry->fe_fib_index);
	s = format (s, " index:%d", fib_entry_get_index(fib_entry));
	s = format (s, " locks:%d", fib_entry->fe_node.fn_locks);

	FOR_EACH_SRC_ADDED(fib_entry, src, source,
        ({
	    s = format (s, "\n  %U", format_fib_source, source);
	    s = format (s, " refs:%d", src->fes_ref_count);
	    if (FIB_ENTRY_FLAG_NONE != src->fes_entry_flags) {
		s = format(s, " entry-flags:%U",
                           format_fib_entry_flags, src->fes_entry_flags);
	    }
	    if (FIB_ENTRY_SRC_FLAG_NONE != src->fes_flags) {
		s = format(s, " src-flags:%U",
                           format_fib_entry_src_flags, src->fes_flags);
	    }
            s = fib_entry_src_format(fib_entry, source, s);
	    s = format (s, "\n");
	    if (FIB_NODE_INDEX_INVALID != src->fes_pl)
	    {
		s = fib_path_list_format(src->fes_pl, s);
	    }
            s = format(s, "%U", format_fib_path_ext_list, &src->fes_path_exts);
	}));
    
	s = format (s, "\n forwarding: ");
    }
    else
    {
	s = format (s, "\n");
    }

    fct = fib_entry_get_default_chain_type(fib_entry);

    if (!dpo_id_is_valid(&fib_entry->fe_lb))
    {
	s = format (s, "  UNRESOLVED\n");
	return (s);
    }
    else
    {
        s = format(s, "  %U-chain\n  %U",
                   format_fib_forw_chain_type, fct,
                   format_dpo_id,
                   &fib_entry->fe_lb,
                   2);
        s = format(s, "\n");

        if (level >= FIB_ENTRY_FORMAT_DETAIL2)
        {
            index_t *fedi;

            s = format (s, " Delegates:\n");
            vec_foreach(fedi, fib_entry->fe_delegates)
            {
                s = format(s, "  %U\n", format_fib_entry_delegate, *fedi);
            }
        }
    }

    if (level >= FIB_ENTRY_FORMAT_DETAIL2)
    {
        s = format(s, " Children:");
        s = fib_node_children_format(fib_entry->fe_node.fn_children, s);
    }

    return (s);
}

static fib_entry_t*
fib_entry_from_fib_node (fib_node_t *node)
{
    ASSERT(FIB_NODE_TYPE_ENTRY == node->fn_type);
    return ((fib_entry_t*)node);
}

static void
fib_entry_last_lock_gone (fib_node_t *node)
{
    fib_entry_delegate_type_t fdt;
    fib_entry_delegate_t *fed;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_from_fib_node(node);

    ASSERT(!dpo_id_is_valid(&fib_entry->fe_lb));

    FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
    {
	dpo_reset(&fed->fd_dpo);
        fib_entry_delegate_remove(fib_entry, fdt);
    });

    FIB_ENTRY_DBG(fib_entry, "last-lock");

    fib_node_deinit(&fib_entry->fe_node);

    ASSERT(0 == vec_len(fib_entry->fe_delegates));
    vec_free(fib_entry->fe_delegates);
    vec_free(fib_entry->fe_srcs);
    pool_put(fib_entry_pool, fib_entry);
}

static fib_entry_src_t*
fib_entry_get_best_src_i (const fib_entry_t *fib_entry)
{
    fib_entry_src_t *bsrc;

    /*
     * the enum of sources is deliberately arranged in priority order
     */
    if (0 == vec_len(fib_entry->fe_srcs))
    {
	bsrc = NULL;
    }
    else
    {
	bsrc = vec_elt_at_index(fib_entry->fe_srcs, 0);
    }

    return (bsrc);
}

static fib_source_t
fib_entry_src_get_source (const fib_entry_src_t *esrc)
{
    if (NULL != esrc)
    {
	return (esrc->fes_src);
    }
    return (FIB_SOURCE_INVALID);
}

static fib_entry_flag_t
fib_entry_src_get_flags (const fib_entry_src_t *esrc)
{
    if (NULL != esrc)
    {
	return (esrc->fes_entry_flags);
    }
    return (FIB_ENTRY_FLAG_NONE);
}

fib_entry_flag_t
fib_entry_get_flags (fib_node_index_t fib_entry_index)
{
    return (fib_entry_get_flags_i(fib_entry_get(fib_entry_index)));
}

/*
 * fib_entry_back_walk_notify
 *
 * A back walk has reach this entry.
 */
static fib_node_back_walk_rc_t
fib_entry_back_walk_notify (fib_node_t *node,
			    fib_node_back_walk_ctx_t *ctx)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_from_fib_node(node);

    if (FIB_NODE_BW_REASON_FLAG_EVALUATE & ctx->fnbw_reason        ||
        FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason      ||
        FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason        ||
	FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason    ||
	FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason  ||
	FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason)
    {
	fib_entry_src_action_reactivate(fib_entry,
                                        fib_entry_get_best_source(
                                            fib_entry_get_index(fib_entry)));
    }

    /*
     * all other walk types can be reclassifed to a re-evaluate to
     * all recursive dependents.
     * By reclassifying we ensure that should any of these walk types meet
     * they can be merged.
     */
    ctx->fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;

    /*
     * ... and nothing is forced sync from now on.
     */
    ctx->fnbw_flags &= ~FIB_NODE_BW_FLAG_FORCE_SYNC;

    FIB_ENTRY_DBG(fib_entry, "bw:%U",
                  format_fib_node_bw_reason, ctx->fnbw_reason);

    /*
     * propagate the backwalk further if we haven't already reached the
     * maximum depth.
     */
    fib_walk_sync(FIB_NODE_TYPE_ENTRY,
		  fib_entry_get_index(fib_entry),
		  ctx);

    return (FIB_NODE_BACK_WALK_CONTINUE);
}

static void
fib_entry_show_memory (void)
{
    u32 n_srcs = 0, n_exts = 0;
    fib_entry_src_t *esrc;
    fib_entry_t *entry;

    fib_show_memory_usage("Entry",
			  pool_elts(fib_entry_pool),
			  pool_len(fib_entry_pool),
			  sizeof(fib_entry_t));

    pool_foreach(entry, fib_entry_pool,
    ({
	n_srcs += vec_len(entry->fe_srcs);
	vec_foreach(esrc, entry->fe_srcs)
	{
	    n_exts += fib_path_ext_list_length(&esrc->fes_path_exts);
	}
    }));

    fib_show_memory_usage("Entry Source",
			  n_srcs, n_srcs, sizeof(fib_entry_src_t));
    fib_show_memory_usage("Entry Path-Extensions",
			  n_exts, n_exts,
			  sizeof(fib_path_ext_t));
}

/*
 * The FIB path-list's graph node virtual function table
 */
static const fib_node_vft_t fib_entry_vft = {
    .fnv_get = fib_entry_get_node,
    .fnv_last_lock = fib_entry_last_lock_gone,
    .fnv_back_walk = fib_entry_back_walk_notify,
    .fnv_mem_show = fib_entry_show_memory,
};

/**
 * @brief Contribute the set of Adjacencies that this entry forwards with
 * to build the uRPF list of its children
 */
void
fib_entry_contribute_urpf (fib_node_index_t entry_index,
			   index_t urpf)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(entry_index);

    return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf));
}

/*
 * If the client is request a chain for multicast forwarding then swap
 * the chain type to one that can provide such transport.
 */
static fib_forward_chain_type_t
fib_entry_chain_type_mcast_to_ucast (fib_forward_chain_type_t fct)
{
    switch (fct)
    {
    case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
    case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
        /*
         * we can only transport IP multicast packets if there is an
         * LSP.
         */
        fct = FIB_FORW_CHAIN_TYPE_MPLS_EOS;
        break;
    case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
    case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
    case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
    case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
    case FIB_FORW_CHAIN_TYPE_ETHERNET:
    case FIB_FORW_CHAIN_TYPE_NSH:
    case FIB_FORW_CHAIN_TYPE_BIER:
        break;
    }

    return (fct);
}

/*
 * fib_entry_contribute_forwarding
 *
 * Get an lock the forwarding information (DPO) contributed by the FIB entry.
 */
void
fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index,
				 fib_forward_chain_type_t fct,
				 dpo_id_t *dpo)
{
    fib_entry_delegate_t *fed;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    /*
     * mfib children ask for mcast chains. fix these to the appropriate ucast types.
     */
    fct = fib_entry_chain_type_mcast_to_ucast(fct);

    if (fct == fib_entry_get_default_chain_type(fib_entry))
    {
        dpo_copy(dpo, &fib_entry->fe_lb);
    }
    else
    {
        fed = fib_entry_delegate_find(fib_entry,
                                      fib_entry_chain_type_to_delegate_type(fct));

        if (NULL == fed)
        {
            /*
             * use a temporary DPO lest the delegate realloc in the recursive
             * calculation.
             */
            dpo_id_t tmp = DPO_INVALID;

            /*
             * on-demand create eos/non-eos.
             * There is no on-demand delete because:
             *   - memory versus complexity & reliability:
             *      leaving unrequired [n]eos LB arounds wastes memory, cleaning
             *      then up on the right trigger is more code. i favour the latter.
             */
            fib_entry_src_mk_lb(fib_entry,
                                fib_entry_get_best_src_i(fib_entry),
                                fct,
                                &tmp);

            fed = fib_entry_delegate_find_or_add(
                fib_entry,
                fib_entry_chain_type_to_delegate_type(fct));

            dpo_copy(&fed->fd_dpo, &tmp);
            dpo_reset(&tmp);
        }

        dpo_copy(dpo, &fed->fd_dpo);
    }
    /*
     * use the drop DPO is nothing else is present
     */
    if (!dpo_id_is_valid(dpo))
    {
        dpo_copy(dpo, drop_dpo_get(fib_forw_chain_type_to_dpo_proto(fct)));
    }

    /*
     * don't allow the special index indicating replicate.vs.load-balance
     * to escape to the clients
     */
    dpo->dpoi_index &= ~MPLS_IS_REPLICATE;
}

const dpo_id_t *
fib_entry_contribute_ip_forwarding (fib_node_index_t fib_entry_index)
{
    fib_forward_chain_type_t fct;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);
    fct = fib_entry_get_default_chain_type(fib_entry);

    ASSERT((fct == FIB_FORW_CHAIN_TYPE_UNICAST_IP4 ||
            fct == FIB_FORW_CHAIN_TYPE_UNICAST_IP6));

    if (dpo_id_is_valid(&fib_entry->fe_lb))
    {
        return (&fib_entry->fe_lb);
    }

    return (drop_dpo_get(fib_forw_chain_type_to_dpo_proto(fct)));
}

adj_index_t
fib_entry_get_adj (fib_node_index_t fib_entry_index)
{
    const dpo_id_t *dpo;

    dpo = fib_entry_contribute_ip_forwarding(fib_entry_index);

    if (dpo_id_is_valid(dpo))
    {
        dpo = load_balance_get_bucket(dpo->dpoi_index, 0);

        if (dpo_is_adj(dpo))
        {
            return (dpo->dpoi_index);
        }
    }
    return (ADJ_INDEX_INVALID);
}

fib_node_index_t
fib_entry_get_path_list (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    return (fib_entry->fe_parent);
}

u32
fib_entry_child_add (fib_node_index_t fib_entry_index,
		     fib_node_type_t child_type,
		     fib_node_index_t child_index)
{
    return (fib_node_child_add(FIB_NODE_TYPE_ENTRY,
                               fib_entry_index,
                               child_type,
                               child_index));
};

void
fib_entry_child_remove (fib_node_index_t fib_entry_index,
			u32 sibling_index)
{
    fib_node_child_remove(FIB_NODE_TYPE_ENTRY,
                          fib_entry_index,
                          sibling_index);

    if (0 == fib_node_get_n_children(FIB_NODE_TYPE_ENTRY,
                                     fib_entry_index))
    {
        /*
         * if there are no children left then there is no reason to keep
         * the non-default forwarding chains. those chains are built only
         * because the children want them.
         */
        fib_entry_delegate_type_t fdt;
        fib_entry_delegate_t *fed;
        fib_entry_t *fib_entry;

        fib_entry = fib_entry_get(fib_entry_index);

        FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
        {
            dpo_reset(&fed->fd_dpo);
            fib_entry_delegate_remove(fib_entry, fdt);
        });
    }
}

static fib_entry_t *
fib_entry_alloc (u32 fib_index,
		 const fib_prefix_t *prefix,
		 fib_node_index_t *fib_entry_index)
{
    fib_entry_t *fib_entry;
    fib_prefix_t *fep;

    pool_get(fib_entry_pool, fib_entry);
    clib_memset(fib_entry, 0, sizeof(*fib_entry));

    fib_node_init(&fib_entry->fe_node,
		  FIB_NODE_TYPE_ENTRY);

    fib_entry->fe_fib_index = fib_index;

    /*
     * the one time we need to update the const prefix is when
     * the entry is first created
     */
    fep = (fib_prefix_t*)&(fib_entry->fe_prefix);
    *fep = *prefix;

    if (FIB_PROTOCOL_MPLS == fib_entry->fe_prefix.fp_proto)
    {
	fep->fp_len = 21;
	if (MPLS_NON_EOS == fep->fp_eos)
	{
	    fep->fp_payload_proto = DPO_PROTO_MPLS;
	}
    	ASSERT(DPO_PROTO_NONE != fib_entry->fe_prefix.fp_payload_proto);
    }

    dpo_reset(&fib_entry->fe_lb);

    *fib_entry_index = fib_entry_get_index(fib_entry);

    return (fib_entry);
}

static fib_entry_t*
fib_entry_post_flag_update_actions (fib_entry_t *fib_entry,
				    fib_entry_flag_t old_flags)
{
    fib_node_index_t fei;

    /*
     * save the index so we can recover from pool reallocs
     */
    fei = fib_entry_get_index(fib_entry);

    /*
     * handle changes to attached export for import entries
     */
    int is_import  = (FIB_ENTRY_FLAG_IMPORT & fib_entry_get_flags_i(fib_entry));
    int was_import = (FIB_ENTRY_FLAG_IMPORT & old_flags);

    if (!was_import && is_import)
    {
	/*
	 * transition from not exported to exported
	 */

	/*
	 * there is an assumption here that the entry resolves via only
	 * one interface and that it is the cross VRF interface.
	 */
	u32 sw_if_index = fib_path_list_get_resolving_interface(fib_entry->fe_parent);

	fib_attached_export_import(fib_entry,
				   fib_table_get_index_for_sw_if_index(
				       fib_entry_get_proto(fib_entry),
                                       sw_if_index));
    }
    else if (was_import && !is_import)
    {
	/*
	 * transition from exported to not exported
	 */
	fib_attached_export_purge(fib_entry);
    }
    /*
     * else
     *   no change. nothing to do.
     */

    /*
     * reload the entry address post possible pool realloc
     */
    fib_entry = fib_entry_get(fei);

    /*
     * handle changes to attached export for export entries
     */
    int is_attached  = (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(fib_entry));
    int was_attached = (FIB_ENTRY_FLAG_ATTACHED & old_flags);

    if (!was_attached && is_attached)
    {
	/*
	 * transition to attached. time to export
	 */
	// FIXME
    }
    // else FIXME

    return (fib_entry);
}

static fib_entry_t*
fib_entry_post_install_actions (fib_entry_t *fib_entry,
				fib_source_t source,
				fib_entry_flag_t old_flags)
{
    fib_entry = fib_entry_post_flag_update_actions(fib_entry,
                                                   old_flags);
    fib_entry = fib_entry_src_action_installed(fib_entry, source);

    return (fib_entry);
}

fib_node_index_t
fib_entry_create (u32 fib_index,
		  const fib_prefix_t *prefix,
		  fib_source_t source,
		  fib_entry_flag_t flags,
		  const fib_route_path_t *paths)
{
    fib_node_index_t fib_entry_index;
    fib_entry_t *fib_entry;

    ASSERT(0 < vec_len(paths));

    fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);

    /*
     * since this is a new entry create, we don't need to check for winning
     * sources - there is only one.
     */
    fib_entry = fib_entry_src_action_add(fib_entry, source, flags,
                                         drop_dpo_get(
                                             fib_proto_to_dpo(
                                                 fib_entry_get_proto(fib_entry))));
    fib_entry_src_action_path_swap(fib_entry,
				   source,
				   flags,
				   paths);
    /*
     * handle possible realloc's by refetching the pointer
     */
    fib_entry = fib_entry_get(fib_entry_index);
    fib_entry_src_action_activate(fib_entry, source);

    fib_entry = fib_entry_post_install_actions(fib_entry, source,
                                               FIB_ENTRY_FLAG_NONE);

    FIB_ENTRY_DBG(fib_entry, "create");

    return (fib_entry_index);
}

fib_node_index_t
fib_entry_create_special (u32 fib_index,
			  const fib_prefix_t *prefix,
			  fib_source_t source,
			  fib_entry_flag_t flags,
			  const dpo_id_t *dpo)
{
    fib_node_index_t fib_entry_index;
    fib_entry_t *fib_entry;

    /*
     * create and initialize the new enty
     */
    fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);

    /*
     * create the path-list
     */
    fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
    fib_entry_src_action_activate(fib_entry, source);

    fib_entry = fib_entry_post_install_actions(fib_entry, source,
                                               FIB_ENTRY_FLAG_NONE);

    FIB_ENTRY_DBG(fib_entry, "create-special");

    return (fib_entry_index);
}

static void
fib_entry_post_update_actions (fib_entry_t *fib_entry,
			       fib_source_t source,
			       fib_entry_flag_t old_flags)
{
    /*
     * backwalk to children to inform then of the change to forwarding.
     */
    fib_node_back_walk_ctx_t bw_ctx = {
	.fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE,
    };

    fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_get_index(fib_entry), &bw_ctx);

    /*
     * then inform any covered prefixes
     */
    fib_entry_cover_update_notify(fib_entry);

    fib_entry_post_install_actions(fib_entry, source, old_flags);
}

void
fib_entry_recalculate_forwarding (fib_node_index_t fib_entry_index)
{
    fib_source_t best_source;
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(fib_entry_index);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);

    fib_entry_src_action_reactivate(fib_entry, best_source);
}

static void
fib_entry_source_change_w_flags (fib_entry_t *fib_entry,
                                 fib_source_t old_source,
                                 fib_entry_flag_t old_flags,
                                 fib_source_t new_source)
{
    switch (fib_source_cmp(new_source, old_source))
    {
    case FIB_SOURCE_CMP_BETTER:
	/*
	 * we have a new winning source.
	 */
	fib_entry_src_action_deactivate(fib_entry, old_source);
	fib_entry_src_action_activate(fib_entry, new_source);
        break;

    case FIB_SOURCE_CMP_WORSE:
        /*
         * the new source loses. Re-activate the winning sources
         * in case it is an interposer and hence relied on the losing
         * source's path-list.
         */
        fib_entry_src_action_reactivate(fib_entry, old_source);
        return;

    case FIB_SOURCE_CMP_EQUAL:
	/*
	 * the new source is one this entry already has.
	 * But the path-list was updated, which will contribute new forwarding,
	 * so install it.
	 */
        fib_entry_src_action_reactivate(fib_entry, new_source);
        break;
    }

    fib_entry_post_update_actions(fib_entry, new_source, old_flags);
}

void
fib_entry_source_change (fib_entry_t *fib_entry,
                         fib_source_t old_source,
			 fib_source_t new_source)
{
    fib_entry_flag_t old_flags;

    old_flags = fib_entry_get_flags_for_source(
        fib_entry_get_index(fib_entry), old_source);

    return (fib_entry_source_change_w_flags(fib_entry, old_source,
                                            old_flags, new_source));
}

void
fib_entry_special_add (fib_node_index_t fib_entry_index,
		       fib_source_t source,
		       fib_entry_flag_t flags,
		       const dpo_id_t *dpo)
{
    fib_source_t best_source;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);
    best_source = fib_entry_get_best_source(fib_entry_index);

    fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
    fib_entry_source_change(fib_entry, best_source, source);
    FIB_ENTRY_DBG(fib_entry, "special-add:%U", format_fib_source, source);
}

void
fib_entry_special_update (fib_node_index_t fib_entry_index,
			  fib_source_t source,
			  fib_entry_flag_t flags,
			  const dpo_id_t *dpo)
{
    fib_source_t best_source;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);
    best_source = fib_entry_get_best_source(fib_entry_index);

    fib_entry = fib_entry_src_action_update(fib_entry, source, flags, dpo);
    fib_entry_source_change(fib_entry, best_source, source);

    FIB_ENTRY_DBG(fib_entry, "special-updated:%U", format_fib_source, source);
}


void
fib_entry_path_add (fib_node_index_t fib_entry_index,
		    fib_source_t source,
		    fib_entry_flag_t flags,
		    const fib_route_path_t *rpaths)
{
    fib_source_t best_source;
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(fib_entry_index);
    ASSERT(NULL != fib_entry);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);
    
    fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpaths);

    fib_entry_source_change(fib_entry, best_source, source);

    FIB_ENTRY_DBG(fib_entry, "path add:%U", format_fib_source, source);
}

static fib_entry_src_flag_t
fib_entry_src_burn_only_inherited (fib_entry_t *fib_entry)
{
    fib_entry_src_t *src;
    fib_source_t source;
    int has_only_inherited_sources = 1;

    FOR_EACH_SRC_ADDED(fib_entry, src, source,
    ({
        if (!(src->fes_flags & FIB_ENTRY_SRC_FLAG_INHERITED))
        {
            has_only_inherited_sources = 0;
            break;
        }
    }));
    if (has_only_inherited_sources)
    {
        FOR_EACH_SRC_ADDED(fib_entry, src, source,
        ({
            fib_entry_src_action_remove(fib_entry, source);
        }));
        return (FIB_ENTRY_SRC_FLAG_NONE);
    }
    else
    {
        return (FIB_ENTRY_SRC_FLAG_ADDED);
    }
}

static fib_entry_src_flag_t
fib_entry_source_removed (fib_entry_t *fib_entry,
                          fib_entry_flag_t old_flags)
{
    const fib_entry_src_t *bsrc;
    fib_source_t best_source;

    /*
     * if all that is left are inherited sources, then burn them
     */
    fib_entry_src_burn_only_inherited(fib_entry);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);

    if (FIB_SOURCE_INVALID == best_source)
    {
        /*
         * no more sources left. this entry is toast.
         */
        fib_entry = fib_entry_post_flag_update_actions(fib_entry, old_flags);
        fib_entry_src_action_uninstall(fib_entry);

        return (FIB_ENTRY_SRC_FLAG_NONE);
    }
    else
    {
        fib_entry_src_action_activate(fib_entry, best_source);
    }

    fib_entry_post_update_actions(fib_entry, best_source, old_flags);

    /*
     * still have sources
     */
    return (FIB_ENTRY_SRC_FLAG_ADDED);
}

/*
 * fib_entry_path_remove
 *
 * remove a path from the entry.
 * return the fib_entry's index if it is still present, INVALID otherwise.
 */
fib_entry_src_flag_t
fib_entry_path_remove (fib_node_index_t fib_entry_index,
		       fib_source_t source,
		       const fib_route_path_t *rpaths)
{
    fib_entry_src_flag_t sflag;
    fib_source_t best_source;
    fib_entry_flag_t bflags;
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(fib_entry_index);
    ASSERT(NULL != fib_entry);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);
    bflags = fib_entry_src_get_flags(bsrc);

    sflag = fib_entry_src_action_path_remove(fib_entry, source, rpaths);

    FIB_ENTRY_DBG(fib_entry, "path remove:%U", format_fib_source, source);

    /*
     * if the path list for the source passed is invalid,
     * then we need to create a new one. else we are updating
     * an existing.
     */
    switch (fib_source_cmp(source, best_source))
    {
    case FIB_SOURCE_CMP_BETTER:
	/*
	 * Que! removing a path from a source that is better than the
	 * one this entry is using.
	 */
	ASSERT(0);
        break;
    case FIB_SOURCE_CMP_WORSE:
	/*
	 * the source is not the best. no need to update forwarding
	 */
	if (FIB_ENTRY_SRC_FLAG_ADDED & sflag)
        {
            /*
             * the source being removed still has paths
             */
            return (FIB_ENTRY_SRC_FLAG_ADDED);
        }
        else
        {
            /*
             * that was the last path from this source, check if those
             * that remain are non-inherited
             */
            return (fib_entry_src_burn_only_inherited(fib_entry));
        }
        break;
    case FIB_SOURCE_CMP_EQUAL:
	/*
	 * removing a path from the path-list we were using.
	 */
	if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
	{
	    /*
	     * the last path from the source was removed.
	     * fallback to lower source
	     */
            return (fib_entry_source_removed(fib_entry, bflags));
	}
	else
	{
	    /*
	     * re-install the new forwarding information
	     */
	    fib_entry_src_action_reactivate(fib_entry, source);
	}
        break;
    }

    fib_entry_post_update_actions(fib_entry, source, bflags);

    /*
     * still have sources
     */
    return (FIB_ENTRY_SRC_FLAG_ADDED);
}

/*
 * fib_entry_special_remove
 *
 * remove a special source from the entry.
 * return the fib_entry's index if it is still present, INVALID otherwise.
 */
fib_entry_src_flag_t
fib_entry_special_remove (fib_node_index_t fib_entry_index,
			  fib_source_t source)
{
    fib_entry_src_flag_t sflag;
    fib_source_t best_source;
    fib_entry_flag_t bflags;
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(fib_entry_index);
    ASSERT(NULL != fib_entry);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);
    bflags = fib_entry_src_get_flags(bsrc);

    FIB_ENTRY_DBG(fib_entry, "special remove:%U", format_fib_source, source);

    sflag = fib_entry_src_action_remove_or_update_inherit(fib_entry, source);

    /*
     * if the path list for the source passed is invalid,
     * then we need to create a new one. else we are updating
     * an existing.
     */
    switch (fib_source_cmp(source, best_source))
    {
    case FIB_SOURCE_CMP_BETTER:
	/*
	 * Que! removing a path from a source that is better than the
	 * one this entry is using. This can only mean it is a source
         * this prefix does not have.
	 */
        return (FIB_ENTRY_SRC_FLAG_ADDED);

    case FIB_SOURCE_CMP_WORSE:
	/*
	 * the source is not the best. no need to update forwarding
	 */
	if (FIB_ENTRY_SRC_FLAG_ADDED & sflag)
        {
            /*
             * the source being removed still has paths
             */
            return (FIB_ENTRY_SRC_FLAG_ADDED);
        }
        else
        {
            /*
             * that was the last path from this source, check if those
             * that remain are non-inherited
             */
            if (FIB_ENTRY_SRC_FLAG_NONE == fib_entry_src_burn_only_inherited(fib_entry))
            {
                /*
                 * no more sources left. this entry is toast.
                 */
                fib_entry = fib_entry_post_flag_update_actions(fib_entry, bflags);
                fib_entry_src_action_uninstall(fib_entry);
                return (FIB_ENTRY_SRC_FLAG_NONE);
            }

            /*
             * reactivate the best source so the interposer gets restacked
             */
            fib_entry_src_action_reactivate(fib_entry, best_source);

            return (FIB_ENTRY_SRC_FLAG_ADDED);
        }
        break;

    case FIB_SOURCE_CMP_EQUAL:
	if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
	{
	    /*
	     * the source was removed. use the next best.
	     */
            return (fib_entry_source_removed(fib_entry, bflags));
	}
	else
	{
	    /*
	     * re-install the new forwarding information
	     */
	    fib_entry_src_action_reactivate(fib_entry, source);
	}
        break;
    }

    fib_entry_post_update_actions(fib_entry, source, bflags);

    /*
     * still have sources
     */
    return (FIB_ENTRY_SRC_FLAG_ADDED);
}

/**
 * fib_entry_inherit
 *
 * If the source on the cover is inheriting then push this source
 * down to the covered.
 */
void
fib_entry_inherit (fib_node_index_t cover,
                   fib_node_index_t covered)
{
    fib_entry_src_inherit(fib_entry_get(cover),
                          fib_entry_get(covered));
}

/**
 * fib_entry_delete
 *
 * The source is withdrawing all the paths it provided
 */
fib_entry_src_flag_t
fib_entry_delete (fib_node_index_t fib_entry_index,
		  fib_source_t source)
{
    return (fib_entry_special_remove(fib_entry_index, source));
}

/**
 * fib_entry_update
 *
 * The source has provided a new set of paths that will replace the old.
 */
void
fib_entry_update (fib_node_index_t fib_entry_index,
		  fib_source_t source,
		  fib_entry_flag_t flags,
		  const fib_route_path_t *paths)
{
    fib_source_t best_source;
    fib_entry_flag_t bflags;
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(fib_entry_index);
    ASSERT(NULL != fib_entry);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    best_source = fib_entry_src_get_source(bsrc);
    bflags = fib_entry_get_flags_i(fib_entry);

    fib_entry = fib_entry_src_action_path_swap(fib_entry,
                                               source,
                                               flags,
                                               paths);

    fib_entry_source_change_w_flags(fib_entry, best_source, bflags, source);
    FIB_ENTRY_DBG(fib_entry, "update");
}


/*
 * fib_entry_cover_changed
 *
 * this entry is tracking its cover and that cover has changed.
 */
void
fib_entry_cover_changed (fib_node_index_t fib_entry_index)
{
    fib_entry_src_cover_res_t res = {
	.install = !0,
	.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
    };
    CLIB_UNUSED(fib_source_t source);
    fib_source_t best_source;
    fib_entry_flag_t bflags;
    fib_entry_t *fib_entry;
    fib_entry_src_t *esrc;
    u32 index;

    bflags = FIB_ENTRY_FLAG_NONE;
    best_source = FIB_SOURCE_FIRST;
    fib_entry = fib_entry_get(fib_entry_index);

    fib_attached_export_cover_change(fib_entry);

    /*
     * propagate the notification to each of the added sources
     */
    index = 0;
    FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
    ({
	if (0 == index)
	{
	    /*
	     * only the best source gets to set the back walk flags
	     */
	    res = fib_entry_src_action_cover_change(fib_entry, esrc);
            bflags = fib_entry_src_get_flags(esrc);
            best_source = fib_entry_src_get_source(esrc);
	}
	else
	{
	    fib_entry_src_action_cover_change(fib_entry, esrc);
	}
	index++;
    }));

    if (res.install)
    {
	fib_entry_src_action_reactivate(fib_entry,
					fib_entry_src_get_source(
					    fib_entry_get_best_src_i(fib_entry)));
        fib_entry = fib_entry_post_install_actions(fib_entry,
                                                   best_source,
                                                   bflags);
    }
    else
    {
	fib_entry_src_action_uninstall(fib_entry);
    }

    if (FIB_NODE_BW_REASON_FLAG_NONE != res.bw_reason)
    {
	/*
	 * time for walkies fido.
	 */
	fib_node_back_walk_ctx_t bw_ctx = {
	    .fnbw_reason = res.bw_reason,
        };

	fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
    }
    FIB_ENTRY_DBG(fib_entry, "cover-changed");
}

/*
 * fib_entry_cover_updated
 *
 * this entry is tracking its cover and that cover has been updated
 * (i.e. its forwarding information has changed).
 */
void
fib_entry_cover_updated (fib_node_index_t fib_entry_index)
{
    fib_entry_src_cover_res_t res = {
	.install = !0,
	.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
    };
    CLIB_UNUSED(fib_source_t source);
    fib_source_t best_source;
    fib_entry_flag_t bflags;
    fib_entry_t *fib_entry;
    fib_entry_src_t *esrc;
    u32 index;

    bflags = FIB_ENTRY_FLAG_NONE;
    best_source = FIB_SOURCE_FIRST;
    fib_entry = fib_entry_get(fib_entry_index);

    fib_attached_export_cover_update(fib_entry);

    /*
     * propagate the notification to each of the added sources
     */
    index = 0;
    FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
    ({
	if (0 == index)
	{
	    /*
	     * only the best source gets to set the back walk flags
	     */
	    res = fib_entry_src_action_cover_update(fib_entry, esrc);
            bflags = fib_entry_src_get_flags(esrc);
            best_source = fib_entry_src_get_source(esrc);
	}
	else
	{
	    fib_entry_src_action_cover_update(fib_entry, esrc);
	}
	index++;
    }));

    if (res.install)
    {
	fib_entry_src_action_reactivate(fib_entry,
					fib_entry_src_get_source(
					    fib_entry_get_best_src_i(fib_entry)));
        fib_entry = fib_entry_post_install_actions(fib_entry,
                                                   best_source,
                                                   bflags);
    }
    else
    {
	fib_entry_src_action_uninstall(fib_entry);
    }

    if (FIB_NODE_BW_REASON_FLAG_NONE != res.bw_reason)
    {
	/*
	 * time for walkies fido.
	 */
	fib_node_back_walk_ctx_t bw_ctx = {
	    .fnbw_reason = res.bw_reason,
        };

	fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
    }
    FIB_ENTRY_DBG(fib_entry, "cover-updated");
}

int
fib_entry_recursive_loop_detect (fib_node_index_t entry_index,
				 fib_node_index_t **entry_indicies)
{
    fib_entry_t *fib_entry;
    int was_looped, is_looped;

    fib_entry = fib_entry_get(entry_index);

    if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
    {
	fib_node_index_t *entries = *entry_indicies;

	vec_add1(entries, entry_index);
	was_looped = fib_path_list_is_looped(fib_entry->fe_parent);
	is_looped = fib_path_list_recursive_loop_detect(fib_entry->fe_parent,
							&entries);

	*entry_indicies = entries;

	if (!!was_looped != !!is_looped)
	{
	    /*
	     * re-evaluate all the entry's forwarding
	     * NOTE: this is an inplace modify
	     */
            fib_entry_delegate_type_t fdt;
            fib_entry_delegate_t *fed;

            FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
            {
                fib_entry_src_mk_lb(fib_entry,
                                    fib_entry_get_best_src_i(fib_entry),
                                    fib_entry_delegate_type_to_chain_type(fdt),
                                    &fed->fd_dpo);
	    });
	}
    }
    else
    {
	/*
	 * the entry is currently not linked to a path-list. this happens
	 * when it is this entry that is re-linking path-lists and has thus
	 * broken the loop
	 */
	is_looped = 0;
    }

    return (is_looped);
}

u32
fib_entry_get_resolving_interface (fib_node_index_t entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(entry_index);

    return (fib_path_list_get_resolving_interface(fib_entry->fe_parent));
}

u32
fib_entry_get_any_resolving_interface (fib_node_index_t entry_index)
{
    const fib_entry_src_t *src;
    fib_entry_t *fib_entry;
    fib_source_t source;
    u32 sw_if_index;

    fib_entry = fib_entry_get(entry_index);

    FOR_EACH_SRC_ADDED(fib_entry, src, source,
    ({
        sw_if_index = fib_entry_get_resolving_interface_for_source (entry_index,
                                                                    source);

        if (~0 != sw_if_index)
            break;
    }));
    return (sw_if_index);
}

fib_source_t
fib_entry_get_best_source (fib_node_index_t entry_index)
{
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    fib_entry = fib_entry_get(entry_index);

    bsrc = fib_entry_get_best_src_i(fib_entry);
    return (fib_entry_src_get_source(bsrc));
}

/**
 * Return !0 is the entry represents a host prefix
 */
int
fib_entry_is_host (fib_node_index_t fib_entry_index)
{
    return (fib_prefix_is_host(fib_entry_get_prefix(fib_entry_index)));
}

/**
 * Return !0 is the entry is resolved, i.e. will return a valid forwarding
 * chain
 */
int
fib_entry_is_resolved (fib_node_index_t fib_entry_index)
{
    fib_entry_delegate_t *fed;
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    fed = fib_entry_delegate_find(fib_entry, FIB_ENTRY_DELEGATE_BFD);

    if (NULL == fed)
    {
        /*
         * no BFD tracking - consider it resolved.
         */
        return (!0);
    }
    else
    {
        /*
         * defer to the state of the BFD tracking
         */
        return (FIB_BFD_STATE_UP == fed->fd_bfd_state);
    }
}

void
fib_entry_set_flow_hash_config (fib_node_index_t fib_entry_index,
                                flow_hash_config_t hash_config)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    /*
     * pass the hash-config on to the load-balance object where it is cached.
     * we can ignore LBs in the delegate chains, since they will not be of the
     * correct protocol type (i.e. they are not IP)
     * There's no way, nor need, to change the hash config for MPLS.
     */
    if (dpo_id_is_valid(&fib_entry->fe_lb))
    {
        load_balance_t *lb;

        ASSERT(DPO_LOAD_BALANCE == fib_entry->fe_lb.dpoi_type);

        lb = load_balance_get(fib_entry->fe_lb.dpoi_index);

        /*
         * atomic update for packets in flight
         */
        lb->lb_hash_config = hash_config;
    }
}

u32
fib_entry_get_stats_index (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    return (fib_entry->fe_lb.dpoi_index);
}

static int
fib_ip4_address_compare (const ip4_address_t * a1,
                         const ip4_address_t * a2)
{
    /*
     * IP addresses are unsigned ints. the return value here needs to be signed
     * a simple subtraction won't cut it.
     * If the addresses are the same, the sort order is undefined, so phoey.
     */
    return ((clib_net_to_host_u32(a1->data_u32) >
	     clib_net_to_host_u32(a2->data_u32) ) ?
	    1 : -1);
}

static int
fib_ip6_address_compare (const ip6_address_t * a1,
                         const ip6_address_t * a2)
{
  int i;
  for (i = 0; i < ARRAY_LEN (a1->as_u16); i++)
  {
      int cmp = (clib_net_to_host_u16 (a1->as_u16[i]) -
		 clib_net_to_host_u16 (a2->as_u16[i]));
      if (cmp != 0)
	  return cmp;
  }
  return 0;
}

static int
fib_entry_cmp (fib_node_index_t fib_entry_index1,
	       fib_node_index_t fib_entry_index2)
{
    fib_entry_t *fib_entry1, *fib_entry2;
    int cmp = 0;

    fib_entry1 = fib_entry_get(fib_entry_index1);
    fib_entry2 = fib_entry_get(fib_entry_index2);

    switch (fib_entry1->fe_prefix.fp_proto)
    {
    case FIB_PROTOCOL_IP4:
        cmp = fib_ip4_address_compare(&fib_entry1->fe_prefix.fp_addr.ip4,
                                      &fib_entry2->fe_prefix.fp_addr.ip4);
        break;
    case FIB_PROTOCOL_IP6:
        cmp = fib_ip6_address_compare(&fib_entry1->fe_prefix.fp_addr.ip6,
                                      &fib_entry2->fe_prefix.fp_addr.ip6);
        break;
    case FIB_PROTOCOL_MPLS:
	cmp = (fib_entry1->fe_prefix.fp_label - fib_entry2->fe_prefix.fp_label);

	if (0 == cmp)
	{
	    cmp = (fib_entry1->fe_prefix.fp_eos - fib_entry2->fe_prefix.fp_eos);
	}
        break;
    }

    if (0 == cmp) {
	cmp = (fib_entry1->fe_prefix.fp_len - fib_entry2->fe_prefix.fp_len);
    }
    return (cmp);   
}

int
fib_entry_cmp_for_sort (void *i1, void *i2)
{
    fib_node_index_t *fib_entry_index1 = i1, *fib_entry_index2 = i2;

    return (fib_entry_cmp(*fib_entry_index1,
			  *fib_entry_index2));
}

void
fib_entry_lock (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    fib_node_lock(&fib_entry->fe_node);
}

void
fib_entry_unlock (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    fib_node_unlock(&fib_entry->fe_node);
}

void
fib_entry_module_init (void)
{
    fib_node_register_type(FIB_NODE_TYPE_ENTRY, &fib_entry_vft);
    fib_entry_logger = vlib_log_register_class("fib", "entry");

    fib_entry_track_module_init();
}

fib_route_path_t *
fib_entry_encode (fib_node_index_t fib_entry_index)
{
    fib_path_ext_list_t *ext_list;
    fib_path_encode_ctx_t ctx = {
        .rpaths = NULL,
    };
    fib_entry_t *fib_entry;
    fib_entry_src_t *bsrc;

    ext_list = NULL;
    fib_entry = fib_entry_get(fib_entry_index);
    bsrc = fib_entry_get_best_src_i(fib_entry);

    if (bsrc)
    {
	ext_list = &bsrc->fes_path_exts;
    }

    if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
    {
        fib_path_list_walk_w_ext(fib_entry->fe_parent,
                                 ext_list,
                                 fib_path_encode,
                                 &ctx);
    }

    return (ctx.rpaths);
}

const fib_prefix_t *
fib_entry_get_prefix (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    return (&fib_entry->fe_prefix);
}

u32
fib_entry_get_fib_index (fib_node_index_t fib_entry_index)
{
    fib_entry_t *fib_entry;

    fib_entry = fib_entry_get(fib_entry_index);

    return (fib_entry->fe_fib_index);
}

u32
fib_entry_pool_size (void)
{
    return (pool_elts(fib_entry_pool));
}

#if CLIB_DEBUG > 0
void
fib_table_assert_empty (const fib_table_t *fib_table)
{
    fib_node_index_t *fei, *feis = NULL;
    fib_entry_t *fib_entry;

    pool_foreach (fib_entry, fib_entry_pool,
    ({
        if (fib_entry->fe_fib_index == fib_table->ft_index)
            vec_add1 (feis, fib_entry_get_index(fib_entry));
    }));

    if (vec_len(feis))
    {
        vec_foreach (fei, feis)
            clib_error ("%U", format_fib_entry, *fei, FIB_ENTRY_FORMAT_DETAIL);
    }

    ASSERT(0);
}
#endif

static clib_error_t *
show_fib_entry_command (vlib_main_t * vm,
			unformat_input_t * input,
			vlib_cli_command_t * cmd)
{
    fib_node_index_t fei;

    if (unformat (input, "%d", &fei))
    {
	/*
	 * show one in detail
	 */
	if (!pool_is_free_index(fib_entry_pool, fei))
	{
	    vlib_cli_output (vm, "%d@%U",
			     fei,
			     format_fib_entry, fei,
			     FIB_ENTRY_FORMAT_DETAIL2);
	}
	else
	{
	    vlib_cli_output (vm, "entry %d invalid", fei);
	}
    }
    else
    {
	/*
	 * show all
	 */
	vlib_cli_output (vm, "FIB Entries:");
	pool_foreach_index(fei, fib_entry_pool,
        ({
	    vlib_cli_output (vm, "%d@%U",
			     fei,
			     format_fib_entry, fei,
			     FIB_ENTRY_FORMAT_BRIEF);
	}));
    }

    return (NULL);
}

VLIB_CLI_COMMAND (show_fib_entry, static) = {
  .path = "show fib entry",
  .function = show_fib_entry_command,
  .short_help = "show fib entry",
};
