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

#include <vlib/vlib.h>
#include <vnet/fib/fib_types.h>
#include <vnet/bier/bier_types.h>
#include <vnet/bier/bier_entry.h>

#include <vnet/dpo/dpo.h>

/**
 * Forward declarations
 */
struct bier_route_update_t_;

/**
 * A BIER Table is the bit-indexed forwarding table.
 * Each entry (bit-position) represents one destination, and its reachability
 *
 * The number of entries in a table is thus the maximum supported
 * bit-position. Since this is smal <4096, the table is a flat arry
 */
typedef struct bier_table_t_ {
    /**
     * required for pool_get_aligned.
     *  memebers used in the switch path come first!
     */
    CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);

    /**
     * Save the MPLS local label associated with the table
     */
    mpls_label_t bt_ll;

    /**
     * The path-list used for the ECMP-tables
     */
    fib_node_index_t bt_pl;

    /**
     * The index of the lfib entry created for this table.
     * Only the EOS is required.
     */
    fib_node_index_t bt_lfei;

    /**
     * Number of locks on the table
     */
    u16 bt_locks;

    /**
     * Entries in the table
     * This is a vector sized to the appropriate number of entries
     * given the table's supported Bit-string length
     */
    index_t *bt_entries;

    /**
     * The identity/key or the table. we need the hdr_len in the data-path
     */
    bier_table_id_t bt_id;

    /**
     * f-masks in the ECMP table
     * This is a vector sized to the appropriate number of entries
     * given the table's supported Bit-string length.
     * In the ECMP table the LB choice has been pre-resolved, so each entry
     * links to just one f-mask, i.e. there is a 1:1 mapping of bit-position to
     * fmask. For efficient forwarding we collapse the fmasks up to the table.
     */
    index_t *bt_fmasks;
} bier_table_t;

STATIC_ASSERT((sizeof(bier_table_t) <= 2*CLIB_CACHE_LINE_BYTES),
              "BIER table fits on 2 cache lines");

extern index_t bier_table_add_or_lock(const bier_table_id_t *id,
                                      mpls_label_t ll);
extern index_t bier_table_lock(const bier_table_id_t *id);
extern void bier_table_unlock(const bier_table_id_t *id);

extern void bier_table_route_path_add(const bier_table_id_t *bti,
                                      bier_bp_t bp,
                                      fib_route_path_t *brp);
extern void bier_table_route_path_remove(const bier_table_id_t *bti,
                                         bier_bp_t bp,
                                         fib_route_path_t *brp);
extern void bier_table_route_path_update(const bier_table_id_t *bti,
                                         bier_bp_t bp,
                                         fib_route_path_t *brp);
extern void bier_table_route_delete(const bier_table_id_t *bti,
                                    bier_bp_t b);

extern void bier_table_show_all(vlib_main_t * vm,
                                bier_show_flags_t flags);

extern const bier_table_id_t *bier_table_get_id(index_t bti);

extern u8 *format_bier_table (u8 *s, va_list *args);
extern u8 *format_bier_table_entry (u8 *s, va_list *args);

extern index_t bier_table_ecmp_create_and_lock(const bier_table_id_t *id);
extern void bier_table_ecmp_unlock(index_t bti);
extern void bier_table_ecmp_set_fmask(index_t bti,
                                      bier_bp_t bp,
                                      index_t bfmi);

extern void bier_table_contribute_forwarding(index_t bti,
                                             dpo_id_t *dpo);

/**
 * Types and functions to walk the ECMP tables of a main table
 */
typedef void (*bier_table_ecmp_walk_fn_t)(index_t btei,
                                          void *ctx);
extern void bier_table_ecmp_walk(index_t bti,
                                 bier_table_ecmp_walk_fn_t fn,
                                 void *ctx);
extern int bier_table_is_main (const bier_table_t *bt);

/**
 * Types and functions to walk all the BIER Tables
 */
typedef void (*bier_tables_walk_fn_t)(const bier_table_t *bt,
                                      void *ctx);
extern void bier_tables_walk(bier_tables_walk_fn_t fn,
                             void *ctx);

/**
 * Types and functions to walk all the entries in one BIER Table
 */
typedef void (*bier_table_walk_fn_t)(const bier_table_t *bt,
                                     const bier_entry_t *be,
                                     void *ctx);
extern void bier_table_walk(const bier_table_id_t *id,
                            bier_table_walk_fn_t fn,
                            void *ctx);

/*
 * provided for fast data plane access.
 */
extern bier_table_t *bier_table_pool;

static inline bier_table_t *
bier_table_get (index_t bti)
{
    return (pool_elt_at_index(bier_table_pool, bti));
}

static inline const index_t
bier_table_lookup (const bier_table_t *bt,
                   bier_bp_t bp)
{
    return (bt->bt_entries[BIER_BP_TO_INDEX(bp)]);
}

static inline const index_t
bier_table_fwd_lookup (const bier_table_t *bt,
                       bier_bp_t bp)
{
    return (bt->bt_fmasks[BIER_BP_TO_INDEX(bp)]);
}

#endif
