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

#include <vnet/dpo/interface_dpo.h>
#include <vnet/fib/fib_node.h>

/*
 * The 'DB' of interface DPOs.
 * There is only one  per-interface per-protocol, so this is a per-interface
 * vector
 */
static index_t *interface_dpo_db[DPO_PROTO_NUM];

static interface_dpo_t *
interface_dpo_alloc (void)
{
    interface_dpo_t *ido;

    pool_get(interface_dpo_pool, ido);

    return (ido);
}

static inline interface_dpo_t *
interface_dpo_get_from_dpo (const dpo_id_t *dpo)
{
    ASSERT(DPO_INTERFACE == dpo->dpoi_type);

    return (interface_dpo_get(dpo->dpoi_index));
}

static inline index_t
interface_dpo_get_index (interface_dpo_t *ido)
{
    return (ido - interface_dpo_pool);
}

static void
interface_dpo_lock (dpo_id_t *dpo)
{
    interface_dpo_t *ido;

    ido = interface_dpo_get_from_dpo(dpo);
    ido->ido_locks++;
}

static void
interface_dpo_unlock (dpo_id_t *dpo)
{
    interface_dpo_t *ido;

    ido = interface_dpo_get_from_dpo(dpo);
    ido->ido_locks--;

    if (0 == ido->ido_locks)
    {
	interface_dpo_db[ido->ido_proto][ido->ido_sw_if_index] =
            INDEX_INVALID;
        pool_put(interface_dpo_pool, ido);
    }
}

/*
 * interface_dpo_add_or_lock
 *
 * Add/create and lock a new or lock an existing for the interface DPO
 * on the interface and protocol given
 */
void
interface_dpo_add_or_lock (dpo_proto_t proto,
                           u32 sw_if_index,
                           dpo_id_t *dpo)
{
    interface_dpo_t *ido;

    vec_validate_init_empty(interface_dpo_db[proto],
                            sw_if_index,
                            INDEX_INVALID);

    if (INDEX_INVALID == interface_dpo_db[proto][sw_if_index])
    {
	ido = interface_dpo_alloc();

        ido->ido_sw_if_index = sw_if_index;
        ido->ido_proto = proto;

	interface_dpo_db[proto][sw_if_index] =
            interface_dpo_get_index(ido);
    }
    else
    {
	ido = interface_dpo_get(interface_dpo_db[proto][sw_if_index]);
    }

    dpo_set(dpo, DPO_INTERFACE, proto, interface_dpo_get_index(ido));
}


static clib_error_t *
interface_dpo_interface_state_change (vnet_main_t * vnm,
                                      u32 sw_if_index,
                                      u32 flags)
{
    /*
     */
    return (NULL);
}

VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(
    interface_dpo_interface_state_change);

/**
 * @brief Registered callback for HW interface state changes
 */
static clib_error_t *
interface_dpo_hw_interface_state_change (vnet_main_t * vnm,
                                         u32 hw_if_index,
                                         u32 flags)
{
    return (NULL);
}

VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(
    interface_dpo_hw_interface_state_change);

static clib_error_t *
interface_dpo_interface_delete (vnet_main_t * vnm,
                                u32 sw_if_index,
                                u32 is_add)
{
    return (NULL);
}

VNET_SW_INTERFACE_ADD_DEL_FUNCTION(
    interface_dpo_interface_delete);

u8*
format_interface_dpo (u8* s, va_list *ap)
{
    index_t index = va_arg(*ap, index_t);
    CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
    vnet_main_t * vnm = vnet_get_main();
    interface_dpo_t *ido = interface_dpo_get(index);

    return (format(s, "%U-dpo: %U",
                   format_vnet_sw_interface_name,
                   vnm,
                   vnet_get_sw_interface(vnm, ido->ido_sw_if_index),
                   format_dpo_proto, ido->ido_proto));
}

static void
interface_dpo_mem_show (void)
{
    fib_show_memory_usage("Interface",
			  pool_elts(interface_dpo_pool),
			  pool_len(interface_dpo_pool),
			  sizeof(interface_dpo_t));
}


const static dpo_vft_t interface_dpo_vft = {
    .dv_lock = interface_dpo_lock,
    .dv_unlock = interface_dpo_unlock,
    .dv_format = format_interface_dpo,
    .dv_mem_show = interface_dpo_mem_show,
};

/**
 * @brief The per-protocol VLIB graph nodes that are assigned to a glean
 *        object.
 *
 * this means that these graph nodes are ones from which a glean is the
 * parent object in the DPO-graph.
 */
const static char* const interface_dpo_ip4_nodes[] =
{
    "interface-dpo-ip4",
    NULL,
};
const static char* const interface_dpo_ip6_nodes[] =
{
    "interface-dpo-ip4",
    NULL,
};

const static char* const * const interface_dpo_nodes[DPO_PROTO_NUM] =
{
    [DPO_PROTO_IP4]  = interface_dpo_ip4_nodes,
    [DPO_PROTO_IP6]  = interface_dpo_ip6_nodes,
    [DPO_PROTO_MPLS] = NULL,
};

void
interface_dpo_module_init (void)
{
    dpo_register(DPO_INTERFACE,
                 &interface_dpo_vft,
                 interface_dpo_nodes);
}

/**
 * @brief Interface DPO trace data
 */
typedef struct interface_dpo_trace_t_
{
    u32 sw_if_index;
} interface_dpo_trace_t;

typedef enum interface_dpo_next_t_
{
    INTERFACE_DPO_DROP = 0,
    INTERFACE_DPO_INPUT = 1,
} interface_dpo_next_t;

always_inline uword
interface_dpo_inline (vlib_main_t * vm,
                      vlib_node_runtime_t * node,
                      vlib_frame_t * from_frame)
{
    u32 n_left_from, next_index, * from, * to_next;
    u32 thread_index = vlib_get_thread_index ();
    vnet_interface_main_t *im;

    im = &vnet_get_main ()->interface_main;
    from = vlib_frame_vector_args (from_frame);
    n_left_from = from_frame->n_vectors;

    next_index = node->cached_next_index;

    while (n_left_from > 0)
    {
        u32 n_left_to_next;

        vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);

	while (n_left_from >= 4 && n_left_to_next > 2)
	{
	    const interface_dpo_t *ido0, *ido1;
	    u32 bi0, idoi0, bi1, idoi1;
	    vlib_buffer_t *b0, *b1;

	    bi0 = from[0];
	    to_next[0] = bi0;
	    bi1 = from[1];
	    to_next[1] = bi1;
	    from += 2;
	    to_next += 2;
	    n_left_from -= 2;
	    n_left_to_next -= 2;

	    b0 = vlib_get_buffer (vm, bi0);
	    b1 = vlib_get_buffer (vm, bi1);

	    idoi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
	    idoi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
	    ido0 = interface_dpo_get(idoi0);
	    ido1 = interface_dpo_get(idoi1);

	    vnet_buffer(b0)->sw_if_index[VLIB_RX] = ido0->ido_sw_if_index;
	    vnet_buffer(b1)->sw_if_index[VLIB_RX] = ido1->ido_sw_if_index;

            vlib_increment_combined_counter (im->combined_sw_if_counters
                                             + VNET_INTERFACE_COUNTER_RX,
                                             thread_index,
                                             ido0->ido_sw_if_index,
                                             1,
                                             vlib_buffer_length_in_chain (vm, b0));
            vlib_increment_combined_counter (im->combined_sw_if_counters
                                             + VNET_INTERFACE_COUNTER_RX,
                                             thread_index,
                                             ido1->ido_sw_if_index,
                                             1,
                                             vlib_buffer_length_in_chain (vm, b1));

	    if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
		interface_dpo_trace_t *tr0;

                tr0 = vlib_add_trace (vm, node, b0, sizeof (*tr0));
		tr0->sw_if_index = ido0->ido_sw_if_index;
	    }
	    if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
		interface_dpo_trace_t *tr1;

                tr1 = vlib_add_trace (vm, node, b1, sizeof (*tr1));
		tr1->sw_if_index = ido1->ido_sw_if_index;
	    }

	    vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
					    n_left_to_next, bi0, bi1,
                                            INTERFACE_DPO_INPUT,
                                            INTERFACE_DPO_INPUT);
	}

	while (n_left_from > 0 && n_left_to_next > 0)
	{
	    const interface_dpo_t * ido0;
	    vlib_buffer_t * b0;
	    u32 bi0, idoi0;

	    bi0 = from[0];
	    to_next[0] = bi0;
	    from += 1;
	    to_next += 1;
	    n_left_from -= 1;
	    n_left_to_next -= 1;

	    b0 = vlib_get_buffer (vm, bi0);

	    idoi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
	    ido0 = interface_dpo_get(idoi0);

            /* Swap the RX interface of the packet to the one the
             * interface DPR represents */
	    vnet_buffer(b0)->sw_if_index[VLIB_RX] = ido0->ido_sw_if_index;

            /* Bump the interface's RX coutners */
            vlib_increment_combined_counter (im->combined_sw_if_counters
                                             + VNET_INTERFACE_COUNTER_RX,
                                             thread_index,
                                             ido0->ido_sw_if_index,
                                             1,
                                             vlib_buffer_length_in_chain (vm, b0));

	    if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
		interface_dpo_trace_t *tr;

                tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
		tr->sw_if_index = ido0->ido_sw_if_index;
	    }

	    vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
					    n_left_to_next, bi0,
                                            INTERFACE_DPO_INPUT);
	}
        vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }
    return from_frame->n_vectors;
}

static u8 *
format_interface_dpo_trace (u8 * s, va_list * args)
{
    CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
    CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
    interface_dpo_trace_t * t = va_arg (*args, interface_dpo_trace_t *);
    uword indent = format_get_indent (s);
    s = format (s, "%U sw_if_index:%d",
                format_white_space, indent,
                t->sw_if_index);
    return s;
}

static uword
interface_dpo_ip4 (vlib_main_t * vm,
                   vlib_node_runtime_t * node,
                   vlib_frame_t * from_frame)
{
    return (interface_dpo_inline(vm, node, from_frame));
}

static uword
interface_dpo_ip6 (vlib_main_t * vm,
                   vlib_node_runtime_t * node,
                   vlib_frame_t * from_frame)
{
    return (interface_dpo_inline(vm, node, from_frame));
}

VLIB_REGISTER_NODE (interface_dpo_ip4_node) = {
    .function = interface_dpo_ip4,
    .name = "interface-dpo-ip4",
    .vector_size = sizeof (u32),
    .format_trace = format_interface_dpo_trace,

    .n_next_nodes = 2,
    .next_nodes = {
        [INTERFACE_DPO_DROP] = "ip4-drop",
        [INTERFACE_DPO_INPUT] = "ip4-input",
    },
};

VLIB_NODE_FUNCTION_MULTIARCH (interface_dpo_ip4_node,
                              interface_dpo_ip4)

VLIB_REGISTER_NODE (interface_dpo_ip6_node) = {
    .function = interface_dpo_ip6,
    .name = "interface-dpo-ip6",
    .vector_size = sizeof (u32),
    .format_trace = format_interface_dpo_trace,

    .n_next_nodes = 2,
    .next_nodes = {
        [INTERFACE_DPO_DROP] = "ip6-drop",
        [INTERFACE_DPO_INPUT] = "ip6-input",
    },
};

VLIB_NODE_FUNCTION_MULTIARCH (interface_dpo_ip6_node,
                              interface_dpo_ip6)

