/*
 * 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 bier_fmask : The BIER fmask
 *
 * The BIER fmask contains the bitString that is applied to packets that
 * egress towards the next-hop. As such the fmask is part of the rewrite
 * (adj) for that next-hop. It it thus an extension of the next-hop and in
 * no way associated with the bit-position(s) that are reachable through it.
 * Fmasks are thus shared by bit-positions that egress through the same
 * nh (BFR-NBR).
 * Deag fmasks are also shared in the event that a router has local
 * bit-positions. This is necessary to prevent the router receiving two copies
 * of each packet. Consequently it also means that they share the same
 * disposition data for the global data.
 */

#ifndef __BIER_FMASK_H__
#define __BIER_FMASK_H__

#include <vlib/vlib.h>

#include <vnet/fib/fib_node.h>
#include <vnet/mpls/packet.h>
#include <vnet/dpo/dpo.h>

#include <vnet/bier/bier_types.h>
#include <vnet/bier/bier_fmask_db.h>

/**
 * A struct that represents the reference counting of the bits
 */
typedef struct bier_fmask_bits_t_ {
    /**
     * each bit in the mask needs to be reference counted
     * and set/cleared on the 0->1 and 1->0 transitions.
     */
    bier_bit_string_t bfmb_input_reset_string;
    u32 *bfmb_refs;

    /**
     * The total number of references to bits set on this mask
     * in effect a count of the number of children.
     */
    u32 bfmb_count;
} bier_fmask_bits_t;

/**
 * Flags on fmask
 */
typedef enum bier_fmask_attributes_t_
{
    BIER_FMASK_ATTR_FIRST,
    BIER_FMASK_ATTR_FORWARDING = BIER_FMASK_ATTR_FIRST,
    BIER_FMASK_ATTR_DISP,
    BIER_FMASK_ATTR_MPLS,
    BIER_FMASK_ATTR_LAST = BIER_FMASK_ATTR_DISP,
} bier_fmask_attributes_t;

#define BIER_FMASK_ATTR_NAMES {                         \
     [BIER_FMASK_ATTR_FORWARDING] = "forwarding",       \
     [BIER_FMASK_ATTR_DISP] = "disposition",            \
     [BIER_FMASK_ATTR_MPLS] = "mpls",                   \
}

#define FOR_EACH_BIER_FMASK_ATTR(_item)          \
    for (_item =  BIER_FMASK_ATTR_FIRST;         \
         _item <= BIER_FMASK_ATTR_LAST;          \
         _item++)

typedef enum bier_fmask_flags_t_
{
    BIER_FMASK_FLAG_FORWARDING = (1 << BIER_FMASK_ATTR_FORWARDING),
    BIER_FMASK_FLAG_DISP = (1 << BIER_FMASK_ATTR_DISP),
    BIER_FMASK_FLAG_MPLS = (1 << BIER_FMASK_ATTR_MPLS),
} bier_fmask_flags_t;

/**
 * An outgoing BIER mask. aka forwarding bit mask (in the RFCs)
 *
 * This mask's function is two-fold
 *  1 - it is logical-AND with the input packet header to produce the
 *      output packet header
 *  2 - it is logical NAND with the input packet header to modify the bit-mask
 *      for the next lookup
 */
typedef struct bier_fmask_t_ {
    /**
     * Required for pool_get_aligned
     */
    CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);

    /**
     * The BIER fmask is a child of a FIB entry in the FIB graph.
     */
    fib_node_t bfm_node;

    /**
     * operational/state flags on the fmask
     */
    bier_fmask_flags_t bfm_flags;

    /**
     * The bits, and their ref counts, that are set on this mask
     * This mask changes as BIER entries link to and from this fmask
     */
    bier_fmask_bits_t bfm_bits;

    /**
     * The key to this fmask - used for store/lookup in the DB
     */
    bier_fmask_id_t *bfm_id;

    /**
     * The MPLS label to paint on the header during forwarding
     */
    mpls_label_t bfm_label;

    /**
     * The path-list
     */
    fib_node_index_t bfm_pl;

    /**
     * the index of this fmask in the parent's child list.
     */
    u32 bfm_sibling;

    /**
     * The index into the adj table for the adj that
     * this fmask resolves via
     */
    dpo_id_t bfm_dpo;
} bier_fmask_t;

extern void bier_fmask_link(index_t bfmi, bier_bp_t bp);
extern void bier_fmask_unlink(index_t bfmi, bier_bp_t bp);
extern void bier_fmask_unlock(index_t bfmi);
extern void bier_fmask_lock(index_t bfmi);

extern index_t bier_fmask_create_and_lock(const bier_fmask_id_t *fmid,
                                          const fib_route_path_t *rpath);

extern u8* format_bier_fmask(u8 *s, va_list *ap);

extern void bier_fmask_contribute_forwarding(index_t bfmi,
                                             dpo_id_t *dpo);

extern u32 bier_fmask_child_add (fib_node_index_t fib_entry_index,
                                 fib_node_type_t child_type,
                                 fib_node_index_t child_index);
extern void bier_fmask_child_remove (fib_node_index_t fib_entry_index,
                                     u32 sibling_index);
extern void bier_fmask_get_stats (index_t bfmi, u64 * packets, u64 * bytes);
extern void bier_fmask_encode (index_t bfmi,
                               bier_table_id_t *btid,
                               fib_route_path_encode_t *rpath);

/*
 * provided for fast data-path access
 */
extern bier_fmask_t *bier_fmask_pool;

static inline bier_fmask_t *
bier_fmask_get (u32 index)
{
    return (pool_elt_at_index(bier_fmask_pool, index));
}

#endif
