/*
 * 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/ip/ip.h>
#include <vnet/dpo/classify_dpo.h>
#include <vnet/mpls/mpls.h>

/*
 * pool of all MPLS Label DPOs
 */
classify_dpo_t *classify_dpo_pool;

static classify_dpo_t *
classify_dpo_alloc (void)
{
    classify_dpo_t *cd;
    vlib_main_t *vm;
    u8 did_barrier_sync;

    dpo_pool_barrier_sync (vm, classify_dpo_pool, did_barrier_sync);
    pool_get_aligned(classify_dpo_pool, cd, CLIB_CACHE_LINE_BYTES);
    dpo_pool_barrier_release (vm, did_barrier_sync);

    clib_memset(cd, 0, sizeof(*cd));

    return (cd);
}

static index_t
classify_dpo_get_index (classify_dpo_t *cd)
{
    return (cd - classify_dpo_pool);
}

index_t
classify_dpo_create (dpo_proto_t proto,
                     u32 classify_table_index)
{
    classify_dpo_t *cd;

    cd = classify_dpo_alloc();
    cd->cd_proto = proto;
    cd->cd_table_index = classify_table_index;

    return (classify_dpo_get_index(cd));
}

u8*
format_classify_dpo (u8 *s, va_list *args)
{
    index_t index = va_arg (*args, index_t);
    CLIB_UNUSED(u32 indent) = va_arg (*args, u32);
    classify_dpo_t *cd;

    cd = classify_dpo_get(index);

    return (format(s, "%U-classify:[%d]:table:%d",
		   format_dpo_proto, cd->cd_proto,
		   index, cd->cd_table_index));
}

static void
classify_dpo_lock (dpo_id_t *dpo)
{
    classify_dpo_t *cd;

    cd = classify_dpo_get(dpo->dpoi_index);

    cd->cd_locks++;
}

static void
classify_dpo_unlock (dpo_id_t *dpo)
{
    classify_dpo_t *cd;

    cd = classify_dpo_get(dpo->dpoi_index);

    cd->cd_locks--;

    if (0 == cd->cd_locks)
    {
	pool_put(classify_dpo_pool, cd);
    }
}

static void
classify_dpo_mem_show (void)
{
    fib_show_memory_usage("Classify",
			  pool_elts(classify_dpo_pool),
			  pool_len(classify_dpo_pool),
			  sizeof(classify_dpo_t));
}

const static dpo_vft_t cd_vft = {
    .dv_lock = classify_dpo_lock,
    .dv_unlock = classify_dpo_unlock,
    .dv_format = format_classify_dpo,
    .dv_mem_show = classify_dpo_mem_show,
};

const static char* const classify_ip4_nodes[] =
{
    "ip4-classify",
    NULL,
};
const static char* const classify_ip6_nodes[] =
{
    "ip6-classify",
    NULL,
};
const static char* const * const classify_nodes[DPO_PROTO_NUM] =
{
    [DPO_PROTO_IP4]  = classify_ip4_nodes,
    [DPO_PROTO_IP6]  = classify_ip6_nodes,
    [DPO_PROTO_MPLS] = NULL,
};

void
classify_dpo_module_init (void)
{
    dpo_register(DPO_CLASSIFY, &cd_vft, classify_nodes);
}
