/*
 * 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 __MFIB_ENTRY_H__
#define __MFIB_ENTRY_H__

#include <vnet/fib/fib_node.h>
#include <vnet/mfib/mfib_types.h>
#include <vnet/mfib/mfib_itf.h>
#include <vnet/ip/ip.h>
#include <vnet/dpo/dpo.h>

/**
 * An entry in a FIB table.
 *
 * This entry represents a route added to the FIB that is stored
 * in one of the FIB tables.
 */
typedef struct mfib_entry_t_ {
    CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
    /**
     * Base class. The entry's node representation in the graph.
     */
    fib_node_t mfe_node;
    /**
     * The prefix of the route
     */
    mfib_prefix_t mfe_prefix;
    /**
     * The index of the FIB table this entry is in
     */
    u32 mfe_fib_index;
    /**
     * the path-list for which this entry is a child. This is also the path-list
     * that is contributing forwarding for this entry.
     */
    fib_node_index_t mfe_parent;
    /**
     * index of this entry in the parent's child list.
     * This is set when this entry is added as a child, but can also
     * be changed by the parent as it manages its list.
     */
    u32 mfe_sibling;

    /**
     * A vector of sources contributing forwarding
     */
    struct mfib_entry_src_t_ *mfe_srcs;

    /**
     * 2nd cache line has the members used in the data plane
     */
    CLIB_CACHE_LINE_ALIGN_MARK(cacheline1);

    /**
     * The Replicate used for forwarding.
     */
    dpo_id_t mfe_rep;

    /**
     * Route flags
     */
    mfib_entry_flags_t mfe_flags;

    /**
     * A hash table of interfaces
     */
    mfib_itf_t *mfe_itfs;
} mfib_entry_t;

#define MFIB_ENTRY_FORMAT_BRIEF   (0x0)
#define MFIB_ENTRY_FORMAT_DETAIL  (0x1)
#define MFIB_ENTRY_FORMAT_DETAIL2 (0x2)

extern u8 *format_mfib_entry(u8 * s, va_list * args);


extern fib_node_index_t mfib_entry_create(u32 fib_index,
                                          mfib_source_t source,
                                          const mfib_prefix_t *prefix,
                                          mfib_entry_flags_t entry_flags);

extern int mfib_entry_update(fib_node_index_t fib_entry_index,
                             mfib_source_t source,
                             mfib_entry_flags_t entry_flags);

extern void mfib_entry_path_update(fib_node_index_t fib_entry_index,
                                   mfib_source_t source,
                                   const fib_route_path_t *rpath,
                                   mfib_itf_flags_t itf_flags);


extern int mfib_entry_path_remove(fib_node_index_t fib_entry_index,
                                  mfib_source_t source,
                                  const fib_route_path_t *rpath);

extern int mfib_entry_delete(fib_node_index_t mfib_entry_index,
                             mfib_source_t source);

extern int mfib_entry_cmp_for_sort(void *i1, void *i2);

extern u32 mfib_entry_child_add(fib_node_index_t mfib_entry_index,
                                fib_node_type_t type,
                                fib_node_index_t child_index);
extern void mfib_entry_child_remove(fib_node_index_t mfib_entry_index,
                                    u32 sibling_index);

extern void mfib_entry_lock(fib_node_index_t fib_entry_index);
extern void mfib_entry_unlock(fib_node_index_t fib_entry_index);

extern void mfib_entry_get_prefix(fib_node_index_t fib_entry_index,
                                  mfib_prefix_t *pfx);
extern u32 mfib_entry_get_fib_index(fib_node_index_t fib_entry_index);

extern void mfib_entry_contribute_forwarding(
    fib_node_index_t mfib_entry_index,
    fib_forward_chain_type_t type,
    dpo_id_t *dpo);

extern void mfib_entry_module_init(void);


extern mfib_entry_t *mfib_entry_pool;

static inline mfib_entry_t *
mfib_entry_get (fib_node_index_t index)
{
    return (pool_elt_at_index(mfib_entry_pool, index));
}
static inline fib_node_index_t
mfib_entry_get_index (const mfib_entry_t *mfe)
{
    return (mfe - mfib_entry_pool);
}


static inline mfib_itf_t *
mfib_entry_itf_find (mfib_itf_t *itfs,
                     u32 sw_if_index)
{
    uword *p;

    p = hash_get(itfs, sw_if_index);

    if (NULL != p)
    {
        return (mfib_itf_get(p[0]));
    }

    return (NULL);
}

static inline mfib_itf_t *
mfib_entry_get_itf (const mfib_entry_t *mfe,
                    u32 sw_if_index)
{
    return (mfib_entry_itf_find(mfe->mfe_itfs, sw_if_index));
}

#endif
