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

#ifndef __REPLICATE_DPO_H__
#define __REPLICATE_DPO_H__

#include <vlib/vlib.h>
#include <vnet/ip/lookup.h>
#include <vnet/dpo/dpo.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/fib/fib_types.h>
#include <vnet/mpls/mpls_types.h>

/**
 * replicate main
 */
typedef struct replicate_main_t_
{
    vlib_combined_counter_main_t repm_counters;

    /* per-cpu vector of cloned packets */
    u32 **clones;
} replicate_main_t;

extern replicate_main_t replicate_main;

/**
 * The number of buckets that a load-balance object can have and still
 * fit in one cache-line
 */
#define REP_NUM_INLINE_BUCKETS 4

/**
 * Flags on the replicate DPO
 */
typedef enum replicate_flags_t_
{
    REPLICATE_FLAGS_NONE,
    REPLICATE_FLAGS_HAS_LOCAL,
} __clib_packed replicate_flags_t;

/**
 * The FIB DPO provieds;
 *  - load-balancing over the next DPOs in the chain/graph
 *  - per-route counters
 */
typedef struct replicate_t_ {
    /**
     * required for pool_get_aligned.
     *  memebers used in the switch path come first!
     */
    CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);

    /**
     * number of buckets in the replicate.
     */
    u16 rep_n_buckets;

   /**
     * The protocol of packets that traverse this REP.
     * need in combination with the flow hash config to determine how to hash.
     * u8.
     */
    dpo_proto_t rep_proto;

    /**
     * Flags specifying the replicate properties/behaviour
     */
    replicate_flags_t rep_flags;

    /**
     * The number of locks, which is approximately the number of users,
     * of this load-balance.
     * Load-balance objects of via-entries are heavily shared by recursives,
     * so the lock count is a u32.
     */
    u32 rep_locks;

    /**
     * Vector of buckets containing the next DPOs, sized as repo_num
     */
    dpo_id_t *rep_buckets;

    /**
     * The rest of the cache line is used for buckets. In the common case
     * where there there are less than 4 buckets, then the buckets are
     * on the same cachlie and we save ourselves a pointer dereferance in 
     * the data-path.
     */
    dpo_id_t rep_buckets_inline[REP_NUM_INLINE_BUCKETS];
} replicate_t;

STATIC_ASSERT(sizeof(replicate_t) <= CLIB_CACHE_LINE_BYTES,
	      "A replicate object size exceeds one cacheline");

/**
 * Flags controlling load-balance formatting/display
 */
typedef enum replicate_format_flags_t_ {
    REPLICATE_FORMAT_NONE,
    REPLICATE_FORMAT_DETAIL = (1 << 0),
} replicate_format_flags_t;

extern index_t replicate_create(u32 num_buckets,
                                dpo_proto_t rep_proto);
extern void replicate_multipath_update(
    const dpo_id_t *dpo,
    load_balance_path_t *next_hops);

extern void replicate_set_bucket(index_t repi,
                                 u32 bucket,
                                 const dpo_id_t *next);

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

extern const dpo_id_t *replicate_get_bucket(index_t repi,
                                            u32 bucket);
extern int replicate_is_drop(const dpo_id_t *dpo);

extern u16 replicate_n_buckets(index_t repi);

extern index_t replicate_dup(replicate_flags_t flags,
                             index_t repi);

/**
 * The encapsulation breakages are for fast DP access
 */
extern replicate_t *replicate_pool;
static inline replicate_t*
replicate_get (index_t repi)
{
    repi &= ~MPLS_IS_REPLICATE;
    return (pool_elt_at_index(replicate_pool, repi));
}

#define REP_HAS_INLINE_BUCKETS(_rep)		\
    ((_rep)->rep_n_buckets <= REP_NUM_INLINE_BUCKETS)

static inline const dpo_id_t *
replicate_get_bucket_i (const replicate_t *rep,
			   u32 bucket)
{
    ASSERT(bucket < rep->rep_n_buckets);

    if (PREDICT_TRUE(REP_HAS_INLINE_BUCKETS(rep)))
    {
	return (&rep->rep_buckets_inline[bucket]);
    }
    else
    {
	return (&rep->rep_buckets[bucket]);
    }
}

extern void replicate_module_init(void);

#endif
