/*
 * 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 throught the same
 * nh (BFR-NBR).
 * Deag fmasks are also shread in the event that a router has local
 * bit-positions. This is necessary to prevent the router recieving 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
